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.

508 lines
12 KiB

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