Skip to content

Commit

Permalink
Changed e2e to use the API
Browse files Browse the repository at this point in the history
- Changed the e2e tests to use the API instead of pkg for interactions
- Changed the e2e tests also to use sqlite instead of redis

Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com>
  • Loading branch information
neilnaveen committed Nov 18, 2024
1 parent a79071d commit a0c27a7
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 92 deletions.
8 changes: 4 additions & 4 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const (
func (o *options) AddFlags(cmd *cobra.Command) {
cmd.Flags().Int32Var(&o.concurrency, "concurrency", defaultConcurrency, "Maximum number of concurrent operations for leaderboard operations")
cmd.Flags().StringVar(&o.addr, "addr", defaultAddr, "Network address and port for the server (e.g. localhost:8089)")
cmd.Flags().StringVar(&o.StorageType, "storage-type", redisStorageType, "Type of storage to use (e.g., redis, sqlite)")
cmd.Flags().StringVar(&o.StorageAddr, "storage-addr", "localhost:6379", "Address for storage backend")
cmd.Flags().StringVar(&o.StorageType, "storage-type", sqliteStorageType, "Type of storage to use (e.g., redis, sqlite)")
cmd.Flags().StringVar(&o.StorageAddr, "storage-addr", "localhost:6379", "Address for redis storage backend")
cmd.Flags().StringVar(&o.StoragePath, "storage-path", "", "Path to the SQLite database file")
cmd.Flags().BoolVar(&o.UseInMemory, "use-in-memory", true, "Use in-memory SQLite database")
}
Expand All @@ -57,7 +57,7 @@ func (o *options) ProvideStorage() (graph.Storage, error) {
}
}

func (o *options) Run(cmd *cobra.Command, args []string) error {
func (o *options) Run(_ *cobra.Command, _ []string) error {

Check warning on line 60 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L60

Added line #L60 was not covered by tests
var err error
o.storage, err = o.ProvideStorage()
if err != nil {
Expand All @@ -71,7 +71,7 @@ func (o *options) Run(cmd *cobra.Command, args []string) error {
return o.startServer(server)
}

func (o *options) PersistentPreRunE(cmd *cobra.Command, args []string) error {
func (o *options) PersistentPreRunE(_ *cobra.Command, _ []string) error {
if o.StorageType != redisStorageType && o.StorageType != sqliteStorageType {
return fmt.Errorf("invalid storage-type %q: must be one of [redis, sqlite]", o.StorageType)
}
Expand Down
111 changes: 71 additions & 40 deletions pkg/storages/e2e_test.go → e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
package storages
package e2e

import (
"context"
"os"
"path/filepath"
"strings"
"testing"

"github.com/bitbomdev/minefield/pkg/graph"
"github.com/bitbomdev/minefield/pkg/tools/ingest"
"connectrpc.com/connect"
apiv1 "github.com/bitbomdev/minefield/api/v1"
service "github.com/bitbomdev/minefield/gen/api/v1"
"github.com/bitbomdev/minefield/pkg/storages"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/types/known/emptypb"
)

func TestParseAndExecute_E2E(t *testing.T) {
if _, ok := os.LookupEnv("e2e"); !ok {
t.Skip("E2E tests are not enabled")
//if _, ok := os.LookupEnv("e2e"); !ok {
// t.Skip("E2E tests are not enabled")
//}
testDBPath := "test_e2e.db"
sqlite, err := storages.SetupSQLTestDB(testDBPath)
if err != nil {
t.Fatal(err)
}
redisStorage := setupTestRedis()
defer os.Remove(testDBPath) // Clean up after the test

sbomPath := filepath.Join("..", "..", "testdata", "sboms")
vulnsPath := filepath.Join("..", "..", "testdata", "osv-vulns")
s := apiv1.NewService(sqlite, 1)

sbomPath := filepath.Join("..", "testdata", "sboms")
vulnsPath := filepath.Join("..", "testdata", "osv-vulns")

// Process SBOM files
sbomFiles, err := os.ReadDir(sbomPath)
Expand All @@ -32,10 +43,11 @@ func TestParseAndExecute_E2E(t *testing.T) {
data, err := os.ReadFile(filepath.Join(sbomPath, file.Name()))
assert.NoError(t, err)

err = ingest.SBOM(redisStorage, data)
if err != nil {
t.Fatalf("Failed to load SBOM from file %s: %v", file.Name(), err)
}
req := connect.NewRequest(&service.IngestSBOMRequest{
Sbom: data,
})
_, err = s.IngestSBOM(context.Background(), req)
assert.NoError(t, err)
}
// Process vulnerability files
vulnFiles, err := os.ReadDir(vulnsPath)
Expand All @@ -49,22 +61,27 @@ func TestParseAndExecute_E2E(t *testing.T) {
data, err := os.ReadFile(filepath.Join(vulnsPath, file.Name()))
assert.NoError(t, err)

err = ingest.Vulnerabilities(redisStorage, data)
req := connect.NewRequest(&service.IngestVulnerabilityRequest{
Vulnerability: data,
})
_, err = s.IngestVulnerability(context.Background(), req)
if err != nil {
t.Fatalf("Failed to load vulnerabilities from file %s: %v", file.Name(), err)
}
}

// Cache data
err = graph.Cache(redisStorage)
req := connect.NewRequest(&emptypb.Empty{})
_, err = s.Cache(context.Background(), req)
assert.NoError(t, err)

tests := []struct {
name string
script string
defaultNodeName string
want uint64
wantErr bool
name string
script string
defaultNodeName string
queryOrLeaderboard bool
want uint64
wantErr bool
}{
{
name: "Simple dependents query",
Expand Down Expand Up @@ -132,11 +149,12 @@ func TestParseAndExecute_E2E(t *testing.T) {
defaultNodeName: "",
},
{
name: "Query with default node name",
script: "dependencies library",
want: 1,
defaultNodeName: "pkg:github/actions/checkout@v3",
wantErr: false,
name: "Query with default node name",
script: "dependencies library",
want: 950,
queryOrLeaderboard: true,
defaultNodeName: "pkg:github/actions/checkout@v3",
wantErr: false,
},
{
name: "Complex query with multiple operations",
Expand All @@ -155,23 +173,36 @@ func TestParseAndExecute_E2E(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
keys, err := redisStorage.GetAllKeys()
assert.NoError(t, err)

nodes, err := redisStorage.GetNodes(keys)
assert.NoError(t, err)

caches, err := redisStorage.GetCaches(keys)
assert.NoError(t, err)

result, err := graph.ParseAndExecute(tt.script, redisStorage, tt.defaultNodeName, nodes, caches, true)
if (err != nil) != tt.wantErr {
t.Errorf("ParseAndExecute() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && result.GetCardinality() != tt.want {
t.Errorf("ParseAndExecute() got cardinality = %v, want cardinality %v", result.GetCardinality(), tt.want)
if tt.queryOrLeaderboard == true {
req := connect.NewRequest(&service.CustomLeaderboardRequest{
Script: tt.script,
})
resp, err := s.CustomLeaderboard(context.Background(), req)
nodes := resp.Msg.Queries

if (err != nil) != tt.wantErr {
t.Errorf("CustomLeaderboard() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && len(nodes[0].Output) != int(tt.want) {
t.Errorf("CustomLeaderboard() got the first nodes output len of = %v, want output len of %v", nodes[0].Output, tt.want)
}
} else {
req := connect.NewRequest(&service.QueryRequest{
Script: tt.script,
})
resp, err := s.Query(context.Background(), req)
nodes := resp.Msg.Nodes

if (err != nil) != tt.wantErr {
t.Errorf("Query() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && len(nodes) != int(tt.want) {
t.Errorf("Query() got cardinality = %v, want cardinality %v", len(nodes), tt.want)
}
}

})
}
}
36 changes: 13 additions & 23 deletions pkg/storages/redis_storage_test.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
package storages

import (
"context"
"testing"

"github.com/RoaringBitmap/roaring"
"github.com/bitbomdev/minefield/pkg/graph"
"github.com/go-redis/redis/v8"
"github.com/goccy/go-json"
"github.com/stretchr/testify/assert"
)

func setupTestRedis() *RedisStorage {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
rdb.FlushDB(context.Background()) // Clear the database before each test
return &RedisStorage{Client: rdb}
}

func TestGenerateID(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
id, err := r.GenerateID()
assert.NoError(t, err)
assert.NotEqual(t, 0, id)
}

func TestSaveNode(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
node := &graph.Node{ID: 1, Name: "test_node", Children: roaring.New(), Parents: roaring.New()}
err := r.SaveNode(node)
assert.NoError(t, err)
Expand All @@ -40,7 +30,7 @@ func TestSaveNode(t *testing.T) {
}

func TestNameToID(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
node := &graph.Node{ID: 1, Name: "test_node", Children: roaring.New(), Parents: roaring.New()}
err := r.SaveNode(node)
assert.NoError(t, err)
Expand All @@ -51,7 +41,7 @@ func TestNameToID(t *testing.T) {
}

func TestGetAllKeys(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
node1 := &graph.Node{ID: 1, Name: "node1", Children: roaring.New(), Parents: roaring.New()}
node2 := &graph.Node{ID: 2, Name: "node2", Children: roaring.New(), Parents: roaring.New()}
err := r.SaveNode(node1)
Expand All @@ -66,7 +56,7 @@ func TestGetAllKeys(t *testing.T) {
}

func TestSaveCache(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
cache := &graph.NodeCache{ID: 1, AllParents: roaring.New(), AllChildren: roaring.New()}
err := r.SaveCache(cache)
assert.NoError(t, err)
Expand All @@ -77,7 +67,7 @@ func TestSaveCache(t *testing.T) {
}

func TestToBeCached(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
nodeID := uint32(1)
err := r.AddNodeToCachedStack(nodeID)
assert.NoError(t, err)
Expand All @@ -88,7 +78,7 @@ func TestToBeCached(t *testing.T) {
}

func TestClearCacheStack(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
nodeID := uint32(1)
err := r.AddNodeToCachedStack(nodeID)
assert.NoError(t, err)
Expand All @@ -102,7 +92,7 @@ func TestClearCacheStack(t *testing.T) {
}

func TestGetNodes(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
// Add test data
node1 := &graph.Node{ID: 1, Name: "test_node1", Children: roaring.New(), Parents: roaring.New()}
node2 := &graph.Node{ID: 2, Name: "test_node2", Children: roaring.New(), Parents: roaring.New()}
Expand All @@ -121,7 +111,7 @@ func TestGetNodes(t *testing.T) {
}

func TestSaveCaches(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
cache1 := &graph.NodeCache{ID: 1, AllParents: roaring.New(), AllChildren: roaring.New()}
cache2 := &graph.NodeCache{ID: 2, AllParents: roaring.New(), AllChildren: roaring.New()}
err := r.SaveCaches([]*graph.NodeCache{cache1, cache2})
Expand All @@ -137,7 +127,7 @@ func TestSaveCaches(t *testing.T) {
}

func TestGetCaches(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
cache1 := &graph.NodeCache{ID: 1, AllParents: roaring.New(), AllChildren: roaring.New()}
cache2 := &graph.NodeCache{ID: 2, AllParents: roaring.New(), AllChildren: roaring.New()}
err := r.SaveCaches([]*graph.NodeCache{cache1, cache2})
Expand All @@ -153,7 +143,7 @@ func TestGetCaches(t *testing.T) {
}

func TestRemoveAllCaches(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
cache1 := &graph.NodeCache{ID: 1, AllParents: roaring.New(), AllChildren: roaring.New()}
cache2 := &graph.NodeCache{ID: 2, AllParents: roaring.New(), AllChildren: roaring.New()}
err := r.SaveCaches([]*graph.NodeCache{cache1, cache2})
Expand All @@ -171,7 +161,7 @@ func TestRemoveAllCaches(t *testing.T) {
}

func TestAddAndGetDataToDB(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
err := r.AddOrUpdateCustomData("test_tag", "test_key1", "test_data1", []byte("test_data1"))
assert.NoError(t, err)
err = r.AddOrUpdateCustomData("test_tag", "test_key1", "test_data2", []byte("test_data2"))
Expand All @@ -191,7 +181,7 @@ func TestAddAndGetDataToDB(t *testing.T) {
}

func TestGetNodesByGlob(t *testing.T) {
r := setupTestRedis()
r := SetupRedisTestDB("localhost:6379")
// Add test nodes
node1 := &graph.Node{ID: 1, Name: "test_node1", Children: roaring.New(), Parents: roaring.New()}
node2 := &graph.Node{ID: 2, Name: "test_node2", Children: roaring.New(), Parents: roaring.New()}
Expand Down
Loading

0 comments on commit a0c27a7

Please sign in to comment.