marshal_test.go 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. // +build all unit
  2. package gocql
  3. import (
  4. "bytes"
  5. "math"
  6. "math/big"
  7. "net"
  8. "reflect"
  9. "strings"
  10. "testing"
  11. "time"
  12. "gopkg.in/inf.v0"
  13. )
  14. type AliasInt int
  15. var marshalTests = []struct {
  16. Info TypeInfo
  17. Data []byte
  18. Value interface{}
  19. }{
  20. {
  21. NativeType{proto: 2, typ: TypeVarchar},
  22. []byte("hello world"),
  23. []byte("hello world"),
  24. },
  25. {
  26. NativeType{proto: 2, typ: TypeVarchar},
  27. []byte("hello world"),
  28. "hello world",
  29. },
  30. {
  31. NativeType{proto: 2, typ: TypeVarchar},
  32. []byte(nil),
  33. []byte(nil),
  34. },
  35. {
  36. NativeType{proto: 2, typ: TypeVarchar},
  37. []byte("hello world"),
  38. MyString("hello world"),
  39. },
  40. {
  41. NativeType{proto: 2, typ: TypeVarchar},
  42. []byte("HELLO WORLD"),
  43. CustomString("hello world"),
  44. },
  45. {
  46. NativeType{proto: 2, typ: TypeBlob},
  47. []byte("hello\x00"),
  48. []byte("hello\x00"),
  49. },
  50. {
  51. NativeType{proto: 2, typ: TypeBlob},
  52. []byte(nil),
  53. []byte(nil),
  54. },
  55. {
  56. NativeType{proto: 2, typ: TypeTimeUUID},
  57. []byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0},
  58. func() UUID {
  59. x, _ := UUIDFromBytes([]byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0})
  60. return x
  61. }(),
  62. },
  63. {
  64. NativeType{proto: 2, typ: TypeInt},
  65. []byte("\x00\x00\x00\x00"),
  66. 0,
  67. },
  68. {
  69. NativeType{proto: 2, typ: TypeInt},
  70. []byte("\x01\x02\x03\x04"),
  71. int(16909060),
  72. },
  73. {
  74. NativeType{proto: 2, typ: TypeInt},
  75. []byte("\x01\x02\x03\x04"),
  76. AliasInt(16909060),
  77. },
  78. {
  79. NativeType{proto: 2, typ: TypeInt},
  80. []byte("\x80\x00\x00\x00"),
  81. int32(math.MinInt32),
  82. },
  83. {
  84. NativeType{proto: 2, typ: TypeInt},
  85. []byte("\x7f\xff\xff\xff"),
  86. int32(math.MaxInt32),
  87. },
  88. {
  89. NativeType{proto: 2, typ: TypeInt},
  90. []byte("\x00\x00\x00\x00"),
  91. "0",
  92. },
  93. {
  94. NativeType{proto: 2, typ: TypeInt},
  95. []byte("\x01\x02\x03\x04"),
  96. "16909060",
  97. },
  98. {
  99. NativeType{proto: 2, typ: TypeInt},
  100. []byte("\x80\x00\x00\x00"),
  101. "-2147483648", // math.MinInt32
  102. },
  103. {
  104. NativeType{proto: 2, typ: TypeInt},
  105. []byte("\x7f\xff\xff\xff"),
  106. "2147483647", // math.MaxInt32
  107. },
  108. {
  109. NativeType{proto: 2, typ: TypeBigInt},
  110. []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
  111. 0,
  112. },
  113. {
  114. NativeType{proto: 2, typ: TypeBigInt},
  115. []byte("\x01\x02\x03\x04\x05\x06\x07\x08"),
  116. 72623859790382856,
  117. },
  118. {
  119. NativeType{proto: 2, typ: TypeBigInt},
  120. []byte("\x80\x00\x00\x00\x00\x00\x00\x00"),
  121. int64(math.MinInt64),
  122. },
  123. {
  124. NativeType{proto: 2, typ: TypeBigInt},
  125. []byte("\x7f\xff\xff\xff\xff\xff\xff\xff"),
  126. int64(math.MaxInt64),
  127. },
  128. {
  129. NativeType{proto: 2, typ: TypeBigInt},
  130. []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
  131. "0",
  132. },
  133. {
  134. NativeType{proto: 2, typ: TypeBigInt},
  135. []byte("\x01\x02\x03\x04\x05\x06\x07\x08"),
  136. "72623859790382856",
  137. },
  138. {
  139. NativeType{proto: 2, typ: TypeBigInt},
  140. []byte("\x80\x00\x00\x00\x00\x00\x00\x00"),
  141. "-9223372036854775808", // math.MinInt64
  142. },
  143. {
  144. NativeType{proto: 2, typ: TypeBigInt},
  145. []byte("\x7f\xff\xff\xff\xff\xff\xff\xff"),
  146. "9223372036854775807", // math.MaxInt64
  147. },
  148. {
  149. NativeType{proto: 2, typ: TypeBoolean},
  150. []byte("\x00"),
  151. false,
  152. },
  153. {
  154. NativeType{proto: 2, typ: TypeBoolean},
  155. []byte("\x01"),
  156. true,
  157. },
  158. {
  159. NativeType{proto: 2, typ: TypeFloat},
  160. []byte("\x40\x49\x0f\xdb"),
  161. float32(3.14159265),
  162. },
  163. {
  164. NativeType{proto: 2, typ: TypeDouble},
  165. []byte("\x40\x09\x21\xfb\x53\xc8\xd4\xf1"),
  166. float64(3.14159265),
  167. },
  168. {
  169. NativeType{proto: 2, typ: TypeDecimal},
  170. []byte("\x00\x00\x00\x00\x00"),
  171. inf.NewDec(0, 0),
  172. },
  173. {
  174. NativeType{proto: 2, typ: TypeDecimal},
  175. []byte("\x00\x00\x00\x00\x64"),
  176. inf.NewDec(100, 0),
  177. },
  178. {
  179. NativeType{proto: 2, typ: TypeDecimal},
  180. []byte("\x00\x00\x00\x02\x19"),
  181. decimalize("0.25"),
  182. },
  183. {
  184. NativeType{proto: 2, typ: TypeDecimal},
  185. []byte("\x00\x00\x00\x13\xD5\a;\x20\x14\xA2\x91"),
  186. decimalize("-0.0012095473475870063"), // From the iconara/cql-rb test suite
  187. },
  188. {
  189. NativeType{proto: 2, typ: TypeDecimal},
  190. []byte("\x00\x00\x00\x13*\xF8\xC4\xDF\xEB]o"),
  191. decimalize("0.0012095473475870063"), // From the iconara/cql-rb test suite
  192. },
  193. {
  194. NativeType{proto: 2, typ: TypeDecimal},
  195. []byte("\x00\x00\x00\x12\xF2\xD8\x02\xB6R\x7F\x99\xEE\x98#\x99\xA9V"),
  196. decimalize("-1042342234234.123423435647768234"), // From the iconara/cql-rb test suite
  197. },
  198. {
  199. NativeType{proto: 2, typ: TypeDecimal},
  200. []byte("\x00\x00\x00\r\nJ\x04\"^\x91\x04\x8a\xb1\x18\xfe"),
  201. decimalize("1243878957943.1234124191998"), // From the datastax/python-driver test suite
  202. },
  203. {
  204. NativeType{proto: 2, typ: TypeDecimal},
  205. []byte("\x00\x00\x00\x06\xe5\xde]\x98Y"),
  206. decimalize("-112233.441191"), // From the datastax/python-driver test suite
  207. },
  208. {
  209. NativeType{proto: 2, typ: TypeDecimal},
  210. []byte("\x00\x00\x00\x14\x00\xfa\xce"),
  211. decimalize("0.00000000000000064206"), // From the datastax/python-driver test suite
  212. },
  213. {
  214. NativeType{proto: 2, typ: TypeDecimal},
  215. []byte("\x00\x00\x00\x14\xff\x052"),
  216. decimalize("-0.00000000000000064206"), // From the datastax/python-driver test suite
  217. },
  218. {
  219. NativeType{proto: 2, typ: TypeDecimal},
  220. []byte("\xff\xff\xff\x9c\x00\xfa\xce"),
  221. inf.NewDec(64206, -100), // From the datastax/python-driver test suite
  222. },
  223. {
  224. NativeType{proto: 2, typ: TypeTimestamp},
  225. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  226. time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  227. },
  228. {
  229. NativeType{proto: 2, typ: TypeTimestamp},
  230. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  231. int64(1376387523000),
  232. },
  233. {
  234. CollectionType{
  235. NativeType: NativeType{proto: 2, typ: TypeList},
  236. Elem: NativeType{proto: 2, typ: TypeInt},
  237. },
  238. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  239. []int{1, 2},
  240. },
  241. {
  242. CollectionType{
  243. NativeType: NativeType{proto: 2, typ: TypeList},
  244. Elem: NativeType{proto: 2, typ: TypeInt},
  245. },
  246. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  247. [2]int{1, 2},
  248. },
  249. {
  250. CollectionType{
  251. NativeType: NativeType{proto: 2, typ: TypeSet},
  252. Elem: NativeType{proto: 2, typ: TypeInt},
  253. },
  254. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  255. []int{1, 2},
  256. },
  257. {
  258. CollectionType{
  259. NativeType: NativeType{proto: 2, typ: TypeSet},
  260. Elem: NativeType{proto: 2, typ: TypeInt},
  261. },
  262. []byte{0, 0}, // encoding of a list should always include the size of the collection
  263. []int{},
  264. },
  265. {
  266. CollectionType{
  267. NativeType: NativeType{proto: 2, typ: TypeMap},
  268. Key: NativeType{proto: 2, typ: TypeVarchar},
  269. Elem: NativeType{proto: 2, typ: TypeInt},
  270. },
  271. []byte("\x00\x01\x00\x03foo\x00\x04\x00\x00\x00\x01"),
  272. map[string]int{"foo": 1},
  273. },
  274. {
  275. CollectionType{
  276. NativeType: NativeType{proto: 2, typ: TypeMap},
  277. Key: NativeType{proto: 2, typ: TypeVarchar},
  278. Elem: NativeType{proto: 2, typ: TypeInt},
  279. },
  280. []byte{0, 0},
  281. map[string]int{},
  282. },
  283. {
  284. CollectionType{
  285. NativeType: NativeType{proto: 2, typ: TypeList},
  286. Elem: NativeType{proto: 2, typ: TypeVarchar},
  287. },
  288. bytes.Join([][]byte{
  289. []byte("\x00\x01\xFF\xFF"),
  290. bytes.Repeat([]byte("X"), 65535)}, []byte("")),
  291. []string{strings.Repeat("X", 65535)},
  292. },
  293. {
  294. CollectionType{
  295. NativeType: NativeType{proto: 2, typ: TypeMap},
  296. Key: NativeType{proto: 2, typ: TypeVarchar},
  297. Elem: NativeType{proto: 2, typ: TypeVarchar},
  298. },
  299. bytes.Join([][]byte{
  300. []byte("\x00\x01\xFF\xFF"),
  301. bytes.Repeat([]byte("X"), 65535),
  302. []byte("\xFF\xFF"),
  303. bytes.Repeat([]byte("Y"), 65535)}, []byte("")),
  304. map[string]string{
  305. strings.Repeat("X", 65535): strings.Repeat("Y", 65535),
  306. },
  307. },
  308. {
  309. NativeType{proto: 2, typ: TypeVarint},
  310. []byte("\x00"),
  311. 0,
  312. },
  313. {
  314. NativeType{proto: 2, typ: TypeVarint},
  315. []byte("\x37\xE2\x3C\xEC"),
  316. int32(937573612),
  317. },
  318. {
  319. NativeType{proto: 2, typ: TypeVarint},
  320. []byte("\x37\xE2\x3C\xEC"),
  321. big.NewInt(937573612),
  322. },
  323. {
  324. NativeType{proto: 2, typ: TypeVarint},
  325. []byte("\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["),
  326. bigintize("1231312312331283012830129382342342412123"), // From the iconara/cql-rb test suite
  327. },
  328. {
  329. NativeType{proto: 2, typ: TypeVarint},
  330. []byte("\xC9v\x8D:\x86"),
  331. big.NewInt(-234234234234), // From the iconara/cql-rb test suite
  332. },
  333. {
  334. NativeType{proto: 2, typ: TypeVarint},
  335. []byte("f\x1e\xfd\xf2\xe3\xb1\x9f|\x04_\x15"),
  336. bigintize("123456789123456789123456789"), // From the datastax/python-driver test suite
  337. },
  338. {
  339. NativeType{proto: 2, typ: TypeVarint},
  340. []byte(nil),
  341. nil,
  342. },
  343. {
  344. NativeType{proto: 2, typ: TypeInet},
  345. []byte("\x7F\x00\x00\x01"),
  346. net.ParseIP("127.0.0.1").To4(),
  347. },
  348. {
  349. NativeType{proto: 2, typ: TypeInet},
  350. []byte("\xFF\xFF\xFF\xFF"),
  351. net.ParseIP("255.255.255.255").To4(),
  352. },
  353. {
  354. NativeType{proto: 2, typ: TypeInet},
  355. []byte("\x7F\x00\x00\x01"),
  356. "127.0.0.1",
  357. },
  358. {
  359. NativeType{proto: 2, typ: TypeInet},
  360. []byte("\xFF\xFF\xFF\xFF"),
  361. "255.255.255.255",
  362. },
  363. {
  364. NativeType{proto: 2, typ: TypeInet},
  365. []byte("\x21\xDA\x00\xd3\x00\x00\x2f\x3b\x02\xaa\x00\xff\xfe\x28\x9c\x5a"),
  366. "21da:d3:0:2f3b:2aa:ff:fe28:9c5a",
  367. },
  368. {
  369. NativeType{proto: 2, typ: TypeInet},
  370. []byte("\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x02\xb3\xff\xfe\x1e\x83\x29"),
  371. "fe80::202:b3ff:fe1e:8329",
  372. },
  373. {
  374. NativeType{proto: 2, typ: TypeInet},
  375. []byte("\x21\xDA\x00\xd3\x00\x00\x2f\x3b\x02\xaa\x00\xff\xfe\x28\x9c\x5a"),
  376. net.ParseIP("21da:d3:0:2f3b:2aa:ff:fe28:9c5a"),
  377. },
  378. {
  379. NativeType{proto: 2, typ: TypeInet},
  380. []byte("\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x02\xb3\xff\xfe\x1e\x83\x29"),
  381. net.ParseIP("fe80::202:b3ff:fe1e:8329"),
  382. },
  383. {
  384. NativeType{proto: 2, typ: TypeInt},
  385. []byte(nil),
  386. nil,
  387. },
  388. {
  389. NativeType{proto: 2, typ: TypeVarchar},
  390. []byte("nullable string"),
  391. func() *string {
  392. value := "nullable string"
  393. return &value
  394. }(),
  395. },
  396. {
  397. NativeType{proto: 2, typ: TypeVarchar},
  398. []byte{},
  399. (*string)(nil),
  400. },
  401. {
  402. NativeType{proto: 2, typ: TypeInt},
  403. []byte("\x7f\xff\xff\xff"),
  404. func() *int {
  405. var value int = math.MaxInt32
  406. return &value
  407. }(),
  408. },
  409. {
  410. NativeType{proto: 2, typ: TypeInt},
  411. []byte(nil),
  412. (*int)(nil),
  413. },
  414. {
  415. NativeType{proto: 2, typ: TypeTimeUUID},
  416. []byte{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0},
  417. &UUID{0x3d, 0xcd, 0x98, 0x0, 0xf3, 0xd9, 0x11, 0xbf, 0x86, 0xd4, 0xb8, 0xe8, 0x56, 0x2c, 0xc, 0xd0},
  418. },
  419. {
  420. NativeType{proto: 2, typ: TypeTimeUUID},
  421. []byte{},
  422. (*UUID)(nil),
  423. },
  424. {
  425. NativeType{proto: 2, typ: TypeTimestamp},
  426. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  427. func() *time.Time {
  428. t := time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC)
  429. return &t
  430. }(),
  431. },
  432. {
  433. NativeType{proto: 2, typ: TypeTimestamp},
  434. []byte(nil),
  435. (*time.Time)(nil),
  436. },
  437. {
  438. NativeType{proto: 2, typ: TypeBoolean},
  439. []byte("\x00"),
  440. func() *bool {
  441. b := false
  442. return &b
  443. }(),
  444. },
  445. {
  446. NativeType{proto: 2, typ: TypeBoolean},
  447. []byte("\x01"),
  448. func() *bool {
  449. b := true
  450. return &b
  451. }(),
  452. },
  453. {
  454. NativeType{proto: 2, typ: TypeBoolean},
  455. []byte(nil),
  456. (*bool)(nil),
  457. },
  458. {
  459. NativeType{proto: 2, typ: TypeFloat},
  460. []byte("\x40\x49\x0f\xdb"),
  461. func() *float32 {
  462. f := float32(3.14159265)
  463. return &f
  464. }(),
  465. },
  466. {
  467. NativeType{proto: 2, typ: TypeFloat},
  468. []byte(nil),
  469. (*float32)(nil),
  470. },
  471. {
  472. NativeType{proto: 2, typ: TypeDouble},
  473. []byte("\x40\x09\x21\xfb\x53\xc8\xd4\xf1"),
  474. func() *float64 {
  475. d := float64(3.14159265)
  476. return &d
  477. }(),
  478. },
  479. {
  480. NativeType{proto: 2, typ: TypeDouble},
  481. []byte(nil),
  482. (*float64)(nil),
  483. },
  484. {
  485. NativeType{proto: 2, typ: TypeInet},
  486. []byte("\x7F\x00\x00\x01"),
  487. func() *net.IP {
  488. ip := net.ParseIP("127.0.0.1").To4()
  489. return &ip
  490. }(),
  491. },
  492. {
  493. NativeType{proto: 2, typ: TypeInet},
  494. []byte(nil),
  495. (*net.IP)(nil),
  496. },
  497. {
  498. CollectionType{
  499. NativeType: NativeType{proto: 2, typ: TypeList},
  500. Elem: NativeType{proto: 2, typ: TypeInt},
  501. },
  502. []byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
  503. func() *[]int {
  504. l := []int{1, 2}
  505. return &l
  506. }(),
  507. },
  508. {
  509. CollectionType{
  510. NativeType: NativeType{proto: 2, typ: TypeList},
  511. Elem: NativeType{proto: 2, typ: TypeInt},
  512. },
  513. []byte(nil),
  514. (*[]int)(nil),
  515. },
  516. {
  517. CollectionType{
  518. NativeType: NativeType{proto: 2, typ: TypeMap},
  519. Key: NativeType{proto: 2, typ: TypeVarchar},
  520. Elem: NativeType{proto: 2, typ: TypeInt},
  521. },
  522. []byte("\x00\x01\x00\x03foo\x00\x04\x00\x00\x00\x01"),
  523. func() *map[string]int {
  524. m := map[string]int{"foo": 1}
  525. return &m
  526. }(),
  527. },
  528. {
  529. CollectionType{
  530. NativeType: NativeType{proto: 2, typ: TypeMap},
  531. Key: NativeType{proto: 2, typ: TypeVarchar},
  532. Elem: NativeType{proto: 2, typ: TypeInt},
  533. },
  534. []byte(nil),
  535. (*map[string]int)(nil),
  536. },
  537. {
  538. NativeType{proto: 2, typ: TypeVarchar},
  539. []byte("HELLO WORLD"),
  540. func() *CustomString {
  541. customString := CustomString("hello world")
  542. return &customString
  543. }(),
  544. },
  545. {
  546. NativeType{proto: 2, typ: TypeVarchar},
  547. []byte(nil),
  548. (*CustomString)(nil),
  549. },
  550. {
  551. NativeType{proto: 2, typ: TypeSmallInt},
  552. []byte("\x7f\xff"),
  553. 32767, // math.MaxInt16
  554. },
  555. {
  556. NativeType{proto: 2, typ: TypeSmallInt},
  557. []byte("\x7f\xff"),
  558. "32767", // math.MaxInt16
  559. },
  560. {
  561. NativeType{proto: 2, typ: TypeSmallInt},
  562. []byte("\x00\x01"),
  563. int16(1),
  564. },
  565. {
  566. NativeType{proto: 2, typ: TypeSmallInt},
  567. []byte("\xff\xff"),
  568. int16(-1),
  569. },
  570. {
  571. NativeType{proto: 2, typ: TypeSmallInt},
  572. []byte("\xff\xff"),
  573. uint16(65535),
  574. },
  575. {
  576. NativeType{proto: 2, typ: TypeTinyInt},
  577. []byte("\x7f"),
  578. 127, // math.MaxInt8
  579. },
  580. {
  581. NativeType{proto: 2, typ: TypeTinyInt},
  582. []byte("\x7f"),
  583. "127", // math.MaxInt8
  584. },
  585. {
  586. NativeType{proto: 2, typ: TypeTinyInt},
  587. []byte("\x01"),
  588. int16(1),
  589. },
  590. {
  591. NativeType{proto: 2, typ: TypeTinyInt},
  592. []byte("\xff"),
  593. int16(-1),
  594. },
  595. {
  596. NativeType{proto: 2, typ: TypeTinyInt},
  597. []byte("\xff"),
  598. uint8(255),
  599. },
  600. {
  601. NativeType{proto: 2, typ: TypeTinyInt},
  602. []byte("\xff"),
  603. uint64(255),
  604. },
  605. {
  606. NativeType{proto: 2, typ: TypeTinyInt},
  607. []byte("\xff"),
  608. uint32(255),
  609. },
  610. {
  611. NativeType{proto: 2, typ: TypeTinyInt},
  612. []byte("\xff"),
  613. uint16(255),
  614. },
  615. {
  616. NativeType{proto: 2, typ: TypeTinyInt},
  617. []byte("\xff"),
  618. uint(255),
  619. },
  620. {
  621. NativeType{proto: 2, typ: TypeBigInt},
  622. []byte("\xff\xff\xff\xff\xff\xff\xff\xff"),
  623. uint64(math.MaxUint64),
  624. },
  625. {
  626. NativeType{proto: 2, typ: TypeInt},
  627. []byte("\xff\xff\xff\xff"),
  628. uint32(math.MaxUint32),
  629. },
  630. }
  631. func decimalize(s string) *inf.Dec {
  632. i, _ := new(inf.Dec).SetString(s)
  633. return i
  634. }
  635. func bigintize(s string) *big.Int {
  636. i, _ := new(big.Int).SetString(s, 10)
  637. return i
  638. }
  639. func TestMarshal_Encode(t *testing.T) {
  640. for i, test := range marshalTests {
  641. data, err := Marshal(test.Info, test.Value)
  642. if err != nil {
  643. t.Errorf("marshalTest[%d]: %v", i, err)
  644. continue
  645. }
  646. if !bytes.Equal(data, test.Data) {
  647. t.Errorf("marshalTest[%d]: expected %q, got %q (%#v)", i, test.Data, data, test.Value)
  648. }
  649. }
  650. }
  651. func TestMarshal_Decode(t *testing.T) {
  652. for i, test := range marshalTests {
  653. if test.Value != nil {
  654. v := reflect.New(reflect.TypeOf(test.Value))
  655. err := Unmarshal(test.Info, test.Data, v.Interface())
  656. if err != nil {
  657. t.Errorf("unmarshalTest[%d] (%v=>%T): %v", i, test.Info, test.Value, err)
  658. continue
  659. }
  660. if !reflect.DeepEqual(v.Elem().Interface(), test.Value) {
  661. t.Errorf("unmarshalTest[%d] (%v=>%T): expected %#v, got %#v.", i, test.Info, test.Value, test.Value, v.Elem().Interface())
  662. }
  663. } else {
  664. if err := Unmarshal(test.Info, test.Data, test.Value); nil == err {
  665. t.Errorf("unmarshalTest[%d] (%v=>%t): %#v not return error.", i, test.Info, test.Value, test.Value)
  666. }
  667. }
  668. }
  669. }
  670. func TestMarshalVarint(t *testing.T) {
  671. varintTests := []struct {
  672. Value interface{}
  673. Marshaled []byte
  674. Unmarshaled *big.Int
  675. }{
  676. {
  677. Value: int8(0),
  678. Marshaled: []byte("\x00"),
  679. Unmarshaled: big.NewInt(0),
  680. },
  681. {
  682. Value: uint8(255),
  683. Marshaled: []byte("\x00\xFF"),
  684. Unmarshaled: big.NewInt(255),
  685. },
  686. {
  687. Value: int8(-1),
  688. Marshaled: []byte("\xFF"),
  689. Unmarshaled: big.NewInt(-1),
  690. },
  691. {
  692. Value: big.NewInt(math.MaxInt32),
  693. Marshaled: []byte("\x7F\xFF\xFF\xFF"),
  694. Unmarshaled: big.NewInt(math.MaxInt32),
  695. },
  696. {
  697. Value: big.NewInt(int64(math.MaxInt32) + 1),
  698. Marshaled: []byte("\x00\x80\x00\x00\x00"),
  699. Unmarshaled: big.NewInt(int64(math.MaxInt32) + 1),
  700. },
  701. {
  702. Value: big.NewInt(math.MinInt32),
  703. Marshaled: []byte("\x80\x00\x00\x00"),
  704. Unmarshaled: big.NewInt(math.MinInt32),
  705. },
  706. {
  707. Value: big.NewInt(int64(math.MinInt32) - 1),
  708. Marshaled: []byte("\xFF\x7F\xFF\xFF\xFF"),
  709. Unmarshaled: big.NewInt(int64(math.MinInt32) - 1),
  710. },
  711. {
  712. Value: math.MinInt64,
  713. Marshaled: []byte("\x80\x00\x00\x00\x00\x00\x00\x00"),
  714. Unmarshaled: big.NewInt(math.MinInt64),
  715. },
  716. {
  717. Value: uint64(math.MaxInt64) + 1,
  718. Marshaled: []byte("\x00\x80\x00\x00\x00\x00\x00\x00\x00"),
  719. Unmarshaled: bigintize("9223372036854775808"),
  720. },
  721. {
  722. Value: bigintize("2361183241434822606848"), // 2**71
  723. Marshaled: []byte("\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00"),
  724. Unmarshaled: bigintize("2361183241434822606848"),
  725. },
  726. {
  727. Value: bigintize("-9223372036854775809"), // -2**63 - 1
  728. Marshaled: []byte("\xFF\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"),
  729. Unmarshaled: bigintize("-9223372036854775809"),
  730. },
  731. }
  732. for i, test := range varintTests {
  733. data, err := Marshal(NativeType{proto: 2, typ: TypeVarint}, test.Value)
  734. if err != nil {
  735. t.Errorf("error marshaling varint: %v (test #%d)", err, i)
  736. }
  737. if !bytes.Equal(test.Marshaled, data) {
  738. t.Errorf("marshaled varint mismatch: expected %v, got %v (test #%d)", test.Marshaled, data, i)
  739. }
  740. binder := new(big.Int)
  741. err = Unmarshal(NativeType{proto: 2, typ: TypeVarint}, test.Marshaled, binder)
  742. if err != nil {
  743. t.Errorf("error unmarshaling varint: %v (test #%d)", err, i)
  744. }
  745. if test.Unmarshaled.Cmp(binder) != 0 {
  746. t.Errorf("unmarshaled varint mismatch: expected %v, got %v (test #%d)", test.Unmarshaled, binder, i)
  747. }
  748. }
  749. varintUint64Tests := []struct {
  750. Value interface{}
  751. Marshaled []byte
  752. Unmarshaled uint64
  753. }{
  754. {
  755. Value: int8(0),
  756. Marshaled: []byte("\x00"),
  757. Unmarshaled: 0,
  758. },
  759. {
  760. Value: uint8(255),
  761. Marshaled: []byte("\x00\xFF"),
  762. Unmarshaled: 255,
  763. },
  764. {
  765. Value: big.NewInt(math.MaxInt32),
  766. Marshaled: []byte("\x7F\xFF\xFF\xFF"),
  767. Unmarshaled: uint64(math.MaxInt32),
  768. },
  769. {
  770. Value: big.NewInt(int64(math.MaxInt32) + 1),
  771. Marshaled: []byte("\x00\x80\x00\x00\x00"),
  772. Unmarshaled: uint64(int64(math.MaxInt32) + 1),
  773. },
  774. {
  775. Value: uint64(math.MaxInt64) + 1,
  776. Marshaled: []byte("\x00\x80\x00\x00\x00\x00\x00\x00\x00"),
  777. Unmarshaled: 9223372036854775808,
  778. },
  779. {
  780. Value: uint64(math.MaxUint64),
  781. Marshaled: []byte("\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"),
  782. Unmarshaled: uint64(math.MaxUint64),
  783. },
  784. }
  785. for i, test := range varintUint64Tests {
  786. data, err := Marshal(NativeType{proto: 2, typ: TypeVarint}, test.Value)
  787. if err != nil {
  788. t.Errorf("error marshaling varint: %v (test #%d)", err, i)
  789. }
  790. if !bytes.Equal(test.Marshaled, data) {
  791. t.Errorf("marshaled varint mismatch: expected %v, got %v (test #%d)", test.Marshaled, data, i)
  792. }
  793. var binder uint64
  794. err = Unmarshal(NativeType{proto: 2, typ: TypeVarint}, test.Marshaled, &binder)
  795. if err != nil {
  796. t.Errorf("error unmarshaling varint to uint64: %v (test #%d)", err, i)
  797. }
  798. if test.Unmarshaled != binder {
  799. t.Errorf("unmarshaled varint mismatch: expected %v, got %v (test #%d)", test.Unmarshaled, binder, i)
  800. }
  801. }
  802. }
  803. func equalStringSlice(leftList, rightList []string) bool {
  804. if len(leftList) != len(rightList) {
  805. return false
  806. }
  807. for index := range leftList {
  808. if rightList[index] != leftList[index] {
  809. return false
  810. }
  811. }
  812. return true
  813. }
  814. func TestMarshalList(t *testing.T) {
  815. typeInfo := CollectionType{
  816. NativeType: NativeType{proto: 2, typ: TypeList},
  817. Elem: NativeType{proto: 2, typ: TypeVarchar},
  818. }
  819. sourceLists := [][]string{
  820. {"valueA"},
  821. {"valueA", "valueB"},
  822. {"valueB"},
  823. }
  824. listDatas := [][]byte{}
  825. for _, list := range sourceLists {
  826. listData, marshalErr := Marshal(typeInfo, list)
  827. if nil != marshalErr {
  828. t.Errorf("Error marshal %+v of type %+v: %s", list, typeInfo, marshalErr)
  829. }
  830. listDatas = append(listDatas, listData)
  831. }
  832. outputLists := [][]string{}
  833. var outputList []string
  834. for _, listData := range listDatas {
  835. if unmarshalErr := Unmarshal(typeInfo, listData, &outputList); nil != unmarshalErr {
  836. t.Error(unmarshalErr)
  837. }
  838. outputLists = append(outputLists, outputList)
  839. }
  840. for index, sourceList := range sourceLists {
  841. outputList := outputLists[index]
  842. if !equalStringSlice(sourceList, outputList) {
  843. t.Errorf("Lists %+v not equal to lists %+v, but should", sourceList, outputList)
  844. }
  845. }
  846. }
  847. type CustomString string
  848. func (c CustomString) MarshalCQL(info TypeInfo) ([]byte, error) {
  849. return []byte(strings.ToUpper(string(c))), nil
  850. }
  851. func (c *CustomString) UnmarshalCQL(info TypeInfo, data []byte) error {
  852. *c = CustomString(strings.ToLower(string(data)))
  853. return nil
  854. }
  855. type MyString string
  856. type MyInt int
  857. var typeLookupTest = []struct {
  858. TypeName string
  859. ExpectedType Type
  860. }{
  861. {"AsciiType", TypeAscii},
  862. {"LongType", TypeBigInt},
  863. {"BytesType", TypeBlob},
  864. {"BooleanType", TypeBoolean},
  865. {"CounterColumnType", TypeCounter},
  866. {"DecimalType", TypeDecimal},
  867. {"DoubleType", TypeDouble},
  868. {"FloatType", TypeFloat},
  869. {"Int32Type", TypeInt},
  870. {"DateType", TypeTimestamp},
  871. {"TimestampType", TypeTimestamp},
  872. {"UUIDType", TypeUUID},
  873. {"UTF8Type", TypeVarchar},
  874. {"IntegerType", TypeVarint},
  875. {"TimeUUIDType", TypeTimeUUID},
  876. {"InetAddressType", TypeInet},
  877. {"MapType", TypeMap},
  878. {"ListType", TypeList},
  879. {"SetType", TypeSet},
  880. {"unknown", TypeCustom},
  881. {"ShortType", TypeSmallInt},
  882. {"ByteType", TypeTinyInt},
  883. }
  884. func testType(t *testing.T, cassType string, expectedType Type) {
  885. if computedType := getApacheCassandraType(apacheCassandraTypePrefix + cassType); computedType != expectedType {
  886. t.Errorf("Cassandra custom type lookup for %s failed. Expected %s, got %s.", cassType, expectedType.String(), computedType.String())
  887. }
  888. }
  889. func TestLookupCassType(t *testing.T) {
  890. for _, lookupTest := range typeLookupTest {
  891. testType(t, lookupTest.TypeName, lookupTest.ExpectedType)
  892. }
  893. }
  894. type MyPointerMarshaler struct{}
  895. func (m *MyPointerMarshaler) MarshalCQL(_ TypeInfo) ([]byte, error) {
  896. return []byte{42}, nil
  897. }
  898. func TestMarshalPointer(t *testing.T) {
  899. m := &MyPointerMarshaler{}
  900. typ := NativeType{proto: 2, typ: TypeInt}
  901. data, err := Marshal(typ, m)
  902. if err != nil {
  903. t.Errorf("Pointer marshaling failed. Error: %s", err)
  904. }
  905. if len(data) != 1 || data[0] != 42 {
  906. t.Errorf("Pointer marshaling failed. Expected %+v, got %+v", []byte{42}, data)
  907. }
  908. }
  909. func TestMarshalTimestamp(t *testing.T) {
  910. var marshalTimestampTests = []struct {
  911. Info TypeInfo
  912. Data []byte
  913. Value interface{}
  914. }{
  915. {
  916. NativeType{proto: 2, typ: TypeTimestamp},
  917. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  918. time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  919. },
  920. {
  921. NativeType{proto: 2, typ: TypeTimestamp},
  922. []byte("\x00\x00\x01\x40\x77\x16\xe1\xb8"),
  923. int64(1376387523000),
  924. },
  925. {
  926. // 9223372036854 is the maximum time representable in ms since the epoch
  927. // with int64 if using UnixNano to convert
  928. NativeType{proto: 2, typ: TypeTimestamp},
  929. []byte("\x00\x00\x08\x63\x7b\xd0\x5a\xf6"),
  930. time.Date(2262, time.April, 11, 23, 47, 16, 854775807, time.UTC),
  931. },
  932. {
  933. // One nanosecond after causes overflow when using UnixNano
  934. // Instead it should resolve to the same time in ms
  935. NativeType{proto: 2, typ: TypeTimestamp},
  936. []byte("\x00\x00\x08\x63\x7b\xd0\x5a\xf6"),
  937. time.Date(2262, time.April, 11, 23, 47, 16, 854775808, time.UTC),
  938. },
  939. {
  940. // -9223372036855 is the minimum time representable in ms since the epoch
  941. // with int64 if using UnixNano to convert
  942. NativeType{proto: 2, typ: TypeTimestamp},
  943. []byte("\xff\xff\xf7\x9c\x84\x2f\xa5\x09"),
  944. time.Date(1677, time.September, 21, 00, 12, 43, 145224192, time.UTC),
  945. },
  946. {
  947. // One nanosecond earlier causes overflow when using UnixNano
  948. // it should resolve to the same time in ms
  949. NativeType{proto: 2, typ: TypeTimestamp},
  950. []byte("\xff\xff\xf7\x9c\x84\x2f\xa5\x09"),
  951. time.Date(1677, time.September, 21, 00, 12, 43, 145224191, time.UTC),
  952. },
  953. {
  954. // Store the zero time as a blank slice
  955. NativeType{proto: 2, typ: TypeTimestamp},
  956. []byte{},
  957. time.Time{},
  958. },
  959. }
  960. for i, test := range marshalTimestampTests {
  961. t.Log(i, test)
  962. data, err := Marshal(test.Info, test.Value)
  963. if err != nil {
  964. t.Errorf("marshalTest[%d]: %v", i, err)
  965. continue
  966. }
  967. if !bytes.Equal(data, test.Data) {
  968. t.Errorf("marshalTest[%d]: expected %x (%v), got %x (%v) for time %s", i,
  969. test.Data, decBigInt(test.Data), data, decBigInt(data), test.Value)
  970. }
  971. }
  972. }
  973. func TestMarshalTuple(t *testing.T) {
  974. info := TupleTypeInfo{
  975. NativeType: NativeType{proto: 3, typ: TypeTuple},
  976. Elems: []TypeInfo{
  977. NativeType{proto: 3, typ: TypeVarchar},
  978. NativeType{proto: 3, typ: TypeVarchar},
  979. },
  980. }
  981. expectedData := []byte("\x00\x00\x00\x03foo\x00\x00\x00\x03bar")
  982. value := []interface{}{"foo", "bar"}
  983. data, err := Marshal(info, value)
  984. if err != nil {
  985. t.Errorf("marshalTest: %v", err)
  986. return
  987. }
  988. if !bytes.Equal(data, expectedData) {
  989. t.Errorf("marshalTest: expected %x (%v), got %x (%v)",
  990. expectedData, decBigInt(expectedData), data, decBigInt(data))
  991. return
  992. }
  993. var s1, s2 string
  994. val := []interface{}{&s1, &s2}
  995. err = Unmarshal(info, expectedData, val)
  996. if err != nil {
  997. t.Errorf("unmarshalTest: %v", err)
  998. return
  999. }
  1000. if s1 != "foo" || s2 != "bar" {
  1001. t.Errorf("unmarshalTest: expected [foo, bar], got [%s, %s]", s1, s2)
  1002. }
  1003. }
  1004. func TestMarshalNil(t *testing.T) {
  1005. types := []Type{
  1006. TypeAscii,
  1007. TypeBlob,
  1008. TypeBoolean,
  1009. TypeBigInt,
  1010. TypeCounter,
  1011. TypeDecimal,
  1012. TypeDouble,
  1013. TypeFloat,
  1014. TypeInt,
  1015. TypeTimestamp,
  1016. TypeUUID,
  1017. TypeVarchar,
  1018. TypeVarint,
  1019. TypeTimeUUID,
  1020. TypeInet,
  1021. }
  1022. for _, typ := range types {
  1023. data, err := Marshal(NativeType{proto: 3, typ: typ}, nil)
  1024. if err != nil {
  1025. t.Errorf("unable to marshal nil %v: %v\n", typ, err)
  1026. } else if data != nil {
  1027. t.Errorf("expected to get nil byte for nil %v got % X", typ, data)
  1028. }
  1029. }
  1030. }
  1031. func TestUnmarshalInetCopyBytes(t *testing.T) {
  1032. data := []byte{127, 0, 0, 1}
  1033. var ip net.IP
  1034. if err := unmarshalInet(NativeType{proto: 2, typ: TypeInet}, data, &ip); err != nil {
  1035. t.Fatal(err)
  1036. }
  1037. copy(data, []byte{0xFF, 0xFF, 0xFF, 0xFF})
  1038. ip2 := net.IP(data)
  1039. if !ip.Equal(net.IPv4(127, 0, 0, 1)) {
  1040. t.Fatalf("IP memory shared with data: ip=%v ip2=%v", ip, ip2)
  1041. }
  1042. }