forked from aws/aws-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
benchmarks.go
120 lines (103 loc) · 2.79 KB
/
benchmarks.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
package performance
import (
"errors"
"fmt"
"os"
"reflect"
"runtime"
"strings"
"testing"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/awstesting/mock"
"github.com/lsegal/gucumber"
)
// mapCreateClients allows for the creation of clients
func mapCreateClients() {
clientFns := []func(){}
for _, c := range clients {
clientFns = append(clientFns, func() { c.Call([]reflect.Value{reflect.ValueOf(mock.Session)}) })
}
gucumber.World["services"] = clientFns
}
func buildAnArrayOfClients() {
methods := []reflect.Value{}
params := [][]reflect.Value{}
for _, c := range clients {
method, param, err := findAndGetMethod(c.Call([]reflect.Value{reflect.ValueOf(mock.Session)}))
if err == nil {
methods = append(methods, method)
params = append(params, param)
}
}
fns := []func(){}
for i := 0; i < len(methods); i++ {
m := methods[i]
p := params[i]
f := func() {
reqs := m.Call(p)
resp := reqs[0].Interface().(*request.Request).Send()
fmt.Println(resp)
}
fns = append(fns, f)
}
gucumber.World["clientFns"] = fns
}
// findAndGetMethod will grab the method, params to be passed to the method, and an error.
// The method that is found, is a method that doesn't have any required input
func findAndGetMethod(client interface{}) (reflect.Value, []reflect.Value, error) {
v := reflect.ValueOf(client).Type()
n := v.NumMethod()
outer:
for i := 0; i < n; i++ {
method := v.Method(i)
if method.Type.NumIn() != 2 || strings.HasSuffix(method.Name, "Request") {
continue
}
param := reflect.New(method.Type.In(1).Elem())
for j := 0; j < param.Elem().NumField(); j++ {
field := param.Elem().Type().Field(j)
req := field.Tag.Get("required")
if req == "true" {
continue outer
}
}
params := []reflect.Value{reflect.ValueOf(client), param}
return method.Func, params, nil
}
return reflect.Value{}, nil, errors.New("No method found")
}
// benchmarkTask takes a unique key to write to the logger with the benchmark
// result's data
func benchmarkTask(key string, fns []func(), i1 int) error {
gucumber.World["error"] = nil
memStatStart := &runtime.MemStats{}
runtime.ReadMemStats(memStatStart)
results := testing.Benchmark(func(b *testing.B) {
for _, f := range fns {
for i := 0; i < i1; i++ {
f()
}
}
})
results.N = i1
memStatEnd := &runtime.MemStats{}
runtime.ReadMemStats(memStatEnd)
l, err := newBenchmarkLogger("stdout")
if err != nil {
return err
}
l.log(key, results)
toDynamodb := os.Getenv("AWS_TESTING_LOG_RESULTS") == "true"
if toDynamodb {
l, err := newBenchmarkLogger("dynamodb")
if err != nil {
return err
}
l.log(key+"_start_benchmarks", memStatStart)
l.log(key+"_end_benchmarks", memStatEnd)
}
if memStatStart.Alloc < memStatEnd.Alloc {
return errors.New("Leaked memory")
}
return nil
}