https://github.com/akihirosuda/go-replay
record-less semi-deterministic replayer for Go programs
https://github.com/akihirosuda/go-replay
Last synced: 3 months ago
JSON representation
record-less semi-deterministic replayer for Go programs
- Host: GitHub
- URL: https://github.com/akihirosuda/go-replay
- Owner: AkihiroSuda
- License: apache-2.0
- Created: 2016-04-21T10:50:17.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2016-09-30T05:13:37.000Z (about 9 years ago)
- Last Synced: 2024-04-19T21:03:46.830Z (over 1 year ago)
- Language: Go
- Size: 22.5 KB
- Stars: 11
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GoReplay: record-less semi-deterministic replayer for Go programs
[](https://godoc.org/github.com/AkihiroSuda/go-replay)
[](https://travis-ci.org/AkihiroSuda/go-replay)
[](https://goreportcard.com/report/github.com/AkihiroSuda/go-replay)GoReplay replays concurrent Go programs _semi-deterministically_ without recording concrete events.
## How it works
GoReplay injects `time.Sleep(time.Duration(hash(seed, context, stack)) % maxInterval)` to arbitrary execution points of the target Go program.* `seed`: environmental variable `GRSEED`. You can replay the execution by remembering and setting `GRSEED`. The default value is empty value and it disables GoReplay.
* `context`: optional `[]byte` slice.
* `stack`: runtime stack. (planned)
* `maxInterval`: environmental variable `GRMAX` (should be `time.Duration` string). The default value is `10ms`.Name|Type|Default|Description
---|---|---|---
`GRSEED`|`string`|(empty)|The seed value for determining the delay. An empty value disables GoReplay.
`GRMAX`|`time.Duration`|`10ms`|Max delay.
`GRZBIAS`|`float64`|`0.0`|Probability of enforcing the delay to be zero. must be in `[0.0, 1.0)`.## Usage
Follow the example: [`example/ex01`](example/ex01).
```go
package mainimport (
"fmt"
"sync""github.com/AkihiroSuda/go-replay"
)func main() {
n := 8
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func(i interface{}) {
msg := fmt.Sprintf("i=%d", i)
replay.Inject([]byte(msg))
fmt.Printf("%s\n", msg)
wg.Done()
}(i)
}
wg.Wait()
}
```The result is non-deterministic without GoReplay:
```
$ go run example/ex01/main.go
i=7
i=5
i=1
i=6
i=0
i=2
i=3
i=4
$ (for f in $(seq 1 10);do go run example/ex01/main.go | sha512sum -; done) | sort | uniq | wc -l
4
```If you set `GRSEED`, the result becomes deterministic:
```
$ (for f in $(seq 1 10);do GRSEED=foo go run example/ex01/main.go | sha512sum -; done) | sort | uniq
7ea818bd9e800609ab8e360688d975189033a9b9277d1ad9c9c96c9013f4ffeb1cf05c16ace9de737dcedaa68bc99162d611ac60b7169a43b4f9b17b1665f121 -$ (for f in $(seq 1 10);do GRSEED=bar go run example/ex01/main.go | sha512sum -; done) | sort | uniq
fc1c177ebbc58baa7e4960102cf26da25173559de0d7a08e00c37a4512eb0a579fc6b4b70f2c708fe1166a1c0641e8839305d5fe7e26624cabbce2cb8274d963 -
```## Practical Examples
- [example/etcd-5155](example/etcd-5155): data race ([coreos/etcd#5155](https://github.com/coreos/etcd/issues/5155))
## Hint
You may use [AspectGo](https://github.com/AkihiroSuda/aspectgo)(WIP) for automatic instrumentation.## Related project
* [Namazu: a programmable fuzzy scheduler for testing distributed systems](https://github.com/osrg/namazu)GoReplay is planned to be merged to Namazu.