Browse Source

codec: bench: replace flags with TestInitBench and support testing.TB(.Helper)

Instead of bench flags, make a TestBenchInit function
that can verify which "checkers" can encode and decode a value correctly.

Removed flags include benchInitDebug, benchDoInitBench, etc.

Also, remove some bench specific flags and delegate to testXXX flags instead.

Finally, add support for testing.TB.Helper() so we get correct file:line numbers
in testing logs.
Ugorji Nwoke 6 years ago
parent
commit
0d00120898

+ 1 - 1
codec/bench/bench.sh

@@ -73,7 +73,7 @@ _suite_any() {
     if [[ "$g" = "g" ]]; then a=( "generated" "generated safe"); fi
     for i in "${a[@]}"; do
         echo ">>>> bench TAGS: 'alltests $x $i' SUITE: $b"
-        go test -run Nothing -tags "alltests $x $i" -bench "$b" -benchmem "$@"
+        go test -tags "alltests $x $i" -bench "$b" -benchmem "$@"
     done 
 }
 

+ 44 - 42
codec/bench/bench_test.go

@@ -17,6 +17,9 @@ import (
 // Sample way to run:
 // go test -bi -bv -bd=1 -benchmem -bench=.
 
+const benchUnscientificRes = true
+const benchVerify = true
+
 func init() {
 	testPreInitFns = append(testPreInitFns, benchPreInit)
 	testPostInitFns = append(testPostInitFns, benchPostInit)
@@ -45,9 +48,9 @@ func benchReinit() {
 }
 
 func benchPreInit() {
-	benchTs = newTestStruc(benchDepth, testNumRepeatString, true, !testSkipIntf, benchMapStringKeyOnly)
+	benchTs = newTestStruc(testDepth, testNumRepeatString, true, !testSkipIntf, testMapStringKeyOnly)
 	approxSize = approxDataSize(reflect.ValueOf(benchTs)) * 3 / 2 // multiply by 1.5 to appease msgp, and prevent alloc
-	// bytesLen := 1024 * 4 * (benchDepth + 1) * (benchDepth + 1)
+	// bytesLen := 1024 * 4 * (testDepth + 1) * (testDepth + 1)
 	// if bytesLen < approxSize {
 	// 	bytesLen = approxSize
 	// }
@@ -65,32 +68,31 @@ func benchPreInit() {
 }
 
 func benchPostInit() {
-	if benchDoInitBench {
-		runBenchInit()
-	}
+	// if benchDoInitBench {
+	// 	runBenchInit()
+	// }
 }
 
-func runBenchInit() {
-	// logTv(nil, "..............................................")
-	logTv(nil, "BENCHMARK INIT: %v", time.Now())
-	// logTv(nil, "To run full benchmark comparing encodings, use: \"go test -bench=.\"")
-	logTv(nil, "Benchmark: ")
-	logTv(nil, "\tStruct recursive Depth:             %d", benchDepth)
+func TestBenchInit(t *testing.T) {
+	testOnce.Do(testInitAll)
+	// logTv(t, "..............................................")
+	logT(t, "BENCHMARK INIT: %v", time.Now())
+	// logTv(t, "To run full benchmark comparing encodings, use: \"go test -bench=.\"")
+	logT(t, "Benchmark: ")
+	logT(t, "\tStruct recursive Depth:             %d", testDepth)
 	if approxSize > 0 {
-		logTv(nil, "\tApproxDeepSize Of benchmark Struct: %d bytes", approxSize)
+		logT(t, "\tApproxDeepSize Of benchmark Struct: %d bytes", approxSize)
 	}
 	if benchUnscientificRes {
-		logTv(nil, "Benchmark One-Pass Run (with Unscientific Encode/Decode times): ")
+		logT(t, "Benchmark One-Pass Run (with Unscientific Encode/Decode times): ")
 	} else {
-		logTv(nil, "Benchmark One-Pass Run:")
+		logT(t, "Benchmark One-Pass Run:")
 	}
 	for _, bc := range benchCheckers {
-		doBenchCheck(bc.name, bc.encodefn, bc.decodefn)
-	}
-	logTv(nil, "..............................................")
-	if benchInitDebug {
-		logTv(nil, "<<<<====>>>> depth: %v, ts: %#v\n", benchDepth, benchTs)
+		doBenchCheck(t, bc.name, bc.encodefn, bc.decodefn)
 	}
+	logTv(t, "..............................................")
+	logTv(t, "<<<<====>>>> depth: %v, ts: %#v\n", testDepth, benchTs)
 	runtime.GC()
 	time.Sleep(100 * time.Millisecond)
 }
@@ -111,29 +113,29 @@ func benchRecoverPanic(t interface{}) {
 	}
 }
 
-func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
+func doBenchCheck(t *testing.T, name string, encfn benchEncFn, decfn benchDecFn) {
 	// if benchUnscientificRes {
-	// 	logTv(nil, "-------------- %s ----------------", name)
+	// 	logTv(t, "-------------- %s ----------------", name)
 	// }
 	defer benchRecoverPanic(nil)
 	runtime.GC()
 	tnow := time.Now()
 	buf, err := encfn(benchTs, nil)
 	if err != nil {
-		logTv(nil, "\t%10s: **** Error encoding benchTs: %v", name, err)
+		logT(t, "\t%10s: **** Error encoding benchTs: %v", name, err)
 		return
 	}
 	encDur := time.Since(tnow)
 	encLen := len(buf)
 	runtime.GC()
 	if !benchUnscientificRes {
-		logTv(nil, "\t%10s: len: %d bytes\n", name, encLen)
+		logT(t, "\t%10s: len: %d bytes\n", name, encLen)
 		return
 	}
 	tnow = time.Now()
 	var ts2 TestStruc
 	if err = decfn(buf, &ts2); err != nil {
-		logTv(nil, "\t%10s: **** Error decoding into new TestStruc: %v", name, err)
+		logT(t, "\t%10s: **** Error decoding into new TestStruc: %v", name, err)
 		return
 	}
 	decDur := time.Since(tnow)
@@ -141,9 +143,9 @@ func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
 	if benchVerify {
 		err = deepEqual(benchTs, &ts2)
 		if err == nil {
-			logTv(nil, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v,\tencoded = decoded", name, encLen, encDur, decDur)
+			logT(t, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v,\tencoded == decoded", name, encLen, encDur, decDur)
 		} else {
-			logTv(nil, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v,\tencoded != decoded: %v", name, encLen, encDur, decDur, err)
+			logT(t, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v,\tencoded != decoded: %v", name, encLen, encDur, decDur, err)
 			// if strings.Contains(name, "json") {
 			// 	println(">>>>>")
 			// 	f1, _ := os.Create("1.out")
@@ -162,16 +164,16 @@ func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
 			// 	f2.Close()
 			// 	f3.Close()
 			// }
-			// logTv(nil, "\t: err: %v,\n benchTs: %#v\n\n, ts2: %#v\n\n", err, benchTs, ts2) // TODO: remove
-			// logTv(nil, "BenchVerify: Error comparing en|decoded TestStruc: %v", err)
+			// logT(t, "\t: err: %v,\n benchTs: %#v\n\n, ts2: %#v\n\n", err, benchTs, ts2) // TODO: remove
+			// logT(t, "BenchVerify: Error comparing en|decoded TestStruc: %v", err)
 			// return
-			// logTv(nil, "BenchVerify: Error comparing benchTs: %v\n--------\n%v\n--------\n%v", err, benchTs, ts2)
+			// logT(t, "BenchVerify: Error comparing benchTs: %v\n--------\n%v\n--------\n%v", err, benchTs, ts2)
 			// if strings.Contains(name, "json") {
-			// 	logTv(nil, "\n\tDECODED FROM\n--------\n%s", buf)
+			// 	logT(t, "\n\tDECODED FROM\n--------\n%s", buf)
 			// }
 		}
 	} else {
-		logTv(nil, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v", name, encLen, encDur, decDur)
+		logT(t, "\t%10s: len: %d bytes,\t encode: %v,\t decode: %v", name, encLen, encDur, decDur)
 	}
 	return
 }
@@ -203,17 +205,17 @@ func fnBenchmarkDecode(b *testing.B, encName string, ts interface{},
 	if err != nil {
 		failT(b, "Error encoding benchTs: %s: %v", encName, err)
 	}
-	if false && benchVerify { // do not do benchVerify during decode
-		// ts2 := newfn()
-		ts1 := ts.(*TestStruc)
-		ts2 := new(TestStruc)
-		if err = decfn(buf, ts2); err != nil {
-			failT(b, "BenchVerify: Error decoding benchTs: %s: %v", encName, err)
-		}
-		if err = deepEqual(ts1, ts2); err != nil {
-			failT(b, "BenchVerify: Error comparing benchTs: %s: %v", encName, err)
-		}
-	}
+	// if false && benchVerify { // do not do benchVerify during decode
+	// 	// ts2 := newfn()
+	// 	ts1 := ts.(*TestStruc)
+	// 	ts2 := new(TestStruc)
+	// 	if err = decfn(buf, ts2); err != nil {
+	// 		failT(b, "BenchVerify: Error decoding benchTs: %s: %v", encName, err)
+	// 	}
+	// 	if err = deepEqual(ts1, ts2); err != nil {
+	// 		failT(b, "BenchVerify: Error comparing benchTs: %s: %v", encName, err)
+	// 	}
+	// }
 	runtime.GC()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {

+ 20 - 34
codec/bench/shared_test.go

@@ -96,6 +96,8 @@ var (
 var (
 	testVerbose 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.
 	testDepth int
 
 	testMaxInitLen int
@@ -110,7 +112,8 @@ var (
 
 	testNumRepeatString int
 
-	testRpcBufsize int
+	testRpcBufsize       int
+	testMapStringKeyOnly bool
 )
 
 // variables that are not flags, but which can configure the handles
@@ -119,18 +122,6 @@ var (
 	testDecodeOptions DecodeOptions
 )
 
-// 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() {
 	log.SetOutput(ioutil.Discard) // don't allow things log to standard out/err
 	testHEDs = make([]testHED, 0, 32)
@@ -153,7 +144,6 @@ func init() {
 func testInitFlags() {
 	// delete(testDecOpts.ExtFuncs, timeTyp)
 	flag.BoolVar(&testVerbose, "tv", false, "Text Extra Verbose Logging if -v if set")
-	flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
 	flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
 	flag.IntVar(&testUseIoEncDec, "ti", -1, "Use IO Reader/Writer for Marshal/Unmarshal ie >= 0")
 	flag.BoolVar(&testUseIoWrapper, "tiw", false, "Wrap the IO Reader/Writer with a base pass-through reader/writer")
@@ -164,15 +154,15 @@ func testInitFlags() {
 	flag.BoolVar(&testUseMust, "tm", true, "Use Must(En|De)code")
 
 	flag.IntVar(&testMaxInitLen, "tx", 0, "Max Init Len")
+
+	flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
+	flag.BoolVar(&testMapStringKeyOnly, "tsk", false, "use maps with string keys only")
 }
 
 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")
+	// flags reproduced here for compatibility (duplicate some in testInitFlags)
+	flag.BoolVar(&testMapStringKeyOnly, "bs", false, "use maps with string keys only")
+	flag.IntVar(&testDepth, "bd", 1, "Bench Depth")
 }
 
 func testHEDGet(h Handle) *testHED {
@@ -287,6 +277,9 @@ func sTestCodecDecode(bs []byte, ts interface{}, h Handle, bh *BasicHandle) (err
 // help with diagnosing a failure, or which are too large.
 func logTv(x interface{}, format string, args ...interface{}) {
 	if testVerbose {
+		if t, ok := x.(testing.TB); ok { // only available from go 1.9
+			t.Helper()
+		}
 		logT(x, format, args...)
 	}
 }
@@ -305,24 +298,17 @@ func logT(x interface{}, format string, args ...interface{}) {
 		fmt.Printf(format, args...)
 		return
 	}
-	switch t := x.(type) {
-	case *testing.T:
-		// TODO: use conditional build files containing logT and failT
-		// t.Helper() // only available from go 1.9
-		t.Logf(format, args...)
-	case *testing.B:
-		// t.Helper() // only available from go 1.9
+	if t, ok := x.(testing.TB); ok { // only available from go 1.9
+		t.Helper()
 		t.Logf(format, args...)
 	}
 }
 
 func failT(x interface{}, args ...interface{}) {
-	// switch t := x.(type) {
-	// case *testing.T:
-	// 	t.Helper() // only available from go 1.9
-	// case *testing.B:
-	// 	t.Helper()
-	// }
+	t, ok := x.(testing.TB) // only available from go 1.9
+	if ok {
+		t.Helper()
+	}
 
 	if len(args) > 0 {
 		if format, ok := args[0].(string); ok {
@@ -333,7 +319,7 @@ func failT(x interface{}, args ...interface{}) {
 			logT(x, "%v", args)
 		}
 	}
-	if t, ok := x.(interface{ FailNow() }); ok {
+	if ok {
 		t.FailNow()
 	}
 }

+ 13 - 45
codec/bench/z_all_bench_test.go

@@ -23,12 +23,8 @@ var benchmarkGroupSave struct {
 	testUseIoEncDec int
 	testUseReset    bool
 
-	benchDepth            int
-	benchMapStringKeyOnly bool
-	benchInitDebug        bool
-	benchVerify           bool
-	benchDoInitBench      bool
-	benchUnscientificRes  bool
+	testDepth            int
+	testMapStringKeyOnly bool
 }
 
 func benchmarkGroupInitAll() {
@@ -36,24 +32,16 @@ func benchmarkGroupInitAll() {
 	benchmarkGroupSave.testUseIoEncDec = testUseIoEncDec
 	benchmarkGroupSave.testUseReset = testUseReset
 
-	benchmarkGroupSave.benchDepth = benchDepth
-	benchmarkGroupSave.benchMapStringKeyOnly = benchMapStringKeyOnly
-	benchmarkGroupSave.benchInitDebug = benchInitDebug
-	benchmarkGroupSave.benchVerify = benchVerify
-	benchmarkGroupSave.benchDoInitBench = benchDoInitBench
-	benchmarkGroupSave.benchUnscientificRes = benchUnscientificRes
+	benchmarkGroupSave.testDepth = testDepth
+	benchmarkGroupSave.testMapStringKeyOnly = testMapStringKeyOnly
 }
 
 func benchmarkGroupReset() {
 	testUseIoEncDec = benchmarkGroupSave.testUseIoEncDec
 	testUseReset = benchmarkGroupSave.testUseReset
 
-	benchDepth = benchmarkGroupSave.benchDepth
-	benchMapStringKeyOnly = benchmarkGroupSave.benchMapStringKeyOnly
-	benchInitDebug = benchmarkGroupSave.benchInitDebug
-	benchVerify = benchmarkGroupSave.benchVerify
-	benchDoInitBench = benchmarkGroupSave.benchDoInitBench
-	benchUnscientificRes = benchmarkGroupSave.benchUnscientificRes
+	testDepth = benchmarkGroupSave.testDepth
+	testMapStringKeyOnly = benchmarkGroupSave.testMapStringKeyOnly
 }
 
 func benchmarkDivider() {
@@ -98,19 +86,6 @@ func benchmarkSuite(t *testing.B, fns ...func(t *testing.B)) {
 
 	benchmarkGroupReset()
 
-	benchVerify = true
-	benchDoInitBench = true
-	benchUnscientificRes = true
-	testReinit()
-	benchReinit()
-	t.Run("init-metrics....", func(t *testing.B) { t.Run("Benchmark__Noop.............", benchmarkSuiteNoop) })
-
-	benchmarkGroupReset()
-
-	benchVerify = false
-	benchDoInitBench = false
-	benchUnscientificRes = false
-
 	testReinit()
 	benchReinit()
 	t.Run("options-false...", f)
@@ -130,13 +105,6 @@ func benchmarkSuite(t *testing.B, fns ...func(t *testing.B)) {
 	t.Run("reset-enc-dec...", f)
 
 	benchmarkGroupReset()
-
-	// benchVerify is kinda lame - serves no real purpose.
-	// benchVerify = true
-	// testReinit()
-	// benchReinit()
-	// t.Run("verify-on-decode", f)
-	// benchVerify = false
 }
 
 func benchmarkVeryQuickSuite(t *testing.B, name string, fns ...func(t *testing.B)) {
@@ -147,29 +115,29 @@ func benchmarkVeryQuickSuite(t *testing.B, name string, fns ...func(t *testing.B
 	// bd=1 2 | ti=-1, 1024 |
 
 	testUseIoEncDec = -1
-	// benchDepth = depth
+	// testDepth = depth
 	testReinit()
 	benchReinit()
 
-	t.Run(name+"-bd"+strconv.Itoa(benchDepth)+"........", benchmarkOneFn(fns))
+	t.Run(name+"-bd"+strconv.Itoa(testDepth)+"........", benchmarkOneFn(fns))
 	benchmarkGroupReset()
 }
 
 func benchmarkQuickSuite(t *testing.B, name string, fns ...func(t *testing.B)) {
 	benchmarkVeryQuickSuite(t, name, fns...)
 
-	// encoded size of TestStruc is between 20K and 30K for bd=1 // consider buffer=1024 * 16 * benchDepth
+	// encoded size of TestStruc is between 20K and 30K for bd=1 // consider buffer=1024 * 16 * testDepth
 	testUseIoEncDec = 1024 // (value of defEncByteBufSize): use smaller buffer, and more flushes - it's ok.
-	// benchDepth = depth
+	// testDepth = depth
 	testReinit()
 	benchReinit()
-	t.Run(name+"-bd"+strconv.Itoa(benchDepth)+"-buf"+strconv.Itoa(testUseIoEncDec), benchmarkOneFn(fns))
+	t.Run(name+"-bd"+strconv.Itoa(testDepth)+"-buf"+strconv.Itoa(testUseIoEncDec), benchmarkOneFn(fns))
 
 	testUseIoEncDec = 0
-	// benchDepth = depth
+	// testDepth = depth
 	testReinit()
 	benchReinit()
-	t.Run(name+"-bd"+strconv.Itoa(benchDepth)+"-io.....", benchmarkOneFn(fns))
+	t.Run(name+"-bd"+strconv.Itoa(testDepth)+"-io.....", benchmarkOneFn(fns))
 
 	benchmarkGroupReset()
 }

+ 135 - 0
codec/goversion_maprange_unsafe_gte_go112.go

@@ -0,0 +1,135 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !safe
+// +build !appengine
+// +build go1.12
+
+package codec
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+type unsafeReflectMapIter struct {
+	m  unsafeReflectValue
+	it unsafe.Pointer
+}
+
+type mapIter struct {
+	t              *reflect.MapIter
+	m, k, v        reflect.Value
+	ktyp, vtyp     unsafe.Pointer
+	kptr, vptr     unsafe.Pointer
+	kisref, visref bool
+	mapvalues      bool
+	done           bool
+	_              uint64 // padding (cache-aligned)
+}
+
+func (t *mapIter) Next() (r bool) {
+	if t.done {
+		return
+	}
+	r = t.t.Next()
+	if r {
+		it := (*unsafeReflectMapIter)(unsafe.Pointer(t.t))
+		mapSet(t.kptr, t.ktyp, mapiterkey(it.it), t.kisref)
+		if t.mapvalues {
+			mapSet(t.vptr, t.vtyp, mapiterelem(it.it), t.visref)
+		}
+	} else {
+		t.done = true
+	}
+	return
+}
+
+func (t *mapIter) Key() reflect.Value {
+	return t.k
+}
+
+func (t *mapIter) Value() (r reflect.Value) {
+	if t.mapvalues {
+		return t.v
+	}
+	return
+}
+
+func mapSet(p, ptyp, p2 unsafe.Pointer, isref bool) {
+	if isref {
+		*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(p2) // p2
+	} else {
+		typedmemmove(ptyp, p, p2) // *(*unsafe.Pointer)(p2)) // p2)
+	}
+}
+
+func mapRange(m, k, v reflect.Value, mapvalues bool) *mapIter {
+	if m.IsNil() {
+		return &mapIter{done: true}
+	}
+	t := &mapIter{
+		m: m, k: k, v: v,
+		t: m.MapRange(), mapvalues: mapvalues,
+	}
+
+	var urv *unsafeReflectValue
+	urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
+	t.ktyp = urv.typ
+	t.kptr = urv.ptr
+	t.kisref = refBitset.isset(byte(k.Kind()))
+	if mapvalues {
+		urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
+		t.vtyp = urv.typ
+		t.vptr = urv.ptr
+		t.visref = refBitset.isset(byte(v.Kind()))
+	}
+
+	return t
+}
+
+func mapIndex(m, k, v reflect.Value) (vv reflect.Value) {
+	var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
+	var kptr unsafe.Pointer
+	if urv.flag&unsafeFlagIndir == 0 {
+		kptr = unsafe.Pointer(&urv.ptr)
+	} else {
+		kptr = urv.ptr
+	}
+
+	urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
+
+	vvptr := mapaccess(urv.typ, rv2ptr(urv), kptr)
+	if vvptr == nil {
+		return
+	}
+	// vvptr = *(*unsafe.Pointer)(vvptr)
+
+	urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
+
+	mapSet(urv.ptr, urv.typ, vvptr, refBitset.isset(byte(v.Kind())))
+	return v
+}
+
+// return an addressable reflect value that can be used in mapRange and mapIndex operations.
+//
+// all calls to mapIndex or mapRange will call here to get an addressable reflect.Value.
+func mapAddressableRV(t reflect.Type) (r reflect.Value) {
+	return reflect.New(t).Elem()
+}
+
+//go:linkname mapiterkey reflect.mapiterkey
+//go:noescape
+func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
+
+//go:linkname mapiterelem reflect.mapiterelem
+//go:noescape
+func mapiterelem(it unsafe.Pointer) (elem unsafe.Pointer)
+
+//go:linkname mapaccess reflect.mapaccess
+//go:noescape
+func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
+
+//go:linkname typedmemmove reflect.typedmemmove
+//go:noescape
+func typedmemmove(typ unsafe.Pointer, dst, src unsafe.Pointer)

+ 20 - 34
codec/shared_test.go

@@ -96,6 +96,8 @@ var (
 var (
 	testVerbose 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.
 	testDepth int
 
 	testMaxInitLen int
@@ -110,7 +112,8 @@ var (
 
 	testNumRepeatString int
 
-	testRpcBufsize int
+	testRpcBufsize       int
+	testMapStringKeyOnly bool
 )
 
 // variables that are not flags, but which can configure the handles
@@ -119,18 +122,6 @@ var (
 	testDecodeOptions DecodeOptions
 )
 
-// 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() {
 	log.SetOutput(ioutil.Discard) // don't allow things log to standard out/err
 	testHEDs = make([]testHED, 0, 32)
@@ -153,7 +144,6 @@ func init() {
 func testInitFlags() {
 	// delete(testDecOpts.ExtFuncs, timeTyp)
 	flag.BoolVar(&testVerbose, "tv", false, "Text Extra Verbose Logging if -v if set")
-	flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
 	flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
 	flag.IntVar(&testUseIoEncDec, "ti", -1, "Use IO Reader/Writer for Marshal/Unmarshal ie >= 0")
 	flag.BoolVar(&testUseIoWrapper, "tiw", false, "Wrap the IO Reader/Writer with a base pass-through reader/writer")
@@ -164,15 +154,15 @@ func testInitFlags() {
 	flag.BoolVar(&testUseMust, "tm", true, "Use Must(En|De)code")
 
 	flag.IntVar(&testMaxInitLen, "tx", 0, "Max Init Len")
+
+	flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
+	flag.BoolVar(&testMapStringKeyOnly, "tsk", false, "use maps with string keys only")
 }
 
 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")
+	// flags reproduced here for compatibility (duplicate some in testInitFlags)
+	flag.BoolVar(&testMapStringKeyOnly, "bs", false, "use maps with string keys only")
+	flag.IntVar(&testDepth, "bd", 1, "Bench Depth")
 }
 
 func testHEDGet(h Handle) *testHED {
@@ -287,6 +277,9 @@ func sTestCodecDecode(bs []byte, ts interface{}, h Handle, bh *BasicHandle) (err
 // help with diagnosing a failure, or which are too large.
 func logTv(x interface{}, format string, args ...interface{}) {
 	if testVerbose {
+		if t, ok := x.(testing.TB); ok { // only available from go 1.9
+			t.Helper()
+		}
 		logT(x, format, args...)
 	}
 }
@@ -305,24 +298,17 @@ func logT(x interface{}, format string, args ...interface{}) {
 		fmt.Printf(format, args...)
 		return
 	}
-	switch t := x.(type) {
-	case *testing.T:
-		// TODO: use conditional build files containing logT and failT
-		// t.Helper() // only available from go 1.9
-		t.Logf(format, args...)
-	case *testing.B:
-		// t.Helper() // only available from go 1.9
+	if t, ok := x.(testing.TB); ok { // only available from go 1.9
+		t.Helper()
 		t.Logf(format, args...)
 	}
 }
 
 func failT(x interface{}, args ...interface{}) {
-	// switch t := x.(type) {
-	// case *testing.T:
-	// 	t.Helper() // only available from go 1.9
-	// case *testing.B:
-	// 	t.Helper()
-	// }
+	t, ok := x.(testing.TB) // only available from go 1.9
+	if ok {
+		t.Helper()
+	}
 
 	if len(args) > 0 {
 		if format, ok := args[0].(string); ok {
@@ -333,7 +319,7 @@ func failT(x interface{}, args ...interface{}) {
 			logT(x, "%v", args)
 		}
 	}
-	if t, ok := x.(interface{ FailNow() }); ok {
+	if ok {
 		t.FailNow()
 	}
 }