Skip to content

Commit 2f9d0b5

Browse files
authored
Hammer: exit criteria (#141)
The hammer can be configured to stop successfully if a desired number of leaves are written, and to fail after a max runtime is reached. These two can be used in conjunction to run a headless test for write performance.
1 parent 1ccc120 commit 2f9d0b5

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

hammer/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,18 @@ go run ./hammer \
2929
--max_write_ops=42
3030
```
3131

32+
For a headless write-only example that could be used for integration tests, this command attempts to write 2500 leaves within 1 minute.
33+
If the target number of leaves is reached then it exits successfully.
34+
If the timeout of 1 minute is reached first, then it exits with an exit code of 1.
35+
36+
```shell
37+
go run ./hammer \
38+
--log_public_key=Test-Betty+df84580a+AQQASqPUZoIHcJAF5mBOryctwFdTV1E0GRY4kEAtTzwB \
39+
--log_url=http://localhost:2024 \
40+
--max_read_ops=0 \
41+
--num_writers=512 \
42+
--max_write_ops=512 \
43+
--max_runtime=1m \
44+
--leaf_write_goal=2500 \
45+
--show_ui=false
46+
```

hammer/hammer.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ var (
5252
leafMinSize = flag.Int("leaf_min_size", 0, "Minimum size in bytes of individual leaves")
5353
dupChance = flag.Float64("dup_chance", 0.1, "The probability of a generated leaf being a duplicate of a previous value")
5454

55+
leafWriteGoal = flag.Int64("leaf_write_goal", 0, "Exit after writing this number of leaves, or 0 to keep going indefinitely")
56+
maxRunTime = flag.Duration("max_runtime", 0, "Fail after this amount of time has passed, or 0 to keep going indefinitely")
57+
5558
showUI = flag.Bool("show_ui", true, "Set to false to disable the text-based UI")
5659

5760
hc = &http.Client{
@@ -68,7 +71,7 @@ func main() {
6871
klog.InitFlags(nil)
6972
flag.Parse()
7073

71-
ctx := context.Background()
74+
ctx, cancel := context.WithCancel(context.Background())
7275

7376
logSigV, err := note.NewVerifier(*logPubKey)
7477
if err != nil {
@@ -95,6 +98,45 @@ func main() {
9598

9699
gen := newLeafGenerator(tracker.LatestConsistent.Size, *leafMinSize, *dupChance)
97100
hammer := NewHammer(&tracker, f.Fetch, w.Write, gen, ha.seqLeafChan, ha.errChan)
101+
102+
exitCode := 0
103+
if *leafWriteGoal > 0 {
104+
go func() {
105+
startTime := time.Now()
106+
goal := tracker.LatestConsistent.Size + uint64(*leafWriteGoal)
107+
klog.Infof("Will exit once tree size is at least %d", goal)
108+
tick := time.NewTicker(1 * time.Second)
109+
for {
110+
select {
111+
case <-ctx.Done():
112+
return
113+
case <-tick.C:
114+
if tracker.LatestConsistent.Size >= goal {
115+
elapsed := time.Since(startTime)
116+
klog.Infof("Reached tree size goal of %d after %s; exiting", goal, elapsed)
117+
cancel()
118+
return
119+
}
120+
}
121+
}
122+
}()
123+
}
124+
if *maxRunTime > 0 {
125+
go func() {
126+
klog.Infof("Will fail after %s", *maxRunTime)
127+
for {
128+
select {
129+
case <-ctx.Done():
130+
return
131+
case <-time.After(*maxRunTime):
132+
klog.Infof("Max runtime reached; exiting")
133+
exitCode = 1
134+
cancel()
135+
return
136+
}
137+
}
138+
}()
139+
}
98140
hammer.Run(ctx)
99141

100142
if *showUI {
@@ -103,6 +145,7 @@ func main() {
103145
} else {
104146
<-ctx.Done()
105147
}
148+
os.Exit(exitCode)
106149
}
107150

108151
func NewHammer(tracker *client.LogStateTracker, f client.Fetcher, w LeafWriter, gen func() []byte, seqLeafChan chan<- leafTime, errChan chan<- error) *Hammer {

0 commit comments

Comments
 (0)