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.

466 lines
11 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. //-------------------------------------
  16. type Animal interface{}
  17. const (
  18. AnimalTypeCat = byte(0x01)
  19. AnimalTypeDog = byte(0x02)
  20. AnimalTypeSnake = byte(0x03)
  21. AnimalTypeViper = byte(0x04)
  22. )
  23. // Implements Animal
  24. type Cat struct {
  25. SimpleStruct
  26. }
  27. // Implements Animal
  28. type Dog struct {
  29. SimpleStruct
  30. }
  31. // Implements Animal
  32. type Snake []byte
  33. // Implements Animal
  34. type Viper struct {
  35. Bytes []byte
  36. }
  37. var _ = RegisterInterface(
  38. struct{ Animal }{},
  39. ConcreteType{Cat{}, AnimalTypeCat},
  40. ConcreteType{Dog{}, AnimalTypeDog},
  41. ConcreteType{Snake{}, AnimalTypeSnake},
  42. ConcreteType{&Viper{}, AnimalTypeViper},
  43. )
  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, 0),
  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.Unix() != 123 {
  100. t.Errorf("Expected cat.Time == 'Unix(123)', got %v", cat.Time)
  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. }
  222. func constructComplexArray() interface{} {
  223. c := ComplexStructArray{
  224. Animals: []Animal{
  225. Cat{
  226. SimpleStruct{
  227. String: "String",
  228. Bytes: []byte("Bytes"),
  229. },
  230. },
  231. Dog{
  232. SimpleStruct{
  233. String: "Woof",
  234. Bytes: []byte("Bark"),
  235. },
  236. },
  237. Snake([]byte("hiss")),
  238. &Viper{
  239. Bytes: []byte("hizz"),
  240. },
  241. },
  242. }
  243. return c
  244. }
  245. func instantiateComplexArray() (interface{}, interface{}) {
  246. return ComplexStructArray{}, &ComplexStructArray{}
  247. }
  248. func validateComplexArray(o interface{}, t *testing.T) {
  249. c2 := o.(ComplexStructArray)
  250. if cat, ok := c2.Animals[0].(Cat); ok {
  251. if cat.String != "String" {
  252. t.Errorf("Expected cat.String == 'String', got %v", cat.String)
  253. }
  254. if string(cat.Bytes) != "Bytes" {
  255. t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
  256. }
  257. } else {
  258. t.Errorf("Expected c2.Animals[0] to be of type cat, got %v", reflect.ValueOf(c2.Animals[0]).Elem().Type())
  259. }
  260. if dog, ok := c2.Animals[1].(Dog); ok {
  261. if dog.String != "Woof" {
  262. t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
  263. }
  264. if string(dog.Bytes) != "Bark" {
  265. t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
  266. }
  267. } else {
  268. t.Errorf("Expected c2.Animals[1] to be of type dog, got %v", reflect.ValueOf(c2.Animals[1]).Elem().Type())
  269. }
  270. if snake, ok := c2.Animals[2].(Snake); ok {
  271. if string(snake) != "hiss" {
  272. t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
  273. }
  274. } else {
  275. t.Errorf("Expected c2.Animals[2] to be of type Snake, got %v", reflect.ValueOf(c2.Animals[2]).Elem().Type())
  276. }
  277. if viper, ok := c2.Animals[3].(*Viper); ok {
  278. if string(viper.Bytes) != "hizz" {
  279. t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
  280. }
  281. } else {
  282. t.Errorf("Expected c2.Animals[3] to be of type *Viper, got %v", reflect.ValueOf(c2.Animals[3]).Elem().Type())
  283. }
  284. }
  285. //-----------------------------------------------------------------------------
  286. var testCases = []TestCase{}
  287. func init() {
  288. testCases = append(testCases, TestCase{constructBasic, instantiateBasic, validateBasic})
  289. testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
  290. testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
  291. testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
  292. testCases = append(testCases, TestCase{constructNilTestStruct, instantiateNilTestStruct, validateNilTestStruct})
  293. }
  294. func TestBinary(t *testing.T) {
  295. for i, testCase := range testCases {
  296. log.Info(fmt.Sprintf("Running test case %v", i))
  297. // Construct an object
  298. o := testCase.Constructor()
  299. // Write the object
  300. data := BinaryBytes(o)
  301. t.Logf("Binary: %X", data)
  302. instance, instancePtr := testCase.Instantiator()
  303. // Read onto a struct
  304. n, err := new(int64), new(error)
  305. res := ReadBinary(instance, bytes.NewReader(data), n, err)
  306. if *err != nil {
  307. t.Fatalf("Failed to read into instance: %v", *err)
  308. }
  309. // Validate object
  310. testCase.Validator(res, t)
  311. // Read onto a pointer
  312. n, err = new(int64), new(error)
  313. res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), n, err)
  314. if *err != nil {
  315. t.Fatalf("Failed to read into instance: %v", *err)
  316. }
  317. if res != instancePtr {
  318. t.Errorf("Expected pointer to pass through")
  319. }
  320. // Validate object
  321. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  322. }
  323. }
  324. func TestJSON(t *testing.T) {
  325. for i, testCase := range testCases {
  326. log.Info(fmt.Sprintf("Running test case %v", i))
  327. // Construct an object
  328. o := testCase.Constructor()
  329. // Write the object
  330. data := JSONBytes(o)
  331. t.Logf("JSON: %v", string(data))
  332. instance, instancePtr := testCase.Instantiator()
  333. // Read onto a struct
  334. err := new(error)
  335. res := ReadJSON(instance, data, err)
  336. if *err != nil {
  337. t.Fatalf("Failed to read cat: %v", *err)
  338. }
  339. // Validate object
  340. testCase.Validator(res, t)
  341. // Read onto a pointer
  342. res = ReadJSON(instancePtr, data, err)
  343. if *err != nil {
  344. t.Fatalf("Failed to read cat: %v", *err)
  345. }
  346. if res != instancePtr {
  347. t.Errorf("Expected pointer to pass through")
  348. }
  349. // Validate object
  350. testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
  351. }
  352. }
  353. //------------------------------------------------------------------------------
  354. type Foo struct {
  355. FieldA string `json:"fieldA"` // json field name is "fieldA"
  356. FieldB string // json field name is "FieldB"
  357. fieldC string // not exported, not serialized.
  358. }
  359. func TestJSONFieldNames(t *testing.T) {
  360. for i := 0; i < 20; i++ { // Try to ensure deterministic success.
  361. foo := Foo{"a", "b", "c"}
  362. stringified := string(JSONBytes(foo))
  363. expected := `{"fieldA":"a","FieldB":"b"}`
  364. if stringified != expected {
  365. t.Fatalf("JSONFieldNames error: expected %v, got %v",
  366. expected, stringified)
  367. }
  368. }
  369. }
  370. //------------------------------------------------------------------------------
  371. func TestBadAlloc(t *testing.T) {
  372. n, err := new(int64), new(error)
  373. instance := new([]byte)
  374. data := RandBytes(ByteSliceChunk * 100)
  375. b := new(bytes.Buffer)
  376. // this slice of data claims to be much bigger than it really is
  377. WriteUvarint(uint(10000000000000000), b, n, err)
  378. b.Write(data)
  379. res := ReadBinary(instance, b, n, err)
  380. fmt.Println(res, *err)
  381. }