mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-05 20:26:47 +02:00
Add a new vet analyzer that checks t.Run subtest names don't contain characters requiring quoting when re-running via "go test -run". This enforces the style guide rule: don't use spaces or punctuation in subtest names. The analyzer flags: - Direct t.Run calls with string literal names containing spaces, regex metacharacters, quotes, or other problematic characters - Table-driven t.Run(tt.name, ...) calls where tt ranges over a slice/map literal with bad name field values Also fix all 978 existing violations across 81 test files, replacing spaces with hyphens and shortening long sentence-like names to concise hyphenated forms. Updates #19242 Change-Id: Ib0ad96a111bd8e764582d1d4902fe2599454ab65 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
121 lines
2.4 KiB
Go
121 lines
2.4 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package syncs_test
|
|
|
|
import (
|
|
"expvar"
|
|
"sync"
|
|
"testing"
|
|
|
|
. "tailscale.com/syncs"
|
|
"tailscale.com/tstest"
|
|
)
|
|
|
|
var (
|
|
_ expvar.Var = (*ShardedInt)(nil)
|
|
// TODO(raggi): future go version:
|
|
// _ encoding.TextAppender = (*ShardedInt)(nil)
|
|
)
|
|
|
|
func BenchmarkShardedInt(b *testing.B) {
|
|
b.ReportAllocs()
|
|
|
|
b.Run("expvar", func(b *testing.B) {
|
|
var m expvar.Int
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
m.Add(1)
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("sharded-int", func(b *testing.B) {
|
|
m := NewShardedInt()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
m.Add(1)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestShardedInt(t *testing.T) {
|
|
t.Run("basics", func(t *testing.T) {
|
|
m := NewShardedInt()
|
|
if got, want := m.Value(), int64(0); got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
m.Add(1)
|
|
if got, want := m.Value(), int64(1); got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
m.Add(2)
|
|
if got, want := m.Value(), int64(3); got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
m.Add(-1)
|
|
if got, want := m.Value(), int64(2); got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
})
|
|
|
|
t.Run("high-concurrency", func(t *testing.T) {
|
|
m := NewShardedInt()
|
|
wg := sync.WaitGroup{}
|
|
numWorkers := 1000
|
|
numIncrements := 1000
|
|
wg.Add(numWorkers)
|
|
for range numWorkers {
|
|
go func() {
|
|
defer wg.Done()
|
|
for range numIncrements {
|
|
m.Add(1)
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
if got, want := m.Value(), int64(numWorkers*numIncrements); got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
for i, shard := range m.GetDistribution() {
|
|
t.Logf("shard %d: %d", i, shard)
|
|
}
|
|
})
|
|
|
|
t.Run("encoding-TextAppender", func(t *testing.T) {
|
|
m := NewShardedInt()
|
|
m.Add(1)
|
|
b := make([]byte, 0, 10)
|
|
b, err := m.AppendText(b)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got, want := string(b), "1"; got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
})
|
|
|
|
t.Run("allocs", func(t *testing.T) {
|
|
m := NewShardedInt()
|
|
tstest.MinAllocsPerRun(t, 0, func() {
|
|
m.Add(1)
|
|
_ = m.Value()
|
|
})
|
|
|
|
// TODO(raggi): fix access to expvar's internal append based
|
|
// interface, unfortunately it's not currently closed for external
|
|
// use, this will alloc when it escapes.
|
|
tstest.MinAllocsPerRun(t, 0, func() {
|
|
m.Add(1)
|
|
_ = m.String()
|
|
})
|
|
|
|
b := make([]byte, 0, 10)
|
|
tstest.MinAllocsPerRun(t, 0, func() {
|
|
m.Add(1)
|
|
m.AppendText(b)
|
|
})
|
|
})
|
|
}
|