subnet_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package subnet
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/coreos/flannel/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd"
  7. "github.com/coreos/flannel/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. extIP, _ := ip.ParseIP4("1.2.3.4")
  127. data := BaseAttrs{
  128. PublicIP: extIP,
  129. }
  130. cancel := make(chan bool)
  131. sn, err := sm.AcquireLease(extIP, data, cancel)
  132. if err != nil {
  133. t.Fatal("AcquireLease failed: ", err)
  134. }
  135. if sn.String() != "10.3.3.0/24" {
  136. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  137. }
  138. // Acquire again, should reuse
  139. if sn, err = sm.AcquireLease(extIP, data, cancel); err != nil {
  140. t.Fatal("AcquireLease failed: ", err)
  141. }
  142. if sn.String() != "10.3.3.0/24" {
  143. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  144. }
  145. }
  146. func TestWatchLeaseAdded(t *testing.T) {
  147. msr := newMockSubnetRegistry(0)
  148. sm, err := newSubnetManager(msr)
  149. if err != nil {
  150. t.Fatalf("Failed to create subnet manager: %s", err)
  151. }
  152. events := make(chan EventBatch)
  153. cancel := make(chan bool)
  154. go sm.WatchLeases(events, cancel)
  155. expected := "10.3.3.0-24"
  156. msr.addCh <- expected
  157. evtBatch, ok := <-events
  158. if !ok {
  159. t.Fatalf("WatchSubnets did not publish")
  160. }
  161. if len(evtBatch) != 1 {
  162. t.Fatalf("WatchSubnets produced wrong sized event batch")
  163. }
  164. evt := evtBatch[0]
  165. if evt.Type != SubnetAdded {
  166. t.Fatalf("WatchSubnets produced wrong event type")
  167. }
  168. actual := evt.Lease.Network.StringSep(".", "-")
  169. if actual != expected {
  170. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  171. }
  172. close(cancel)
  173. }
  174. func TestWatchLeaseRemoved(t *testing.T) {
  175. msr := newMockSubnetRegistry(0)
  176. sm, err := newSubnetManager(msr)
  177. if err != nil {
  178. t.Fatalf("Failed to create subnet manager: %s", err)
  179. }
  180. events := make(chan EventBatch)
  181. cancel := make(chan bool)
  182. go sm.WatchLeases(events, cancel)
  183. expected := "10.3.4.0-24"
  184. msr.delCh <- expected
  185. evtBatch, ok := <-events
  186. if !ok {
  187. t.Fatalf("WatchSubnets did not publish")
  188. }
  189. if len(evtBatch) != 1 {
  190. t.Fatalf("WatchSubnets produced wrong sized event batch")
  191. }
  192. evt := evtBatch[0]
  193. if evt.Type != SubnetRemoved {
  194. t.Fatalf("WatchSubnets produced wrong event type")
  195. }
  196. actual := evt.Lease.Network.StringSep(".", "-")
  197. if actual != expected {
  198. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  199. }
  200. close(cancel)
  201. }
  202. func TestRenewLease(t *testing.T) {
  203. msr := newMockSubnetRegistry(1)
  204. sm, err := newSubnetManager(msr)
  205. if err != nil {
  206. t.Fatalf("Failed to create subnet manager: %s", err)
  207. }
  208. extIP, _ := ip.ParseIP4("1.2.3.4")
  209. data := BaseAttrs{
  210. PublicIP: extIP,
  211. }
  212. cancel := make(chan bool)
  213. defer close(cancel)
  214. sn, err := sm.AcquireLease(extIP, data, cancel)
  215. if err != nil {
  216. t.Fatal("AcquireLease failed: ", err)
  217. }
  218. go sm.LeaseRenewer(cancel)
  219. fmt.Println("Waiting for lease to pass original expiration")
  220. time.Sleep(2 * time.Second)
  221. // check that it's still good
  222. for _, n := range msr.subnets.Nodes {
  223. if n.Key == sn.StringSep(".", "-") {
  224. if n.Expiration.Before(time.Now()) {
  225. t.Fatalf("Failed to renew lease")
  226. }
  227. return
  228. }
  229. }
  230. t.Fatalf("Failed to find acquired lease")
  231. }