github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/applet/zz_applet_test.go (about) 1 package applet_test 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "runtime" 8 "testing" 9 10 "github.com/DATA-DOG/go-sqlmock" 11 "github.com/agiledragon/gomonkey/v2" 12 "github.com/golang/mock/gomock" 13 . "github.com/onsi/gomega" 14 15 confid "github.com/machinefi/w3bstream/pkg/depends/conf/id" 16 conflog "github.com/machinefi/w3bstream/pkg/depends/conf/log" 17 "github.com/machinefi/w3bstream/pkg/depends/kit/httptransport/transformer" 18 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder" 19 "github.com/machinefi/w3bstream/pkg/depends/x/contextx" 20 "github.com/machinefi/w3bstream/pkg/errors/status" 21 "github.com/machinefi/w3bstream/pkg/models" 22 "github.com/machinefi/w3bstream/pkg/modules/applet" 23 mock_sqlx "github.com/machinefi/w3bstream/pkg/test/mock_depends_kit_sqlx" 24 "github.com/machinefi/w3bstream/pkg/test/patch_models" 25 "github.com/machinefi/w3bstream/pkg/test/patch_modules" 26 "github.com/machinefi/w3bstream/pkg/types" 27 "github.com/machinefi/w3bstream/pkg/types/wasm" 28 ) 29 30 func TestCondArgs_Condition(t *testing.T) { 31 expr := (&applet.CondArgs{}).Condition() 32 NewWithT(t).Expect(expr.IsNil()).To(BeTrue()) 33 34 ex := builder.ResolveExpr( 35 (&applet.CondArgs{ 36 ProjectID: 100, 37 AppletIDs: types.SFIDs{100}, 38 Names: []string{"test_cond"}, 39 NameLike: "test_cond", 40 LNameLike: "test_cond", 41 }).Condition(), 42 ) 43 NewWithT(t).Expect(len(ex.Args())).To(Equal(5)) 44 t.Log(ex.Query(), ex.Args()) 45 } 46 47 func TestCreateReq_BuildStrategies(t *testing.T) { 48 ctx := contextx.WithContextCompose( 49 conflog.WithLoggerContext(conflog.Std()), 50 confid.WithSFIDGeneratorContext(confid.MustNewSFIDGenerator()), 51 types.WithAppletContext(&models.Applet{}), 52 types.WithProjectContext(&models.Project{}), 53 )(context.Background()) 54 55 r := &applet.CreateReq{ 56 File: nil, 57 Info: applet.Info{}, 58 } 59 60 // len(r.Strategies) == 0 build with default strategy info 61 strategies := r.BuildStrategies(ctx) 62 NewWithT(t).Expect(len(strategies)).To(Equal(1)) 63 64 // len(r.Strategies) == 0 build with input strategy info 65 r.Info.Strategies = append(r.Info.Strategies, models.StrategyInfo{}) 66 strategies = r.BuildStrategies(ctx) 67 NewWithT(t).Expect(len(strategies)).To(Equal(len(r.Info.Strategies))) 68 } 69 70 func TestApplet(t *testing.T) { 71 c := gomock.NewController(t) 72 defer c.Finish() 73 74 d := &struct { 75 *mock_sqlx.MockDBExecutor 76 *mock_sqlx.MockTxExecutor 77 }{ 78 MockDBExecutor: mock_sqlx.NewMockDBExecutor(c), 79 MockTxExecutor: mock_sqlx.NewMockTxExecutor(c), 80 } 81 idg := confid.MustNewSFIDGenerator() 82 ctx := contextx.WithContextCompose( 83 types.WithMgrDBExecutorContext(d), 84 conflog.WithLoggerContext(conflog.Std()), 85 confid.WithSFIDGeneratorContext(idg), 86 types.WithProjectContext(&models.Project{}), 87 types.WithAccountContext(&models.Account{}), 88 types.WithAppletContext(&models.Applet{}), 89 )(context.Background()) 90 91 d.MockDBExecutor.EXPECT().T(gomock.Any()).Return(&builder.Table{}).AnyTimes() 92 d.MockDBExecutor.EXPECT().Context().Return(ctx).AnyTimes() 93 d.MockTxExecutor.EXPECT().IsTx().Return(true).AnyTimes() 94 95 t.Run("GetBySFID", func(t *testing.T) { 96 t.Run("#Failed", func(t *testing.T) { 97 t.Run("#AppletNotFound", func(t *testing.T) { 98 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(mock_sqlx.ErrNotFound).Times(1) 99 100 _, err := applet.GetBySFID(ctx, idg.MustGenSFID()) 101 mock_sqlx.ExpectError(t, err, status.AppletNotFound) 102 }) 103 t.Run("#DatabaseError", func(t *testing.T) { 104 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(mock_sqlx.ErrDatabase).Times(1) 105 106 _, err := applet.GetBySFID(ctx, idg.MustGenSFID()) 107 mock_sqlx.ExpectError(t, err, status.DatabaseError) 108 }) 109 }) 110 111 t.Run("#Success", func(t *testing.T) { 112 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(nil).Times(1) 113 114 _, err := applet.GetBySFID(ctx, idg.MustGenSFID()) 115 NewWithT(t).Expect(err).To(BeNil()) 116 }) 117 }) 118 119 cause := func(msg string) error { return errors.New(msg) } 120 121 t.Run("RemoveBySFID", func(t *testing.T) { 122 t.Run("#Failed", func(t *testing.T) { 123 t.Run("#DeleteByAppletIDFailed", func(t *testing.T) { 124 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, cause(t.Name())).Times(1) 125 err := applet.RemoveBySFID(ctx, 100) 126 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 127 }) 128 t.Run("RemoveStrategyFailed", func(t *testing.T) { 129 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, nil).Times(1) 130 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, cause(t.Name())).Times(1) 131 err := applet.RemoveBySFID(ctx, 100) 132 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 133 }) 134 t.Run("#RemoveInstanceFailed", func(t *testing.T) { 135 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, nil).Times(2) 136 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(cause(t.Name())).Times(1) 137 err := applet.RemoveBySFID(ctx, idg.MustGenSFID()) 138 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 139 }) 140 }) 141 142 t.Run("#Success", func(t *testing.T) { 143 if runtime.GOOS == `darwin` { 144 return 145 } 146 patch := gomonkey.NewPatches() 147 defer patch.Reset() 148 149 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, nil).Times(2) 150 patch = patch_modules.DeployRemoveByAppletSFID(patch, nil) 151 152 err := applet.RemoveBySFID(ctx, idg.MustGenSFID()) 153 NewWithT(t).Expect(err).To(BeNil()) 154 }) 155 }) 156 157 t.Run("Remove", func(t *testing.T) { 158 patch := gomonkey.NewPatches() 159 defer patch.Reset() 160 161 req := &applet.CondArgs{} 162 t.Run("#Failed", func(t *testing.T) { 163 t.Run("#ListAppletFailed", func(t *testing.T) { 164 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(cause(t.Name())).Times(1) 165 err := applet.Remove(ctx, req) 166 mock_sqlx.ExpectError(t, err, status.DatabaseError) 167 }) 168 t.Run("#BatchRemoveAppletFailed", func(t *testing.T) { 169 if runtime.GOOS == `darwin` { 170 return 171 } 172 173 patch = patch_models.AppletList(patch, []models.Applet{{}}, nil) 174 patch = patch_modules.AppletRemoveBySFID(patch, cause(t.Name())) 175 176 err := applet.Remove(ctx, req) 177 mock_sqlx.ExpectError(t, err, status.BatchRemoveAppletFailed) 178 }) 179 }) 180 t.Run("#Success", func(t *testing.T) { 181 if runtime.GOOS == `darwin` { 182 return 183 } 184 patch = patch_models.AppletList(patch, nil, nil) 185 186 err := applet.Remove(ctx, req) 187 NewWithT(t).Expect(err).To(BeNil()) 188 }) 189 }) 190 191 t.Run("List", func(t *testing.T) { 192 req := &applet.ListReq{} 193 t.Run("#Failed", func(t *testing.T) { 194 t.Run("#ListFailed", func(t *testing.T) { 195 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(cause(t.Name())).Times(1) 196 _, err := applet.List(ctx, req) 197 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 198 }) 199 t.Run("#CountFailed", func(t *testing.T) { 200 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(nil).Times(1) 201 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(cause(t.Name())).Times(1) 202 _, err := applet.List(ctx, req) 203 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 204 }) 205 }) 206 t.Run("#Success", func(t *testing.T) { 207 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(nil).Times(2) 208 _, err := applet.List(ctx, req) 209 NewWithT(t).Expect(err).To(BeNil()) 210 }) 211 }) 212 213 t.Run("ListDetail", func(t *testing.T) { 214 patch := gomonkey.NewPatches() 215 defer patch.Reset() 216 217 req := &applet.ListReq{} 218 t.Run("#Failed", func(t *testing.T) { 219 t.Run("#AppletListFailed", func(t *testing.T) { 220 d.MockDBExecutor.EXPECT().QueryAndScan(gomock.Any(), gomock.Any()).Return(cause(t.Name())).Times(1) 221 _, err := applet.ListDetail(ctx, req) 222 mock_sqlx.ExpectError(t, err, status.DatabaseError, t.Name()) 223 }) 224 225 t.Run("#AppendDetailFailed", func(t *testing.T) { 226 if runtime.GOOS == `darwin` { 227 return 228 } 229 patch = patch_modules.AppletList(patch, &applet.ListRsp{ 230 Data: []models.Applet{{}}, 231 Total: 1, 232 }, nil) 233 patch = patch_modules.DeployGetByAppletSFID(patch, &models.Instance{}, nil) 234 patch = patch_modules.ResourceGetBySFID(patch, nil, cause(t.Name()+"#1")) 235 236 _, err := applet.ListDetail(ctx, req) 237 NewWithT(t).Expect(err.Error()).To(Equal(t.Name() + "#1")) 238 239 patch = patch_modules.DeployGetByAppletSFID(patch, nil, cause(t.Name())) 240 _, err = applet.ListDetail(ctx, req) 241 NewWithT(t).Expect(err).To(BeNil()) 242 }) 243 }) 244 245 t.Run("#Success", func(t *testing.T) { 246 if runtime.GOOS == `darwin` { 247 return 248 } 249 patch = patch_modules.DeployGetByAppletSFID(patch, &models.Instance{}, nil) 250 patch = patch_modules.ResourceGetBySFID(patch, &models.Resource{}, nil) 251 _, err := applet.ListDetail(ctx, req) 252 NewWithT(t).Expect(err).To(BeNil()) 253 }) 254 }) 255 256 t.Run("Create", func(t *testing.T) { 257 if runtime.GOOS == `darwin` { 258 return 259 } 260 261 patch := gomonkey.NewPatches() 262 defer patch.Reset() 263 264 var ( 265 req = &applet.CreateReq{} 266 code = []byte("any") 267 ) 268 t.Run("#Failed", func(t *testing.T) { 269 t.Run("#CreateResourceFailed", func(t *testing.T) { 270 patch = patch_modules.ResourceCreate(patch, nil, nil, cause(t.Name())) 271 _, err := applet.Create(ctx, req) 272 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 273 }) 274 275 patch = patch_modules.ResourceCreate(patch, &models.Resource{}, code, nil) 276 277 t.Run("#CreateAppletFailed", func(t *testing.T) { 278 t.Run("#AppletNameConflict", func(t *testing.T) { 279 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, mock_sqlx.ErrConflict).Times(1) 280 _, err := applet.Create(ctx, req) 281 mock_sqlx.ExpectError(t, err, status.AppletNameConflict) 282 }) 283 t.Run("#DatabaseError", func(t *testing.T) { 284 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, mock_sqlx.ErrDatabase).Times(1) 285 _, err := applet.Create(ctx, req) 286 mock_sqlx.ExpectError(t, err, status.DatabaseError) 287 }) 288 }) 289 290 patch = patch_modules.StrategyBatchCreate(patch, nil) 291 292 t.Run("#DeployUpsertByCodeFailed", func(t *testing.T) { 293 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, nil).Times(1) 294 patch = patch_modules.DeployUpsertByCode(patch, nil, cause(t.Name())) 295 _, err := applet.Create(ctx, req) 296 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 297 }) 298 }) 299 300 t.Run("#Success", func(t *testing.T) { 301 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, nil).Times(1) 302 patch = patch_modules.DeployUpsertByCode(patch, &models.Instance{}, nil) 303 304 r := *req 305 r.WasmCache = &wasm.Cache{} 306 _, err := applet.Create(ctx, &r) 307 NewWithT(t).Expect(err).To(BeNil()) 308 }) 309 }) 310 311 t.Run("Update", func(t *testing.T) { 312 if runtime.GOOS == `darwin` { 313 return 314 } 315 316 patch := gomonkey.NewPatches() 317 defer patch.Reset() 318 319 var ( 320 req = &applet.UpdateReq{} 321 code = []byte("any") 322 323 header, err = transformer.NewFileHeader("file", "any_file", bytes.NewBuffer(code)) 324 ) 325 NewWithT(t).Expect(err).To(BeNil()) 326 327 t.Run("#Failed", func(t *testing.T) { 328 t.Run("#ResourceCreateFailed", func(t *testing.T) { 329 r := *req 330 r.File = header 331 332 patch = patch_modules.ResourceCreate(patch, nil, nil, cause(t.Name())) 333 _, err = applet.Update(ctx, &r) 334 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 335 }) 336 337 patch = patch_modules.ResourceCreate(patch, &models.Resource{}, code, nil) 338 339 t.Run("#UpdateStrategyFailed", func(t *testing.T) { 340 r := *req 341 r.Strategies = []models.StrategyInfo{{}} 342 t.Run("#StrategyRemoveFailed", func(t *testing.T) { 343 patch = patch_modules.StrategyRemove(patch, cause(t.Name())) 344 _, err = applet.Update(ctx, &r) 345 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 346 }) 347 348 patch = patch_modules.StrategyRemove(patch, nil) 349 350 t.Run("#StrategyBatchCreateFailed", func(t *testing.T) { 351 patch = patch_modules.StrategyBatchCreate(patch, cause(t.Name())) 352 _, err = applet.Update(ctx, &r) 353 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 354 }) 355 }) 356 357 patch = patch_modules.StrategyBatchCreate(patch, nil) 358 359 t.Run("#UpdateAppletDatabaseFailed", func(t *testing.T) { 360 r := *req 361 r.AppletName = "any" 362 r.File = header 363 364 t.Run("#AppletNameConflict", func(t *testing.T) { 365 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, mock_sqlx.ErrConflict).Times(1) 366 _, err = applet.Update(ctx, &r) 367 mock_sqlx.ExpectError(t, err, status.AppletNameConflict) 368 }) 369 t.Run("#DatabaseError", func(t *testing.T) { 370 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(nil, mock_sqlx.ErrDatabase).Times(1) 371 _, err = applet.Update(ctx, &r) 372 mock_sqlx.ExpectError(t, err, status.DatabaseError) 373 }) 374 }) 375 376 d.MockDBExecutor.EXPECT().Exec(gomock.Any()).Return(sqlmock.NewResult(1, 1), nil).AnyTimes() 377 378 t.Run("#UpdateAndDeployInstanceFailed", func(t *testing.T) { 379 r := *req 380 r.File = header 381 r.WasmCache = &wasm.Cache{} 382 t.Run("#DeployGetByAppletSFIDFailed", func(t *testing.T) { 383 patch = patch_modules.DeployGetByAppletSFID(patch, &models.Instance{}, cause(t.Name())) 384 _, err = applet.Update(ctx, &r) 385 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 386 }) 387 388 patch = patch_modules.DeployGetByAppletSFID(patch, &models.Instance{}, nil) 389 390 t.Run("#DeployGetByAppletSFIDFailed", func(t *testing.T) { 391 patch = patch_modules.DeployUpsertByCode(patch, nil, cause(t.Name())) 392 _, err = applet.Update(ctx, &r) 393 NewWithT(t).Expect(err.Error()).To(Equal(t.Name())) 394 }) 395 }) 396 }) 397 t.Run("#Success", func(t *testing.T) { 398 patch = patch_modules.DeployUpsertByCode(patch, &models.Instance{}, nil) 399 400 r := *req 401 _, err = applet.Update(ctx, &r) 402 NewWithT(t).Expect(err).To(BeNil()) 403 404 r.Strategies = []models.StrategyInfo{{}} 405 _, err = applet.Update(ctx, &r) 406 NewWithT(t).Expect(err).To(BeNil()) 407 }) 408 }) 409 }