package bridge import ( "database/sql" "errors" "fmt" "path/filepath" "testing" ) const createMetaV2 = `CREATE TABLE meta_v2 ( key TEXT PRIMARY KEY, group_version_resource TEXT, namespace TEXT, name TEXT, resource_version INTEGER, value TEXT )` const createMeta = `CREATE TABLE meta (key TEXT PRIMARY KEY, type TEXT, value TEXT)` func classJSON(name, handler string) string { return fmt.Sprintf(`{"apiVersion":"node.k8s.io/v1","kind":"RuntimeClass","metadata":{"name":%q},"handler":%q}`, name, handler) } func seedDB(t *testing.T, statements []string) string { t.Helper() path := filepath.Join(t.TempDir(), "edgecore.db") db, err := sql.Open("sqlite3", path) if err != nil { t.Fatalf("open seed db: %v", err) } defer func() { _ = db.Close() }() for _, q := range statements { if _, err := db.Exec(q); err != nil { t.Fatalf("seed statement %q: %v", q, err) } } return path } func TestListFromMetaV2(t *testing.T) { path := seedDB(t, []string{ createMetaV2, `INSERT INTO meta_v2 (key, group_version_resource, namespace, name, resource_version, value) VALUES ('/node.k8s.io/v1/runtimeclasses/null/kata', 'node.k8s.io/v1, Resource=runtimeclasses', 'null', 'kata', 7, '` + classJSON("kata", "kata") + `')`, }) store, err := OpenStore(path) if err != nil { t.Fatalf("OpenStore: %v", err) } defer func() { _ = store.Close() }() classes, err := store.ListRuntimeClasses() if err != nil { t.Fatalf("ListRuntimeClasses: %v", err) } if len(classes) != 1 || classes[0].Name != "kata" || classes[0].Handler != "kata" { t.Fatalf("unexpected classes: %+v", classes) } } func TestListFromLegacyMeta(t *testing.T) { path := seedDB(t, []string{ createMeta, `INSERT INTO meta (key, type, value) VALUES ('null/runtimeclasses/runsc', 'runtimeclasses', '` + classJSON("runsc", "runsc") + `')`, }) store, err := OpenStore(path) if err != nil { t.Fatalf("OpenStore: %v", err) } defer func() { _ = store.Close() }() classes, err := store.ListRuntimeClasses() if err != nil { t.Fatalf("ListRuntimeClasses: %v", err) } if len(classes) != 1 || classes[0].Name != "runsc" || classes[0].Handler != "runsc" { t.Fatalf("unexpected classes: %+v", classes) } } func TestListBothTablesSortedAndDeduped(t *testing.T) { path := seedDB(t, []string{ createMetaV2, createMeta, `INSERT INTO meta_v2 (key, group_version_resource, namespace, name, resource_version, value) VALUES ('/node.k8s.io/v1/runtimeclasses/null/kata', 'node.k8s.io/v1, Resource=runtimeclasses', 'null', 'kata', 1, '` + classJSON("kata", "kata") + `')`, `INSERT INTO meta_v2 (key, group_version_resource, namespace, name, resource_version, value) VALUES ('/node.k8s.io/v1/runtimeclasses/null/runsc', 'node.k8s.io/v1, Resource=runtimeclasses', 'null', 'runsc', 2, '` + classJSON("runsc", "runsc") + `')`, `INSERT INTO meta (key, type, value) VALUES ('null/runtimeclasses/kata', 'runtimeclasses', '` + classJSON("kata", "kata") + `')`, }) store, err := OpenStore(path) if err != nil { t.Fatalf("OpenStore: %v", err) } defer func() { _ = store.Close() }() classes, err := store.ListRuntimeClasses() if err != nil { t.Fatalf("ListRuntimeClasses: %v", err) } if len(classes) != 2 || classes[0].Name != "kata" || classes[1].Name != "runsc" { t.Fatalf("unexpected classes: %+v", classes) } } func TestListIgnoresNonRuntimeClassObjects(t *testing.T) { path := seedDB(t, []string{ createMetaV2, `INSERT INTO meta_v2 (key, group_version_resource, namespace, name, resource_version, value) VALUES ('/core/v1/secrets/default/mine', 'core/v1, Resource=secrets', 'default', 'mine', 3, '{"apiVersion":"v1","kind":"Secret","metadata":{"name":"mine"}}')`, }) store, err := OpenStore(path) if err != nil { t.Fatalf("OpenStore: %v", err) } defer func() { _ = store.Close() }() classes, err := store.ListRuntimeClasses() if err != nil { t.Fatalf("ListRuntimeClasses: %v", err) } if len(classes) != 0 { t.Fatalf("expected no classes, got %+v", classes) } } func TestListMissingTablesTreatedAsEmpty(t *testing.T) { path := seedDB(t, []string{`CREATE TABLE unrelated (id INTEGER)`}) store, err := OpenStore(path) if err != nil { t.Fatalf("OpenStore: %v", err) } defer func() { _ = store.Close() }() classes, err := store.ListRuntimeClasses() if err != nil { t.Fatalf("ListRuntimeClasses: %v", err) } if len(classes) != 0 { t.Fatalf("expected no classes, got %+v", classes) } } func TestOpenStoreMissingFile(t *testing.T) { path := filepath.Join(t.TempDir(), "does-not-exist.db") _, err := OpenStore(path) if !errors.Is(err, ErrStoreNotFound) { t.Fatalf("expected ErrStoreNotFound, got %v", err) } }