github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/devicetwin/dtclient/deviceattr_db_test.go (about) 1 /* 2 Copyright 2018 The KubeEdge Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package dtclient 18 19 import ( 20 "testing" 21 22 "github.com/astaxie/beego/orm" 23 "github.com/golang/mock/gomock" 24 25 "github.com/kubeedge/kubeedge/edge/mocks/beego" 26 "github.com/kubeedge/kubeedge/edge/pkg/common/dbm" 27 ) 28 29 // TestSaveDeviceAttr is function to test SaveDeviceAttr 30 func TestSaveDeviceAttr(t *testing.T) { 31 //Initialize Global Variables (Mocks) 32 // ormerMock is mocked Ormer implementation 33 var ormerMock *beego.MockOrmer 34 35 mockCtrl := gomock.NewController(t) 36 defer mockCtrl.Finish() 37 ormerMock = beego.NewMockOrmer(mockCtrl) 38 dbm.DBAccess = ormerMock 39 40 cases := []struct { 41 // name is name of the testcase 42 name string 43 // returnInt is first return of mock interface ormerMock 44 returnInt int64 45 // returnErr is second return of mock interface ormerMock which is also expected error 46 returnErr error 47 }{{ 48 // Success Case 49 name: "SuccessCase", 50 returnInt: int64(1), 51 returnErr: nil, 52 }, { 53 // Failure Case 54 name: "FailureCase", 55 returnInt: int64(1), 56 returnErr: errFailedDBOperation, 57 }, 58 } 59 60 // run the test cases 61 for _, test := range cases { 62 t.Run(test.name, func(t *testing.T) { 63 ormerMock.EXPECT().Insert(gomock.Any()).Return(test.returnInt, test.returnErr).Times(1) 64 err := SaveDeviceAttr(&DeviceAttr{}) 65 if test.returnErr != err { 66 t.Errorf("Save Device Attr Case failed: wanted error %v and got error %v", test.returnErr, err) 67 } 68 }) 69 } 70 } 71 72 // TestDeleteDeviceAttrByDeviceID is function to test DeleteDeviceAttrByDeviceID 73 func TestDeleteDeviceAttrByDeviceID(t *testing.T) { 74 // ormerMock is mocked Ormer implementation 75 var ormerMock *beego.MockOrmer 76 // querySeterMock is mocked QuerySeter implementation 77 var querySeterMock *beego.MockQuerySeter 78 79 mockCtrl := gomock.NewController(t) 80 defer mockCtrl.Finish() 81 ormerMock = beego.NewMockOrmer(mockCtrl) 82 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 83 dbm.DBAccess = ormerMock 84 85 cases := []struct { 86 // name is name of the testcase 87 name string 88 // filterReturn is the return of mock interface querySeterMock's filter function 89 filterReturn orm.QuerySeter 90 // deleteReturnInt is the first return of mock interface querySeterMock's delete function 91 deleteReturnInt int64 92 // deleteReturnErr is the second return of mock interface querySeterMocks's delete function also expected error 93 deleteReturnErr error 94 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 95 queryTableReturn orm.QuerySeter 96 }{{ 97 // Success Case 98 name: "SuccessCase", 99 filterReturn: querySeterMock, 100 deleteReturnInt: int64(1), 101 deleteReturnErr: nil, 102 queryTableReturn: querySeterMock, 103 }, { 104 // Failure Case 105 name: "FailureCase", 106 filterReturn: querySeterMock, 107 deleteReturnInt: int64(0), 108 deleteReturnErr: errFailedDBOperation, 109 queryTableReturn: querySeterMock, 110 }, 111 } 112 113 // run the test cases 114 for _, test := range cases { 115 t.Run(test.name, func(t *testing.T) { 116 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(1) 117 querySeterMock.EXPECT().Delete().Return(test.deleteReturnInt, test.deleteReturnErr).Times(1) 118 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 119 err := DeleteDeviceAttrByDeviceID("test") 120 if test.deleteReturnErr != err { 121 t.Errorf("DeleteDeviceAttrByDeviceID Case failed: wanted error %v and got error %v", test.deleteReturnErr, err) 122 } 123 }) 124 } 125 } 126 127 // TestDeleteDeviceAttr is function to test DeleteDeviceAttr 128 func TestDeleteDeviceAttr(t *testing.T) { 129 // ormerMock is mocked Ormer implementation 130 var ormerMock *beego.MockOrmer 131 // querySeterMock is mocked QuerySeter implementation 132 var querySeterMock *beego.MockQuerySeter 133 134 mockCtrl := gomock.NewController(t) 135 defer mockCtrl.Finish() 136 ormerMock = beego.NewMockOrmer(mockCtrl) 137 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 138 dbm.DBAccess = ormerMock 139 140 cases := []struct { 141 // name is name of the testcase 142 name string 143 // filterReturn is the return of mock interface querySeterMock's filter function 144 filterReturn orm.QuerySeter 145 // deleteReturnInt is the first return of mock interface querySeterMock's delete function 146 deleteReturnInt int64 147 // deleteReturnErr is the second return of mock interface querySeterMocks's delete function also expected error 148 deleteReturnErr error 149 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 150 queryTableReturn orm.QuerySeter 151 }{{ 152 // Success Case 153 name: "SuccessCase", 154 filterReturn: querySeterMock, 155 deleteReturnInt: int64(1), 156 deleteReturnErr: nil, 157 queryTableReturn: querySeterMock, 158 }, { 159 // Failure Case 160 name: "FailureCase", 161 filterReturn: querySeterMock, 162 deleteReturnInt: int64(0), 163 deleteReturnErr: errFailedDBOperation, 164 queryTableReturn: querySeterMock, 165 }, 166 } 167 168 // run the test cases 169 for _, test := range cases { 170 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(2) 171 querySeterMock.EXPECT().Delete().Return(test.deleteReturnInt, test.deleteReturnErr).Times(1) 172 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 173 err := DeleteDeviceAttr("test", "test") 174 t.Run(test.name, func(t *testing.T) { 175 if test.deleteReturnErr != err { 176 t.Errorf("DeleteDeviceAttr Case failed: wanted error %v and got error %v", test.deleteReturnErr, err) 177 } 178 }) 179 } 180 } 181 182 // TestUpdateDeviceAttrField is function to test UpdateDeviceAttrField 183 func TestUpdateDeviceAttrField(t *testing.T) { 184 // ormerMock is mocked Ormer implementation 185 var ormerMock *beego.MockOrmer 186 // querySeterMock is mocked QuerySeter implementation 187 var querySeterMock *beego.MockQuerySeter 188 189 mockCtrl := gomock.NewController(t) 190 defer mockCtrl.Finish() 191 ormerMock = beego.NewMockOrmer(mockCtrl) 192 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 193 dbm.DBAccess = ormerMock 194 195 cases := []struct { 196 // name is name of the testcase 197 name string 198 // filterReturn is the return of mock interface querySeterMock's filter function 199 filterReturn orm.QuerySeter 200 // updateReturnInt is the first return of mock interface querySeterMock's update function 201 updateReturnInt int64 202 // updateReturnErr is the second return of mock interface querySeterMocks's update function also expected error 203 updateReturnErr error 204 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 205 queryTableReturn orm.QuerySeter 206 }{{ 207 // Success Case 208 name: "SuccessCase", 209 filterReturn: querySeterMock, 210 updateReturnInt: int64(1), 211 updateReturnErr: nil, 212 queryTableReturn: querySeterMock, 213 }, { 214 // Failure Case 215 name: "FailureCase", 216 filterReturn: querySeterMock, 217 updateReturnInt: int64(0), 218 updateReturnErr: errFailedDBOperation, 219 queryTableReturn: querySeterMock, 220 }, 221 } 222 223 // run the test cases 224 for _, test := range cases { 225 t.Run(test.name, func(t *testing.T) { 226 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(2) 227 querySeterMock.EXPECT().Update(gomock.Any()).Return(test.updateReturnInt, test.updateReturnErr).Times(1) 228 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 229 err := UpdateDeviceAttrField("test", "test", "test", "test") 230 if test.updateReturnErr != err { 231 t.Errorf("UpdateDeviceAttrField Case failed: wanted error %v and got error %v", test.updateReturnErr, err) 232 } 233 }) 234 } 235 } 236 237 // TestUpdateDeviceAttrFields is function to test UpdateDeviceAttrFields 238 func TestUpdateDeviceAttrFields(t *testing.T) { 239 // ormerMock is mocked Ormer implementation 240 var ormerMock *beego.MockOrmer 241 // querySeterMock is mocked QuerySeter implementation 242 var querySeterMock *beego.MockQuerySeter 243 244 mockCtrl := gomock.NewController(t) 245 defer mockCtrl.Finish() 246 ormerMock = beego.NewMockOrmer(mockCtrl) 247 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 248 dbm.DBAccess = ormerMock 249 250 cases := []struct { 251 // name is name of the testcase 252 name string 253 // filterReturn is the return of mock interface querySeterMock's filter function 254 filterReturn orm.QuerySeter 255 // updateReturnInt is the first return of mock interface querySeterMock's update function 256 updateReturnInt int64 257 // updateReturnErr is the second return of mock interface querySeterMocks's update function also expected error 258 updateReturnErr error 259 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 260 queryTableReturn orm.QuerySeter 261 }{{ 262 // Success Case 263 name: "SuccessCase", 264 filterReturn: querySeterMock, 265 updateReturnInt: int64(1), 266 updateReturnErr: nil, 267 queryTableReturn: querySeterMock, 268 }, { 269 // Failure Case 270 name: "FailureCase", 271 filterReturn: querySeterMock, 272 updateReturnInt: int64(0), 273 updateReturnErr: errFailedDBOperation, 274 queryTableReturn: querySeterMock, 275 }, 276 } 277 278 // run the test cases 279 for _, test := range cases { 280 t.Run(test.name, func(t *testing.T) { 281 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(2) 282 querySeterMock.EXPECT().Update(gomock.Any()).Return(test.updateReturnInt, test.updateReturnErr).Times(1) 283 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 284 err := UpdateDeviceAttrFields("test", "test", make(map[string]interface{})) 285 if test.updateReturnErr != err { 286 t.Errorf("UpdateDeviceAttrFields Case failed: wanted error %v and got error %v", test.updateReturnErr, err) 287 } 288 }) 289 } 290 } 291 292 // TestQueryDeviceAttr is function to test QueryDeviceAttr 293 func TestQueryDeviceAttr(t *testing.T) { 294 // ormerMock is mocked Ormer implementation 295 var ormerMock *beego.MockOrmer 296 // querySeterMock is mocked QuerySeter implementation 297 var querySeterMock *beego.MockQuerySeter 298 299 mockCtrl := gomock.NewController(t) 300 defer mockCtrl.Finish() 301 ormerMock = beego.NewMockOrmer(mockCtrl) 302 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 303 dbm.DBAccess = ormerMock 304 305 cases := []struct { 306 // name is name of the testcase 307 name string 308 // filterReturn is the return of mock interface querySeterMock's filter function 309 filterReturn orm.QuerySeter 310 // allReturnInt is the first return of mock interface querySeterMock's all function 311 allReturnInt int64 312 // allReturnErr is the second return of mock interface querySeterMocks's all function also expected error 313 allReturnErr error 314 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 315 queryTableReturn orm.QuerySeter 316 }{{ 317 // Success Case 318 name: "SuccessCase", 319 filterReturn: querySeterMock, 320 allReturnInt: int64(1), 321 allReturnErr: nil, 322 queryTableReturn: querySeterMock, 323 }, { 324 // Failure Case 325 name: "FailureCase", 326 filterReturn: querySeterMock, 327 allReturnInt: int64(0), 328 allReturnErr: errFailedDBOperation, 329 queryTableReturn: querySeterMock, 330 }, 331 } 332 333 // fakeDeviceAttr is used to set the argument of All function 334 fakeDeviceAttr := new([]DeviceAttr) 335 fakeDeviceAttrArray := make([]DeviceAttr, 1) 336 fakeDeviceAttrArray[0] = DeviceAttr{DeviceID: "Test"} 337 fakeDeviceAttr = &fakeDeviceAttrArray 338 339 // run the test cases 340 for _, test := range cases { 341 t.Run(test.name, func(t *testing.T) { 342 querySeterMock.EXPECT().All(gomock.Any()).SetArg(0, *fakeDeviceAttr).Return(test.allReturnInt, test.allReturnErr).Times(1) 343 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(1) 344 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 345 device, err := QueryDeviceAttr("test", "test") 346 if test.allReturnErr != err { 347 t.Errorf("QueryDeviceAttr Case failed: wanted error %v and got error %v", test.allReturnErr, err) 348 } 349 350 if err == nil { 351 if len(*device) != 1 { 352 t.Errorf("QueryDeviceAttr Case failed: wanted length 1 and got length %v", len(*device)) 353 } 354 } 355 }) 356 } 357 } 358 359 // TestUpdateDeviceAttrMulti is function to test UpdateDeviceAttrMulti 360 func TestUpdateDeviceAttrMulti(t *testing.T) { 361 // ormerMock is mocked Ormer implementation 362 var ormerMock *beego.MockOrmer 363 // querySeterMock is mocked QuerySeter implementation 364 var querySeterMock *beego.MockQuerySeter 365 366 mockCtrl := gomock.NewController(t) 367 defer mockCtrl.Finish() 368 ormerMock = beego.NewMockOrmer(mockCtrl) 369 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 370 dbm.DBAccess = ormerMock 371 372 cases := []struct { 373 // name is name of the testcase 374 name string 375 // filterReturn is the return of mock interface querySeterMock's filter function 376 filterReturn orm.QuerySeter 377 // updateReturnInt is the first return of mock interface querySeterMock's update function 378 updateReturnInt int64 379 // updateReturnErr is the second return of mock interface querySeterMocks's update function also expected error 380 updateReturnErr error 381 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 382 queryTableReturn orm.QuerySeter 383 }{{ 384 // Success Case 385 name: "SuccessCase", 386 filterReturn: querySeterMock, 387 updateReturnInt: int64(1), 388 updateReturnErr: nil, 389 queryTableReturn: querySeterMock, 390 }, { 391 // Failure Case 392 name: "FailureCase", 393 filterReturn: querySeterMock, 394 updateReturnInt: int64(0), 395 updateReturnErr: errFailedDBOperation, 396 queryTableReturn: querySeterMock, 397 }, 398 } 399 400 // updateDevice is argument to UpdateDeviceAttrMulti function 401 updateDevice := make([]DeviceAttrUpdate, 0) 402 updateDevice = append(updateDevice, DeviceAttrUpdate{DeviceID: "test"}) 403 404 // run the test cases 405 for _, test := range cases { 406 t.Run(test.name, func(t *testing.T) { 407 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(2) 408 querySeterMock.EXPECT().Update(gomock.Any()).Return(test.updateReturnInt, test.updateReturnErr).Times(1) 409 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(1) 410 err := UpdateDeviceAttrMulti(updateDevice) 411 if test.updateReturnErr != err { 412 t.Errorf("UpdateDeviceAttrMulti Case failed: wanted error %v and got error %v", test.updateReturnErr, err) 413 } 414 }) 415 } 416 } 417 418 // TestDeviceAttrTrans is function to test DeviceAttrTrans 419 func TestDeviceAttrTrans(t *testing.T) { 420 // ormerMock is mocked Ormer implementation 421 var ormerMock *beego.MockOrmer 422 // querySeterMock is mocked QuerySeter implementation 423 var querySeterMock *beego.MockQuerySeter 424 425 mockCtrl := gomock.NewController(t) 426 defer mockCtrl.Finish() 427 ormerMock = beego.NewMockOrmer(mockCtrl) 428 querySeterMock = beego.NewMockQuerySeter(mockCtrl) 429 dbm.DBAccess = ormerMock 430 431 cases := []struct { 432 // name is name of the testcase 433 name string 434 // rollBackTimes is number of times rollback is expected 435 rollBackTimes int 436 // commitTimes is number of times commit is expected 437 commitTimes int 438 // beginTimes is number of times begin is expected 439 beginTimes int 440 // filterReturn is the return of mock interface querySeterMock's filter function 441 filterReturn orm.QuerySeter 442 // filterTimes is the number of times filter is called 443 filterTimes int 444 // insertReturnInt is the first return of mock interface ormerMock's Insert function 445 insertReturnInt int64 446 // insertReturnErr is the second return of mock interface ormerMock's Insert function 447 insertReturnErr error 448 // insertTimes is number of times Insert is expected 449 insertTimes int 450 // deleteReturnInt is the first return of mock interface ormerMock's Delete function 451 deleteReturnInt int64 452 // deleteReturnErr is the second return of mock interface ormerMock's Delete function 453 deleteReturnErr error 454 // deleteTimes is number of times Delete is expected 455 deleteTimes int 456 // updateReturnInt is the first return of mock interface ormerMock's Update function 457 updateReturnInt int64 458 // updateReturnErr is the second return of mock interface ormerMock's Update function 459 updateReturnErr error 460 // updateTimes is number of times Update is expected 461 updateTimes int 462 // queryTableReturn is the return of mock interface ormerMock's QueryTable function 463 queryTableReturn orm.QuerySeter 464 // queryTableTimes is the number of times queryTable is called 465 queryTableTimes int 466 // wantErr is expected error 467 wantErr error 468 }{{ 469 // Failure Case SaveDeviceAttr 470 name: "DeviceAttrTransSaveDeviceAttrFailureCase", 471 rollBackTimes: 1, 472 commitTimes: 0, 473 beginTimes: 1, 474 filterReturn: nil, 475 filterTimes: 0, 476 insertReturnInt: int64(1), 477 insertReturnErr: errFailedDBOperation, 478 insertTimes: 1, 479 deleteReturnInt: int64(1), 480 deleteReturnErr: nil, 481 deleteTimes: 0, 482 updateReturnInt: int64(1), 483 updateReturnErr: nil, 484 updateTimes: 0, 485 queryTableReturn: nil, 486 queryTableTimes: 0, 487 wantErr: errFailedDBOperation, 488 }, { 489 // Failure Case DeleteDeviceAttr 490 name: "DeviceAttrTransDeleteDeviceAttrFailureCase", 491 rollBackTimes: 1, 492 commitTimes: 0, 493 beginTimes: 1, 494 filterReturn: querySeterMock, 495 filterTimes: 2, 496 insertReturnInt: int64(1), 497 insertReturnErr: nil, 498 insertTimes: 1, 499 deleteReturnInt: int64(1), 500 deleteReturnErr: errFailedDBOperation, 501 deleteTimes: 1, 502 updateReturnInt: int64(1), 503 updateReturnErr: nil, 504 updateTimes: 0, 505 queryTableReturn: querySeterMock, 506 queryTableTimes: 1, 507 wantErr: errFailedDBOperation, 508 }, { 509 // Failure Case UpdateDeviceAttrFields 510 name: "DeviceAttrTransUpdateDeviceAttrFieldsFailureCase", 511 rollBackTimes: 1, 512 commitTimes: 0, 513 beginTimes: 1, 514 filterReturn: querySeterMock, 515 filterTimes: 4, 516 insertReturnInt: int64(1), 517 insertReturnErr: nil, 518 insertTimes: 1, 519 deleteReturnInt: int64(1), 520 deleteReturnErr: nil, 521 deleteTimes: 1, 522 updateReturnInt: int64(1), 523 updateReturnErr: errFailedDBOperation, 524 updateTimes: 1, 525 queryTableReturn: querySeterMock, 526 queryTableTimes: 2, 527 wantErr: errFailedDBOperation, 528 }, { 529 // Success Case 530 name: "DeviceAttrTransSuccessCase", 531 rollBackTimes: 0, 532 commitTimes: 1, 533 beginTimes: 1, 534 filterReturn: querySeterMock, 535 filterTimes: 4, 536 insertReturnInt: int64(1), 537 insertReturnErr: nil, 538 insertTimes: 1, 539 deleteReturnInt: int64(1), 540 deleteReturnErr: nil, 541 deleteTimes: 1, 542 updateReturnInt: int64(1), 543 updateReturnErr: nil, 544 updateTimes: 1, 545 queryTableReturn: querySeterMock, 546 queryTableTimes: 2, 547 wantErr: nil, 548 }, 549 } 550 551 // adds is fake DeviceAttr used as argument 552 adds := make([]DeviceAttr, 0) 553 // deletes is fake DeviceDelete used as argument 554 deletes := make([]DeviceDelete, 0) 555 // updates is fake DeviceAttrUpdate used as argument 556 updates := make([]DeviceAttrUpdate, 0) 557 adds = append(adds, DeviceAttr{DeviceID: "Test"}) 558 deletes = append(deletes, DeviceDelete{DeviceID: "test", Name: "test"}) 559 updates = append(updates, DeviceAttrUpdate{DeviceID: "test", Name: "test", Cols: make(map[string]interface{})}) 560 561 // run the test cases 562 for _, test := range cases { 563 t.Run(test.name, func(t *testing.T) { 564 ormerMock.EXPECT().Rollback().Return(nil).Times(test.rollBackTimes) 565 ormerMock.EXPECT().Commit().Return(nil).Times(test.commitTimes) 566 ormerMock.EXPECT().Begin().Return(nil).Times(test.beginTimes) 567 ormerMock.EXPECT().Insert(gomock.Any()).Return(test.insertReturnInt, test.insertReturnErr).Times(test.insertTimes) 568 ormerMock.EXPECT().QueryTable(gomock.Any()).Return(test.queryTableReturn).Times(test.queryTableTimes) 569 570 querySeterMock.EXPECT().Filter(gomock.Any(), gomock.Any()).Return(test.filterReturn).Times(test.filterTimes) 571 querySeterMock.EXPECT().Delete().Return(test.deleteReturnInt, test.deleteReturnErr).Times(test.deleteTimes) 572 querySeterMock.EXPECT().Update(gomock.Any()).Return(test.updateReturnInt, test.updateReturnErr).Times(test.updateTimes) 573 err := DeviceAttrTrans(adds, deletes, updates) 574 if test.wantErr != err { 575 t.Errorf("TestDeviceAttrTrans Case failed: wanted error %v and got error %v", test.wantErr, err) 576 } 577 }) 578 } 579 }