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  }