You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
2.7 KiB

  1. // Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
  2. // All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license that can be
  5. // found in the LICENSE file.
  6. package testutil
  7. import (
  8. "bytes"
  9. "flag"
  10. "math/rand"
  11. "reflect"
  12. "sync"
  13. "github.com/onsi/ginkgo/config"
  14. "github.com/syndtr/goleveldb/leveldb/comparer"
  15. )
  16. var (
  17. runfn = make(map[string][]func())
  18. runmu sync.Mutex
  19. )
  20. func Defer(args ...interface{}) bool {
  21. var (
  22. group string
  23. fn func()
  24. )
  25. for _, arg := range args {
  26. v := reflect.ValueOf(arg)
  27. switch v.Kind() {
  28. case reflect.String:
  29. group = v.String()
  30. case reflect.Func:
  31. r := reflect.ValueOf(&fn).Elem()
  32. r.Set(v)
  33. }
  34. }
  35. if fn != nil {
  36. runmu.Lock()
  37. runfn[group] = append(runfn[group], fn)
  38. runmu.Unlock()
  39. }
  40. return true
  41. }
  42. func RunDefer(groups ...string) bool {
  43. if len(groups) == 0 {
  44. groups = append(groups, "")
  45. }
  46. runmu.Lock()
  47. var runfn_ []func()
  48. for _, group := range groups {
  49. runfn_ = append(runfn_, runfn[group]...)
  50. delete(runfn, group)
  51. }
  52. runmu.Unlock()
  53. for _, fn := range runfn_ {
  54. fn()
  55. }
  56. return runfn_ != nil
  57. }
  58. func RandomSeed() int64 {
  59. if !flag.Parsed() {
  60. panic("random seed not initialized")
  61. }
  62. return config.GinkgoConfig.RandomSeed
  63. }
  64. func NewRand() *rand.Rand {
  65. return rand.New(rand.NewSource(RandomSeed()))
  66. }
  67. var cmp = comparer.DefaultComparer
  68. func BytesSeparator(a, b []byte) []byte {
  69. if bytes.Equal(a, b) {
  70. return b
  71. }
  72. i, n := 0, len(a)
  73. if n > len(b) {
  74. n = len(b)
  75. }
  76. for ; i < n && (a[i] == b[i]); i++ {
  77. }
  78. x := append([]byte{}, a[:i]...)
  79. if i < n {
  80. if c := a[i] + 1; c < b[i] {
  81. return append(x, c)
  82. }
  83. x = append(x, a[i])
  84. i++
  85. }
  86. for ; i < len(a); i++ {
  87. if c := a[i]; c < 0xff {
  88. return append(x, c+1)
  89. } else {
  90. x = append(x, c)
  91. }
  92. }
  93. if len(b) > i && b[i] > 0 {
  94. return append(x, b[i]-1)
  95. }
  96. return append(x, 'x')
  97. }
  98. func BytesAfter(b []byte) []byte {
  99. var x []byte
  100. for _, c := range b {
  101. if c < 0xff {
  102. return append(x, c+1)
  103. } else {
  104. x = append(x, c)
  105. }
  106. }
  107. return append(x, 'x')
  108. }
  109. func RandomIndex(rnd *rand.Rand, n, round int, fn func(i int)) {
  110. if rnd == nil {
  111. rnd = NewRand()
  112. }
  113. for x := 0; x < round; x++ {
  114. fn(rnd.Intn(n))
  115. }
  116. return
  117. }
  118. func ShuffledIndex(rnd *rand.Rand, n, round int, fn func(i int)) {
  119. if rnd == nil {
  120. rnd = NewRand()
  121. }
  122. for x := 0; x < round; x++ {
  123. for _, i := range rnd.Perm(n) {
  124. fn(i)
  125. }
  126. }
  127. return
  128. }
  129. func RandomRange(rnd *rand.Rand, n, round int, fn func(start, limit int)) {
  130. if rnd == nil {
  131. rnd = NewRand()
  132. }
  133. for x := 0; x < round; x++ {
  134. start := rnd.Intn(n)
  135. length := 0
  136. if j := n - start; j > 0 {
  137. length = rnd.Intn(j)
  138. }
  139. fn(start, start+length)
  140. }
  141. return
  142. }
  143. func Max(x, y int) int {
  144. if x > y {
  145. return x
  146. }
  147. return y
  148. }
  149. func Min(x, y int) int {
  150. if x < y {
  151. return x
  152. }
  153. return y
  154. }