values_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /* // +build testing */
  2. // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
  3. // Use of this source code is governed by a MIT license found in the LICENSE file.
  4. package codec
  5. // This file contains values used by tests and benchmarks.
  6. // The benchmarks will test performance against other libraries (encoding/json, json-iterator, bson, gob, etc).
  7. // Consequently, we only use values that will parse well in all engines,
  8. // and only leverage features that work across multiple libraries for a truer comparison.
  9. // For example,
  10. // - JSON/BSON do not like maps with keys that are not strings,
  11. // so we only use maps with string keys here.
  12. // - _struct options are not honored by other libraries,
  13. // so we don't use them in this file.
  14. import (
  15. "math"
  16. "strings"
  17. )
  18. type wrapSliceUint64 []uint64
  19. type wrapSliceString []string
  20. type wrapUint64 uint64
  21. type wrapString string
  22. type wrapUint64Slice []wrapUint64
  23. type wrapStringSlice []wrapString
  24. type stringUint64T struct {
  25. S string
  26. U uint64
  27. }
  28. type AnonInTestStruc struct {
  29. AS string
  30. AI64 int64
  31. AI16 int16
  32. AUi64 uint64
  33. ASslice []string
  34. AI64slice []int64
  35. AUi64slice []uint64
  36. AF64slice []float64
  37. AF32slice []float32
  38. // AMI32U32 map[int32]uint32
  39. // AMU32F64 map[uint32]float64 // json/bson do not like it
  40. AMSU16 map[string]uint16
  41. // use these to test 0-len or nil slices/maps/arrays
  42. AI64arr0 [0]int64
  43. A164slice0 []int64
  44. AUi64sliceN []uint64
  45. AMSU16N map[string]uint16
  46. AMSU16E map[string]uint16
  47. }
  48. type testSimpleFields struct {
  49. S string
  50. I64 int64
  51. I32 int32
  52. I16 int16
  53. I8 int8
  54. I64n int64
  55. I32n int32
  56. I16n int16
  57. I8n int8
  58. Ui64 uint64
  59. Ui32 uint32
  60. Ui16 uint16
  61. Ui8 uint8
  62. F64 float64
  63. F32 float32
  64. B bool
  65. By uint8 // byte: msgp doesn't like byte
  66. Sslice []string
  67. I64slice []int64
  68. I16slice []int16
  69. Ui64slice []uint64
  70. Ui8slice []uint8
  71. Bslice []bool
  72. Byslice []byte
  73. Iptrslice []*int64
  74. // TODO: test these separately, specifically for reflection and codecgen.
  75. // Unfortunately, ffjson doesn't support these. Its compilation even fails.
  76. WrapSliceInt64 wrapSliceUint64
  77. WrapSliceString wrapSliceString
  78. Msi64 map[string]int64
  79. }
  80. type TestStrucCommon struct {
  81. S string
  82. I64 int64
  83. I32 int32
  84. I16 int16
  85. I8 int8
  86. I64n int64
  87. I32n int32
  88. I16n int16
  89. I8n int8
  90. Ui64 uint64
  91. Ui32 uint32
  92. Ui16 uint16
  93. Ui8 uint8
  94. F64 float64
  95. F32 float32
  96. B bool
  97. By uint8 // byte: msgp doesn't like byte
  98. Sslice []string
  99. I64slice []int64
  100. I16slice []int16
  101. Ui64slice []uint64
  102. Ui8slice []uint8
  103. Bslice []bool
  104. Byslice []byte
  105. Iptrslice []*int64
  106. // TODO: test these separately, specifically for reflection and codecgen.
  107. // Unfortunately, ffjson doesn't support these. Its compilation even fails.
  108. WrapSliceInt64 wrapSliceUint64
  109. WrapSliceString wrapSliceString
  110. Msi64 map[string]int64
  111. Simplef testSimpleFields
  112. AnonInTestStruc
  113. NotAnon AnonInTestStruc
  114. // R Raw // Testing Raw must be explicitly turned on, so use standalone test
  115. // Rext RawExt // Testing RawExt is tricky, so use standalone test
  116. Nmap map[string]bool //don't set this, so we can test for nil
  117. Nslice []byte //don't set this, so we can test for nil
  118. Nint64 *int64 //don't set this, so we can test for nil
  119. }
  120. type TestStruc struct {
  121. // _struct struct{} `json:",omitempty"` //set omitempty for every field
  122. TestStrucCommon
  123. Mtsptr map[string]*TestStruc
  124. Mts map[string]TestStruc
  125. Its []*TestStruc
  126. Nteststruc *TestStruc
  127. }
  128. func populateTestStrucCommon(ts *TestStrucCommon, n int, bench, useInterface, useStringKeyOnly bool) {
  129. var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464
  130. // if bench, do not use uint64 values > math.MaxInt64, as bson, etc cannot decode them
  131. var a = AnonInTestStruc{
  132. // There's more leeway in altering this.
  133. AS: strRpt(n, "A-String"),
  134. AI64: -64646464,
  135. AI16: 1616,
  136. AUi64: 64646464,
  137. // (U+1D11E)G-clef character may be represented in json as "\uD834\uDD1E".
  138. // single reverse solidus character may be represented in json as "\u005C".
  139. // include these in ASslice below.
  140. ASslice: []string{
  141. strRpt(n, "Aone"),
  142. strRpt(n, "Atwo"),
  143. strRpt(n, "Athree"),
  144. strRpt(n, "Afour.reverse_solidus.\u005c"),
  145. strRpt(n, "Afive.Gclef.\U0001d11E\"ugorji\"done.")},
  146. AI64slice: []int64{
  147. 0, 1, -1, -22, 333, -4444, 55555, -666666,
  148. // msgpack ones
  149. -48, -32, -24, -8, 32, 127, 192, 255,
  150. // standard ones
  151. 0, -1, 1,
  152. math.MaxInt8, math.MaxInt8 + 4, math.MaxInt8 - 4,
  153. math.MaxInt16, math.MaxInt16 + 4, math.MaxInt16 - 4,
  154. math.MaxInt32, math.MaxInt32 + 4, math.MaxInt32 - 4,
  155. math.MaxInt64, math.MaxInt64 - 4,
  156. math.MinInt8, math.MinInt8 + 4, math.MinInt8 - 4,
  157. math.MinInt16, math.MinInt16 + 4, math.MinInt16 - 4,
  158. math.MinInt32, math.MinInt32 + 4, math.MinInt32 - 4,
  159. math.MinInt64, math.MinInt64 + 4,
  160. },
  161. AUi64slice: []uint64{
  162. 0, 1, 22, 333, 4444, 55555, 666666,
  163. // standard ones
  164. math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
  165. math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
  166. math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4,
  167. },
  168. AMSU16: map[string]uint16{strRpt(n, "1"): 1, strRpt(n, "22"): 2, strRpt(n, "333"): 3, strRpt(n, "4444"): 4},
  169. // Note: +/- inf, NaN, and other non-representable numbers should not be explicitly tested here
  170. AF64slice: []float64{
  171. 11.11e-11, -11.11e+11,
  172. 2.222E+12, -2.222E-12,
  173. -555.55E-5, 555.55E+5,
  174. 666.66E-6, -666.66E+6,
  175. 7777.7777E-7, -7777.7777E-7,
  176. -8888.8888E+8, 8888.8888E+8,
  177. -99999.9999E+9, 99999.9999E+9,
  178. // these below are hairy enough to need strconv.ParseFloat
  179. 33.33E-33, -33.33E+33,
  180. 44.44e+44, -44.44e-44,
  181. // standard ones
  182. 0, -1, 1,
  183. // math.Inf(1), math.Inf(-1),
  184. math.Pi, math.Phi, math.E,
  185. math.MaxFloat64, math.SmallestNonzeroFloat64,
  186. },
  187. AF32slice: []float32{
  188. 11.11e-11, -11.11e+11,
  189. 2.222E+12, -2.222E-12,
  190. -555.55E-5, 555.55E+5,
  191. 666.66E-6, -666.66E+6,
  192. 7777.7777E-7, -7777.7777E-7,
  193. -8888.8888E+8, 8888.8888E+8,
  194. -99999.9999E+9, 99999.9999E+9,
  195. // these below are hairy enough to need strconv.ParseFloat
  196. 33.33E-33, -33.33E+33,
  197. // standard ones
  198. 0, -1, 1,
  199. // math.Float32frombits(0x7FF00000), math.Float32frombits(0xFFF00000), //+inf and -inf
  200. math.MaxFloat32, math.SmallestNonzeroFloat32,
  201. },
  202. A164slice0: []int64{},
  203. AUi64sliceN: nil,
  204. AMSU16N: nil,
  205. AMSU16E: map[string]uint16{},
  206. }
  207. if !bench {
  208. a.AUi64slice = append(a.AUi64slice, math.MaxUint64, math.MaxUint64-4)
  209. }
  210. *ts = TestStrucCommon{
  211. S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
  212. // set the numbers close to the limits
  213. I8: math.MaxInt8 * 2 / 3, // 8,
  214. I8n: math.MinInt8 * 2 / 3, // 8,
  215. I16: math.MaxInt16 * 2 / 3, // 16,
  216. I16n: math.MinInt16 * 2 / 3, // 16,
  217. I32: math.MaxInt32 * 2 / 3, // 32,
  218. I32n: math.MinInt32 * 2 / 3, // 32,
  219. I64: math.MaxInt64 * 2 / 3, // 64,
  220. I64n: math.MinInt64 * 2 / 3, // 64,
  221. Ui64: math.MaxUint64 * 2 / 3, // 64
  222. Ui32: math.MaxUint32 * 2 / 3, // 32
  223. Ui16: math.MaxUint16 * 2 / 3, // 16
  224. Ui8: math.MaxUint8 * 2 / 3, // 8
  225. F32: 3.402823e+38, // max representable float32 without losing precision
  226. F64: 3.40281991833838838338e+53,
  227. B: true,
  228. By: 5,
  229. Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")},
  230. I64slice: []int64{1111, 2222, 3333},
  231. I16slice: []int16{44, 55, 66},
  232. Ui64slice: []uint64{12121212, 34343434, 56565656},
  233. Ui8slice: []uint8{210, 211, 212},
  234. Bslice: []bool{true, false, true, false},
  235. Byslice: []byte{13, 14, 15},
  236. Msi64: map[string]int64{
  237. strRpt(n, "one"): 1,
  238. strRpt(n, "two"): 2,
  239. strRpt(n, "\"three\""): 3,
  240. },
  241. WrapSliceInt64: []uint64{4, 16, 64, 256},
  242. WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
  243. // R: Raw([]byte("goodbye")),
  244. // Rext: RawExt{ 120, []byte("hello"), }, // TODO: don't set this - it's hard to test
  245. // DecodeNaked bombs here, because the stringUint64T is decoded as a map,
  246. // and a map cannot be the key type of a map.
  247. // Thus, don't initialize this here.
  248. // Msu2wss: map[stringUint64T]wrapStringSlice{
  249. // {"5", 5}: []wrapString{"1", "2", "3", "4", "5"},
  250. // {"3", 3}: []wrapString{"1", "2", "3"},
  251. // },
  252. // make Simplef same as top-level
  253. // TODO: should this have slightly different values???
  254. Simplef: testSimpleFields{
  255. S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
  256. // set the numbers close to the limits
  257. I8: math.MaxInt8 * 2 / 3, // 8,
  258. I8n: math.MinInt8 * 2 / 3, // 8,
  259. I16: math.MaxInt16 * 2 / 3, // 16,
  260. I16n: math.MinInt16 * 2 / 3, // 16,
  261. I32: math.MaxInt32 * 2 / 3, // 32,
  262. I32n: math.MinInt32 * 2 / 3, // 32,
  263. I64: math.MaxInt64 * 2 / 3, // 64,
  264. I64n: math.MinInt64 * 2 / 3, // 64,
  265. Ui64: math.MaxUint64 * 2 / 3, // 64
  266. Ui32: math.MaxUint32 * 2 / 3, // 32
  267. Ui16: math.MaxUint16 * 2 / 3, // 16
  268. Ui8: math.MaxUint8 * 2 / 3, // 8
  269. F32: 3.402823e+38, // max representable float32 without losing precision
  270. F64: 3.40281991833838838338e+53,
  271. B: true,
  272. By: 5,
  273. Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")},
  274. I64slice: []int64{1111, 2222, 3333},
  275. I16slice: []int16{44, 55, 66},
  276. Ui64slice: []uint64{12121212, 34343434, 56565656},
  277. Ui8slice: []uint8{210, 211, 212},
  278. Bslice: []bool{true, false, true, false},
  279. Byslice: []byte{13, 14, 15},
  280. Msi64: map[string]int64{
  281. strRpt(n, "one"): 1,
  282. strRpt(n, "two"): 2,
  283. strRpt(n, "\"three\""): 3,
  284. },
  285. WrapSliceInt64: []uint64{4, 16, 64, 256},
  286. WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
  287. },
  288. AnonInTestStruc: a,
  289. NotAnon: a,
  290. }
  291. if bench {
  292. ts.Ui64 = math.MaxInt64 * 2 / 3
  293. ts.Simplef.Ui64 = ts.Ui64
  294. }
  295. //For benchmarks, some things will not work.
  296. if !bench {
  297. //json and bson require string keys in maps
  298. //ts.M = map[interface{}]interface{}{
  299. // true: "true",
  300. // int8(9): false,
  301. //}
  302. //gob cannot encode nil in element in array (encodeArray: nil element)
  303. ts.Iptrslice = []*int64{nil, &i64a, nil, &i64b, nil, &i64c, nil, &i64d, nil}
  304. // ts.Iptrslice = nil
  305. }
  306. if !useStringKeyOnly {
  307. // ts.AnonInTestStruc.AMU32F64 = map[uint32]float64{1: 1, 2: 2, 3: 3} // Json/Bson barf
  308. }
  309. }
  310. func newTestStruc(depth, n int, bench, useInterface, useStringKeyOnly bool) (ts *TestStruc) {
  311. ts = &TestStruc{}
  312. populateTestStrucCommon(&ts.TestStrucCommon, n, bench, useInterface, useStringKeyOnly)
  313. if depth > 0 {
  314. depth--
  315. if ts.Mtsptr == nil {
  316. ts.Mtsptr = make(map[string]*TestStruc)
  317. }
  318. if ts.Mts == nil {
  319. ts.Mts = make(map[string]TestStruc)
  320. }
  321. ts.Mtsptr[strRpt(n, "0")] = newTestStruc(depth, n, bench, useInterface, useStringKeyOnly)
  322. ts.Mts[strRpt(n, "0")] = *(ts.Mtsptr[strRpt(n, "0")])
  323. ts.Its = append(ts.Its, ts.Mtsptr[strRpt(n, "0")])
  324. }
  325. return
  326. }
  327. var testStrRptMap = make(map[int]map[string]string)
  328. func strRpt(n int, s string) string {
  329. if false {
  330. // fmt.Printf(">>>> calling strings.Repeat on n: %d, key: %s\n", n, s)
  331. return strings.Repeat(s, n)
  332. }
  333. m1, ok := testStrRptMap[n]
  334. if !ok {
  335. // fmt.Printf(">>>> making new map for n: %v\n", n)
  336. m1 = make(map[string]string)
  337. testStrRptMap[n] = m1
  338. }
  339. v1, ok := m1[s]
  340. if !ok {
  341. // fmt.Printf(">>>> creating new entry for key: %s\n", s)
  342. v1 = strings.Repeat(s, n)
  343. m1[s] = v1
  344. }
  345. return v1
  346. }
  347. // func wstrRpt(n int, s string) wrapBytes {
  348. // return wrapBytes(bytes.Repeat([]byte(s), n))
  349. // }