parser_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. package hbaseutil
  2. import (
  3. "encoding/binary"
  4. "encoding/json"
  5. "github.com/tsuna/gohbase/hrpc"
  6. "reflect"
  7. "testing"
  8. "time"
  9. )
  10. func uint64ToByte(value uint64) []byte {
  11. var buf = make([]byte, 8)
  12. binary.BigEndian.PutUint64(buf, value)
  13. return buf
  14. }
  15. func uint32ToByte(value uint32) []byte {
  16. var buf = make([]byte, 4)
  17. binary.BigEndian.PutUint32(buf, value)
  18. return buf
  19. }
  20. func uint16ToByte(value uint16) []byte {
  21. var buf = make([]byte, 2)
  22. binary.BigEndian.PutUint16(buf, value)
  23. return buf
  24. }
  25. type testStruct struct {
  26. A int64 `family:"f" qualifier:"q64"`
  27. B *int32 `family:"f" qualifier:"q32"`
  28. C int16 `family:"f" qualifier:"q16"`
  29. D int `qualifier:"q"`
  30. S *string `qualifier:"s"`
  31. FailField bool `family:"f" qualifier:"fail"`
  32. MapInt map[string]int `family:"m1"`
  33. MapString map[string]string `family:"m2"`
  34. }
  35. func (t *testStruct) equal(o testStruct) bool {
  36. return t.A == o.A &&
  37. *t.B == *o.B &&
  38. t.C == o.C &&
  39. t.D == o.D &&
  40. *t.S == *o.S &&
  41. t.FailField == o.FailField &&
  42. reflect.DeepEqual(t.MapInt, o.MapInt) &&
  43. reflect.DeepEqual(t.MapString, o.MapString)
  44. }
  45. var testcase = [][]*hrpc.Cell{
  46. {
  47. {Family: []byte("f"), Qualifier: []byte("q64"), Value: uint64ToByte(10000000000)},
  48. {Family: []byte("f"), Qualifier: []byte("q32"), Value: uint32ToByte(1000000)},
  49. {Family: []byte("f"), Qualifier: []byte("q16"), Value: uint16ToByte(100)},
  50. {Family: []byte("f"), Qualifier: []byte("q"), Value: uint64ToByte(1000000)},
  51. {Family: []byte("f"), Qualifier: []byte("s"), Value: []byte("just test")},
  52. {Family: []byte("f"), Qualifier: []byte("fail"), Value: []byte("1")},
  53. {Family: []byte("m1"), Qualifier: []byte("k1"), Value: uint32ToByte(1)},
  54. {Family: []byte("m1"), Qualifier: []byte("k2"), Value: uint16ToByte(2)},
  55. {Family: []byte("m2"), Qualifier: []byte("k1"), Value: []byte("1")},
  56. {Family: []byte("m2"), Qualifier: []byte("k2"), Value: []byte("2")},
  57. },
  58. {
  59. {Family: []byte("f"), Qualifier: []byte("q64"), Value: uint64ToByte(10000000000)},
  60. {Family: []byte("f"), Qualifier: []byte("q32"), Value: uint64ToByte(10000000000)},
  61. {Family: []byte("f"), Qualifier: []byte("q16"), Value: uint64ToByte(10000000000)},
  62. {Family: []byte("f"), Qualifier: []byte("q"), Value: uint64ToByte(10000000000)},
  63. {Family: []byte("f"), Qualifier: []byte("s"), Value: []byte("just test2")},
  64. {Family: []byte("f"), Qualifier: []byte("fail"), Value: []byte("1")},
  65. },
  66. }
  67. var resultb = []int32{
  68. 1000000,
  69. 10000000000 & 0xffffffff,
  70. }
  71. var results = []string{
  72. "just test",
  73. "just test2",
  74. }
  75. var resultcase = []testStruct{
  76. {A: 10000000000, B: &resultb[0], C: 100, D: 1000000, S: &results[0],
  77. MapInt: map[string]int{"k1": 1, "k2": 2},
  78. MapString: map[string]string{"k1": "1", "k2": "2"}},
  79. {A: 10000000000, B: &resultb[1], C: -7168, D: int(10000000000), S: &results[1]},
  80. }
  81. func TestParser_Parse(t *testing.T) {
  82. var parser = Parser{}
  83. for i, cells := range testcase {
  84. var result testStruct
  85. var err = parser.Parse(cells, &result)
  86. if err != nil {
  87. t.Logf("err=%v", err)
  88. t.Fail()
  89. }
  90. t.Logf("result=%v, expect=%v", result, resultcase[i])
  91. if !resultcase[i].equal(result) {
  92. t.Logf("fail case: index=%d", i)
  93. t.Fail()
  94. }
  95. }
  96. }
  97. var testcase2 = [][]*hrpc.Cell{
  98. {
  99. {Family: []byte("f"), Qualifier: []byte("q64"), Value: []byte("10000000000")},
  100. {Family: []byte("f"), Qualifier: []byte("q32"), Value: []byte("1000000")},
  101. {Family: []byte("f"), Qualifier: []byte("q16"), Value: []byte("100")},
  102. {Family: []byte("f"), Qualifier: []byte("q"), Value: []byte("1000000")},
  103. {Family: []byte("f"), Qualifier: []byte("s"), Value: []byte("just test")},
  104. {Family: []byte("f"), Qualifier: []byte("fail"), Value: []byte("1")},
  105. {Family: []byte("m1"), Qualifier: []byte("k1"), Value: []byte("1")},
  106. {Family: []byte("m1"), Qualifier: []byte("k2"), Value: []byte("2")},
  107. {Family: []byte("m2"), Qualifier: []byte("k1"), Value: []byte("1")},
  108. {Family: []byte("m2"), Qualifier: []byte("k2"), Value: []byte("2")},
  109. },
  110. }
  111. var resultcase2 = []testStruct{
  112. {A: 10000000000, B: &resultb[0], C: 100, D: 1000000, S: &results[0],
  113. MapInt: map[string]int{"k1": 1, "k2": 2},
  114. MapString: map[string]string{"k1": "1", "k2": "2"}},
  115. }
  116. func TestParser_ParseCustomParseInt(t *testing.T) {
  117. var parser = Parser{
  118. ParseIntFunc: StringToUint,
  119. }
  120. for i, cells := range testcase2 {
  121. var result testStruct
  122. var err = parser.Parse(cells, &result)
  123. if err != nil {
  124. t.Logf("err=%v", err)
  125. t.Fail()
  126. }
  127. t.Logf("result=%v, expect=%v", result, resultcase[i])
  128. if !resultcase2[i].equal(result) {
  129. t.Logf("fail case: index=%d", i)
  130. t.Fail()
  131. }
  132. }
  133. }
  134. func TestParser_StringInt(t *testing.T) {
  135. var testcase2 = [][]*hrpc.Cell{
  136. {
  137. {Family: []byte("f"), Qualifier: []byte("q64"), Value: []byte("9223372036854775807")},
  138. {Family: []byte("f"), Qualifier: []byte("q32"), Value: []byte("1000000")},
  139. {Family: []byte("f"), Qualifier: []byte("q16"), Value: []byte("10000")},
  140. {Family: []byte("f"), Qualifier: []byte("q"), Value: []byte("100")},
  141. },
  142. {
  143. {Family: []byte("f"), Qualifier: []byte("q64"), Value: []byte("-9223372036854775808")},
  144. {Family: []byte("f"), Qualifier: []byte("q32"), Value: []byte("-2")},
  145. {Family: []byte("f"), Qualifier: []byte("q16"), Value: []byte("-3")},
  146. {Family: []byte("f"), Qualifier: []byte("q"), Value: []byte("-4")},
  147. {Family: []byte("f"), Qualifier: []byte("u64"), Value: []byte("18446744073709551615")},
  148. {Family: []byte("f"), Qualifier: []byte("u32"), Value: []byte("2147483648")},
  149. {Family: []byte("f"), Qualifier: []byte("u16"), Value: []byte("32768")},
  150. {Family: []byte("f"), Qualifier: []byte("u8"), Value: []byte("128")},
  151. },
  152. }
  153. type testStruct struct {
  154. A int64 `family:"f" qualifier:"q64"`
  155. B int32 `family:"f" qualifier:"q32"`
  156. C int16 `family:"f" qualifier:"q16"`
  157. D int8 `qualifier:"q"`
  158. U64 uint64 `family:"f" qualifier:"u64"`
  159. U32 uint32 `family:"f" qualifier:"u32"`
  160. U16 uint16 `family:"f" qualifier:"u16"`
  161. U8 uint8 `family:"f" qualifier:"u8"`
  162. }
  163. var expect = []testStruct{
  164. {
  165. A: 9223372036854775807, B: 1000000, C: 10000, D: 100,
  166. },
  167. {
  168. A: -9223372036854775808, B: -2, C: -3, D: -4,
  169. U64: 18446744073709551615, U32: 2147483648, U16: 32768, U8: 128,
  170. },
  171. }
  172. var parser = Parser{
  173. ParseIntFunc: StringToUint,
  174. }
  175. for i, cells := range testcase2 {
  176. var result testStruct
  177. var err = parser.Parse(cells, &result)
  178. if err != nil {
  179. t.Logf("err=%v", err)
  180. t.Fail()
  181. }
  182. t.Logf("result=%+v, expect=%+v", result, expect[i])
  183. if !reflect.DeepEqual(expect[i], result) {
  184. t.Logf("fail case: index=%d", i)
  185. t.Fail()
  186. }
  187. }
  188. }
  189. func TestParser_InterfaceInterface(t *testing.T) {
  190. var parser = Parser{}
  191. for i, cells := range testcase {
  192. var st testStruct
  193. var result interface{} = &st
  194. var err = parser.Parse(cells, result)
  195. if err != nil {
  196. t.Logf("err=%v", err)
  197. t.Fail()
  198. }
  199. t.Logf("result=%v, expect=%v", result, resultcase[i])
  200. if !resultcase[i].equal(*result.(*testStruct)) {
  201. t.Logf("fail case: index=%d", i)
  202. t.Fail()
  203. }
  204. }
  205. }
  206. type testOnlyQualifier struct {
  207. A int64 `qualifier:"q64"`
  208. B *int32 `qualifier:"q32"`
  209. C int16 `qualifier:"q16"`
  210. D int `qualifier:"q"`
  211. S *string `qualifier:"s"`
  212. FailField bool `qualifier:"fail"`
  213. MapInt map[string]int `family:"m1"`
  214. MapString map[string]string `family:"m2"`
  215. }
  216. var testcase3 = [][]*hrpc.Cell{
  217. {
  218. {Family: []byte("f"), Qualifier: []byte("q64"), Value: uint64ToByte(10000000000)},
  219. {Family: []byte("f"), Qualifier: []byte("q32"), Value: uint32ToByte(1000000)},
  220. {Family: []byte("f"), Qualifier: []byte("q16"), Value: uint16ToByte(100)},
  221. {Family: []byte("f"), Qualifier: []byte("q"), Value: uint64ToByte(1000000)},
  222. {Family: []byte("f"), Qualifier: []byte("s"), Value: []byte("just test")},
  223. {Family: []byte("f"), Qualifier: []byte("fail"), Value: []byte("1")},
  224. {Family: []byte("m1"), Qualifier: []byte("k1"), Value: uint32ToByte(1)},
  225. {Family: []byte("m1"), Qualifier: []byte("k2"), Value: uint16ToByte(2)},
  226. {Family: []byte("m2"), Qualifier: []byte("k1"), Value: []byte("1")},
  227. {Family: []byte("m2"), Qualifier: []byte("k2"), Value: []byte("2")},
  228. },
  229. }
  230. var resultcase3 = []testOnlyQualifier{
  231. {A: 10000000000, B: &resultb[0], C: 100, D: 1000000, S: &results[0],
  232. MapInt: map[string]int{"k1": 1, "k2": 2},
  233. MapString: map[string]string{"k1": "1", "k2": "2"}},
  234. }
  235. func (t *testOnlyQualifier) equal(o testOnlyQualifier) bool {
  236. return t.A == o.A &&
  237. *t.B == *o.B &&
  238. t.C == o.C &&
  239. t.D == o.D &&
  240. *t.S == *o.S &&
  241. t.FailField == o.FailField &&
  242. reflect.DeepEqual(t.MapInt, o.MapInt) &&
  243. reflect.DeepEqual(t.MapString, o.MapString)
  244. }
  245. func TestParser_OnlyQualifier(t *testing.T) {
  246. var parser = Parser{}
  247. for i, cells := range testcase3 {
  248. var result testOnlyQualifier
  249. var err = parser.Parse(cells, &result)
  250. if err != nil {
  251. t.Logf("err=%v", err)
  252. t.Fail()
  253. }
  254. t.Logf("result=%v, expect=%v", result, resultcase3[i])
  255. if !resultcase3[i].equal(result) {
  256. t.Logf("fail case: index=%d", i)
  257. t.Fail()
  258. }
  259. }
  260. }
  261. func TestParser_PartialFamilyPartPartialQualifier(t *testing.T) {
  262. var testcase = [][]*hrpc.Cell{
  263. {
  264. {Family: []byte("f"), Qualifier: []byte("q64"), Value: uint64ToByte(10000000000)},
  265. {Family: []byte("f"), Qualifier: []byte("q32"), Value: uint32ToByte(1000000)},
  266. {Family: []byte("f"), Qualifier: []byte("q16"), Value: uint16ToByte(100)},
  267. {Family: []byte("f"), Qualifier: []byte("q"), Value: uint64ToByte(1000000)},
  268. {Family: []byte("f"), Qualifier: []byte("s"), Value: []byte("just test")},
  269. {Family: []byte("f"), Qualifier: []byte("fail"), Value: []byte("1")},
  270. },
  271. }
  272. type testStruct struct {
  273. A int `family:"f" qualifier:"q64"`
  274. Map map[string]int `family:"f"`
  275. }
  276. var resultcase = []testStruct{
  277. {A: 10000000000,
  278. Map: map[string]int{
  279. "q32": 1000000,
  280. "q16": 100,
  281. "q": 1000000,
  282. "fail": int('1'),
  283. }},
  284. }
  285. var parser = Parser{}
  286. for i, cells := range testcase {
  287. var result testStruct
  288. var resInterface interface{} = &result
  289. var start = time.Now()
  290. var err = parser.Parse(cells, &resInterface)
  291. var elapse = time.Since(start)
  292. if err != nil {
  293. t.Logf("err=%v", err)
  294. t.Fail()
  295. }
  296. t.Logf("result=%v, expect=%v, parse time=%v", resInterface, resultcase[i], elapse)
  297. if !reflect.DeepEqual(resultcase[i], result) {
  298. t.Logf("fail case: index=%d", i)
  299. t.Fail()
  300. }
  301. }
  302. }
  303. func TestParser_SetBasicValue(t *testing.T) {
  304. var (
  305. i32s int32 = -2
  306. i64s int64 = -3
  307. i16s int16 = -4
  308. i32d int32
  309. i64d int64
  310. i16d int16
  311. i64Bytes = uint64ToByte(uint64(i64s))
  312. i32Bytes = uint32ToByte(uint32(i32s))
  313. i16Bytes = uint16ToByte(uint16(i16s))
  314. )
  315. var rvi32 = reflect.ValueOf(&i32d)
  316. var e = setBasicValue(i32Bytes, rvi32, "rvi32", ByteBigEndianToUint64)
  317. if e != nil {
  318. t.Errorf("fail, err=%+v", e)
  319. t.FailNow()
  320. }
  321. if i32s != i32d {
  322. t.Errorf("fail,expect=%d, got=%d", i32d, i32s)
  323. t.FailNow()
  324. }
  325. var rvi64 = reflect.ValueOf(&i64d)
  326. e = setBasicValue(i64Bytes, rvi64, "rvi64", ByteBigEndianToUint64)
  327. if e != nil {
  328. t.Errorf("fail, err=%+v", e)
  329. t.FailNow()
  330. }
  331. if i64s != i64d {
  332. t.Errorf("fail,expect=%d, got=%d", i64d, i64s)
  333. t.FailNow()
  334. }
  335. var rvi16 = reflect.ValueOf(&i16d)
  336. e = setBasicValue(i16Bytes, rvi16, "rvi16", ByteBigEndianToUint64)
  337. if e != nil {
  338. t.Errorf("fail, err=%+v", e)
  339. t.FailNow()
  340. }
  341. if i16s != i16d {
  342. t.Errorf("fail,expect=%d, got=%d", i16d, i16s)
  343. t.FailNow()
  344. }
  345. }
  346. func TestParser_Minus(t *testing.T) {
  347. var i64 int64 = -2
  348. var i32 int32 = -3
  349. var i16 int16 = -4
  350. var i8 int8 = -128
  351. var testcase = [][]*hrpc.Cell{
  352. {
  353. {Family: []byte("f"), Qualifier: []byte("i64"), Value: uint64ToByte(uint64(i64))},
  354. {Family: []byte("f"), Qualifier: []byte("i32"), Value: uint32ToByte(uint32(i32))},
  355. {Family: []byte("f"), Qualifier: []byte("i16"), Value: uint16ToByte(uint16(i16))},
  356. {Family: []byte("f"), Qualifier: []byte("i8"), Value: []byte{uint8(i8)}},
  357. },
  358. }
  359. type testStruct struct {
  360. I64 int64 `family:"f" qualifier:"i64"`
  361. I32 int32 `family:"f" qualifier:"i32"`
  362. I16 int16 `family:"f" qualifier:"i16"`
  363. I8 int8 `family:"f" qualifier:"i8"`
  364. }
  365. var resultcase = []testStruct{
  366. {
  367. I64: i64,
  368. I32: i32,
  369. I16: i16,
  370. I8: i8,
  371. },
  372. }
  373. var parser = Parser{}
  374. for i, cells := range testcase {
  375. var result testStruct
  376. var resInterface interface{} = &result
  377. var start = time.Now()
  378. var err = parser.Parse(cells, &resInterface)
  379. var elapse = time.Since(start)
  380. if err != nil {
  381. t.Logf("err=%v", err)
  382. t.Fail()
  383. }
  384. t.Logf("result=%v, expect=%v, parse time=%v", resInterface, resultcase[i], elapse)
  385. if !reflect.DeepEqual(resultcase[i], result) {
  386. t.Logf("fail case: index=%d", i)
  387. t.Fail()
  388. }
  389. }
  390. }
  391. func TestParser_Overflow(t *testing.T) {
  392. var testcase = [][]*hrpc.Cell{
  393. {
  394. {Family: []byte("f"), Qualifier: []byte("i64"), Value: uint64ToByte(0xff01020304050607)},
  395. {Family: []byte("f"), Qualifier: []byte("i32"), Value: uint64ToByte(0xff01020304050607)},
  396. {Family: []byte("f"), Qualifier: []byte("i16"), Value: uint64ToByte(0xff01020304050607)},
  397. {Family: []byte("f"), Qualifier: []byte("i8"), Value: uint64ToByte(0xff01020304050607)},
  398. },
  399. }
  400. type testStruct struct {
  401. I64 int64 `family:"f" qualifier:"i64"`
  402. I32 int32 `family:"f" qualifier:"i32"`
  403. I16 int16 `family:"f" qualifier:"i16"`
  404. I8 int8 `family:"f" qualifier:"i8"`
  405. }
  406. var resultcase = []testStruct{
  407. {
  408. I64: -(0xffffffffffffffff - 0xff01020304050607 + 1),
  409. I32: 0xff01020304050607 & 0xffffffff,
  410. I16: 0xff01020304050607 & 0xffff,
  411. I8: 0xff01020304050607 & 0xff,
  412. },
  413. }
  414. var parser = Parser{}
  415. for i, cells := range testcase {
  416. var result testStruct
  417. var resInterface interface{} = &result
  418. var start = time.Now()
  419. var err = parser.Parse(cells, &resInterface)
  420. var elapse = time.Since(start)
  421. if err != nil {
  422. t.Logf("err=%v", err)
  423. t.Fail()
  424. }
  425. t.Logf("result=%v, expect=%v, parse time=%v", resInterface, resultcase[i], elapse)
  426. if !reflect.DeepEqual(resultcase[i], result) {
  427. t.Logf("fail case: index=%d", i)
  428. t.Fail()
  429. }
  430. }
  431. }
  432. func BenchmarkParser(b *testing.B) {
  433. var testcase = [][]*hrpc.Cell{
  434. {
  435. {Family: []byte("f"), Qualifier: []byte("q64"), Value: uint64ToByte(10000000000)},
  436. {Family: []byte("f"), Qualifier: []byte("q32"), Value: uint32ToByte(1000000)},
  437. {Family: []byte("f"), Qualifier: []byte("q16"), Value: uint16ToByte(100)},
  438. {Family: []byte("f"), Qualifier: []byte("q"), Value: uint64ToByte(1000000)},
  439. {Family: []byte("f"), Qualifier: []byte("fail"), Value: uint64ToByte(100)},
  440. },
  441. }
  442. type testStruct struct {
  443. A int `family:"f" qualifier:"q64"`
  444. B int32 `family:"f" qualifier:"q32"`
  445. C int16 `family:"f" qualifier:"q16"`
  446. D int `qualifier:"q"`
  447. S string `qualifier:"s"`
  448. Map map[string]int `family:"f"`
  449. }
  450. var parser Parser
  451. b.Logf("bench parser")
  452. for i := 0; i < b.N; i++ {
  453. var result testStruct
  454. parser.Parse(testcase[0], &result)
  455. }
  456. }
  457. func BenchmarkJson(b *testing.B) {
  458. var text = []byte("{\"a\": 123, \"b\": \"1234\", \"c\": \"1234\", \"d\": \"1234\", \"e\" :{\"a\": 123, \"b\": \"1234\"}}")
  459. var result struct {
  460. A int `json:"a"`
  461. B string `json:"b"`
  462. C string `json:"c"`
  463. D string `json:"d"`
  464. E struct {
  465. A int `json:"a"`
  466. B string `json:"b"`
  467. } `json:"e"`
  468. }
  469. b.Logf("bench json")
  470. for i := 0; i < b.N; i++ {
  471. if err := json.Unmarshal(text, &result); err != nil {
  472. b.FailNow()
  473. }
  474. }
  475. }