subnet_test.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. // Copyright 2015 flannel authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package etcdv2
  15. import (
  16. "encoding/json"
  17. "reflect"
  18. "testing"
  19. "time"
  20. "github.com/coreos/flannel/pkg/ip"
  21. . "github.com/coreos/flannel/subnet"
  22. "github.com/jonboulle/clockwork"
  23. "golang.org/x/net/context"
  24. )
  25. func newDummyRegistry() *MockSubnetRegistry {
  26. attrs := LeaseAttrs{
  27. PublicIP: ip.MustParseIP4("1.1.1.1"),
  28. }
  29. exp := time.Time{}
  30. subnets := []Lease{
  31. // leases within SubnetMin-SubnetMax range
  32. {ip.IP4Net{ip.MustParseIP4("10.3.1.0"), 24}, attrs, exp, 10},
  33. {ip.IP4Net{ip.MustParseIP4("10.3.2.0"), 24}, attrs, exp, 11},
  34. {ip.IP4Net{ip.MustParseIP4("10.3.4.0"), 24}, attrs, exp, 12},
  35. {ip.IP4Net{ip.MustParseIP4("10.3.5.0"), 24}, attrs, exp, 13},
  36. // hand created lease outside the range of subnetMin-SubnetMax for testing removal
  37. {ip.IP4Net{ip.MustParseIP4("10.3.31.0"), 24}, attrs, exp, 13},
  38. }
  39. config := `{ "Network": "10.3.0.0/16", "SubnetMin": "10.3.1.0", "SubnetMax": "10.3.25.0" }`
  40. return NewMockRegistry(config, subnets)
  41. }
  42. func TestAcquireLease(t *testing.T) {
  43. msr := newDummyRegistry()
  44. sm := NewMockManager(msr)
  45. extIaddr, _ := ip.ParseIP4("1.2.3.4")
  46. attrs := LeaseAttrs{
  47. PublicIP: extIaddr,
  48. }
  49. l, err := sm.AcquireLease(context.Background(), &attrs)
  50. if err != nil {
  51. t.Fatal("AcquireLease failed: ", err)
  52. }
  53. if !inAllocatableRange(context.Background(), sm, l.Subnet) {
  54. t.Fatal("Subnet mismatch: expected 10.3.3.0/24, got: ", l.Subnet)
  55. }
  56. // Acquire again, should reuse
  57. l2, err := sm.AcquireLease(context.Background(), &attrs)
  58. if err != nil {
  59. t.Fatal("AcquireLease failed: ", err)
  60. }
  61. if !l.Subnet.Equal(l2.Subnet) {
  62. t.Fatalf("AcquireLease did not reuse subnet; expected %v, got %v", l.Subnet, l2.Subnet)
  63. }
  64. // Test if a previous subnet will be used
  65. msr2 := newDummyRegistry()
  66. prevSubnet := ip.IP4Net{ip.MustParseIP4("10.3.6.0"), 24}
  67. sm2 := NewMockManagerWithSubnet(msr2, prevSubnet)
  68. prev, err := sm2.AcquireLease(context.Background(), &attrs)
  69. if err != nil {
  70. t.Fatal("AcquireLease failed: ", err)
  71. }
  72. if !prev.Subnet.Equal(prevSubnet) {
  73. t.Fatalf("AcquireLease did not reuse subnet from previous run; expected %v, got %v", prevSubnet, prev.Subnet)
  74. }
  75. // Test that a previous subnet will not be used if it does not match the registry config
  76. msr3 := newDummyRegistry()
  77. invalidSubnet := ip.IP4Net{ip.MustParseIP4("10.4.1.0"), 24}
  78. sm3 := NewMockManagerWithSubnet(msr3, invalidSubnet)
  79. l3, err := sm3.AcquireLease(context.Background(), &attrs)
  80. if err != nil {
  81. t.Fatal("AcquireLease failed: ", err)
  82. }
  83. if l3.Subnet.Equal(invalidSubnet) {
  84. t.Fatalf("AcquireLease reused invalid subnet from previous run; reused %v", l3.Subnet)
  85. }
  86. }
  87. func TestConfigChanged(t *testing.T) {
  88. msr := newDummyRegistry()
  89. sm := NewMockManager(msr)
  90. extIaddr, _ := ip.ParseIP4("1.2.3.4")
  91. attrs := LeaseAttrs{
  92. PublicIP: extIaddr,
  93. }
  94. l, err := sm.AcquireLease(context.Background(), &attrs)
  95. if err != nil {
  96. t.Fatal("AcquireLease failed: ", err)
  97. }
  98. if !inAllocatableRange(context.Background(), sm, l.Subnet) {
  99. t.Fatal("Acquired subnet outside of valid range: ", l.Subnet)
  100. }
  101. // Change config
  102. config := `{ "Network": "10.4.0.0/16" }`
  103. msr.setConfig(config)
  104. // Acquire again, should not reuse
  105. if l, err = sm.AcquireLease(context.Background(), &attrs); err != nil {
  106. t.Fatal("AcquireLease failed: ", err)
  107. }
  108. if !inAllocatableRange(context.Background(), sm, l.Subnet) {
  109. t.Fatal("Acquired subnet outside of valid range: ", l.Subnet)
  110. }
  111. }
  112. func newIP4Net(ipaddr string, prefix uint) ip.IP4Net {
  113. a, err := ip.ParseIP4(ipaddr)
  114. if err != nil {
  115. panic("failed to parse ipaddr")
  116. }
  117. return ip.IP4Net{
  118. IP: a,
  119. PrefixLen: prefix,
  120. }
  121. }
  122. func acquireLease(ctx context.Context, t *testing.T, sm Manager) *Lease {
  123. extIaddr, _ := ip.ParseIP4("1.2.3.4")
  124. attrs := LeaseAttrs{
  125. PublicIP: extIaddr,
  126. }
  127. l, err := sm.AcquireLease(ctx, &attrs)
  128. if err != nil {
  129. t.Fatal("AcquireLease failed: ", err)
  130. }
  131. return l
  132. }
  133. func TestWatchLeaseAdded(t *testing.T) {
  134. msr := newDummyRegistry()
  135. sm := NewMockManager(msr)
  136. ctx, cancel := context.WithCancel(context.Background())
  137. defer cancel()
  138. l := acquireLease(ctx, t, sm)
  139. events := make(chan []Event)
  140. go WatchLeases(ctx, sm, l, events)
  141. evtBatch := <-events
  142. for _, evt := range evtBatch {
  143. if evt.Lease.Key() == l.Key() {
  144. t.Errorf("WatchLeases returned our own lease")
  145. }
  146. }
  147. expected := ip.IP4Net{
  148. IP: ip.MustParseIP4("10.3.30.0"),
  149. PrefixLen: 24,
  150. }
  151. // Sanity check to make sure acquired lease is not this.
  152. // It shouldn't be as SubnetMin/SubnetMax in config is [10.3.1.0/24 to 10.3.25.0/24]
  153. if l.Subnet.Equal(expected) {
  154. t.Fatalf("Acquired lease conflicts with one about to create")
  155. }
  156. attrs := &LeaseAttrs{
  157. PublicIP: ip.MustParseIP4("1.1.1.1"),
  158. }
  159. _, err := msr.createSubnet(ctx, expected, attrs, 0)
  160. if err != nil {
  161. t.Fatalf("createSubnet filed: %v", err)
  162. }
  163. evtBatch = <-events
  164. if len(evtBatch) != 1 {
  165. t.Fatalf("WatchLeases produced wrong sized event batch: got %v, expected 1", len(evtBatch))
  166. }
  167. evt := evtBatch[0]
  168. if evt.Type != EventAdded {
  169. t.Fatalf("WatchLeases produced wrong event type")
  170. }
  171. actual := evt.Lease.Subnet
  172. if !actual.Equal(expected) {
  173. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  174. }
  175. }
  176. func TestWatchLeaseRemoved(t *testing.T) {
  177. msr := newDummyRegistry()
  178. sm := NewMockManager(msr)
  179. ctx, cancel := context.WithCancel(context.Background())
  180. defer cancel()
  181. l := acquireLease(ctx, t, sm)
  182. events := make(chan []Event)
  183. go WatchLeases(ctx, sm, l, events)
  184. evtBatch := <-events
  185. for _, evt := range evtBatch {
  186. if evt.Lease.Key() == l.Key() {
  187. t.Errorf("WatchLeases returned our own lease")
  188. }
  189. }
  190. expected := ip.IP4Net{ip.MustParseIP4("10.3.31.0"), 24}
  191. // Sanity check to make sure acquired lease is not this.
  192. // It shouldn't be as SubnetMin/SubnetMax in config is [10.3.1.0/24 to 10.3.25.0/24]
  193. if l.Subnet.Equal(expected) {
  194. t.Fatalf("Acquired lease conflicts with one about to create")
  195. }
  196. msr.expireSubnet("_", expected)
  197. evtBatch = <-events
  198. if len(evtBatch) != 1 {
  199. t.Fatalf("WatchLeases produced wrong sized event batch: %#v", evtBatch)
  200. }
  201. evt := evtBatch[0]
  202. if evt.Type != EventRemoved {
  203. t.Fatalf("WatchLeases produced wrong event type")
  204. }
  205. actual := evt.Lease.Subnet
  206. if !actual.Equal(expected) {
  207. t.Errorf("WatchSubnet produced wrong subnet: expected %s, got %s", expected, actual)
  208. }
  209. }
  210. type leaseData struct {
  211. Dummy string
  212. }
  213. func TestRenewLease(t *testing.T) {
  214. msr := newDummyRegistry()
  215. sm := NewMockManager(msr)
  216. now := time.Now()
  217. fakeClock := clockwork.NewFakeClockAt(now)
  218. clock = fakeClock
  219. // Create LeaseAttrs
  220. extIaddr, _ := ip.ParseIP4("1.2.3.4")
  221. attrs := LeaseAttrs{
  222. PublicIP: extIaddr,
  223. BackendType: "vxlan",
  224. }
  225. ld, err := json.Marshal(&leaseData{Dummy: "test string"})
  226. if err != nil {
  227. t.Fatalf("Failed to marshal leaseData: %v", err)
  228. }
  229. attrs.BackendData = json.RawMessage(ld)
  230. // Acquire lease
  231. ctx, cancel := context.WithCancel(context.Background())
  232. defer cancel()
  233. l, err := sm.AcquireLease(ctx, &attrs)
  234. if err != nil {
  235. t.Fatal("AcquireLease failed: ", err)
  236. }
  237. now = now.Add(subnetTTL)
  238. fakeClock.Advance(24 * time.Hour)
  239. if err := sm.RenewLease(ctx, l); err != nil {
  240. t.Fatal("RenewLease failed: ", err)
  241. }
  242. // check that it's still good
  243. n, err := msr.getNetwork(ctx)
  244. if err != nil {
  245. t.Errorf("Failed to renew lease: could not get networks: %v", err)
  246. }
  247. for _, sn := range n.subnets {
  248. if sn.Subnet.Equal(l.Subnet) {
  249. expected := now.Add(subnetTTL)
  250. if !sn.Expiration.Equal(expected) {
  251. t.Errorf("Failed to renew lease: bad expiration; expected %v, got %v", expected, sn.Expiration)
  252. }
  253. if !reflect.DeepEqual(sn.Attrs, attrs) {
  254. t.Errorf("LeaseAttrs changed: was %#v, now %#v", attrs, sn.Attrs)
  255. }
  256. return
  257. }
  258. }
  259. t.Fatal("Failed to find acquired lease")
  260. }
  261. func inAllocatableRange(ctx context.Context, sm Manager, ipn ip.IP4Net) bool {
  262. cfg, err := sm.GetNetworkConfig(ctx)
  263. if err != nil {
  264. panic(err)
  265. }
  266. return ipn.IP >= cfg.SubnetMin || ipn.IP <= cfg.SubnetMax
  267. }