github.com/scraniel/migrate@v0.0.0-20230320185700-339088f36cee/database/util_test.go (about) 1 package database 2 3 import ( 4 "errors" 5 "go.uber.org/atomic" 6 "testing" 7 ) 8 9 func TestGenerateAdvisoryLockId(t *testing.T) { 10 testcases := []struct { 11 dbname string 12 additional []string 13 expectedID string // empty string signifies that an error is expected 14 }{ 15 { 16 dbname: "database_name", 17 expectedID: "1764327054", 18 }, 19 { 20 dbname: "database_name", 21 additional: []string{"schema_name_1"}, 22 expectedID: "2453313553", 23 }, 24 { 25 dbname: "database_name", 26 additional: []string{"schema_name_2"}, 27 expectedID: "235207038", 28 }, 29 { 30 dbname: "database_name", 31 additional: []string{"schema_name_1", "schema_name_2"}, 32 expectedID: "3743845847", 33 }, 34 } 35 36 for _, tc := range testcases { 37 t.Run(tc.dbname, func(t *testing.T) { 38 if id, err := GenerateAdvisoryLockId(tc.dbname, tc.additional...); err == nil { 39 if id != tc.expectedID { 40 t.Error("Generated incorrect ID:", id, "!=", tc.expectedID) 41 } 42 } else { 43 if tc.expectedID != "" { 44 t.Error("Got unexpected error:", err) 45 } 46 } 47 }) 48 } 49 } 50 51 func TestCasRestoreOnErr(t *testing.T) { 52 casErr := errors.New("test lock CAS failure") 53 fErr := errors.New("test callback error") 54 55 testcases := []struct { 56 name string 57 lock *atomic.Bool 58 from bool 59 to bool 60 expectLock bool 61 fErr error 62 expectError error 63 }{ 64 { 65 name: "Test positive CAS lock", 66 lock: atomic.NewBool(false), 67 from: false, 68 to: true, 69 expectLock: true, 70 fErr: nil, 71 expectError: nil, 72 }, 73 { 74 name: "Test negative CAS lock", 75 lock: atomic.NewBool(true), 76 from: false, 77 to: true, 78 expectLock: true, 79 fErr: nil, 80 expectError: casErr, 81 }, 82 { 83 name: "Test negative with callback lock", 84 lock: atomic.NewBool(false), 85 from: false, 86 to: true, 87 expectLock: false, 88 fErr: fErr, 89 expectError: fErr, 90 }, 91 } 92 93 for _, tc := range testcases { 94 t.Run(tc.name, func(t *testing.T) { 95 if err := CasRestoreOnErr(tc.lock, tc.from, tc.to, casErr, func() error { 96 return tc.fErr 97 }); err != tc.expectError { 98 t.Error("Incorrect error value returned") 99 } 100 101 if tc.lock.Load() != tc.expectLock { 102 t.Error("Incorrect state of lock") 103 } 104 }) 105 } 106 }