1 // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
2 // Use of this source code is governed by a MIT license found in the LICENSE file.
6 // This file sets up the variables used, including testInitFns.
7 // Each file should add initialization that should be performed
8 // after flags are parsed.
10 // init is a multi-step process:
11 // - setup vars (handled by init functions in each file)
13 // - setup derived vars (handled by pre-init registered functions - registered in init function)
14 // - post init (handled by post-init registered functions - registered in init function)
15 // This way, no one has to manage carefully control the initialization
16 // using file names, etc.
18 // Tests which require external dependencies need the -tag=x parameter.
19 // They should be run as:
20 // go test -tags=x -run=. <other parameters ...>
21 // Benchmarks should also take this parameter, to include the sereal, xdr, etc.
22 // To run against codecgen, etc, make sure you pass extra parameters.
24 // go test "-tags=x codecgen" -bench=. <other parameters ...>
26 // To fully test everything:
27 // go test -tags=x -benchtime=100ms -tv -bg -bi -brw -bu -v -run=. -bench=.
30 // codec_test.go will define a set of global flags for testing, including:
32 // - Use IO reader/writer (vs direct bytes)
34 // - Set InternStrings
37 // This way, we can test them all by running same set of tests with a different
40 // Following this, all the benchmarks will utilize flags set by codec_test.go
41 // and will not redefine these "global" flags.
54 // DO NOT REMOVE - replacement line for go-codec-bench import declaration tag //
62 type ioReaderWrapper struct {
66 func (x ioReaderWrapper) Read(p []byte) (n int, err error) {
70 type ioWriterWrapper struct {
74 func (x ioWriterWrapper) Write(p []byte) (n int, err error) {
79 // testNoopH = NoopHandle(8)
80 testMsgpackH = &MsgpackHandle{}
81 testBincH = &BincHandle{}
82 testSimpleH = &SimpleHandle{}
83 testCborH = &CborHandle{}
84 testJsonH = &JsonHandle{}
87 testPreInitFns []func()
88 testPostInitFns []func()
95 // flag variables used by tests (and bench)
101 testStructToArray bool
107 testCheckCircRef bool
110 testUseIoWrapper bool
114 testNumRepeatString int
119 // variables that are not flags, but which can configure the handles
121 testEncodeOptions EncodeOptions
122 testDecodeOptions DecodeOptions
125 // flag variables used by bench
127 benchDoInitBench bool
129 benchUnscientificRes bool = false
130 benchMapStringKeyOnly bool
131 //depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
132 //For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
138 log.SetOutput(ioutil.Discard) // don't allow things log to standard out/err
139 testHEDs = make([]testHED, 0, 32)
140 testHandles = append(testHandles,
142 testMsgpackH, testBincH, testSimpleH,
143 testCborH, testJsonH)
148 func testInitFlags() {
149 // delete(testDecOpts.ExtFuncs, timeTyp)
150 flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
151 flag.BoolVar(&testVerbose, "tv", false, "Test Verbose (no longer used - here for compatibility)")
152 flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
153 flag.IntVar(&testUseIoEncDec, "ti", -1, "Use IO Reader/Writer for Marshal/Unmarshal ie >= 0")
154 flag.BoolVar(&testUseIoWrapper, "tiw", false, "Wrap the IO Reader/Writer with a base pass-through reader/writer")
155 flag.BoolVar(&testStructToArray, "ts", false, "Set StructToArray option")
156 flag.BoolVar(&testCanonical, "tc", false, "Set Canonical option")
157 flag.BoolVar(&testInternStr, "te", false, "Set InternStr option")
158 flag.BoolVar(&testSkipIntf, "tf", false, "Skip Interfaces")
159 flag.BoolVar(&testUseReset, "tr", false, "Use Reset")
160 flag.IntVar(&testNumRepeatString, "trs", 8, "Create string variables by repeating a string N times")
161 flag.IntVar(&testMaxInitLen, "tx", 0, "Max Init Len")
162 flag.BoolVar(&testUseMust, "tm", true, "Use Must(En|De)code")
163 flag.BoolVar(&testCheckCircRef, "tl", false, "Use Check Circular Ref")
166 func benchInitFlags() {
167 flag.BoolVar(&benchMapStringKeyOnly, "bs", false, "Bench use maps with string keys only")
168 flag.BoolVar(&benchInitDebug, "bg", false, "Bench Debug")
169 flag.IntVar(&benchDepth, "bd", 1, "Bench Depth")
170 flag.BoolVar(&benchDoInitBench, "bi", false, "Run Bench Init")
171 flag.BoolVar(&benchVerify, "bv", false, "Verify Decoded Value during Benchmark")
172 flag.BoolVar(&benchUnscientificRes, "bu", false, "Show Unscientific Results during Benchmark")
175 func testHEDGet(h Handle) *testHED {
176 for i := range testHEDs {
182 testHEDs = append(testHEDs, testHED{h, NewEncoder(nil, h), NewDecoder(nil, h)})
183 return &testHEDs[len(testHEDs)-1]
187 testOnce = sync.Once{}
192 // only parse it once.
196 for _, f := range testPreInitFns {
199 for _, f := range testPostInitFns {
204 func sTestCodecEncode(ts interface{}, bsIn []byte, fn func([]byte) *bytes.Buffer,
205 h Handle, bh *BasicHandle) (bs []byte, err error) {
206 // bs = make([]byte, 0, approxSize)
208 var buf *bytes.Buffer
212 e = NewEncoder(nil, h)
214 var oldWriteBufferSize int
215 if testUseIoEncDec >= 0 {
217 // set the encode options for using a buffer
218 oldWriteBufferSize = bh.WriterBufferSize
219 bh.WriterBufferSize = testUseIoEncDec
220 if testUseIoWrapper {
221 e.Reset(ioWriterWrapper{buf})
234 if testUseIoEncDec >= 0 {
236 bh.WriterBufferSize = oldWriteBufferSize
241 func sTestCodecDecode(bs []byte, ts interface{}, h Handle, bh *BasicHandle) (err error) {
243 // var buf *bytes.Reader
247 d = NewDecoder(nil, h)
249 var oldReadBufferSize int
250 if testUseIoEncDec >= 0 {
251 buf := bytes.NewReader(bs)
252 oldReadBufferSize = bh.ReaderBufferSize
253 bh.ReaderBufferSize = testUseIoEncDec
254 if testUseIoWrapper {
255 d.Reset(ioReaderWrapper{buf})
267 if testUseIoEncDec >= 0 {
268 bh.ReaderBufferSize = oldReadBufferSize
273 // --- functions below are used by both benchmarks and tests
275 func logT(x interface{}, format string, args ...interface{}) {
276 if t, ok := x.(*testing.T); ok && t != nil {
277 t.Logf(format, args...)
278 } else if b, ok := x.(*testing.B); ok && b != nil {
279 b.Logf(format, args...)
280 } else { // if testing.Verbose() { // if testVerbose {
281 if len(format) == 0 || format[len(format)-1] != '\n' {
282 format = format + "\n"
284 fmt.Printf(format, args...)
288 // --- functions below are used only by benchmarks alone
290 func fnBenchmarkByteBuf(bsIn []byte) (buf *bytes.Buffer) {
291 // var buf bytes.Buffer
292 // buf.Grow(approxSize)
293 buf = bytes.NewBuffer(bsIn)
298 // func benchFnCodecEncode(ts interface{}, bsIn []byte, h Handle) (bs []byte, err error) {
299 // return testCodecEncode(ts, bsIn, fnBenchmarkByteBuf, h)
302 // func benchFnCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
303 // return testCodecDecode(bs, ts, h)