|
@@ -0,0 +1,228 @@
|
|
|
|
|
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
|
|
|
|
+// Use of this source code is governed by a MIT license found in the LICENSE file.
|
|
|
|
|
+
|
|
|
|
|
+package codec
|
|
|
|
|
+
|
|
|
|
|
+// This file sets up the variables used, including testInitFns.
|
|
|
|
|
+// Each file should add initialization that should be performed
|
|
|
|
|
+// after flags are parsed.
|
|
|
|
|
+//
|
|
|
|
|
+// init is a multi-step process:
|
|
|
|
|
+// - setup vars (handled by init functions in each file)
|
|
|
|
|
+// - parse flags
|
|
|
|
|
+// - setup derived vars (handled by pre-init registered functions - registered in init function)
|
|
|
|
|
+// - post init (handled by post-init registered functions - registered in init function)
|
|
|
|
|
+// This way, no one has to manage carefully control the initialization
|
|
|
|
|
+// using file names, etc.
|
|
|
|
|
+//
|
|
|
|
|
+// Tests which require external dependencies need the -tag=x parameter.
|
|
|
|
|
+// They should be run as:
|
|
|
|
|
+// go test -tags=x -run=. <other parameters ...>
|
|
|
|
|
+// Benchmarks should also take this parameter, to include the sereal, xdr, etc.
|
|
|
|
|
+// To run against codecgen, etc, make sure you pass extra parameters.
|
|
|
|
|
+// Example usage:
|
|
|
|
|
+// go test "-tags=x codecgen unsafe" -bench=. <other parameters ...>
|
|
|
|
|
+//
|
|
|
|
|
+// To fully test everything:
|
|
|
|
|
+// go test -tags=x -benchtime=100ms -tv -bg -bi -brw -bu -v -run=. -bench=.
|
|
|
|
|
+
|
|
|
|
|
+// Handling flags
|
|
|
|
|
+// codec_test.go will define a set of global flags for testing, including:
|
|
|
|
|
+// - Use Reset
|
|
|
|
|
+// - Use IO reader/writer (vs direct bytes)
|
|
|
|
|
+// - Set Canonical
|
|
|
|
|
+// - Set InternStrings
|
|
|
|
|
+// - Use Symbols
|
|
|
|
|
+//
|
|
|
|
|
+// This way, we can test them all by running same set of tests with a different
|
|
|
|
|
+// set of flags.
|
|
|
|
|
+//
|
|
|
|
|
+// Following this, all the benchmarks will utilize flags set by codec_test.go
|
|
|
|
|
+// and will not redefine these "global" flags.
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "bytes"
|
|
|
|
|
+ "flag"
|
|
|
|
|
+ "sync"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// DO NOT REMOVE - replacement line for go-codec-bench import declaration tag //
|
|
|
|
|
+
|
|
|
|
|
+type testHED struct {
|
|
|
|
|
+ H Handle
|
|
|
|
|
+ E *Encoder
|
|
|
|
|
+ D *Decoder
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+var (
|
|
|
|
|
+ testNoopH = NoopHandle(8)
|
|
|
|
|
+ testMsgpackH = &MsgpackHandle{}
|
|
|
|
|
+ testBincH = &BincHandle{}
|
|
|
|
|
+ testSimpleH = &SimpleHandle{}
|
|
|
|
|
+ testCborH = &CborHandle{}
|
|
|
|
|
+ testJsonH = &JsonHandle{}
|
|
|
|
|
+
|
|
|
|
|
+ testHandles []Handle
|
|
|
|
|
+ testPreInitFns []func()
|
|
|
|
|
+ testPostInitFns []func()
|
|
|
|
|
+
|
|
|
|
|
+ testOnce sync.Once
|
|
|
|
|
+
|
|
|
|
|
+ testHEDs []testHED
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// flag variables used by tests (and bench)
|
|
|
|
|
+var (
|
|
|
|
|
+ testVerbose bool
|
|
|
|
|
+ testInitDebug bool
|
|
|
|
|
+ testUseIoEncDec bool
|
|
|
|
|
+ testStructToArray bool
|
|
|
|
|
+ testCanonical bool
|
|
|
|
|
+ testUseReset bool
|
|
|
|
|
+ testWriteNoSymbols bool
|
|
|
|
|
+ testSkipIntf bool
|
|
|
|
|
+ testInternStr bool
|
|
|
|
|
+ testUseMust bool
|
|
|
|
|
+ testCheckCircRef bool
|
|
|
|
|
+ testJsonIndent int
|
|
|
|
|
+ testMaxInitLen int
|
|
|
|
|
+
|
|
|
|
|
+ testJsonHTMLCharsAsIs bool
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// flag variables used by bench
|
|
|
|
|
+var (
|
|
|
|
|
+ benchDoInitBench bool
|
|
|
|
|
+ benchVerify bool
|
|
|
|
|
+ benchUnscientificRes bool = false
|
|
|
|
|
+ benchMapStringKeyOnly bool
|
|
|
|
|
+ //depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
|
|
|
|
|
+ //For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
|
|
|
|
|
+ benchDepth int
|
|
|
|
|
+ benchInitDebug bool
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+func init() {
|
|
|
|
|
+ testHEDs = make([]testHED, 0, 32)
|
|
|
|
|
+ testHandles = append(testHandles,
|
|
|
|
|
+ testNoopH, testMsgpackH, testBincH, testSimpleH,
|
|
|
|
|
+ testCborH, testJsonH)
|
|
|
|
|
+ testInitFlags()
|
|
|
|
|
+ benchInitFlags()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testInitFlags() {
|
|
|
|
|
+ // delete(testDecOpts.ExtFuncs, timeTyp)
|
|
|
|
|
+ flag.BoolVar(&testVerbose, "tv", false, "Test Verbose")
|
|
|
|
|
+ flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
|
|
|
|
|
+ flag.BoolVar(&testUseIoEncDec, "ti", false, "Use IO Reader/Writer for Marshal/Unmarshal")
|
|
|
|
|
+ flag.BoolVar(&testStructToArray, "ts", false, "Set StructToArray option")
|
|
|
|
|
+ flag.BoolVar(&testWriteNoSymbols, "tn", false, "Set NoSymbols option")
|
|
|
|
|
+ flag.BoolVar(&testCanonical, "tc", false, "Set Canonical option")
|
|
|
|
|
+ flag.BoolVar(&testInternStr, "te", false, "Set InternStr option")
|
|
|
|
|
+ flag.BoolVar(&testSkipIntf, "tf", false, "Skip Interfaces")
|
|
|
|
|
+ flag.BoolVar(&testUseReset, "tr", false, "Use Reset")
|
|
|
|
|
+ flag.IntVar(&testJsonIndent, "td", 0, "Use JSON Indent")
|
|
|
|
|
+ flag.IntVar(&testMaxInitLen, "tx", 0, "Max Init Len")
|
|
|
|
|
+ flag.BoolVar(&testUseMust, "tm", true, "Use Must(En|De)code")
|
|
|
|
|
+ flag.BoolVar(&testCheckCircRef, "tl", false, "Use Check Circular Ref")
|
|
|
|
|
+ flag.BoolVar(&testJsonHTMLCharsAsIs, "tas", false, "Set JSON HTMLCharsAsIs")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func benchInitFlags() {
|
|
|
|
|
+ flag.BoolVar(&benchMapStringKeyOnly, "bs", false, "Bench use maps with string keys only")
|
|
|
|
|
+ flag.BoolVar(&benchInitDebug, "bg", false, "Bench Debug")
|
|
|
|
|
+ flag.IntVar(&benchDepth, "bd", 1, "Bench Depth")
|
|
|
|
|
+ flag.BoolVar(&benchDoInitBench, "bi", false, "Run Bench Init")
|
|
|
|
|
+ flag.BoolVar(&benchVerify, "bv", false, "Verify Decoded Value during Benchmark")
|
|
|
|
|
+ flag.BoolVar(&benchUnscientificRes, "bu", false, "Show Unscientific Results during Benchmark")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testHEDGet(h Handle) *testHED {
|
|
|
|
|
+ for i := range testHEDs {
|
|
|
|
|
+ v := &testHEDs[i]
|
|
|
|
|
+ if v.H == h {
|
|
|
|
|
+ return v
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ testHEDs = append(testHEDs, testHED{h, NewEncoder(nil, h), NewDecoder(nil, h)})
|
|
|
|
|
+ return &testHEDs[len(testHEDs)-1]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testInitAll() {
|
|
|
|
|
+ flag.Parse()
|
|
|
|
|
+ for _, f := range testPreInitFns {
|
|
|
|
|
+ f()
|
|
|
|
|
+ }
|
|
|
|
|
+ for _, f := range testPostInitFns {
|
|
|
|
|
+ f()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testCodecEncode(ts interface{}, bsIn []byte,
|
|
|
|
|
+ fn func([]byte) *bytes.Buffer, h Handle) (bs []byte, err error) {
|
|
|
|
|
+ // bs = make([]byte, 0, approxSize)
|
|
|
|
|
+ var e *Encoder
|
|
|
|
|
+ var buf *bytes.Buffer
|
|
|
|
|
+ if testUseReset {
|
|
|
|
|
+ e = testHEDGet(h).E
|
|
|
|
|
+ } else {
|
|
|
|
|
+ e = NewEncoder(nil, h)
|
|
|
|
|
+ }
|
|
|
|
|
+ if testUseIoEncDec {
|
|
|
|
|
+ buf = fn(bsIn)
|
|
|
|
|
+ e.Reset(buf)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ bs = bsIn
|
|
|
|
|
+ e.ResetBytes(&bs)
|
|
|
|
|
+ }
|
|
|
|
|
+ if testUseMust {
|
|
|
|
|
+ e.MustEncode(ts)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ err = e.Encode(ts)
|
|
|
|
|
+ }
|
|
|
|
|
+ if testUseIoEncDec {
|
|
|
|
|
+ bs = buf.Bytes()
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
|
|
|
|
|
+ var d *Decoder
|
|
|
|
|
+ var buf *bytes.Reader
|
|
|
|
|
+ if testUseReset {
|
|
|
|
|
+ d = testHEDGet(h).D
|
|
|
|
|
+ } else {
|
|
|
|
|
+ d = NewDecoder(nil, h)
|
|
|
|
|
+ }
|
|
|
|
|
+ if testUseIoEncDec {
|
|
|
|
|
+ buf = bytes.NewReader(bs)
|
|
|
|
|
+ d.Reset(buf)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ d.ResetBytes(bs)
|
|
|
|
|
+ }
|
|
|
|
|
+ if testUseMust {
|
|
|
|
|
+ d.MustDecode(ts)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ err = d.Decode(ts)
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ----- functions below are used only by benchmarks alone
|
|
|
|
|
+
|
|
|
|
|
+func fnBenchmarkByteBuf(bsIn []byte) (buf *bytes.Buffer) {
|
|
|
|
|
+ // var buf bytes.Buffer
|
|
|
|
|
+ // buf.Grow(approxSize)
|
|
|
|
|
+ buf = bytes.NewBuffer(bsIn)
|
|
|
|
|
+ buf.Truncate(0)
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func benchFnCodecEncode(ts interface{}, bsIn []byte, h Handle) (bs []byte, err error) {
|
|
|
|
|
+ return testCodecEncode(ts, bsIn, fnBenchmarkByteBuf, h)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func benchFnCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
|
|
|
|
|
+ return testCodecDecode(bs, ts, h)
|
|
|
|
|
+}
|