(t *testing.T)
| 1894 | } |
| 1895 | |
| 1896 | func TestUpdatePrincipalCASRetry(t *testing.T) { |
| 1897 | base.SetUpTestLogging(t, base.LevelDebug, base.KeyAuth, base.KeyCRUD) |
| 1898 | |
| 1899 | // ensure we don't batch sequences so that the number of released sequences is deterministic |
| 1900 | defer SuspendSequenceBatching()() |
| 1901 | |
| 1902 | tb := base.GetTestBucket(t) |
| 1903 | defer tb.Close(base.TestCtx(t)) |
| 1904 | |
| 1905 | tests := []struct { |
| 1906 | numCASRetries int32 |
| 1907 | expectError bool |
| 1908 | }{ |
| 1909 | {numCASRetries: 0}, |
| 1910 | {numCASRetries: 1}, |
| 1911 | {numCASRetries: 2}, |
| 1912 | {numCASRetries: 5}, |
| 1913 | {numCASRetries: 10}, |
| 1914 | {numCASRetries: auth.PrincipalUpdateMaxCasRetries - 1}, |
| 1915 | {numCASRetries: auth.PrincipalUpdateMaxCasRetries, expectError: true}, |
| 1916 | {numCASRetries: auth.PrincipalUpdateMaxCasRetries + 1, expectError: true}, |
| 1917 | } |
| 1918 | |
| 1919 | var ( |
| 1920 | casRetryCount atomic.Int32 |
| 1921 | totalCASRetries atomic.Int32 |
| 1922 | enableCASRetry base.AtomicBool |
| 1923 | ) |
| 1924 | |
| 1925 | lb := base.NewLeakyBucket(tb, base.LeakyBucketConfig{ |
| 1926 | UpdateCallback: func(key string) { |
| 1927 | casRetryCountInt, totalCASRetriesInt := casRetryCount.Load(), totalCASRetries.Load() |
| 1928 | if enableCASRetry.IsTrue() && casRetryCountInt < totalCASRetriesInt { |
| 1929 | casRetryCount.Add(1) |
| 1930 | casRetryCountInt = casRetryCount.Load() |
| 1931 | t.Logf("foreceCASRetry %d/%d: Forcing CAS retry for key: %q", casRetryCountInt, totalCASRetriesInt, key) |
| 1932 | var body []byte |
| 1933 | originalCAS, err := tb.GetMetadataStore().Get(key, &body) |
| 1934 | require.NoError(t, err) |
| 1935 | err = tb.GetMetadataStore().Set(key, 0, nil, body) |
| 1936 | require.NoError(t, err) |
| 1937 | newCAS, err := tb.GetMetadataStore().Get(key, &body) |
| 1938 | require.NoError(t, err) |
| 1939 | t.Logf("foreceCASRetry %d/%d: Doc %q CAS changed from %d to %d", casRetryCountInt, totalCASRetriesInt, key, originalCAS, newCAS) |
| 1940 | } |
| 1941 | }, |
| 1942 | IgnoreClose: true, |
| 1943 | }) |
| 1944 | |
| 1945 | db, ctx := setupTestDBForBucket(t, lb) |
| 1946 | defer db.Close(ctx) |
| 1947 | |
| 1948 | // Create a user with access to channel ABC |
| 1949 | authenticator := db.Authenticator(ctx) |
| 1950 | user, err := authenticator.NewUser("naomi", "letmein", channels.BaseSetOf(t, "ABC")) |
| 1951 | require.NoError(t, err) |
| 1952 | require.NoError(t, authenticator.Save(user)) |
| 1953 |
nothing calls this directly
no test coverage detected