You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

507 lines
12 KiB

10 years ago
  1. package binary
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "testing"
  7. "time"
  8. . "github.com/tendermint/tendermint/common"
  9. )
  10. type SimpleStruct struct {
  11. String string
  12. Bytes []byte
  13. Time time.Time
  14. }
  15. type Animal interface{}
  16. const (
  17. AnimalTypeCat = byte(0x01)
  18. AnimalTypeDog = byte(0x02)
  19. AnimalTypeSnake = byte(0x03)
  20. AnimalTypeViper = byte(0x04)
  21. )
  22. // Implements Animal
  23. type Cat struct {
  24. SimpleStruct
  25. }
  26. // Implements Animal
  27. type Dog struct {
  28. SimpleStruct
  29. }
  30. // Implements Animal
  31. type Snake []byte
  32. // Implements Animal
  33. type Viper struct {
  34. Bytes []byte
  35. }
  36. var _ = RegisterInterface(
  37. struct{ Animal }{},
  38. ConcreteType{Cat{}, AnimalTypeCat},
  39. ConcreteType{Dog{}, AnimalTypeDog},
  40. ConcreteType{Snake{}, AnimalTypeSnake},
  41. ConcreteType{&Viper{}, AnimalTypeViper},
  42. )
  43. func TestAnimalInterface(t *testing.T) {
  44. var foo Animal
  45. // Type of pointer to Animal
  46. rt := reflect.TypeOf(&foo)
  47. fmt.Printf("rt: %v\n", rt)
  48. // Type of Animal itself.
  49. // NOTE: normally this is acquired through other means
  50. // like introspecting on method signatures, or struct fields.
  51. rte := rt.Elem()
  52. fmt.Printf("rte: %v\n", rte)
  53. // Get a new pointer to the interface
  54. // NOTE: calling .Interface() is to get the actual value,
  55. // instead of reflection values.
  56. ptr := reflect.New(rte).Interface()
  57. fmt.Printf("ptr: %v", ptr)
  58. // Make a binary byteslice that represents a *snake.
  59. foo = Snake([]byte("snake"))
  60. snakeBytes := BinaryBytes(foo)
  61. snakeReader := bytes.NewReader(snakeBytes)
  62. // Now you can read it.
  63. n, err := new(int64), new(error)
  64. it := ReadBinary(foo, snakeReader, n, err).(Animal)
  65. fmt.Println(it, reflect.TypeOf(it))
  66. }
  67. //-------------------------------------
  68. type Constructor func() interface{}
  69. type Instantiator func() (o interface{}, ptr interface{})
  70. type Validator func(o interface{}, t *testing.T)
  71. type TestCase struct {
  72. Constructor
  73. Instantiator
  74. Validator
  75. }
  76. //-------------------------------------
  77. func constructBasic() interface{} {
  78. cat := Cat{
  79. SimpleStruct{
  80. String: "String",
  81. Bytes: []byte("Bytes"),
  82. Time: time.Unix(123, 0),
  83. },
  84. }
  85. return cat
  86. }
  87. func instantiateBasic() (interface{}, interface{}) {
  88. return Cat{}, &Cat{}
  89. }
  90. func validateBasic(o interface{}, t *testing.T) {
  91. cat := o.(Cat)
  92. if cat.String != "String" {
  93. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  94. }
  95. if string(cat.Bytes) != "Bytes" {
  96. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  97. }
  98. if cat.Time.Unix() != 123 {
  99. t.Errorf("Expected cat.Time == 'Unix(123)', got %v", cat.Time)
  100. }
  101. }
  102. //-------------------------------------
  103. type NilTestStruct struct {
  104. IntPtr *int
  105. CatPtr *Cat
  106. Animal Animal
  107. }
  108. func constructNilTestStruct() interface{} {
  109. return NilTestStruct{}
  110. }
  111. func instantiateNilTestStruct() (interface{}, interface{}) {
  112. return NilTestStruct{}, &NilTestStruct{}
  113. }
  114. func validateNilTestStruct(o interface{}, t *testing.T) {
  115. nts := o.(NilTestStruct)
  116. if nts.IntPtr != nil {
  117. t.Errorf("Expected nts.IntPtr to be nil, got %v", nts.IntPtr)
  118. }
  119. if nts.CatPtr != nil {
  120. t.Errorf("Expected nts.CatPtr to be nil, got %v", nts.CatPtr)
  121. }
  122. if nts.Animal != nil {
  123. t.Errorf("Expected nts.Animal to be nil, got %v", nts.Animal)
  124. }
  125. }
  126. //-------------------------------------
  127. type ComplexStruct struct {
  128. Name string
  129. Animal Animal
  130. }
  131. func constructComplex() interface{} {
  132. c := ComplexStruct{
  133. Name: "Complex",
  134. Animal: constructBasic(),
  135. }
  136. return c
  137. }
  138. func instantiateComplex() (interface{}, interface{}) {
  139. return ComplexStruct{}, &ComplexStruct{}
  140. }
  141. func validateComplex(o interface{}, t *testing.T) {
  142. c2 := o.(ComplexStruct)
  143. if cat, ok := c2.Animal.(Cat); ok {
  144. validateBasic(cat, t)
  145. } else {
  146. t.Errorf("Expected c2.Animal to be of type cat, got %v", reflect.ValueOf(c2.Animal).Elem().Type())
  147. }
  148. }
  149. //-------------------------------------
  150. type ComplexStruct2 struct {
  151. Cat Cat
  152. Dog *Dog
  153. Snake Snake
  154. Snake2 *Snake
  155. Viper Viper
  156. Viper2 *Viper
  157. }
  158. func constructComplex2() interface{} {
  159. snake_ := Snake([]byte("hiss"))
  160. snakePtr_ := &snake_
  161. c := ComplexStruct2{
  162. Cat: Cat{
  163. SimpleStruct{
  164. String: "String",
  165. Bytes: []byte("Bytes"),
  166. },
  167. },
  168. Dog: &Dog{
  169. SimpleStruct{
  170. String: "Woof",
  171. Bytes: []byte("Bark"),
  172. },
  173. },
  174. Snake: Snake([]byte("hiss")),
  175. Snake2: snakePtr_,
  176. Viper: Viper{Bytes: []byte("hizz")},
  177. Viper2: &Viper{Bytes: []byte("hizz")},
  178. }
  179. return c
  180. }
  181. func instantiateComplex2() (interface{}, interface{}) {
  182. return ComplexStruct2{}, &ComplexStruct2{}
  183. }
  184. func validateComplex2(o interface{}, t *testing.T) {
  185. c2 := o.(ComplexStruct2)
  186. cat := c2.Cat
  187. if cat.String != "String" {
  188. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  189. }
  190. if string(cat.Bytes) != "Bytes" {
  191. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  192. }
  193. dog := c2.Dog
  194. if dog.String != "Woof" {
  195. t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
  196. }
  197. if string(dog.Bytes) != "Bark" {
  198. t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
  199. }
  200. snake := c2.Snake
  201. if string(snake) != "hiss" {
  202. t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
  203. }
  204. snake2 := c2.Snake2
  205. if string(*snake2) != "hiss" {
  206. t.Errorf("Expected string(snake2) == 'hiss', got %v", string(*snake2))
  207. }
  208. viper := c2.Viper
  209. if string(viper.Bytes) != "hizz" {
  210. t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
  211. }
  212. viper2 := c2.Viper2
  213. if string(viper2.Bytes) != "hizz" {
  214. t.Errorf("Expected string(viper2.Bytes) == 'hizz', got %v", string(viper2.Bytes))
  215. }
  216. }
  217. //-------------------------------------
  218. type ComplexStructArray struct {
  219. Animals []Animal
  220. Bytes [5]byte
  221. Ints [5]int
  222. Array SimpleArray
  223. }
  224. func constructComplexArray() interface{} {
  225. c := ComplexStructArray{
  226. Animals: []Animal{
  227. Cat{
  228. SimpleStruct{
  229. String: "String",
  230. Bytes: []byte("Bytes"),
  231. },
  232. },
  233. Dog{
  234. SimpleStruct{
  235. String: "Woof",
  236. Bytes: []byte("Bark"),
  237. },
  238. },
  239. Snake([]byte("hiss")),
  240. &Viper{
  241. Bytes: []byte("hizz"),
  242. },
  243. },
  244. Bytes: [5]byte{1, 10, 50, 100, 200},
  245. Ints: [5]int{1, 2, 3, 4, 5},
  246. Array: SimpleArray([5]byte{1, 10, 50, 100, 200}),
  247. }
  248. return c
  249. }
  250. func instantiateComplexArray() (interface{}, interface{}) {
  251. return ComplexStructArray{}, &ComplexStructArray{}
  252. }
  253. func validateComplexArray(o interface{}, t *testing.T) {
  254. c2 := o.(ComplexStructArray)
  255. if cat, ok := c2.Animals[0].(Cat); ok {
  256. if cat.String != "String" {
  257. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  258. }
  259. if string(cat.Bytes) != "Bytes" {
  260. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  261. }
  262. } else {
  263. t.Errorf("Expected c2.Animals[0] to be of type cat, got %v", reflect.ValueOf(c2.Animals[0]).Elem().Type())
  264. }
  265. if dog, ok := c2.Animals[1].(Dog); ok {
  266. if dog.String != "Woof" {
  267. t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
  268. }
  269. if string(dog.Bytes) != "Bark" {
  270. t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
  271. }
  272. } else {
  273. t.Errorf("Expected c2.Animals[1] to be of type dog, got %v", reflect.ValueOf(c2.Animals[1]).Elem().Type())
  274. }
  275. if snake, ok := c2.Animals[2].(Snake); ok {
  276. if string(snake) != "hiss" {
  277. t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
  278. }
  279. } else {
  280. t.Errorf("Expected c2.Animals[2] to be of type Snake, got %v", reflect.ValueOf(c2.Animals[2]).Elem().Type())
  281. }
  282. if viper, ok := c2.Animals[3].(*Viper); ok {
  283. if string(viper.Bytes) != "hizz" {
  284. t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
  285. }
  286. } else {
  287. t.Errorf("Expected c2.Animals[3] to be of type *Viper, got %v", reflect.ValueOf(c2.Animals[3]).Elem().Type())
  288. }
  289. }
  290. //-----------------------------------------------------------------------------
  291. var testCases = []TestCase{}
  292. func init() {
  293. testCases = append(testCases, TestCase{constructBasic, instantiateBasic, validateBasic})
  294. testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
  295. testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
  296. testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
  297. testCases = append(testCases, TestCase{constructNilTestStruct, instantiateNilTestStruct, validateNilTestStruct})
  298. }
  299. func TestBinary(t *testing.T) {
  300. for i, testCase := range testCases {
  301. log.Notice(fmt.Sprintf("Running test case %v", i))
  302. // Construct an object
  303. o := testCase.Constructor()
  304. // Write the object
  305. data := BinaryBytes(o)
  306. t.Logf("Binary: %X", data)
  307. instance, instancePtr := testCase.Instantiator()
  308. // Read onto a struct
  309. n, err := new(int64), new(error)
  310. res := ReadBinary(instance, bytes.NewReader(data), n, err)
  311. if *err != nil {
  312. t.Fatalf("Failed to read into instance: %v", *err)
  313. }
  314. // Validate object
  315. testCase.Validator(res, t)
  316. // Read onto a pointer
  317. n, err = new(int64), new(error)
  318. res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), n, err)
  319. if *err != nil {
  320. t.Fatalf("Failed to read into instance: %v", *err)
  321. }
  322. if res != instancePtr {
  323. t.Errorf("Expected pointer to pass through")
  324. }
  325. // Validate object
  326. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  327. }
  328. }
  329. func TestJSON(t *testing.T) {
  330. for i, testCase := range testCases {
  331. log.Notice(fmt.Sprintf("Running test case %v", i))
  332. // Construct an object
  333. o := testCase.Constructor()
  334. // Write the object
  335. data := JSONBytes(o)
  336. t.Logf("JSON: %v", string(data))
  337. instance, instancePtr := testCase.Instantiator()
  338. // Read onto a struct
  339. err := new(error)
  340. res := ReadJSON(instance, data, err)
  341. if *err != nil {
  342. t.Fatalf("Failed to read cat: %v", *err)
  343. }
  344. // Validate object
  345. testCase.Validator(res, t)
  346. // Read onto a pointer
  347. res = ReadJSON(instancePtr, data, err)
  348. if *err != nil {
  349. t.Fatalf("Failed to read cat: %v", *err)
  350. }
  351. if res != instancePtr {
  352. t.Errorf("Expected pointer to pass through")
  353. }
  354. // Validate object
  355. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  356. }
  357. }
  358. //------------------------------------------------------------------------------
  359. type Foo struct {
  360. FieldA string `json:"fieldA"` // json field name is "fieldA"
  361. FieldB string // json field name is "FieldB"
  362. fieldC string // not exported, not serialized.
  363. }
  364. func TestJSONFieldNames(t *testing.T) {
  365. for i := 0; i < 20; i++ { // Try to ensure deterministic success.
  366. foo := Foo{"a", "b", "c"}
  367. stringified := string(JSONBytes(foo))
  368. expected := `{"fieldA":"a","FieldB":"b"}`
  369. if stringified != expected {
  370. t.Fatalf("JSONFieldNames error: expected %v, got %v",
  371. expected, stringified)
  372. }
  373. }
  374. }
  375. //------------------------------------------------------------------------------
  376. func TestBadAlloc(t *testing.T) {
  377. n, err := new(int64), new(error)
  378. instance := new([]byte)
  379. data := RandBytes(100 * 1024)
  380. b := new(bytes.Buffer)
  381. // this slice of data claims to be much bigger than it really is
  382. WriteUvarint(uint(10000000000000000), b, n, err)
  383. b.Write(data)
  384. res := ReadBinary(instance, b, n, err)
  385. fmt.Println(res, *err)
  386. }
  387. //------------------------------------------------------------------------------
  388. type SimpleArray [5]byte
  389. func TestSimpleArray(t *testing.T) {
  390. var foo SimpleArray
  391. // Type of pointer to array
  392. rt := reflect.TypeOf(&foo)
  393. fmt.Printf("rt: %v\n", rt) // *binary.SimpleArray
  394. // Type of array itself.
  395. // NOTE: normally this is acquired through other means
  396. // like introspecting on method signatures, or struct fields.
  397. rte := rt.Elem()
  398. fmt.Printf("rte: %v\n", rte) // binary.SimpleArray
  399. // Get a new pointer to the array
  400. // NOTE: calling .Interface() is to get the actual value,
  401. // instead of reflection values.
  402. ptr := reflect.New(rte).Interface()
  403. fmt.Printf("ptr: %v\n", ptr) // &[0 0 0 0 0]
  404. // Make a simple int aray
  405. fooArray := SimpleArray([5]byte{1, 10, 50, 100, 200})
  406. fooBytes := BinaryBytes(fooArray)
  407. fooReader := bytes.NewReader(fooBytes)
  408. // Now you can read it.
  409. n, err := new(int64), new(error)
  410. it := ReadBinary(foo, fooReader, n, err).(SimpleArray)
  411. if !bytes.Equal(it[:], fooArray[:]) {
  412. t.Errorf("Expected %v but got %v", fooArray, it)
  413. }
  414. }