package services import ( "context" "database/sql" "errors" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/google/uuid" "github.com/stretchr/testify/assert" "edge-infra.dev/pkg/edge/api/graph/model" "edge-infra.dev/pkg/edge/api/services/artifacts" clustersvc "edge-infra.dev/pkg/edge/api/services/cluster" sqlquery "edge-infra.dev/pkg/edge/api/sql" "edge-infra.dev/pkg/edge/api/types" edgeCapabilities "edge-infra.dev/pkg/edge/capabilities" edgeconstants "edge-infra.dev/pkg/edge/constants" "edge-infra.dev/pkg/edge/constants/api/fleet" "edge-infra.dev/pkg/lib/runtime/version" ) func TestCreateCluster(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() clusterGUID := uuid.NewString() mock.MatchExpectationsInOrder(false) mock.ExpectBegin() mock.ExpectExec(sqlquery.ClusterInsertQuery).WithArgs("test-cluster", "test-project", true, true, clusterGUID, "banner_edge_id", sql.NullString{String: "site_123", Valid: true}, edgeconstants.DefaultClusterLocation, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetLabelTypeByKey). WithArgs("gke", "edge-type"). WillReturnRows(mock.NewRows([]string{"uuid"}). AddRow(1)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(clusterGUID, "1"). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetLabelsByBannerQuery). WithArgs("banner_edge_id"). WillReturnRows(mock.NewRows([]string{"labelid", "labelkey", "color", "visible", "editable", "banner", "unique", "description", "label_type"}). AddRow(testLabelID, edgeCapabilities.EdgeIDPallet, "#eeeeee", true, false, "banner_edge_id", false, "optional pallet edge capability", edgeCapabilities.EdgeCapabilitiesLabel). AddRow(testLabelID2, edgeCapabilities.BSLShimsPallet, "#eeeeee", true, false, "banner_edge_id", false, "optional pallet edge capability", edgeCapabilities.EdgeCapabilitiesLabel). AddRow(testLabelID3, edgeCapabilities.MetricsPallet, "#eeeeee", true, false, "banner_edge_id", false, "optional pallet edge capability", edgeCapabilities.EdgeCapabilitiesLabel). AddRow(testLabelID4, "non-edge-capability-label", "#000000", true, false, "banner_edge_id", false, "test-label", "test-label")) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(clusterGUID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(clusterGUID, testLabelID2). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(clusterGUID, testLabelID3). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetLabelTypeByKey). WithArgs("store", "edge-fleet"). WillReturnRows(mock.NewRows([]string{"uuid"}). AddRow(2)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(clusterGUID, "2"). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(clusterGUID, fleet.Store, version.New().SemVer). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.UpdateClusterConfig).WithArgs(clusterGUID, AutoUpdateEnabledKey, "true", sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(clusterGUID, edgeCapabilities.EdgeIDPallet, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(clusterGUID, edgeCapabilities.BSLShimsPallet, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(clusterGUID, edgeCapabilities.MetricsPallet, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) labelsvc := NewLabelService(artifactsService, db) regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, db, nil, nil, nil, nil, labelsvc) latest := version.New().SemVer autoUpdate := true payload := &model.RegistrationPayload{ Name: "test-cluster", ClusterType: "gke", Fleet: fleet.Store, FleetVersion: &latest, AutoUpdateEnabled: &autoUpdate, } if err = regService.CreateClusterSQLEntry(context.Background(), payload, "test-project", clusterGUID, "site_123", "banner_edge_id", true, edgeconstants.DefaultClusterLocation); err != nil { t.Errorf("error was not expected while adding cluster: %s", err) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestCreateClusterError(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() clusterGUID := uuid.NewString() mock.ExpectBegin() mock.ExpectExec(sqlquery.ClusterInsertQuery).WillReturnError(errors.New("bad statement")) mock.ExpectRollback() regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, db, nil, nil, nil, nil, nil) latest := types.DefaultVersionTag autoUpdate := true payload := &model.RegistrationPayload{ Name: "test-cluster", ClusterType: "gke", Fleet: fleet.Store, FleetVersion: &latest, AutoUpdateEnabled: &autoUpdate, } if err = regService.CreateClusterSQLEntry(context.Background(), payload, "test-project", clusterGUID, "", "banner_edge_id", false, edgeconstants.DefaultClusterLocation); err == nil { t.Fatal("Error was expected") } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestIsClusterSQLEntryExist(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() mock.ExpectQuery(sqlquery.IsClusterExistQuery).WithArgs("test-cluster", "test-project").WillReturnRows(mock.NewRows([]string{"exist"}).AddRow(true)) regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, db, nil, nil, nil, nil, nil) exist, err := regService.IsClusterSQLEntryExist(context.Background(), "test-cluster", "test-project") if err != nil { t.Errorf("error was not expected while updating cluster: %s", err) } if !exist { t.Errorf("cluster was not expected to exist") } } func TestUpdateCluster(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() mock.MatchExpectationsInOrder(false) mock.ExpectExec(sqlquery.ClusterUpdateQuery).WithArgs(true, "mv8wx3jwjgtg").WillReturnResult(sqlmock.NewResult(1, 1)) regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, db, nil, nil, nil, nil, nil) if err = regService.UpdateClusterSQLEntry(context.Background(), true, "mv8wx3jwjgtg"); err != nil { t.Errorf("error was not expected while updating cluster: %s", err) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestUpdateClusterError(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() mock.ExpectExec(sqlquery.ClusterUpdateQuery).WillReturnError(errors.New("bad statement")) regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, db, nil, nil, nil, nil, nil) if err = regService.UpdateClusterSQLEntry(context.Background(), false, ""); err == nil { t.Fatal("Error was expected") } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestCreateAClusterCR(t *testing.T) { regService := NewRegistrationService(nil, "test", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) optional := "test-value" clusterInfo := &model.ClusterInfo{ Location: "test-location", NodeVersion: &optional, MachineType: "test-machine-type", NumNodes: 3, Autoscale: false, MinNodes: nil, MaxNodes: nil, } banner := &model.Banner{ Name: "test-banner", BannerEdgeID: "test-banner-edge-id", } clusterCRBase64, err := regService.CreateAClusterCR(context.Background(), "gke", "test-cluster", "test-project", "store", "test-org", uuid.NewString(), banner, clusterInfo) assert.NoError(t, err) assert.NotEmpty(t, clusterCRBase64) }