shared_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a MIT license found in the LICENSE file.
  3. package codec
  4. // This file sets up the variables used, including testInitFns.
  5. // Each file should add initialization that should be performed
  6. // after flags are parsed.
  7. //
  8. // init is a multi-step process:
  9. // - setup vars (handled by init functions in each file)
  10. // - parse flags
  11. // - setup derived vars (handled by pre-init registered functions - registered in init function)
  12. // - post init (handled by post-init registered functions - registered in init function)
  13. // This way, no one has to manage carefully control the initialization
  14. // using file names, etc.
  15. //
  16. // Tests which require external dependencies need the -tag=x parameter.
  17. // They should be run as:
  18. // go test -tags=x -run=. <other parameters ...>
  19. // Benchmarks should also take this parameter, to include the sereal, xdr, etc.
  20. // To run against codecgen, etc, make sure you pass extra parameters.
  21. // Example usage:
  22. // go test "-tags=x codecgen" -bench=. <other parameters ...>
  23. //
  24. // To fully test everything:
  25. // go test -tags=x -benchtime=100ms -tv -bg -bi -brw -bu -v -run=. -bench=.
  26. // Handling flags
  27. // codec_test.go will define a set of global flags for testing, including:
  28. // - Use Reset
  29. // - Use IO reader/writer (vs direct bytes)
  30. // - Set Canonical
  31. // - Set InternStrings
  32. // - Use Symbols
  33. //
  34. // This way, we can test them all by running same set of tests with a different
  35. // set of flags.
  36. //
  37. // Following this, all the benchmarks will utilize flags set by codec_test.go
  38. // and will not redefine these "global" flags.
  39. import (
  40. "bytes"
  41. "flag"
  42. "sync"
  43. )
  44. // DO NOT REMOVE - replacement line for go-codec-bench import declaration tag //
  45. type testHED struct {
  46. H Handle
  47. E *Encoder
  48. D *Decoder
  49. }
  50. var (
  51. testNoopH = NoopHandle(8)
  52. testMsgpackH = &MsgpackHandle{}
  53. testBincH = &BincHandle{}
  54. testSimpleH = &SimpleHandle{}
  55. testCborH = &CborHandle{}
  56. testJsonH = &JsonHandle{}
  57. testHandles []Handle
  58. testPreInitFns []func()
  59. testPostInitFns []func()
  60. testOnce sync.Once
  61. testHEDs []testHED
  62. )
  63. // flag variables used by tests (and bench)
  64. var (
  65. testVerbose bool
  66. testInitDebug bool
  67. testUseIoEncDec bool
  68. testStructToArray bool
  69. testCanonical bool
  70. testUseReset bool
  71. testWriteNoSymbols bool
  72. testSkipIntf bool
  73. testInternStr bool
  74. testUseMust bool
  75. testCheckCircRef bool
  76. testJsonIndent int
  77. testMaxInitLen int
  78. testJsonHTMLCharsAsIs bool
  79. testJsonPreferFloat bool
  80. )
  81. // flag variables used by bench
  82. var (
  83. benchDoInitBench bool
  84. benchVerify bool
  85. benchUnscientificRes bool = false
  86. benchMapStringKeyOnly bool
  87. //depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
  88. //For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
  89. benchDepth int
  90. benchInitDebug bool
  91. )
  92. func init() {
  93. testHEDs = make([]testHED, 0, 32)
  94. testHandles = append(testHandles,
  95. testNoopH, testMsgpackH, testBincH, testSimpleH,
  96. testCborH, testJsonH)
  97. testInitFlags()
  98. benchInitFlags()
  99. }
  100. func testInitFlags() {
  101. // delete(testDecOpts.ExtFuncs, timeTyp)
  102. flag.BoolVar(&testVerbose, "tv", false, "Test Verbose")
  103. flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
  104. flag.BoolVar(&testUseIoEncDec, "ti", false, "Use IO Reader/Writer for Marshal/Unmarshal")
  105. flag.BoolVar(&testStructToArray, "ts", false, "Set StructToArray option")
  106. flag.BoolVar(&testWriteNoSymbols, "tn", false, "Set NoSymbols option")
  107. flag.BoolVar(&testCanonical, "tc", false, "Set Canonical option")
  108. flag.BoolVar(&testInternStr, "te", false, "Set InternStr option")
  109. flag.BoolVar(&testSkipIntf, "tf", false, "Skip Interfaces")
  110. flag.BoolVar(&testUseReset, "tr", false, "Use Reset")
  111. flag.IntVar(&testJsonIndent, "td", 0, "Use JSON Indent")
  112. flag.IntVar(&testMaxInitLen, "tx", 0, "Max Init Len")
  113. flag.BoolVar(&testUseMust, "tm", true, "Use Must(En|De)code")
  114. flag.BoolVar(&testCheckCircRef, "tl", false, "Use Check Circular Ref")
  115. flag.BoolVar(&testJsonHTMLCharsAsIs, "tas", false, "Set JSON HTMLCharsAsIs")
  116. flag.BoolVar(&testJsonPreferFloat, "tjf", false, "Prefer Float in json")
  117. }
  118. func benchInitFlags() {
  119. flag.BoolVar(&benchMapStringKeyOnly, "bs", false, "Bench use maps with string keys only")
  120. flag.BoolVar(&benchInitDebug, "bg", false, "Bench Debug")
  121. flag.IntVar(&benchDepth, "bd", 1, "Bench Depth")
  122. flag.BoolVar(&benchDoInitBench, "bi", false, "Run Bench Init")
  123. flag.BoolVar(&benchVerify, "bv", false, "Verify Decoded Value during Benchmark")
  124. flag.BoolVar(&benchUnscientificRes, "bu", false, "Show Unscientific Results during Benchmark")
  125. }
  126. func testHEDGet(h Handle) *testHED {
  127. for i := range testHEDs {
  128. v := &testHEDs[i]
  129. if v.H == h {
  130. return v
  131. }
  132. }
  133. testHEDs = append(testHEDs, testHED{h, NewEncoder(nil, h), NewDecoder(nil, h)})
  134. return &testHEDs[len(testHEDs)-1]
  135. }
  136. func testReinit() {
  137. testOnce = sync.Once{}
  138. testHEDs = nil
  139. }
  140. func testInitAll() {
  141. // only parse it once.
  142. if !flag.Parsed() {
  143. flag.Parse()
  144. }
  145. for _, f := range testPreInitFns {
  146. f()
  147. }
  148. for _, f := range testPostInitFns {
  149. f()
  150. }
  151. }
  152. func testCodecEncode(ts interface{}, bsIn []byte,
  153. fn func([]byte) *bytes.Buffer, h Handle) (bs []byte, err error) {
  154. // bs = make([]byte, 0, approxSize)
  155. var e *Encoder
  156. var buf *bytes.Buffer
  157. if testUseReset {
  158. e = testHEDGet(h).E
  159. } else {
  160. e = NewEncoder(nil, h)
  161. }
  162. if testUseIoEncDec {
  163. buf = fn(bsIn)
  164. e.Reset(buf)
  165. } else {
  166. bs = bsIn
  167. e.ResetBytes(&bs)
  168. }
  169. if testUseMust {
  170. e.MustEncode(ts)
  171. } else {
  172. err = e.Encode(ts)
  173. }
  174. if testUseIoEncDec {
  175. bs = buf.Bytes()
  176. }
  177. return
  178. }
  179. func testCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
  180. var d *Decoder
  181. var buf *bytes.Reader
  182. if testUseReset {
  183. d = testHEDGet(h).D
  184. } else {
  185. d = NewDecoder(nil, h)
  186. }
  187. if testUseIoEncDec {
  188. buf = bytes.NewReader(bs)
  189. d.Reset(buf)
  190. } else {
  191. d.ResetBytes(bs)
  192. }
  193. if testUseMust {
  194. d.MustDecode(ts)
  195. } else {
  196. err = d.Decode(ts)
  197. }
  198. return
  199. }
  200. // ----- functions below are used only by benchmarks alone
  201. func fnBenchmarkByteBuf(bsIn []byte) (buf *bytes.Buffer) {
  202. // var buf bytes.Buffer
  203. // buf.Grow(approxSize)
  204. buf = bytes.NewBuffer(bsIn)
  205. buf.Truncate(0)
  206. return
  207. }
  208. func benchFnCodecEncode(ts interface{}, bsIn []byte, h Handle) (bs []byte, err error) {
  209. return testCodecEncode(ts, bsIn, fnBenchmarkByteBuf, h)
  210. }
  211. func benchFnCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
  212. return testCodecDecode(bs, ts, h)
  213. }