OSDN Git Service

feat(warder): add warder backbone (#181)
[bytom/vapor.git] / vendor / github.com / ugorji / go / codec / shared_test.go
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.
3
4 package codec
5
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.
9 //
10 // init is a multi-step process:
11 //   - setup vars (handled by init functions in each file)
12 //   - parse flags
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.
17 //
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.
23 // Example usage:
24 //    go test "-tags=x codecgen" -bench=. <other parameters ...>
25 //
26 // To fully test everything:
27 //    go test -tags=x -benchtime=100ms -tv -bg -bi  -brw -bu -v -run=. -bench=.
28
29 // Handling flags
30 // codec_test.go will define a set of global flags for testing, including:
31 //   - Use Reset
32 //   - Use IO reader/writer (vs direct bytes)
33 //   - Set Canonical
34 //   - Set InternStrings
35 //   - Use Symbols
36 //
37 // This way, we can test them all by running same set of tests with a different
38 // set of flags.
39 //
40 // Following this, all the benchmarks will utilize flags set by codec_test.go
41 // and will not redefine these "global" flags.
42
43 import (
44         "bytes"
45         "flag"
46         "fmt"
47         "io"
48         "io/ioutil"
49         "log"
50         "sync"
51         "testing"
52 )
53
54 // DO NOT REMOVE - replacement line for go-codec-bench import declaration tag //
55
56 type testHED struct {
57         H Handle
58         E *Encoder
59         D *Decoder
60 }
61
62 type ioReaderWrapper struct {
63         r io.Reader
64 }
65
66 func (x ioReaderWrapper) Read(p []byte) (n int, err error) {
67         return x.r.Read(p)
68 }
69
70 type ioWriterWrapper struct {
71         w io.Writer
72 }
73
74 func (x ioWriterWrapper) Write(p []byte) (n int, err error) {
75         return x.w.Write(p)
76 }
77
78 var (
79         // testNoopH    = NoopHandle(8)
80         testMsgpackH = &MsgpackHandle{}
81         testBincH    = &BincHandle{}
82         testSimpleH  = &SimpleHandle{}
83         testCborH    = &CborHandle{}
84         testJsonH    = &JsonHandle{}
85
86         testHandles     []Handle
87         testPreInitFns  []func()
88         testPostInitFns []func()
89
90         testOnce sync.Once
91
92         testHEDs []testHED
93 )
94
95 // flag variables used by tests (and bench)
96 var (
97         testDepth int
98
99         testVerbose       bool
100         testInitDebug     bool
101         testStructToArray bool
102         testCanonical     bool
103         testUseReset      bool
104         testSkipIntf      bool
105         testInternStr     bool
106         testUseMust       bool
107         testCheckCircRef  bool
108
109         testUseIoEncDec  int
110         testUseIoWrapper bool
111
112         testMaxInitLen int
113
114         testNumRepeatString int
115
116         testRpcBufsize int
117 )
118
119 // variables that are not flags, but which can configure the handles
120 var (
121         testEncodeOptions EncodeOptions
122         testDecodeOptions DecodeOptions
123 )
124
125 // flag variables used by bench
126 var (
127         benchDoInitBench      bool
128         benchVerify           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.
133         benchDepth     int
134         benchInitDebug bool
135 )
136
137 func init() {
138         log.SetOutput(ioutil.Discard) // don't allow things log to standard out/err
139         testHEDs = make([]testHED, 0, 32)
140         testHandles = append(testHandles,
141                 // testNoopH,
142                 testMsgpackH, testBincH, testSimpleH,
143                 testCborH, testJsonH)
144         testInitFlags()
145         benchInitFlags()
146 }
147
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")
164 }
165
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")
173 }
174
175 func testHEDGet(h Handle) *testHED {
176         for i := range testHEDs {
177                 v := &testHEDs[i]
178                 if v.H == h {
179                         return v
180                 }
181         }
182         testHEDs = append(testHEDs, testHED{h, NewEncoder(nil, h), NewDecoder(nil, h)})
183         return &testHEDs[len(testHEDs)-1]
184 }
185
186 func testReinit() {
187         testOnce = sync.Once{}
188         testHEDs = nil
189 }
190
191 func testInitAll() {
192         // only parse it once.
193         if !flag.Parsed() {
194                 flag.Parse()
195         }
196         for _, f := range testPreInitFns {
197                 f()
198         }
199         for _, f := range testPostInitFns {
200                 f()
201         }
202 }
203
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)
207         var e *Encoder
208         var buf *bytes.Buffer
209         if testUseReset {
210                 e = testHEDGet(h).E
211         } else {
212                 e = NewEncoder(nil, h)
213         }
214         var oldWriteBufferSize int
215         if testUseIoEncDec >= 0 {
216                 buf = fn(bsIn)
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})
222                 } else {
223                         e.Reset(buf)
224                 }
225         } else {
226                 bs = bsIn
227                 e.ResetBytes(&bs)
228         }
229         if testUseMust {
230                 e.MustEncode(ts)
231         } else {
232                 err = e.Encode(ts)
233         }
234         if testUseIoEncDec >= 0 {
235                 bs = buf.Bytes()
236                 bh.WriterBufferSize = oldWriteBufferSize
237         }
238         return
239 }
240
241 func sTestCodecDecode(bs []byte, ts interface{}, h Handle, bh *BasicHandle) (err error) {
242         var d *Decoder
243         // var buf *bytes.Reader
244         if testUseReset {
245                 d = testHEDGet(h).D
246         } else {
247                 d = NewDecoder(nil, h)
248         }
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})
256                 } else {
257                         d.Reset(buf)
258                 }
259         } else {
260                 d.ResetBytes(bs)
261         }
262         if testUseMust {
263                 d.MustDecode(ts)
264         } else {
265                 err = d.Decode(ts)
266         }
267         if testUseIoEncDec >= 0 {
268                 bh.ReaderBufferSize = oldReadBufferSize
269         }
270         return
271 }
272
273 // --- functions below are used by both benchmarks and tests
274
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"
283                 }
284                 fmt.Printf(format, args...)
285         }
286 }
287
288 // --- functions below are used only by benchmarks alone
289
290 func fnBenchmarkByteBuf(bsIn []byte) (buf *bytes.Buffer) {
291         // var buf bytes.Buffer
292         // buf.Grow(approxSize)
293         buf = bytes.NewBuffer(bsIn)
294         buf.Truncate(0)
295         return
296 }
297
298 // func benchFnCodecEncode(ts interface{}, bsIn []byte, h Handle) (bs []byte, err error) {
299 //      return testCodecEncode(ts, bsIn, fnBenchmarkByteBuf, h)
300 // }
301
302 // func benchFnCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
303 //      return testCodecDecode(bs, ts, h)
304 // }