protocol_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. // All rights reserved. Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. package protocol
  5. import (
  6. "errors"
  7. "io"
  8. "testing"
  9. "testing/quick"
  10. )
  11. var (
  12. c0ID = NewNodeID([]byte{1})
  13. c1ID = NewNodeID([]byte{2})
  14. )
  15. func TestHeaderFunctions(t *testing.T) {
  16. f := func(ver, id, typ int) bool {
  17. ver = int(uint(ver) % 16)
  18. id = int(uint(id) % 4096)
  19. typ = int(uint(typ) % 256)
  20. h0 := header{ver, id, typ}
  21. h1 := decodeHeader(encodeHeader(h0))
  22. return h0 == h1
  23. }
  24. if err := quick.Check(f, nil); err != nil {
  25. t.Error(err)
  26. }
  27. }
  28. func TestHeaderLayout(t *testing.T) {
  29. var e, a uint32
  30. // Version are the first four bits
  31. e = 0xf0000000
  32. a = encodeHeader(header{0xf, 0, 0})
  33. if a != e {
  34. t.Errorf("Header layout incorrect; %08x != %08x", a, e)
  35. }
  36. // Message ID are the following 12 bits
  37. e = 0x0fff0000
  38. a = encodeHeader(header{0, 0xfff, 0})
  39. if a != e {
  40. t.Errorf("Header layout incorrect; %08x != %08x", a, e)
  41. }
  42. // Type are the last 8 bits before reserved
  43. e = 0x0000ff00
  44. a = encodeHeader(header{0, 0, 0xff})
  45. if a != e {
  46. t.Errorf("Header layout incorrect; %08x != %08x", a, e)
  47. }
  48. }
  49. func TestPing(t *testing.T) {
  50. ar, aw := io.Pipe()
  51. br, bw := io.Pipe()
  52. c0 := NewConnection(c0ID, ar, bw, nil, "name").(wireFormatConnection).next.(*rawConnection)
  53. c1 := NewConnection(c1ID, br, aw, nil, "name").(wireFormatConnection).next.(*rawConnection)
  54. if ok := c0.ping(); !ok {
  55. t.Error("c0 ping failed")
  56. }
  57. if ok := c1.ping(); !ok {
  58. t.Error("c1 ping failed")
  59. }
  60. }
  61. func TestPingErr(t *testing.T) {
  62. e := errors.New("something broke")
  63. for i := 0; i < 12; i++ {
  64. for j := 0; j < 12; j++ {
  65. m0 := newTestModel()
  66. m1 := newTestModel()
  67. ar, aw := io.Pipe()
  68. br, bw := io.Pipe()
  69. eaw := &ErrPipe{PipeWriter: *aw, max: i, err: e}
  70. ebw := &ErrPipe{PipeWriter: *bw, max: j, err: e}
  71. c0 := NewConnection(c0ID, ar, ebw, m0, "name").(wireFormatConnection).next.(*rawConnection)
  72. NewConnection(c1ID, br, eaw, m1, "name")
  73. res := c0.ping()
  74. if (i < 4 || j < 4) && res {
  75. t.Errorf("Unexpected ping success; i=%d, j=%d", i, j)
  76. } else if (i >= 8 && j >= 8) && !res {
  77. t.Errorf("Unexpected ping fail; i=%d, j=%d", i, j)
  78. }
  79. }
  80. }
  81. }
  82. // func TestRequestResponseErr(t *testing.T) {
  83. // e := errors.New("something broke")
  84. // var pass bool
  85. // for i := 0; i < 48; i++ {
  86. // for j := 0; j < 38; j++ {
  87. // m0 := newTestModel()
  88. // m0.data = []byte("response data")
  89. // m1 := newTestModel()
  90. // ar, aw := io.Pipe()
  91. // br, bw := io.Pipe()
  92. // eaw := &ErrPipe{PipeWriter: *aw, max: i, err: e}
  93. // ebw := &ErrPipe{PipeWriter: *bw, max: j, err: e}
  94. // NewConnection(c0ID, ar, ebw, m0, nil)
  95. // c1 := NewConnection(c1ID, br, eaw, m1, nil).(wireFormatConnection).next.(*rawConnection)
  96. // d, err := c1.Request("default", "tn", 1234, 5678)
  97. // if err == e || err == ErrClosed {
  98. // t.Logf("Error at %d+%d bytes", i, j)
  99. // if !m1.isClosed() {
  100. // t.Fatal("c1 not closed")
  101. // }
  102. // if !m0.isClosed() {
  103. // t.Fatal("c0 not closed")
  104. // }
  105. // continue
  106. // }
  107. // if err != nil {
  108. // t.Fatal(err)
  109. // }
  110. // if string(d) != "response data" {
  111. // t.Fatalf("Incorrect response data %q", string(d))
  112. // }
  113. // if m0.repo != "default" {
  114. // t.Fatalf("Incorrect repo %q", m0.repo)
  115. // }
  116. // if m0.name != "tn" {
  117. // t.Fatalf("Incorrect name %q", m0.name)
  118. // }
  119. // if m0.offset != 1234 {
  120. // t.Fatalf("Incorrect offset %d", m0.offset)
  121. // }
  122. // if m0.size != 5678 {
  123. // t.Fatalf("Incorrect size %d", m0.size)
  124. // }
  125. // t.Logf("Pass at %d+%d bytes", i, j)
  126. // pass = true
  127. // }
  128. // }
  129. // if !pass {
  130. // t.Fatal("Never passed")
  131. // }
  132. // }
  133. func TestVersionErr(t *testing.T) {
  134. m0 := newTestModel()
  135. m1 := newTestModel()
  136. ar, aw := io.Pipe()
  137. br, bw := io.Pipe()
  138. c0 := NewConnection(c0ID, ar, bw, m0, "name").(wireFormatConnection).next.(*rawConnection)
  139. NewConnection(c1ID, br, aw, m1, "name")
  140. c0.xw.WriteUint32(encodeHeader(header{
  141. version: 2,
  142. msgID: 0,
  143. msgType: 0,
  144. }))
  145. c0.flush()
  146. if !m1.isClosed() {
  147. t.Error("Connection should close due to unknown version")
  148. }
  149. }
  150. func TestTypeErr(t *testing.T) {
  151. m0 := newTestModel()
  152. m1 := newTestModel()
  153. ar, aw := io.Pipe()
  154. br, bw := io.Pipe()
  155. c0 := NewConnection(c0ID, ar, bw, m0, "name").(wireFormatConnection).next.(*rawConnection)
  156. NewConnection(c1ID, br, aw, m1, "name")
  157. c0.xw.WriteUint32(encodeHeader(header{
  158. version: 0,
  159. msgID: 0,
  160. msgType: 42,
  161. }))
  162. c0.flush()
  163. if !m1.isClosed() {
  164. t.Error("Connection should close due to unknown message type")
  165. }
  166. }
  167. func TestClose(t *testing.T) {
  168. m0 := newTestModel()
  169. m1 := newTestModel()
  170. ar, aw := io.Pipe()
  171. br, bw := io.Pipe()
  172. c0 := NewConnection(c0ID, ar, bw, m0, "name").(wireFormatConnection).next.(*rawConnection)
  173. NewConnection(c1ID, br, aw, m1, "name")
  174. c0.close(nil)
  175. <-c0.closed
  176. if !m0.isClosed() {
  177. t.Fatal("Connection should be closed")
  178. }
  179. // None of these should panic, some should return an error
  180. if c0.ping() {
  181. t.Error("Ping should not return true")
  182. }
  183. c0.Index("default", nil)
  184. c0.Index("default", nil)
  185. if _, err := c0.Request("default", "foo", 0, 0); err == nil {
  186. t.Error("Request should return an error")
  187. }
  188. }