-
Notifications
You must be signed in to change notification settings - Fork 2
/
taglocker_test.go
152 lines (133 loc) · 3.55 KB
/
taglocker_test.go
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package plc
import (
"fmt"
"math/rand"
"strings"
"testing"
)
// Generates a random fully-qualified tag, and returns
// paths to that tag but also all intermediary prefixes.
// We will test that we can lock intermediary nodes by
// randomly choosing from these returned values.
func genPaths() []string {
var paths []string
/*
* The EBNF is:
*
* tag ::= SYMBOLIC_SEG ( tag_seg )* ( bit_seg )?
*
* tag_seg ::= '.' SYMBOLIC_SEG
* '[' array_seg ']'
*
* bit_seg ::= '.' [0-9]+
*
* array_seg ::= NUMERIC_SEG ( ',' NUMERIC_SEG )*
*
* SYMBOLIC_SEG ::= [a-zA-Z]([a-zA-Z0-9_]*)
*
* NUMERIC_SEG ::= [0-9]+
*
*/
genSymbolicSeg := func() string {
length := 1 + rand.Intn(10)
bs := make([]byte, length)
bs[0] = alphaCharset[rand.Intn(len(alphaCharset))]
for i := 1; i < len(bs); i++ {
bs[i] = alphanumCharset[rand.Intn(len(alphanumCharset))]
}
return string(bs)
}
genNumericSeg := func() string {
return fmt.Sprintf("%d", rand.Intn(10))
}
genArraySeg := func() string {
// TODO: when the parser supports comma-separated multidimensional
// arrays, include potentially generating those.
return genNumericSeg()
}
genTagSeg := func() string {
if rand.Intn(2) == 0 {
return "." + genSymbolicSeg()
}
return fmt.Sprintf("[%s]", genArraySeg())
}
// tag ::= SYMBOLIC_SEG ( tag_seg )* ( bit_seg )?
var sb strings.Builder
sb.WriteString(genSymbolicSeg())
for i := 0; i < rand.Intn(5); i++ {
//paths = append(paths, sb.String())
sb.WriteString(genTagSeg())
}
paths = append(paths, sb.String())
return paths
}
func BenchmarkSerialTagLocking(b *testing.B) {
benchmarkTagLockLocking(b, serialTestConcurrency, testWritePrecentage)
}
func BenchmarkLowConcurrencyTagLocking(b *testing.B) {
benchmarkTagLockLocking(b, lowTestConcurrency, testWritePrecentage)
}
func BenchmarkMedConcurrencyTagLocking(b *testing.B) {
benchmarkTagLockLocking(b, mediumTestConcurrency, testWritePrecentage)
}
func BenchmarkHighConcurrencyTagLocking(b *testing.B) {
benchmarkTagLockLocking(b, highTestConcurrency, testWritePrecentage)
}
func BenchmarkSerialTagLockingWithHeavyWrites(b *testing.B) {
benchmarkTagLockLocking(b, serialTestConcurrency, heavyWritePerc)
}
func BenchmarkLowConcurrencyTagLockingWithHeavyWrites(b *testing.B) {
benchmarkTagLockLocking(b, lowTestConcurrency, heavyWritePerc)
}
func BenchmarkMedConcurrencyTagLockingWithHeavyWrites(b *testing.B) {
benchmarkTagLockLocking(b, mediumTestConcurrency, heavyWritePerc)
}
func BenchmarkHighConcurrencyTagLockingWithHeavyWrites(b *testing.B) {
benchmarkTagLockLocking(b, highTestConcurrency, heavyWritePerc)
}
func benchmarkTagLockLocking(b *testing.B, concurrency int, writePerc int) {
const numTags = 10
barrier := make(chan bool, concurrency)
tl := NewTagLocker(newMockReadWriter())
read := func(name string) {
var garbage uint32
err := tl.ReadTag(name, garbage)
if err != nil {
b.Errorf("%v\n", err)
}
<-barrier
}
write := func(name string) {
err := tl.WriteTag(name, 42)
if err != nil {
b.Errorf("%v\n", err)
}
<-barrier
}
// Generate `numTags` randomly-named tags; the slice of tags
// stores those tags but also all intermediary prefixes to
// those tags, so larger structures can be locked.
var tags []string
for i := 0; i < numTags; i++ {
tags = append(tags, genPaths()...)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
tag := tags[rand.Intn(len(tags))]
isWrite := rand.Intn(100) < writePerc
barrier <- true
if isWrite {
go write(tag)
} else {
go read(tag)
}
}
for {
select {
case <-barrier:
default:
b.StopTimer()
return
}
}
}