package services import ( "context" "encoding/json" "fmt" "strings" "testing" "time" "github.com/DATA-DOG/go-sqlmock" kustomizeApi "github.com/fluxcd/kustomize-controller/api/v1" "github.com/golang/mock/gomock" "github.com/google/go-containerregistry/pkg/name" "github.com/stretchr/testify/assert" "edge-infra.dev/pkg/edge/api/graph/model" "edge-infra.dev/pkg/edge/api/mocks" sqlquery "edge-infra.dev/pkg/edge/api/sql" "edge-infra.dev/pkg/edge/api/types" ctypes "edge-infra.dev/pkg/edge/constants/api/cluster" palletconst "edge-infra.dev/pkg/edge/constants/api/pallet" "edge-infra.dev/pkg/f8n/warehouse/oci" "edge-infra.dev/pkg/f8n/warehouse/pallet" "edge-infra.dev/test/fixtures" ) func TestCreateKustomizations(t *testing.T) { kus, err := CreateKustomizations(context.Background(), "test-bucket", "test-cluster-id", "latest") assert.NoError(t, err) assert.Equal(t, 1, len(kus)) names := map[string]bool{} paths := map[string]bool{} for _, k := range kus { fluxKustomize := &kustomizeApi.Kustomization{} err := json.Unmarshal([]byte(k), fluxKustomize) assert.NoError(t, err) assert.Equal(t, "test-bucket", fluxKustomize.Spec.SourceRef.Name) paths[fluxKustomize.Spec.Path] = true names[fluxKustomize.Name] = true } _, ok := names["flux-config-kustomization"] assert.True(t, ok) } func TestCreateKustomizations2(t *testing.T) { kus, err := CreateKustomizations(context.Background(), "edge-bucket", "test-cluster-edge-id", "latest") assert.NoError(t, err) assert.Equal(t, 1, len(kus)) names := map[string]bool{} paths := map[string]bool{} for _, k := range kus { fluxKustomize := &kustomizeApi.Kustomization{} err := json.Unmarshal([]byte(k), fluxKustomize) assert.NoError(t, err) assert.Equal(t, "edge-bucket", fluxKustomize.Spec.SourceRef.Name) paths[fluxKustomize.Spec.Path] = true names[fluxKustomize.Name] = true } _, ok := paths["./test-cluster-edge-id/fluxcfg/"] assert.True(t, ok) _, ok = names["flux-config-kustomization"] assert.True(t, ok) } func TestGetInstallManifests(t *testing.T) { mock := gomock.NewController(t) c := mocks.NewMockArtifactRegistryClient(mock) path, err := fixtures.Layout() assert.NoError(t, err) c.EXPECT(). Get(gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn(func(_ string, artifactName string, _ string) (oci.Artifact, error) { if artifactName == "k8s-admission-controller" { return getPallet(path, artifactName, "latest") } // TODO: Make all pallets use the above so that the tests are being // run on the correct pallets? return getPallet(path, "edge-bsl", "latest") }).AnyTimes() testClusterEdgeID := "498e13f0-a6fb-4589-9ee8-18f2529dc61b" db, dbmock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() callExpectQueryFn := func() *sqlmock.ExpectedQuery { return dbmock.ExpectQuery(sqlquery.GetClusterFleetVersion). WithArgs(testClusterEdgeID). WillReturnRows(sqlmock.NewRows([]string{"fleet_version"}).AddRow("latest")) } bsService := NewBootstrapService("top-level", c, db) cluster := &model.Cluster{ClusterEdgeID: testClusterEdgeID, ProjectID: "test-project"} type test struct { provider string pallets []types.Pallet palletTypes string expectQueryHook func() *sqlmock.ExpectedQuery expectManifestsLen int } tests := []test{ { provider: ctypes.Generic, palletTypes: "bootstrap", pallets: palletconst.BootstrapPallets, expectQueryHook: callExpectQueryFn, expectManifestsLen: 36, }, { provider: ctypes.GKE, palletTypes: "bootstrap", pallets: palletconst.BootstrapPallets, expectQueryHook: callExpectQueryFn, expectManifestsLen: 36, }, { provider: ctypes.GKE, palletTypes: "prebootstrap", pallets: palletconst.PreBootstrapPallets, expectQueryHook: callExpectQueryFn, expectManifestsLen: 23, }, { provider: ctypes.DSDS, palletTypes: "prebootstrap", pallets: palletconst.PreBootstrapPallets, expectQueryHook: callExpectQueryFn, expectManifestsLen: 23, }, { provider: ctypes.DSDS, palletTypes: "prebootstrapstatic", pallets: palletconst.PreBootstrapStaticPallets, expectQueryHook: callExpectQueryFn, expectManifestsLen: 1, }, } for _, tc := range tests { name := fmt.Sprintf("expect_%d_manifests_for_%s_%s", tc.expectManifestsLen, tc.provider, tc.palletTypes) tc.expectQueryHook() t.Run(name, func(t *testing.T) { manifests, err := bsService.GetManifests( context.Background(), tc.provider, tc.pallets, cluster, ) assert.NoError(t, err) assert.Len(t, manifests, tc.expectManifestsLen) }) } } func getPallet(path *fixtures.Path, palletName string, fleetVersion string) (pallet.Pallet, error) { palletIdentifier := strings.Join([]string{palletName, fleetVersion}, ":") palletRef, err := name.ParseReference(palletIdentifier) if err != nil { return nil, err } artifact, err := path.Get(palletRef) if err != nil { return nil, err } return pallet.New(artifact) } func TestCreateClusterBootstrapTokenEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() secretName := "secret-name" clusterEdgeID := "3396a52c-6a22-4049-9593-5a63b596a200" expireAt := time.Now().Add(time.Minute) mock.ExpectExec(sqlquery.CreateClusterBootstrapToken).WithArgs(sqlmock.AnyArg(), secretName, clusterEdgeID, expireAt).WillReturnResult(sqlmock.NewResult(1, 1)) bsService := NewBootstrapService("top-level", nil, db) err = bsService.CreateClusterBootstrapTokenEntry(context.Background(), clusterEdgeID, secretName, expireAt) assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } func TestDeleteExpiredClusterBootstrapTokens(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() clusterEdgeID := "3396a52c-6a22-4049-9593-5a63b596a200" mock.ExpectExec(sqlquery.DeleteExpiredClusterBootstrapTokens).WithArgs(clusterEdgeID).WillReturnResult(sqlmock.NewResult(1, 1)) bsService := NewBootstrapService("top-level", nil, db) err = bsService.DeleteExpiredClusterBootstrapTokens(context.Background(), clusterEdgeID) assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) }