feat(epictest) tests and benchmarks
License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>
Brian Tiger Chow committed
Dec 13, 2014 at 05:16 UTC
be982269e56e326d532372b8239049d2a4877e4d
3 files changed
+272
epictest/addcat_test.go
new
+160
@@ -0,0 +1,160 @@
1
+package epictest
2
+
3
+import (
4
+ "bytes"
5
+ randcrypto "crypto/rand"
6
+ "fmt"
7
+ "io"
8
+ "os"
9
+ "testing"
10
+ "time"
11
+
12
+ blockservice "github.com/jbenet/go-ipfs/blockservice"
13
+ bitswap "github.com/jbenet/go-ipfs/exchange/bitswap"
14
+ tn "github.com/jbenet/go-ipfs/exchange/bitswap/testnet"
15
+ importer "github.com/jbenet/go-ipfs/importer"
16
+ chunk "github.com/jbenet/go-ipfs/importer/chunk"
17
+ merkledag "github.com/jbenet/go-ipfs/merkledag"
18
+ path "github.com/jbenet/go-ipfs/path"
19
+ mockrouting "github.com/jbenet/go-ipfs/routing/mock"
20
+ uio "github.com/jbenet/go-ipfs/unixfs/io"
21
+ util "github.com/jbenet/go-ipfs/util"
22
+ errors "github.com/jbenet/go-ipfs/util/debugerror"
23
+ delay "github.com/jbenet/go-ipfs/util/delay"
24
+)
25
+
26
+func Test100MBInstantaneous(t *testing.T) {
27
+ t.Log("a sanity check")
28
+
29
+ t.Parallel()
30
+
31
+ conf := Config{
32
+ NetworkLatency: 0,
33
+ RoutingLatency: 0,
34
+ BlockstoreLatency: 0,
35
+ DataAmountBytes: 100 * 1024 * 1024,
36
+ }
37
+
38
+ AddCatBytes(conf)
39
+}
40
+
41
+func TestDegenerateSlowBlockstore(t *testing.T) {
42
+ SkipUnlessEpic(t)
43
+ t.Parallel()
44
+
45
+ conf := Config{BlockstoreLatency: 50 * time.Millisecond}
46
+
47
+ if err := AddCatPowers(conf, 128); err != nil {
48
+ t.Fatal(err)
49
+ }
50
+}
51
+
52
+func TestDegenerateSlowNetwork(t *testing.T) {
53
+ SkipUnlessEpic(t)
54
+ t.Parallel()
55
+
56
+ conf := Config{NetworkLatency: 400 * time.Millisecond}
57
+
58
+ if err := AddCatPowers(conf, 128); err != nil {
59
+ t.Fatal(err)
60
+ }
61
+}
62
+
63
+func TestDegenerateSlowRouting(t *testing.T) {
64
+ SkipUnlessEpic(t)
65
+ t.Parallel()
66
+
67
+ conf := Config{RoutingLatency: 400 * time.Millisecond}
68
+
69
+ if err := AddCatPowers(conf, 128); err != nil {
70
+ t.Fatal(err)
71
+ }
72
+}
73
+
74
+func Test100MBMacbookCoastToCoast(t *testing.T) {
75
+ SkipUnlessEpic(t)
76
+ t.Parallel()
77
+
78
+ conf := Config{
79
+ DataAmountBytes: 100 * 1024 * 1024,
80
+ }.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow()
81
+
82
+ if err := AddCatBytes(conf); err != nil {
83
+ t.Fatal(err)
84
+ }
85
+}
86
+
87
+func AddCatPowers(conf Config, megabytesMax int64) error {
88
+ var i int64
89
+ for i = 1; i < megabytesMax; i = i * 2 {
90
+ fmt.Printf("%d MB\n", i)
91
+ conf.DataAmountBytes = i * 1024 * 1024
92
+ if err := AddCatBytes(conf); err != nil {
93
+ return err
94
+ }
95
+ }
96
+ return nil
97
+}
98
+
99
+func AddCatBytes(conf Config) error {
100
+
101
+ sessionGenerator := bitswap.NewSessionGenerator(
102
+ tn.VirtualNetwork(delay.Fixed(conf.NetworkLatency)), // TODO rename VirtualNetwork
103
+ mockrouting.NewServerWithDelay(delay.Fixed(conf.RoutingLatency)),
104
+ )
105
+
106
+ adder := sessionGenerator.Next()
107
+ catter := sessionGenerator.Next()
108
+ catter.SetBlockstoreLatency(conf.BlockstoreLatency)
109
+
110
+ adder.SetBlockstoreLatency(0) // disable blockstore latency during add operation
111
+ var data bytes.Buffer
112
+ // FIXME replace with a random data generator that reproduces data given a seed value
113
+ io.Copy(&data, &io.LimitedReader{R: randcrypto.Reader, N: conf.DataAmountBytes})
114
+ keyAdded, err := add(adder, bytes.NewReader(data.Bytes()))
115
+ if err != nil {
116
+ return err
117
+ }
118
+ adder.SetBlockstoreLatency(conf.BlockstoreLatency) // add some blockstore delay to make the catter wait
119
+
120
+ readerCatted, err := cat(catter, keyAdded)
121
+ if err != nil {
122
+ return err
123
+ }
124
+
125
+ // verify
126
+ var bufout bytes.Buffer
127
+ io.Copy(&bufout, readerCatted)
128
+ if 0 != bytes.Compare(bufout.Bytes(), data.Bytes()) {
129
+ return errors.New("catted data does not match added data")
130
+ }
131
+ return nil
132
+}
133
+
134
+func cat(catter bitswap.Instance, k util.Key) (io.Reader, error) {
135
+ catterdag := merkledag.NewDAGService(&blockservice.BlockService{catter.Blockstore(), catter.Exchange})
136
+ nodeCatted, err := (&path.Resolver{catterdag}).ResolvePath(k.String())
137
+ if err != nil {
138
+ return nil, err
139
+ }
140
+ return uio.NewDagReader(nodeCatted, catterdag)
141
+}
142
+
143
+func add(adder bitswap.Instance, r io.Reader) (util.Key, error) {
144
+ nodeAdded, err := importer.BuildDagFromReader(
145
+ r,
146
+ merkledag.NewDAGService(&blockservice.BlockService{adder.Blockstore(), adder.Exchange}),
147
+ nil,
148
+ chunk.DefaultSplitter,
149
+ )
150
+ if err != nil {
151
+ return "", err
152
+ }
153
+ return nodeAdded.Key()
154
+}
155
+
156
+func SkipUnlessEpic(t *testing.T) {
157
+ if os.Getenv("IPFS_EPIC_TEST") == "" {
158
+ t.SkipNow()
159
+ }
160
+}
epictest/bench_test.go
new
+57
@@ -0,0 +1,57 @@
1
+package epictest
2
+
3
+import "testing"
4
+
5
+func benchmarkAddCat(conf Config, b *testing.B) {
6
+ b.SetBytes(conf.DataAmountBytes)
7
+ for n := 0; n < b.N; n++ {
8
+ if err := AddCatBytes(conf); err != nil {
9
+ b.Fatal(err)
10
+ }
11
+ }
12
+}
13
+
14
+var instant = Config{}.All_Instantaneous()
15
+
16
+func BenchmarkInstantaneousAddCat1MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(1), b) }
17
+func BenchmarkInstantaneousAddCat2MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(2), b) }
18
+func BenchmarkInstantaneousAddCat4MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(4), b) }
19
+func BenchmarkInstantaneousAddCat8MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(8), b) }
20
+func BenchmarkInstantaneousAddCat16MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(16), b) }
21
+func BenchmarkInstantaneousAddCat32MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(32), b) }
22
+func BenchmarkInstantaneousAddCat64MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(64), b) }
23
+func BenchmarkInstantaneousAddCat128MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(128), b) }
24
+func BenchmarkInstantaneousAddCat256MB(b *testing.B) { benchmarkAddCat(instant.Megabytes(256), b) }
25
+
26
+var routing = Config{}.Routing_Slow()
27
+
28
+func BenchmarkRoutingSlowAddCat1MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(1), b) }
29
+func BenchmarkRoutingSlowAddCat2MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(2), b) }
30
+func BenchmarkRoutingSlowAddCat4MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(4), b) }
31
+func BenchmarkRoutingSlowAddCat8MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(8), b) }
32
+func BenchmarkRoutingSlowAddCat16MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(16), b) }
33
+func BenchmarkRoutingSlowAddCat32MB(b *testing.B) { benchmarkAddCat(routing.Megabytes(32), b) }
34
+
35
+var network = Config{}.Network_NYtoSF()
36
+
37
+func BenchmarkNetworkSlowAddCat1MB(b *testing.B) { benchmarkAddCat(network.Megabytes(1), b) }
38
+func BenchmarkNetworkSlowAddCat2MB(b *testing.B) { benchmarkAddCat(network.Megabytes(2), b) }
39
+func BenchmarkNetworkSlowAddCat4MB(b *testing.B) { benchmarkAddCat(network.Megabytes(4), b) }
40
+func BenchmarkNetworkSlowAddCat8MB(b *testing.B) { benchmarkAddCat(network.Megabytes(8), b) }
41
+func BenchmarkNetworkSlowAddCat16MB(b *testing.B) { benchmarkAddCat(network.Megabytes(16), b) }
42
+func BenchmarkNetworkSlowAddCat32MB(b *testing.B) { benchmarkAddCat(network.Megabytes(32), b) }
43
+func BenchmarkNetworkSlowAddCat64MB(b *testing.B) { benchmarkAddCat(network.Megabytes(64), b) }
44
+func BenchmarkNetworkSlowAddCat128MB(b *testing.B) { benchmarkAddCat(network.Megabytes(128), b) }
45
+func BenchmarkNetworkSlowAddCat256MB(b *testing.B) { benchmarkAddCat(network.Megabytes(256), b) }
46
+
47
+var blockstore = Config{}.Blockstore_7200RPM()
48
+
49
+func BenchmarkBlockstoreSlowAddCat1MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(1), b) }
50
+func BenchmarkBlockstoreSlowAddCat2MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(2), b) }
51
+func BenchmarkBlockstoreSlowAddCat4MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(4), b) }
52
+func BenchmarkBlockstoreSlowAddCat8MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(8), b) }
53
+func BenchmarkBlockstoreSlowAddCat16MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(16), b) }
54
+func BenchmarkBlockstoreSlowAddCat32MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(32), b) }
55
+func BenchmarkBlockstoreSlowAddCat64MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(64), b) }
56
+func BenchmarkBlockstoreSlowAddCat128MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(128), b) }
57
+func BenchmarkBlockstoreSlowAddCat256MB(b *testing.B) { benchmarkAddCat(blockstore.Megabytes(256), b) }
epictest/test_config.go
new
+55
@@ -0,0 +1,55 @@
1
+package epictest
2
+
3
+import "time"
4
+
5
+type Config struct {
6
+ BlockstoreLatency time.Duration
7
+ NetworkLatency time.Duration
8
+ RoutingLatency time.Duration
9
+ DataAmountBytes int64
10
+}
11
+
12
+func (c Config) All_Instantaneous() Config {
13
+ // Could use a zero value but whatever. Consistency of interface
14
+ c.NetworkLatency = 0
15
+ c.RoutingLatency = 0
16
+ c.BlockstoreLatency = 0
17
+ return c
18
+}
19
+
20
+func (c Config) Network_NYtoSF() Config {
21
+ c.NetworkLatency = 20 * time.Millisecond
22
+ return c
23
+}
24
+
25
+func (c Config) Network_IntraDatacenter2014() Config {
26
+ c.NetworkLatency = 250 * time.Microsecond
27
+ return c
28
+}
29
+
30
+func (c Config) Blockstore_FastSSD2014() Config {
31
+ const iops = 100000
32
+ c.BlockstoreLatency = (1 / iops) * time.Second
33
+ return c
34
+}
35
+
36
+func (c Config) Blockstore_SlowSSD2014() Config {
37
+ c.BlockstoreLatency = 150 * time.Microsecond
38
+ return c
39
+}
40
+
41
+func (c Config) Blockstore_7200RPM() Config {
42
+ c.BlockstoreLatency = 8 * time.Millisecond
43
+ return c
44
+}
45
+
46
+func (c Config) Routing_Slow() Config {
47
+ c.BlockstoreLatency = 200 * time.Millisecond
48
+ return c
49
+}
50
+
51
+// Megabytes is a convenience method to set DataAmountBytes
52
+func (c Config) Megabytes(mb int64) Config {
53
+ c.DataAmountBytes = mb * 1024 * 1024
54
+ return c
55
+}