benchmarks.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // +build integration
  2. package performance
  3. import (
  4. "errors"
  5. "fmt"
  6. "os"
  7. "reflect"
  8. "runtime"
  9. "strings"
  10. "testing"
  11. "github.com/aws/aws-sdk-go/aws/request"
  12. "github.com/aws/aws-sdk-go/awstesting/mock"
  13. "github.com/gucumber/gucumber"
  14. )
  15. // mapCreateClients allows for the creation of clients
  16. func mapCreateClients() {
  17. clientFns := []func(){}
  18. for _, c := range clients {
  19. clientFns = append(clientFns, func() { c.Call([]reflect.Value{reflect.ValueOf(mock.Session)}) })
  20. }
  21. gucumber.World["services"] = clientFns
  22. }
  23. func buildAnArrayOfClients() {
  24. methods := []reflect.Value{}
  25. params := [][]reflect.Value{}
  26. for _, c := range clients {
  27. method, param, err := findAndGetMethod(c.Call([]reflect.Value{reflect.ValueOf(mock.Session)}))
  28. if err == nil {
  29. methods = append(methods, method)
  30. params = append(params, param)
  31. }
  32. }
  33. fns := []func(){}
  34. for i := 0; i < len(methods); i++ {
  35. m := methods[i]
  36. p := params[i]
  37. f := func() {
  38. reqs := m.Call(p)
  39. resp := reqs[0].Interface().(*request.Request).Send()
  40. fmt.Println(resp)
  41. }
  42. fns = append(fns, f)
  43. }
  44. gucumber.World["clientFns"] = fns
  45. }
  46. // findAndGetMethod will grab the method, params to be passed to the method, and an error.
  47. // The method that is found, is a method that doesn't have any required input
  48. func findAndGetMethod(client interface{}) (reflect.Value, []reflect.Value, error) {
  49. v := reflect.ValueOf(client).Type()
  50. n := v.NumMethod()
  51. outer:
  52. for i := 0; i < n; i++ {
  53. method := v.Method(i)
  54. if method.Type.NumIn() != 2 || strings.HasSuffix(method.Name, "Request") {
  55. continue
  56. }
  57. param := reflect.New(method.Type.In(1).Elem())
  58. for j := 0; j < param.Elem().NumField(); j++ {
  59. field := param.Elem().Type().Field(j)
  60. req := field.Tag.Get("required")
  61. if req == "true" {
  62. continue outer
  63. }
  64. }
  65. params := []reflect.Value{reflect.ValueOf(client), param}
  66. return method.Func, params, nil
  67. }
  68. return reflect.Value{}, nil, errors.New("No method found")
  69. }
  70. // benchmarkTask takes a unique key to write to the logger with the benchmark
  71. // result's data
  72. func benchmarkTask(key string, fns []func(), i1 int) error {
  73. gucumber.World["error"] = nil
  74. memStatStart := &runtime.MemStats{}
  75. runtime.ReadMemStats(memStatStart)
  76. results := testing.Benchmark(func(b *testing.B) {
  77. for _, f := range fns {
  78. for i := 0; i < i1; i++ {
  79. f()
  80. }
  81. }
  82. })
  83. results.N = i1
  84. memStatEnd := &runtime.MemStats{}
  85. runtime.ReadMemStats(memStatEnd)
  86. l, err := newBenchmarkLogger("stdout")
  87. if err != nil {
  88. return err
  89. }
  90. l.log(key, results)
  91. toDynamodb := os.Getenv("AWS_TESTING_LOG_RESULTS") == "true"
  92. if toDynamodb {
  93. l, err := newBenchmarkLogger("dynamodb")
  94. if err != nil {
  95. return err
  96. }
  97. l.log(key+"_start_benchmarks", memStatStart)
  98. l.log(key+"_end_benchmarks", memStatEnd)
  99. }
  100. if memStatStart.Alloc < memStatEnd.Alloc {
  101. return errors.New("Leaked memory")
  102. }
  103. return nil
  104. }