From c0ef3540a586fa81cb164e890ed89b8db53eb602 Mon Sep 17 00:00:00 2001 From: Kacper Sawicki Date: Fri, 6 Mar 2026 15:09:58 +0100 Subject: [PATCH] feat(namesgenerator): expand auto-generated name digit suffix to 00-99 (#22665) --- coderd/util/namesgenerator/namesgenerator.go | 12 +++++------- .../namesgenerator_internal_test.go | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/coderd/util/namesgenerator/namesgenerator.go b/coderd/util/namesgenerator/namesgenerator.go index 23bd9e9a6e..404ff7d47f 100644 --- a/coderd/util/namesgenerator/namesgenerator.go +++ b/coderd/util/namesgenerator/namesgenerator.go @@ -9,6 +9,7 @@ package namesgenerator import ( + "fmt" "math/rand/v2" "strconv" "strings" @@ -34,17 +35,14 @@ func NameWith(delim string) string { return adjective + delim + last } -// NameDigitWith returns a random name with a single random digit suffix (1-9), -// in the format "[adjective][delim][surname][digit]" e.g. "happy_smith9". +// NameDigitWith returns a random name with a two-digit suffix (00-99), +// in the format "[adjective][delim][surname][digit]" e.g. "happy_smith42". // Provides some collision resistance while keeping names short and clean. // Not guaranteed to be unique. func NameDigitWith(delim string) string { - const ( - minDigit = 1 - maxDigit = 9 - ) //nolint:gosec // The random digit doesn't need to be cryptographically secure. - return NameWith(delim) + strconv.Itoa(rand.IntN(maxDigit-minDigit+1)) + name := NameWith(delim) + fmt.Sprintf("%02d", rand.IntN(100)) + return truncate(name, maxNameLen) } // UniqueName returns a random name with a monotonically increasing suffix, diff --git a/coderd/util/namesgenerator/namesgenerator_internal_test.go b/coderd/util/namesgenerator/namesgenerator_internal_test.go index a69b66bdaa..83e0bd8363 100644 --- a/coderd/util/namesgenerator/namesgenerator_internal_test.go +++ b/coderd/util/namesgenerator/namesgenerator_internal_test.go @@ -93,6 +93,21 @@ func TestUniqueNameWithLength(t *testing.T) { } } +func TestNameDigitWithLength(t *testing.T) { + t.Parallel() + + const iter = 10000 + for range iter { + name := NameDigitWith("_") + assert.LessOrEqual(t, len(name), maxNameLen) + assert.Contains(t, name, "_") + assert.Equal(t, name, strings.ToLower(name)) + verifyNoWhitespace(t, name) + // Must end with exactly 2 digits. + assert.Regexp(t, `[a-z]\d{2}$`, name) + } +} + func verifyNoWhitespace(t *testing.T, s string) { t.Helper() for _, r := range s {