subnet_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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. Value: `{"PublicIP": "1.1.1.1"}`,
  92. ModifiedIndex: msr.index,
  93. }
  94. msr.subnets.Nodes = append(msr.subnets.Nodes, &n)
  95. return &etcd.Response{
  96. Action: "add",
  97. Node: &n,
  98. }, nil
  99. case sn = <-msr.delCh:
  100. for i, n := range msr.subnets.Nodes {
  101. if n.Key == sn {
  102. msr.subnets.Nodes[i] = msr.subnets.Nodes[len(msr.subnets.Nodes)-1]
  103. msr.subnets.Nodes = msr.subnets.Nodes[:len(msr.subnets.Nodes)-2]
  104. return &etcd.Response{
  105. Action: "expire",
  106. Node: n,
  107. }, nil
  108. }
  109. }
  110. return nil, fmt.Errorf("Subnet (%s) to delete was not found: ", sn)
  111. }
  112. }
  113. func (msr *mockSubnetRegistry) hasSubnet(sn string) bool {
  114. for _, n := range msr.subnets.Nodes {
  115. if n.Key == sn {
  116. return true
  117. }
  118. }
  119. return false
  120. }
  121. func TestAcquireLease(t *testing.T) {
  122. msr := newMockSubnetRegistry(0)
  123. sm, err := newSubnetManager(msr)
  124. if err != nil {
  125. t.Fatalf("Failed to create subnet manager: %s", err)
  126. }
  127. extIP, _ := ip.ParseIP4("1.2.3.4")
  128. attrs := LeaseAttrs{
  129. PublicIP: extIP,
  130. }
  131. cancel := make(chan bool)
  132. sn, err := sm.AcquireLease(&attrs, cancel)
  133. if err != nil {
  134. t.Fatal("AcquireLease failed: ", err)
  135. }
  136. if sn.String() != "10.3.3.0/24" {
  137. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  138. }
  139. // Acquire again, should reuse
  140. if sn, err = sm.AcquireLease(&attrs, cancel); err != nil {
  141. t.Fatal("AcquireLease failed: ", err)
  142. }
  143. if sn.String() != "10.3.3.0/24" {
  144. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", sn)
  145. }
  146. }
  147. func TestWatchLeaseAdded(t *testing.T) {
  148. msr := newMockSubnetRegistry(0)
  149. sm, err := newSubnetManager(msr)
  150. if err != nil {
  151. t.Fatalf("Failed to create subnet manager: %s", err)
  152. }
  153. events := make(chan EventBatch)
  154. cancel := make(chan bool)
  155. go sm.WatchLeases(events, cancel)
  156. expected := "10.3.3.0-24"
  157. msr.addCh <- expected
  158. evtBatch, ok := <-events
  159. if !ok {
  160. t.Fatalf("WatchSubnets did not publish")
  161. }
  162. if len(evtBatch) != 1 {
  163. t.Fatalf("WatchSubnets produced wrong sized event batch")
  164. }
  165. evt := evtBatch[0]
  166. if evt.Type != SubnetAdded {
  167. t.Fatalf("WatchSubnets produced wrong event type")
  168. }
  169. actual := evt.Lease.Network.StringSep(".", "-")
  170. if actual != expected {
  171. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  172. }
  173. close(cancel)
  174. }
  175. func TestWatchLeaseRemoved(t *testing.T) {
  176. msr := newMockSubnetRegistry(0)
  177. sm, err := newSubnetManager(msr)
  178. if err != nil {
  179. t.Fatalf("Failed to create subnet manager: %s", err)
  180. }
  181. events := make(chan EventBatch)
  182. cancel := make(chan bool)
  183. go sm.WatchLeases(events, cancel)
  184. expected := "10.3.4.0-24"
  185. msr.delCh <- expected
  186. evtBatch, ok := <-events
  187. if !ok {
  188. t.Fatalf("WatchSubnets did not publish")
  189. }
  190. if len(evtBatch) != 1 {
  191. t.Fatalf("WatchSubnets produced wrong sized event batch")
  192. }
  193. evt := evtBatch[0]
  194. if evt.Type != SubnetRemoved {
  195. t.Fatalf("WatchSubnets produced wrong event type")
  196. }
  197. actual := evt.Lease.Network.StringSep(".", "-")
  198. if actual != expected {
  199. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  200. }
  201. close(cancel)
  202. }
  203. func TestRenewLease(t *testing.T) {
  204. msr := newMockSubnetRegistry(1)
  205. sm, err := newSubnetManager(msr)
  206. if err != nil {
  207. t.Fatalf("Failed to create subnet manager: %s", err)
  208. }
  209. extIP, _ := ip.ParseIP4("1.2.3.4")
  210. attrs := LeaseAttrs{
  211. PublicIP: extIP,
  212. }
  213. cancel := make(chan bool)
  214. defer close(cancel)
  215. sn, err := sm.AcquireLease(&attrs, cancel)
  216. if err != nil {
  217. t.Fatal("AcquireLease failed: ", err)
  218. }
  219. go sm.LeaseRenewer(cancel)
  220. fmt.Println("Waiting for lease to pass original expiration")
  221. time.Sleep(2 * time.Second)
  222. // check that it's still good
  223. for _, n := range msr.subnets.Nodes {
  224. if n.Key == sn.StringSep(".", "-") {
  225. if n.Expiration.Before(time.Now()) {
  226. t.Fatalf("Failed to renew lease")
  227. }
  228. return
  229. }
  230. }
  231. t.Fatalf("Failed to find acquired lease")
  232. }