@cryptotaxi247 / kubo / commits / be982269e

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 +}