whatcanGOwrong
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// countertest provides testing utilities for counters.
|
||||
// This package cannot be used except for testing.
|
||||
package countertest
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/telemetry/counter"
|
||||
ic "golang.org/x/telemetry/internal/counter"
|
||||
"golang.org/x/telemetry/internal/telemetry"
|
||||
)
|
||||
|
||||
var (
|
||||
openedMu sync.Mutex
|
||||
opened bool
|
||||
)
|
||||
|
||||
// SupportedPlatform reports if this platform supports Open()
|
||||
const SupportedPlatform = !telemetry.DisabledOnPlatform
|
||||
|
||||
func isOpen() bool {
|
||||
openedMu.Lock()
|
||||
defer openedMu.Unlock()
|
||||
return opened
|
||||
}
|
||||
|
||||
// Open enables telemetry data writing to disk.
|
||||
// This is supposed to be called once during the program execution
|
||||
// (i.e. typically in TestMain), and must not be used with
|
||||
// golang.org/x/telemetry/counter.Open.
|
||||
func Open(telemetryDir string) {
|
||||
openedMu.Lock()
|
||||
defer openedMu.Unlock()
|
||||
if opened {
|
||||
panic("Open was called more than once")
|
||||
}
|
||||
telemetry.Default = telemetry.NewDir(telemetryDir)
|
||||
|
||||
// TODO(rfindley): reinstate test coverage with counter rotation enabled.
|
||||
// Before the [counter.Open] and [counter.OpenAndRotate] APIs were split,
|
||||
// this called counter.Open (which rotated!).
|
||||
counter.Open()
|
||||
opened = true
|
||||
}
|
||||
|
||||
// ReadCounter reads the given counter.
|
||||
func ReadCounter(c *counter.Counter) (count uint64, _ error) {
|
||||
return ic.Read(c)
|
||||
}
|
||||
|
||||
// ReadStackCounter reads the given StackCounter.
|
||||
func ReadStackCounter(c *counter.StackCounter) (stackCounts map[string]uint64, _ error) {
|
||||
return ic.ReadStack(c)
|
||||
}
|
||||
|
||||
// ReadFile reads the counters and stack counters from the given file.
|
||||
func ReadFile(name string) (counters, stackCounters map[string]uint64, _ error) {
|
||||
return ic.ReadFile(name)
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.21
|
||||
|
||||
package countertest
|
||||
|
||||
import "testing"
|
||||
|
||||
func init() {
|
||||
// Extra safety check for go1.21+.
|
||||
if !testing.Testing() {
|
||||
panic("use of this package is disallowed in non-testing code")
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.21
|
||||
|
||||
package countertest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/telemetry/counter"
|
||||
"golang.org/x/telemetry/internal/telemetry"
|
||||
"golang.org/x/telemetry/internal/testenv"
|
||||
)
|
||||
|
||||
func TestReadCounter(t *testing.T) {
|
||||
testenv.SkipIfUnsupportedPlatform(t)
|
||||
c := counter.New("foobar")
|
||||
|
||||
got, err := ReadCounter(c)
|
||||
if err != nil {
|
||||
t.Errorf("ReadCounter = (%d, %v), want (0,nil)", got, err)
|
||||
}
|
||||
if got != 0 {
|
||||
t.Fatalf("ReadCounter = %d, want 0", got)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(100)
|
||||
for i := 0; i < 100; i++ {
|
||||
go func() {
|
||||
c.Inc()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
if got, err := ReadCounter(c); err != nil || got != 100 {
|
||||
t.Errorf("ReadCounter = (%v, %v), want (%v, nil)", got, err, 100)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadStackCounter(t *testing.T) {
|
||||
testenv.SkipIfUnsupportedPlatform(t)
|
||||
c := counter.NewStack("foobar", 8)
|
||||
|
||||
if got, err := ReadStackCounter(c); err != nil || len(got) != 0 {
|
||||
t.Errorf("ReadStackCounter = (%q, %v), want (%v, nil)", got, err, 0)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(100)
|
||||
for i := 0; i < 100; i++ {
|
||||
go func() {
|
||||
c.Inc() // one stack!
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
got, err := ReadStackCounter(c)
|
||||
if err != nil || len(got) != 1 {
|
||||
t.Fatalf("ReadStackCounter = (%v, %v), want to read one entry", stringify(got), err)
|
||||
}
|
||||
for k, v := range got {
|
||||
if !strings.Contains(k, t.Name()) || v != 100 {
|
||||
t.Fatalf("ReadStackCounter = %v, want a stack counter with value 100", got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSupport(t *testing.T) {
|
||||
if SupportedPlatform == telemetry.DisabledOnPlatform {
|
||||
t.Errorf("supported mismatch: us %v, telemetry.internal.Disabled %v",
|
||||
SupportedPlatform, telemetry.DisabledOnPlatform)
|
||||
}
|
||||
}
|
||||
|
||||
func stringify(m map[string]uint64) string {
|
||||
kv := make([]string, 0, len(m))
|
||||
for k, v := range m {
|
||||
kv = append(kv, fmt.Sprintf("%q:%v", k, v))
|
||||
}
|
||||
slices.Sort(kv)
|
||||
return "{" + strings.Join(kv, " ") + "}"
|
||||
}
|
||||
Reference in New Issue
Block a user