-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgoid_test.go
More file actions
133 lines (111 loc) · 2.92 KB
/
Copy pathgoid_test.go
File metadata and controls
133 lines (111 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2025, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package goid
import (
"fmt"
"sync"
"testing"
)
func BenchmarkGet(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = Get()
}
}
func BenchmarkGetFromStack(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = GetFromStack()
}
}
func TestGoroutineIDUniquenessAndConsistency(t *testing.T) {
const numGoroutines = 100
// Channel to collect results from goroutines
type result struct {
goroutineIndex int
getID uint64
getFromStackID uint64
err error
}
results := make(chan result, numGoroutines)
var wg sync.WaitGroup
// Launch 100 goroutines
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
// Get IDs using both methods
getID := Get()
getFromStackID := GetFromStack()
// Verify both methods return the same value
var err error
if getID != getFromStackID {
err = fmt.Errorf("goroutine %d: Get()=%d != GetFromStack()=%d",
index, getID, getFromStackID)
}
results <- result{
goroutineIndex: index,
getID: getID,
getFromStackID: getFromStackID,
err: err,
}
}(i)
}
// Wait for all goroutines to complete
wg.Wait()
close(results)
// Collect and analyze results
seenIDs := make(map[uint64][]int) // map[goid][]goroutineIndexes
var errors []error
for res := range results {
if res.err != nil {
errors = append(errors, res.err)
continue
}
// Track which goroutines had this ID
seenIDs[res.getID] = append(seenIDs[res.getID], res.goroutineIndex)
}
// Report any consistency errors between Get() and GetFromStack()
if len(errors) > 0 {
for _, err := range errors {
t.Error(err)
}
}
// Verify uniqueness - each goroutine should have a unique ID
var duplicates []string
for goid, goroutineIndexes := range seenIDs {
if len(goroutineIndexes) > 1 {
duplicates = append(duplicates, fmt.Sprintf("goid %d used by goroutines %v", goid, goroutineIndexes))
}
}
if len(duplicates) > 0 {
t.Errorf("Found duplicate goroutine IDs:\n%s", fmt.Sprintf(" %s\n", duplicates))
}
// Verify we got results from all goroutines
if len(seenIDs) != numGoroutines {
t.Errorf("Expected %d unique goroutine IDs, got %d", numGoroutines, len(seenIDs))
}
// Log success summary
t.Logf("Successfully tested %d goroutines:", numGoroutines)
t.Logf(" - All goroutine IDs are unique: %v", len(duplicates) == 0)
t.Logf(" - Get() and GetFromStack() are consistent: %v", len(errors) == 0)
t.Logf(" - ID range: %d to %d", minID(seenIDs), maxID(seenIDs))
}
// Helper function to find minimum ID
func minID(seenIDs map[uint64][]int) uint64 {
var min uint64 = ^uint64(0) // max uint64
for id := range seenIDs {
if id < min {
min = id
}
}
return min
}
// Helper function to find maximum ID
func maxID(seenIDs map[uint64][]int) uint64 {
var max uint64
for id := range seenIDs {
if id > max {
max = id
}
}
return max
}