package artifacts import ( "context" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/google/uuid" "github.com/stretchr/testify/assert" clustersvc "edge-infra.dev/pkg/edge/api/services/cluster" clusterlabel "edge-infra.dev/pkg/edge/api/services/cluster/label" sqlquery "edge-infra.dev/pkg/edge/api/sql" "edge-infra.dev/pkg/edge/constants/api/fleet" "edge-infra.dev/pkg/lib/runtime/version" ) func TestGetClusterArtifactVersions(t *testing.T) { ceid := uuid.NewString() fversion := "sha256:d00a39e1a5dce242e7928cb8377df2540197f9d8710f2e6ccd620cb2e324a64a" //nolint 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.GetClusterArtifactVersions).WithArgs(ceid). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(fleet.Store, fversion)) svc := NewArtifactsService(db, nil) result, err := svc.GetClusterArtifactVersions(context.Background(), ceid) assert.NoError(t, err) assert.Len(t, result, 1) assert.NoError(t, mock.ExpectationsWereMet()) } func TestUpdateClusterFleetVersionAndArtifact(t *testing.T) { ceid := uuid.NewString() fversion := "0.14" 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(clusterlabel.FetchFleetType).WithArgs(ceid). WillReturnRows(mock.NewRows([]string{"label_key"}).AddRow(fleet.Store)) mock.ExpectBegin() mock.ExpectExec(sqlquery.UpdateClusterFleetVersion).WithArgs(ceid, fversion).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(sqlquery.UpdateClusterArtifactVersions).WithArgs(ceid, fversion).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) svc := NewArtifactsService(db, clusterLabelSvc) assert.NoError(t, svc.UpdateClusterFleetVersionAndArtifact(context.Background(), ceid, fversion)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestUpdateClusterFleetVersionAndArtifact_Validation(t *testing.T) { type tc struct { fleet string version string valid bool } tcs := []tc{ // valid {fleet: fleet.Store, version: "0.14", valid: true}, {fleet: fleet.Store, version: "sha256:d00a39e1a5dce242e7928cb8377df2540197f9d8710f2e6ccd620cb2e324a64a", valid: true}, { // probably meant to be a digest, but is technically a valid tag fleet: fleet.Store, version: "d00a39e1a5dce242e7928cb8377df2540197f9d8710f2e6ccd620cb2e324a64", valid: true, }, // invalid {fleet: fleet.Store, version: "", valid: false}, {fleet: fleet.Store, version: "sha255:d00a39e1a5dce242e7928cb8377df2540197f9d8710f2e6ccd620cb2e324a64a", valid: false}, {fleet: fleet.Store, version: "", valid: false}, {fleet: fleet.Store, version: "-api.quan", valid: false}, {fleet: fleet.Store, version: "-api/quan", valid: false}, {fleet: fleet.Store, version: ".14", valid: false}, {fleet: "", version: "0.14", valid: false}, {fleet: "sto re", version: "0.14", valid: false}, {fleet: "store ", version: ":0.14", valid: false}, {fleet: "store ", version: ".14", valid: false}, } for _, test := range tcs { err := validateWeakImageRef(test.fleet, test.version) if test.valid { assert.NoError(t, err, test) } else { assert.Error(t, err, test) } } } func TestGetAvailableArtifactVersions(t *testing.T) { fversion := "0.X-test" 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.GetAvailableArtifactVersions).WithArgs(fleet.Store). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(fleet.Store, fversion)) svc := NewArtifactsService(db, nil) result, err := svc.GetAvailableArtifactVersions(context.Background(), fleet.Store) assert.NoError(t, err) assert.Len(t, result, 1) assert.NoError(t, mock.ExpectationsWereMet()) } func TestGetLatestAvailableArtifactVersion(t *testing.T) { fversion := "X.Y.Z-test" 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.GetLatestAvailableArtifactVersion).WithArgs(fleet.Store). WillReturnRows(mock.NewRows([]string{"version_str"}).AddRow(fversion)) svc := NewArtifactsService(db, nil) result, err := svc.GetLatestAvailableArtifactVersion(context.Background(), fleet.Store) assert.NoError(t, err) assert.Equal(t, fversion, result.Version) assert.NoError(t, mock.ExpectationsWereMet()) } func TestAddClusterArtifactVersion(t *testing.T) { ctx := context.Background() ceid := uuid.NewString() artifactVersion := "0.18" artifactName := "distributed-storage" 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.ExpectBegin() tx, _ := db.Begin() mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs(ceid). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(fleet.Store, artifactVersion)) mock.ExpectQuery(clusterlabel.FetchFleetType).WithArgs(ceid). WillReturnRows(mock.NewRows([]string{"label_key"}).AddRow(fleet.Store)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(ceid, artifactName, artifactVersion).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) svc := NewArtifactsService(db, clusterLabelSvc) assert.NoError(t, svc.AddClusterArtifactVersion(ctx, tx, ceid, artifactName)) assert.NoError(t, tx.Commit()) assert.NoError(t, mock.ExpectationsWereMet()) } func TestDeleteClusterArtifactVersion(t *testing.T) { ctx := context.Background() ceid := uuid.NewString() artifactName := "distributed-storage" version := version.New() 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.ExpectBegin() tx, _ := db.Begin() mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs(ceid). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs(ceid, artifactName).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() svc := NewArtifactsService(db, nil) assert.NoError(t, svc.DeleteClusterArtifactVersion(ctx, tx, ceid, artifactName)) assert.NoError(t, tx.Commit()) assert.NoError(t, mock.ExpectationsWereMet()) }