1 package integration
2
3 import (
4 "context"
5 "database/sql"
6 "os"
7 "testing"
8
9 "github.com/google/uuid"
10 "github.com/stretchr/testify/assert"
11
12 "edge-infra.dev/pkg/edge/api/services"
13 "edge-infra.dev/pkg/edge/api/services/artifacts"
14 clustersvc "edge-infra.dev/pkg/edge/api/services/cluster"
15 sqlquery "edge-infra.dev/pkg/edge/api/sql"
16 "edge-infra.dev/pkg/edge/api/sql/plugin"
17 sqlutils "edge-infra.dev/pkg/edge/api/sql/utils"
18 "edge-infra.dev/pkg/edge/api/testutils/seededpostgres"
19 "edge-infra.dev/pkg/edge/api/types"
20 "edge-infra.dev/pkg/edge/constants/api/fleet"
21 "edge-infra.dev/pkg/lib/runtime/version"
22 "edge-infra.dev/test/f2"
23 "edge-infra.dev/test/f2/x/postgres"
24 )
25
26 var (
27 f f2.Framework
28 )
29
30 func TestMain(m *testing.M) {
31 f = f2.New(
32 context.Background(),
33 f2.WithExtensions(
34 postgres.New(postgres.ApplySeedModel()),
35 )).
36 Setup(func(ctx f2.Context) (f2.Context, error) {
37
38
39 return ctx, nil
40 })
41 os.Exit(f.Run(m))
42 }
43
44 func TestArtifactsService_AutoUpdates(t *testing.T) {
45 latestVersionForTest := "0.16.0"
46 seedData := seededpostgres.Seed
47
48
49
50 clusterEdgeID := uuid.New().String()
51 seedData = append(seedData,
52 plugin.Seed{
53 Name: "seed-clusters.tmpl",
54 Priority: 4,
55 Data: []sqlutils.Cluster{
56 {
57 EdgeID: clusterEdgeID,
58 ProjectID: "test-org",
59 Active: true,
60 Registered: true,
61 SiteID: "test_bsl_site_id",
62 Name: "test_auto_store_cluster",
63 BannerID: "3396a52c-6a22-4049-9593-5a63b596a101",
64 FleetVersion: "1.2.3-test",
65 },
66 },
67 },
68 plugin.Seed{
69 Name: "seed-cluster-labels.tmpl",
70 Priority: 6,
71 Data: []sqlutils.ClusterLabel{
72 {
73 ClusterEdgeID: clusterEdgeID,
74
75
76 LabelEdgeID: "e0ad2eca-03af-4fd1-91b0-36f98ca0c2cc",
77 },
78 },
79 },
80 plugin.Seed{
81 Name: "seed-cluster-artifact-versions.tmpl",
82 Priority: 21,
83 Data: []sqlutils.ClusterArtifactVersion{
84 {
85 ClusterEdgeID: clusterEdgeID,
86 ArtifactName: fleet.Store,
87 ArtifactVersion: "1.2.3-test",
88 },
89 },
90 },
91 plugin.Seed{
92 Name: "seed-cluster-config.tmpl",
93 Priority: 21,
94 Data: []sqlutils.ClusterConfig{
95 {
96 ClusterConfigEdgeID: uuid.NewString(),
97 ClusterEdgeID: clusterEdgeID,
98 ConfigKey: "auto_update_enabled",
99 ConfigValue: "true",
100 },
101 },
102 },
103 )
104 feat := f2.NewFeature("Artifact auto-updates").
105 Setup("Add Seed data", postgres.WithData(seedData)).
106 Test("Service automatically applies latest version to clusters with auto-update enabled", func(ctx f2.Context, t *testing.T) f2.Context {
107 pg := postgres.FromContextT(ctx, t)
108 db := pg.DB()
109 clusterLabelSvc := clustersvc.NewLabelService(db)
110 svc := artifacts.NewArtifactsService(db, clusterLabelSvc)
111 bsSvc := services.NewBootstrapService("", nil, db)
112
113 storeUUID := "6ae03a3b-654d-4140-ac50-69d8b93a94ea"
114
115
116 fleetType, err := clusterLabelSvc.FetchFleetType(ctx, storeUUID)
117 assert.NoError(t, err)
118 assert.Equal(t, fleet.Store, fleetType.String())
119 version, err := bsSvc.GetClusterFleetVersion(ctx, storeUUID)
120 assert.NoError(t, err)
121
122 assert.Equal(t, "0.15.0", version)
123 artifacts, err := svc.GetClusterArtifactVersions(ctx, storeUUID)
124 assert.NoError(t, err)
125 assert.Len(t, artifacts, 1)
126 assert.Equal(t, types.ArtifactVersion{
127 Name: fleet.Store,
128 Version: "0.0.0-test",
129 }, artifacts[0])
130
131
132
133 assert.NoError(t, insertNewLatestArtifactVersion(db, fleet.Store, latestVersionForTest))
134 n, err := svc.UpdateClustersToLatestArtifactVersion(ctx, fleet.Store)
135 assert.NoError(t, err)
136 assert.Equal(t, 2, n)
137 versionUpdated, err := bsSvc.GetClusterFleetVersion(ctx, storeUUID)
138 assert.NoError(t, err)
139 assert.Equal(t, latestVersionForTest, versionUpdated)
140 artifactsUpdated, err := svc.GetClusterArtifactVersions(ctx, storeUUID)
141 assert.NoError(t, err)
142 assert.Equal(t, types.ArtifactVersion{
143 Name: fleet.Store,
144 Version: latestVersionForTest,
145 }, artifactsUpdated[0])
146
147 return ctx
148 }).
149 Test("Auto-update only affects clusters with a fleet type matching the new artifact", func(ctx f2.Context, t *testing.T) f2.Context {
150 pg := postgres.FromContextT(ctx, t)
151 db := pg.DB()
152 svc := artifacts.NewArtifactsService(db, nil)
153 bsSvc := services.NewBootstrapService("", nil, db)
154
155
156 n, err := svc.UpdateClustersToLatestArtifactVersion(ctx, fleet.BasicStore)
157 assert.NoError(t, err)
158 assert.Equal(t, 0, n)
159
160
161 nonStoreClusterVersion, err := bsSvc.GetClusterFleetVersion(ctx, clusterEdgeID)
162 assert.NoError(t, err)
163 assert.Equal(t, "0.16.0", nonStoreClusterVersion)
164 nonStoreClusterArtifactsUpdated, err := svc.GetClusterArtifactVersions(ctx, clusterEdgeID)
165 assert.NoError(t, err)
166 assert.Equal(t, types.ArtifactVersion{
167 Name: fleet.Store,
168 Version: "0.16.0",
169 }, nonStoreClusterArtifactsUpdated[0])
170
171 return ctx
172 }).Feature()
173 f.Test(t, feat)
174 }
175
176 func TestArtifactsService(t *testing.T) {
177 seedData := seededpostgres.Seed
178 feat := f2.NewFeature("Artifacts service").
179 Setup("Add Seed data", postgres.WithData(seedData)).
180 Test("Service handles getting and updating cluster fleet versions", func(ctx f2.Context, t *testing.T) f2.Context {
181 pg := postgres.FromContextT(ctx, t)
182 db := pg.DB()
183 clusterLabelSvc := clustersvc.NewLabelService(db)
184 svc := artifacts.NewArtifactsService(db, clusterLabelSvc)
185 bsSvc := services.NewBootstrapService("", nil, db)
186 storeUUID := "dc8e59c3-6338-4c28-a776-f54e93a19ff4"
187
188
189 fleetType, err := clusterLabelSvc.FetchFleetType(ctx, storeUUID)
190 assert.NoError(t, err)
191 assert.Equal(t, fleet.Store, fleetType.String())
192 version, err := bsSvc.GetClusterFleetVersion(ctx, storeUUID)
193 assert.NoError(t, err)
194 assert.Equal(t, "0.14.0-seed", version)
195
196
197 artifacts, err := svc.GetClusterArtifactVersions(ctx, storeUUID)
198 assert.NoError(t, err)
199 assert.Len(t, artifacts, 1)
200 assert.Equal(t, types.ArtifactVersion{
201 Name: fleet.Store,
202 Version: "0.14.0-seed",
203 }, artifacts[0])
204
205
206 assert.NoError(t, svc.UpdateClusterFleetVersionAndArtifact(ctx,
207 storeUUID, "0.15"),
208 )
209 versionUpdated, err := bsSvc.GetClusterFleetVersion(ctx, storeUUID)
210 assert.NoError(t, err)
211 assert.Equal(t, "0.15", versionUpdated)
212 artifactsUpdated, err := svc.GetClusterArtifactVersions(ctx, storeUUID)
213 assert.NoError(t, err)
214 assert.Equal(t, types.ArtifactVersion{
215 Name: fleet.Store,
216 Version: "0.15",
217 }, artifactsUpdated[0])
218
219 return ctx
220 }).Feature()
221 f.Test(t, feat)
222 }
223
224 func TestArtifactsService_Migrations(t *testing.T) {
225 feat := f2.NewFeature("Migration manager successfully runs artifact migrations").
226 Setup("Add Seed data", postgres.WithData(seededpostgres.Seed)).
227 Test("Latest tags are converted to static versions", func(ctx f2.Context, t *testing.T) f2.Context {
228 pg := postgres.FromContextT(ctx, t)
229 db := pg.DB()
230
231 row := db.QueryRowContext(ctx, "SELECT count(*) FROM clusters WHERE fleet_version = 'latest'")
232 assert.NoError(t, row.Err())
233 var clusterCount int
234 assert.NoError(t, row.Scan(&clusterCount))
235 assert.Equal(t, 0, clusterCount, "expected 0 clusters to have fleet_version = 'latest' after migration runs")
236
237 row = db.QueryRowContext(ctx, "SELECT count(*) FROM cluster_artifact_versions WHERE artifact_version = 'latest'")
238 assert.NoError(t, row.Err())
239 var artifactCount int
240 assert.NoError(t, row.Scan(&artifactCount))
241 assert.Equal(t, 0, artifactCount, "expected 0 cluster_artifacts to have artifact_version = 'latest' after migration runs")
242
243 return ctx
244 }).Feature()
245 f.Test(t, feat)
246 }
247
248
249
250 func insertNewLatestArtifactVersion(db *sql.DB, artifactName, artifactVersion string) error {
251 v := version.New()
252 v.SemVer = artifactVersion
253 major, minor, patch, err := v.SemVerMajorMinorPatch()
254 if err != nil {
255 return err
256 }
257 if _, err = db.Exec(sqlquery.AddCurrentVersionToAvailableArtifacts, artifactName, artifactVersion, major, minor, patch); err != nil {
258 return err
259 }
260 if _, err = db.Exec(sqlquery.UpdateLatestAvailableArtifact, artifactName, major, minor, patch); err != nil {
261 return err
262 }
263 return nil
264 }
265
View as plain text