subnet_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package subnet
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/coreos-inc/rudder/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd"
  7. "github.com/coreos-inc/rudder/pkg/ip"
  8. )
  9. type mockSubnetRegistry struct {
  10. subnets *etcd.Node
  11. addCh chan string
  12. delCh chan string
  13. index uint64
  14. ttl uint64
  15. }
  16. func newMockSubnetRegistry(ttlOverride uint64) *mockSubnetRegistry {
  17. subnodes := []*etcd.Node{
  18. &etcd.Node{Key: "10.3.1.0-24", Value: `{ "PublicIP": "1.1.1.1" }`, ModifiedIndex: 10},
  19. &etcd.Node{Key: "10.3.2.0-24", Value: `{ "PublicIP": "1.1.1.1" }`, ModifiedIndex: 11},
  20. &etcd.Node{Key: "10.3.4.0-24", Value: `{ "PublicIP": "1.1.1.1" }`, ModifiedIndex: 12},
  21. &etcd.Node{Key: "10.3.5.0-24", Value: `{ "PublicIP": "1.1.1.1" }`, ModifiedIndex: 13},
  22. }
  23. return &mockSubnetRegistry{
  24. subnets: &etcd.Node{
  25. Nodes: subnodes,
  26. },
  27. addCh: make(chan string),
  28. delCh: make(chan string),
  29. index: 14,
  30. ttl: ttlOverride,
  31. }
  32. }
  33. func (msr *mockSubnetRegistry) getConfig() (*etcd.Response, error) {
  34. return &etcd.Response{
  35. EtcdIndex: msr.index,
  36. Node: &etcd.Node{
  37. Value: `{ "Network": "10.3.0.0/16", "SubnetMin": "10.3.1.0", "SubnetMax": "10.3.5.0" }`,
  38. },
  39. }, nil
  40. }
  41. func (msr *mockSubnetRegistry) getSubnets() (*etcd.Response, error) {
  42. return &etcd.Response{
  43. Node: msr.subnets,
  44. EtcdIndex: msr.index,
  45. }, nil
  46. }
  47. func (msr *mockSubnetRegistry) createSubnet(sn, data string, ttl uint64) (*etcd.Response, error) {
  48. msr.index += 1
  49. if msr.ttl > 0 {
  50. ttl = msr.ttl
  51. }
  52. // add squared durations :)
  53. exp := time.Now().Add(time.Duration(ttl) * time.Second)
  54. node := &etcd.Node{
  55. Key: sn,
  56. Value: data,
  57. ModifiedIndex: msr.index,
  58. Expiration: &exp,
  59. }
  60. msr.subnets.Nodes = append(msr.subnets.Nodes, node)
  61. return &etcd.Response{
  62. Node: node,
  63. EtcdIndex: msr.index,
  64. }, nil
  65. }
  66. func (msr *mockSubnetRegistry) updateSubnet(sn, data string, ttl uint64) (*etcd.Response, error) {
  67. msr.index += 1
  68. // add squared durations :)
  69. exp := time.Now().Add(time.Duration(ttl) * time.Second)
  70. for _, n := range msr.subnets.Nodes {
  71. if n.Key == sn {
  72. n.Value = data
  73. n.ModifiedIndex = msr.index
  74. n.Expiration = &exp
  75. return &etcd.Response{
  76. Node: n,
  77. EtcdIndex: msr.index,
  78. }, nil
  79. }
  80. }
  81. return nil, fmt.Errorf("Subnet not found")
  82. }
  83. func (msr *mockSubnetRegistry) watchSubnets(since uint64, stop chan bool) (*etcd.Response, error) {
  84. var sn string
  85. select {
  86. case <-stop:
  87. return nil, nil
  88. case sn = <-msr.addCh:
  89. n := etcd.Node{
  90. Key: sn,
  91. ModifiedIndex: msr.index,
  92. }
  93. msr.subnets.Nodes = append(msr.subnets.Nodes, &n)
  94. return &etcd.Response{
  95. Action: "add",
  96. Node: &n,
  97. }, nil
  98. case sn = <-msr.delCh:
  99. for i, n := range msr.subnets.Nodes {
  100. if n.Key == sn {
  101. msr.subnets.Nodes[i] = msr.subnets.Nodes[len(msr.subnets.Nodes)-1]
  102. msr.subnets.Nodes = msr.subnets.Nodes[:len(msr.subnets.Nodes)-2]
  103. return &etcd.Response{
  104. Action: "expire",
  105. Node: n,
  106. }, nil
  107. }
  108. }
  109. return nil, fmt.Errorf("Subnet (%s) to delete was not found: ", sn)
  110. }
  111. }
  112. func (msr *mockSubnetRegistry) hasSubnet(sn string) bool {
  113. for _, n := range msr.subnets.Nodes {
  114. if n.Key == sn {
  115. return true
  116. }
  117. }
  118. return false
  119. }
  120. func TestAcquireLease(t *testing.T) {
  121. msr := newMockSubnetRegistry(0)
  122. sm, err := newSubnetManager(msr)
  123. if err != nil {
  124. t.Fatalf("Failed to create subnet manager: %s", err)
  125. }
  126. ip, _ := ip.ParseIP4("1.2.3.4")
  127. data := `{ "PublicIP": "1.2.3.4" }`
  128. sn, err := sm.AcquireLease(ip, data)
  129. if err != nil {
  130. t.Fatal("AcquireLease failed: ", err)
  131. }
  132. if sn.String() != "10.3.3.0/24" {
  133. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  134. }
  135. // Acquire again, should reuse
  136. if sn, err = sm.AcquireLease(ip, data); err != nil {
  137. t.Fatal("AcquireLease failed: ", err)
  138. }
  139. if sn.String() != "10.3.3.0/24" {
  140. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  141. }
  142. }
  143. func TestWatchLeaseAdded(t *testing.T) {
  144. msr := newMockSubnetRegistry(0)
  145. sm, err := newSubnetManager(msr)
  146. if err != nil {
  147. t.Fatalf("Failed to create subnet manager: %s", err)
  148. }
  149. events := make(chan EventBatch)
  150. sm.Start(events)
  151. expected := "10.3.3.0-24"
  152. msr.addCh <- expected
  153. evtBatch, ok := <-events
  154. if !ok {
  155. t.Fatalf("WatchSubnets did not publish")
  156. }
  157. if len(evtBatch) != 1 {
  158. t.Fatalf("WatchSubnets produced wrong sized event batch")
  159. }
  160. evt := evtBatch[0]
  161. if evt.Type != SubnetAdded {
  162. t.Fatalf("WatchSubnets produced wrong event type")
  163. }
  164. actual := evt.Lease.Network.StringSep(".", "-")
  165. if actual != expected {
  166. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  167. }
  168. sm.Stop()
  169. }
  170. func TestWatchLeaseRemoved(t *testing.T) {
  171. msr := newMockSubnetRegistry(0)
  172. sm, err := newSubnetManager(msr)
  173. if err != nil {
  174. t.Fatalf("Failed to create subnet manager: %s", err)
  175. }
  176. events := make(chan EventBatch)
  177. sm.Start(events)
  178. expected := "10.3.4.0-24"
  179. msr.delCh <- expected
  180. evtBatch, ok := <-events
  181. if !ok {
  182. t.Fatalf("WatchSubnets did not publish")
  183. }
  184. if len(evtBatch) != 1 {
  185. t.Fatalf("WatchSubnets produced wrong sized event batch")
  186. }
  187. evt := evtBatch[0]
  188. if evt.Type != SubnetRemoved {
  189. t.Fatalf("WatchSubnets produced wrong event type")
  190. }
  191. actual := evt.Lease.Network.StringSep(".", "-")
  192. if actual != expected {
  193. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  194. }
  195. sm.Stop()
  196. }
  197. func TestRenewLease(t *testing.T) {
  198. msr := newMockSubnetRegistry(1)
  199. sm, err := newSubnetManager(msr)
  200. if err != nil {
  201. t.Fatalf("Failed to create subnet manager: %s", err)
  202. }
  203. ip, _ := ip.ParseIP4("1.2.3.4")
  204. data := `{ "PublicIP": "1.2.3.4" }`
  205. sn, err := sm.AcquireLease(ip, data)
  206. if err != nil {
  207. t.Fatal("AcquireLease failed: ", err)
  208. }
  209. events := make(chan EventBatch)
  210. sm.Start(events)
  211. fmt.Println("Waiting for lease to pass original expiration")
  212. time.Sleep(2 * time.Second)
  213. // check that it's still good
  214. for _, n := range msr.subnets.Nodes {
  215. if n.Key == sn.StringSep(".", "-") {
  216. if n.Expiration.Before(time.Now()) {
  217. t.Fatalf("Failed to renew lease")
  218. }
  219. return
  220. }
  221. }
  222. t.Fatalf("Failed to find acquired lease")
  223. }