From 9e134185658490ad2e2735684b8f9e400c8e8121 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Sun, 31 Aug 2025 23:15:31 +0300 Subject: [PATCH] retry the random func to minimize tests flakiness --- tools/security/random_by_regex_test.go | 54 ++++++++++------- tools/security/random_test.go | 81 ++++++++++++++++---------- 2 files changed, 82 insertions(+), 53 deletions(-) diff --git a/tools/security/random_by_regex_test.go b/tools/security/random_by_regex_test.go index 86d8c769..208e8553 100644 --- a/tools/security/random_by_regex_test.go +++ b/tools/security/random_by_regex_test.go @@ -35,31 +35,41 @@ func TestRandomStringByRegex(t *testing.T) { for i, s := range scenarios { t.Run(fmt.Sprintf("%d_%q", i, s.pattern), func(t *testing.T) { - str, err := security.RandomStringByRegex(s.pattern, s.flags...) + var run func(int) + run = func(attempt int) { + str, err := security.RandomStringByRegex(s.pattern, s.flags...) - hasErr := err != nil - if hasErr != s.expectError { - t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, err) + hasErr := err != nil + if hasErr != s.expectError { + t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, err) + } + + if hasErr { + return + } + + r, err := regexp.Compile(s.pattern) + if err != nil { + t.Fatal(err) + } + if !r.Match([]byte(str)) { + t.Fatalf("Expected %q to match pattern %v", str, s.pattern) + } + + if slices.Contains(generated, str) { + if attempt > 3 { + t.Fatalf("The generated string %q already exists in\n%v", str, generated) + } + + // rerun + run(attempt + 1) + return + } + + generated = append(generated, str) } - if hasErr { - return - } - - r, err := regexp.Compile(s.pattern) - if err != nil { - t.Fatal(err) - } - - if !r.Match([]byte(str)) { - t.Fatalf("Expected %q to match pattern %v", str, s.pattern) - } - - if slices.Contains(generated, str) { - t.Fatalf("The generated string %q already exists in\n%v", str, generated) - } - - generated = append(generated, str) + run(1) }) } } diff --git a/tools/security/random_test.go b/tools/security/random_test.go index d9177792..d0f8ecea 100644 --- a/tools/security/random_test.go +++ b/tools/security/random_test.go @@ -3,6 +3,7 @@ package security_test import ( "fmt" "regexp" + "slices" "testing" "github.com/pocketbase/pocketbase/tools/security" @@ -38,55 +39,73 @@ func testRandomStringWithAlphabet(t *testing.T, randomFunc func(n int, alphabet for i, s := range scenarios { t.Run(fmt.Sprintf("%d_%q", i, s.alphabet), func(t *testing.T) { - generated := make([]string, 0, 1000) + generated := make([]string, 0, 500) length := 10 - for j := 0; j < 1000; j++ { - result := randomFunc(length, s.alphabet) + for j := 0; j < 500; j++ { + var run func(int) + run = func(attempt int) { + result := randomFunc(length, s.alphabet) - if len(result) != length { - t.Fatalf("(%d) Expected the length of the string to be %d, got %d", j, length, len(result)) - } - - reg := regexp.MustCompile(s.expectPattern) - if match := reg.MatchString(result); !match { - t.Fatalf("(%d) The generated string should have only %s characters, got %q", j, s.expectPattern, result) - } - - for _, str := range generated { - if str == result { - t.Fatalf("(%d) Repeating random string - found %q in %q", j, result, generated) + if len(result) != length { + t.Fatalf("(%d) Expected the length of the string to be %d, got %d", j, length, len(result)) } + + reg := regexp.MustCompile(s.expectPattern) + if match := reg.MatchString(result); !match { + t.Fatalf("(%d) The generated string should have only %s characters, got %q", j, s.expectPattern, result) + } + + if slices.Contains(generated, result) { + if attempt > 3 { + t.Fatalf("(%d) Repeating random string - found %q in %q", j, result, generated) + } + + // rerun + run(attempt + 1) + return + } + + generated = append(generated, result) } - generated = append(generated, result) + run(1) } }) } } func testRandomString(t *testing.T, randomFunc func(n int) string) { - generated := make([]string, 0, 1000) + generated := make([]string, 0, 500) reg := regexp.MustCompile(`[a-zA-Z0-9]+`) length := 10 - for i := 0; i < 1000; i++ { - result := randomFunc(length) + for i := 0; i < 500; i++ { + var run func(int) + run = func(attempt int) { + result := randomFunc(length) - if len(result) != length { - t.Fatalf("(%d) Expected the length of the string to be %d, got %d", i, length, len(result)) - } - - if match := reg.MatchString(result); !match { - t.Fatalf("(%d) The generated string should have only [a-zA-Z0-9]+ characters, got %q", i, result) - } - - for _, str := range generated { - if str == result { - t.Fatalf("(%d) Repeating random string - found %q in \n%v", i, result, generated) + if len(result) != length { + t.Fatalf("(%d) Expected the length of the string to be %d, got %d", i, length, len(result)) } + + if match := reg.MatchString(result); !match { + t.Fatalf("(%d) The generated string should have only [a-zA-Z0-9]+ characters, got %q", i, result) + } + + if slices.Contains(generated, result) { + if attempt > 3 { + t.Fatalf("(%d) Repeating random string - found %q in \n%v", i, result, generated) + } + + // rerun + run(attempt + 1) + return + } + + generated = append(generated, result) } - generated = append(generated, result) + run(1) } }