~ubuntu-branches/ubuntu/trusty/juju-core/trusty-proposed

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/state/state_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-03 09:22:46 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20140203092246-e03vg402vztzo4qa
Tags: 1.17.2-0ubuntu1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
        "launchpad.net/juju-core/errors"
21
21
        "launchpad.net/juju-core/instance"
22
22
        "launchpad.net/juju-core/names"
 
23
        "launchpad.net/juju-core/replicaset"
23
24
        "launchpad.net/juju-core/state"
24
25
        "launchpad.net/juju-core/state/api/params"
25
26
        statetesting "launchpad.net/juju-core/state/testing"
61
62
 
62
63
func (s *StateSuite) TestAddresses(c *gc.C) {
63
64
        var err error
64
 
        machines := make([]*state.Machine, 3)
65
 
        machines[0], err = s.State.AddMachine("quantal", state.JobHostUnits)
66
 
        c.Assert(err, gc.IsNil)
67
 
        machines[1], err = s.State.AddMachine("quantal", state.JobManageState, state.JobHostUnits)
68
 
        c.Assert(err, gc.IsNil)
69
 
        machines[2], err = s.State.AddMachine("quantal", state.JobManageState)
 
65
        machines := make([]*state.Machine, 4)
 
66
        machines[0], err = s.State.AddMachine("quantal", state.JobManageEnviron, state.JobHostUnits)
 
67
        c.Assert(err, gc.IsNil)
 
68
        machines[1], err = s.State.AddMachine("quantal", state.JobHostUnits)
 
69
        c.Assert(err, gc.IsNil)
 
70
        err = s.State.EnsureAvailability(3, constraints.Value{}, "quantal")
 
71
        c.Assert(err, gc.IsNil)
 
72
        machines[2], err = s.State.Machine("2")
 
73
        c.Assert(err, gc.IsNil)
 
74
        machines[3], err = s.State.Machine("3")
70
75
        c.Assert(err, gc.IsNil)
71
76
 
72
77
        for i, m := range machines {
94
99
 
95
100
        addrs, err := s.State.Addresses()
96
101
        c.Assert(err, gc.IsNil)
97
 
        c.Assert(addrs, gc.HasLen, 2)
 
102
        c.Assert(addrs, gc.HasLen, 3)
98
103
        c.Assert(addrs, jc.SameContents, []string{
99
 
                fmt.Sprintf("10.0.0.1:%d", envConfig.StatePort()),
 
104
                fmt.Sprintf("10.0.0.0:%d", envConfig.StatePort()),
100
105
                fmt.Sprintf("10.0.0.2:%d", envConfig.StatePort()),
 
106
                fmt.Sprintf("10.0.0.3:%d", envConfig.StatePort()),
101
107
        })
102
108
 
103
109
        addrs, err = s.State.APIAddresses()
104
110
        c.Assert(err, gc.IsNil)
105
 
        c.Assert(addrs, gc.HasLen, 2)
 
111
        c.Assert(addrs, gc.HasLen, 3)
106
112
        c.Assert(addrs, jc.SameContents, []string{
107
 
                fmt.Sprintf("10.0.0.1:%d", envConfig.APIPort()),
 
113
                fmt.Sprintf("10.0.0.0:%d", envConfig.APIPort()),
108
114
                fmt.Sprintf("10.0.0.2:%d", envConfig.APIPort()),
 
115
                fmt.Sprintf("10.0.0.3:%d", envConfig.APIPort()),
109
116
        })
110
117
}
111
118
 
122
129
        c.Assert(err2, jc.Satisfies, errors.IsNotFoundError)
123
130
}
124
131
 
 
132
func (s *StateSuite) dummyCharm(c *gc.C, curlOverride string) (ch charm.Charm, curl *charm.URL, bundleURL *url.URL, bundleSHA256 string) {
 
133
        var err error
 
134
        ch = testing.Charms.Dir("dummy")
 
135
        if curlOverride != "" {
 
136
                curl = charm.MustParseURL(curlOverride)
 
137
        } else {
 
138
                curl = charm.MustParseURL(
 
139
                        fmt.Sprintf("local:quantal/%s-%d", ch.Meta().Name, ch.Revision()),
 
140
                )
 
141
        }
 
142
        bundleURL, err = url.Parse("http://bundles.testing.invalid/dummy-1")
 
143
        c.Assert(err, gc.IsNil)
 
144
        bundleSHA256 = "dummy-1-sha256"
 
145
        return ch, curl, bundleURL, bundleSHA256
 
146
}
 
147
 
125
148
func (s *StateSuite) TestAddCharm(c *gc.C) {
126
149
        // Check that adding charms from scratch works correctly.
127
 
        ch := testing.Charms.Dir("dummy")
128
 
        curl := charm.MustParseURL(
129
 
                fmt.Sprintf("local:quantal/%s-%d", ch.Meta().Name, ch.Revision()),
130
 
        )
131
 
        bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
132
 
        c.Assert(err, gc.IsNil)
133
 
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
150
        ch, curl, bundleURL, bundleSHA256 := s.dummyCharm(c, "")
 
151
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
134
152
        c.Assert(err, gc.IsNil)
135
153
        c.Assert(dummy.URL().String(), gc.Equals, curl.String())
136
154
 
154
172
        // Add a deployed charm.
155
173
        bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
156
174
        c.Assert(err, gc.IsNil)
157
 
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
175
        bundleSHA256 := "dummy-1-sha256"
 
176
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
158
177
        c.Assert(err, gc.IsNil)
159
178
        c.Assert(dummy.URL().String(), gc.Equals, curl.String())
160
179
 
224
243
        c.Assert(curl.Revision, gc.Equals, 1234)
225
244
}
226
245
 
 
246
func (s *StateSuite) TestPrepareStoreCharmUpload(c *gc.C) {
 
247
        // First test the sanity checks.
 
248
        sch, err := s.State.PrepareStoreCharmUpload(charm.MustParseURL("cs:quantal/dummy"))
 
249
        c.Assert(err, gc.ErrorMatches, "expected charm URL with revision, got .*")
 
250
        c.Assert(sch, gc.IsNil)
 
251
        sch, err = s.State.PrepareStoreCharmUpload(charm.MustParseURL("local:quantal/dummy"))
 
252
        c.Assert(err, gc.ErrorMatches, "expected charm URL with cs schema, got .*")
 
253
        c.Assert(sch, gc.IsNil)
 
254
 
 
255
        // No charm in state, so the call should respect given revision.
 
256
        testCurl := charm.MustParseURL("cs:quantal/missing-123")
 
257
        sch, err = s.State.PrepareStoreCharmUpload(testCurl)
 
258
        c.Assert(err, gc.IsNil)
 
259
        c.Assert(sch.URL(), gc.DeepEquals, testCurl)
 
260
        c.Assert(sch.IsUploaded(), jc.IsFalse)
 
261
 
 
262
        s.assertPendingCharmExists(c, sch.URL())
 
263
 
 
264
        // Try adding it again with the same revision and ensure we get the same document.
 
265
        schCopy, err := s.State.PrepareStoreCharmUpload(testCurl)
 
266
        c.Assert(err, gc.IsNil)
 
267
        c.Assert(sch, jc.DeepEquals, schCopy)
 
268
 
 
269
        // Now add a charm and try again - we should get the same result
 
270
        // as with AddCharm.
 
271
        ch, curl, bundleURL, bundleSHA256 := s.dummyCharm(c, "cs:precise/dummy-2")
 
272
        sch, err = s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
 
273
        c.Assert(err, gc.IsNil)
 
274
        schCopy, err = s.State.PrepareStoreCharmUpload(curl)
 
275
        c.Assert(err, gc.IsNil)
 
276
        c.Assert(sch, jc.DeepEquals, schCopy)
 
277
 
 
278
        // Finally, try poking around the state with a placeholder and
 
279
        // bundlesha256 to make sure we do the right thing.
 
280
        curl = curl.WithRevision(999)
 
281
        first := state.TransactionHook{
 
282
                Before: func() {
 
283
                        err := s.State.AddStoreCharmPlaceholder(curl)
 
284
                        c.Assert(err, gc.IsNil)
 
285
                },
 
286
                After: func() {
 
287
                        err := s.charms.RemoveId(curl)
 
288
                        c.Assert(err, gc.IsNil)
 
289
                },
 
290
        }
 
291
        second := state.TransactionHook{
 
292
                Before: func() {
 
293
                        err := s.State.AddStoreCharmPlaceholder(curl)
 
294
                        c.Assert(err, gc.IsNil)
 
295
                },
 
296
                After: func() {
 
297
                        err := s.charms.UpdateId(curl, D{{"$set", D{
 
298
                                {"bundlesha256", "fake"}},
 
299
                        }})
 
300
                        c.Assert(err, gc.IsNil)
 
301
                },
 
302
        }
 
303
        defer state.SetTransactionHooks(
 
304
                c, s.State, first, second, first,
 
305
        ).Check()
 
306
 
 
307
        _, err = s.State.PrepareStoreCharmUpload(curl)
 
308
        c.Assert(err, gc.Equals, state.ErrExcessiveContention)
 
309
}
 
310
 
227
311
func (s *StateSuite) TestUpdateUploadedCharm(c *gc.C) {
228
 
        ch := testing.Charms.Dir("dummy")
229
 
        curl := charm.MustParseURL(
230
 
                fmt.Sprintf("local:quantal/%s-%d", ch.Meta().Name, ch.Revision()),
231
 
        )
232
 
        bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
233
 
        c.Assert(err, gc.IsNil)
234
 
        _, err = s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
312
        ch, curl, bundleURL, bundleSHA256 := s.dummyCharm(c, "")
 
313
        _, err := s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
235
314
        c.Assert(err, gc.IsNil)
236
315
 
237
 
        // First test with already uploaded and a missing charms.
238
 
        sch, err := s.State.UpdateUploadedCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
316
        // Test with already uploaded and a missing charms.
 
317
        sch, err := s.State.UpdateUploadedCharm(ch, curl, bundleURL, bundleSHA256)
239
318
        c.Assert(err, gc.ErrorMatches, fmt.Sprintf("charm %q already uploaded", curl))
240
319
        c.Assert(sch, gc.IsNil)
241
320
        missingCurl := charm.MustParseURL("local:quantal/missing-1")
243
322
        c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
244
323
        c.Assert(sch, gc.IsNil)
245
324
 
246
 
        // Now try with an uploaded charm.
 
325
        // Test with with an uploaded local charm.
247
326
        _, err = s.State.PrepareLocalCharmUpload(missingCurl)
248
327
        c.Assert(err, gc.IsNil)
249
328
        sch, err = s.State.UpdateUploadedCharm(ch, missingCurl, bundleURL, "missing")
251
330
        c.Assert(sch.URL(), gc.DeepEquals, missingCurl)
252
331
        c.Assert(sch.Revision(), gc.Equals, missingCurl.Revision)
253
332
        c.Assert(sch.IsUploaded(), jc.IsTrue)
 
333
        c.Assert(sch.IsPlaceholder(), jc.IsFalse)
254
334
        c.Assert(sch.Meta(), gc.DeepEquals, ch.Meta())
255
335
        c.Assert(sch.Config(), gc.DeepEquals, ch.Config())
256
336
        c.Assert(sch.BundleURL(), gc.DeepEquals, bundleURL)
278
358
 
279
359
func (s *StateSuite) TestLatestPlaceholderCharm(c *gc.C) {
280
360
        // Add a deployed charm
281
 
        ch := testing.Charms.Dir("dummy")
282
 
        curl := charm.MustParseURL("cs:quantal/dummy-1")
283
 
        bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
284
 
        c.Assert(err, gc.IsNil)
285
 
        _, err = s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
361
        ch, curl, bundleURL, bundleSHA256 := s.dummyCharm(c, "cs:quantal/dummy-1")
 
362
        _, err := s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
286
363
        c.Assert(err, gc.IsNil)
287
364
 
288
365
        // Deployed charm not found.
334
411
 
335
412
func (s *StateSuite) assertAddStoreCharmPlaceholder(c *gc.C) (*charm.URL, *charm.URL, *state.Charm) {
336
413
        // Add a deployed charm
337
 
        ch := testing.Charms.Dir("dummy")
338
 
        curl := charm.MustParseURL("cs:quantal/dummy-1")
339
 
        bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
340
 
        c.Assert(err, gc.IsNil)
341
 
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
 
414
        ch, curl, bundleURL, bundleSHA256 := s.dummyCharm(c, "cs:quantal/dummy-1")
 
415
        dummy, err := s.State.AddCharm(ch, curl, bundleURL, bundleSHA256)
342
416
        c.Assert(err, gc.IsNil)
343
417
 
344
418
        // Add a charm placeholder
411
485
        c.Assert(err, gc.ErrorMatches, "cannot add a new machine: duplicate job: .*")
412
486
}
413
487
 
414
 
func (s *StateSuite) TestAddMachines(c *gc.C) {
415
 
        oneJob := []state.MachineJob{state.JobHostUnits}
416
 
        m0, err := s.State.AddMachine("quantal", oneJob...)
 
488
func (s *StateSuite) TestAddMachine(c *gc.C) {
 
489
        allJobs := []state.MachineJob{
 
490
                state.JobHostUnits,
 
491
                state.JobManageEnviron,
 
492
        }
 
493
        m0, err := s.State.AddMachine("quantal", allJobs...)
417
494
        c.Assert(err, gc.IsNil)
418
495
        check := func(m *state.Machine, id, series string, jobs []state.MachineJob) {
419
496
                c.Assert(m.Id(), gc.Equals, id)
421
498
                c.Assert(m.Jobs(), gc.DeepEquals, jobs)
422
499
                s.assertMachineContainers(c, m, nil)
423
500
        }
424
 
        check(m0, "0", "quantal", oneJob)
 
501
        check(m0, "0", "quantal", allJobs)
425
502
        m0, err = s.State.Machine("0")
426
503
        c.Assert(err, gc.IsNil)
427
 
        check(m0, "0", "quantal", oneJob)
 
504
        check(m0, "0", "quantal", allJobs)
428
505
 
429
 
        allJobs := []state.MachineJob{
430
 
                state.JobHostUnits,
431
 
                state.JobManageEnviron,
432
 
                state.JobManageState,
433
 
        }
434
 
        m1, err := s.State.AddMachine("blahblah", allJobs...)
 
506
        oneJob := []state.MachineJob{state.JobHostUnits}
 
507
        m1, err := s.State.AddMachine("blahblah", oneJob...)
435
508
        c.Assert(err, gc.IsNil)
436
 
        check(m1, "1", "blahblah", allJobs)
 
509
        check(m1, "1", "blahblah", oneJob)
437
510
 
438
511
        m1, err = s.State.Machine("1")
439
512
        c.Assert(err, gc.IsNil)
440
 
        check(m1, "1", "blahblah", allJobs)
 
513
        check(m1, "1", "blahblah", oneJob)
441
514
 
442
515
        m, err := s.State.AllMachines()
443
516
        c.Assert(err, gc.IsNil)
444
517
        c.Assert(m, gc.HasLen, 2)
445
 
        check(m[0], "0", "quantal", oneJob)
446
 
        check(m[1], "1", "blahblah", allJobs)
 
518
        check(m[0], "0", "quantal", allJobs)
 
519
        check(m[1], "1", "blahblah", oneJob)
 
520
}
 
521
 
 
522
func (s *StateSuite) TestAddMachines(c *gc.C) {
 
523
        oneJob := []state.MachineJob{state.JobHostUnits}
 
524
        cons := constraints.MustParse("mem=4G")
 
525
        hc := instance.MustParseHardware("mem=2G")
 
526
        machineTemplate := state.MachineTemplate{
 
527
                Series:                  "precise",
 
528
                Constraints:             cons,
 
529
                HardwareCharacteristics: hc,
 
530
                InstanceId:              "inst-id",
 
531
                Nonce:                   "nonce",
 
532
                Jobs:                    oneJob,
 
533
        }
 
534
        machines, err := s.State.AddMachines(machineTemplate)
 
535
        c.Assert(err, gc.IsNil)
 
536
        c.Assert(machines, gc.HasLen, 1)
 
537
        m, err := s.State.Machine(machines[0].Id())
 
538
        c.Assert(err, gc.IsNil)
 
539
        instId, err := m.InstanceId()
 
540
        c.Assert(err, gc.IsNil)
 
541
        c.Assert(string(instId), gc.Equals, "inst-id")
 
542
        c.Assert(m.CheckProvisioned("nonce"), jc.IsTrue)
 
543
        c.Assert(m.Series(), gc.Equals, "precise")
 
544
        mcons, err := m.Constraints()
 
545
        c.Assert(err, gc.IsNil)
 
546
        c.Assert(mcons, gc.DeepEquals, cons)
 
547
        mhc, err := m.HardwareCharacteristics()
 
548
        c.Assert(err, gc.IsNil)
 
549
        c.Assert(*mhc, gc.DeepEquals, hc)
 
550
        // Clear the deprecated machineDoc InstanceId attribute and do it again.
 
551
        // still works as expected with the new data model.
 
552
        state.SetMachineInstanceId(m, "")
 
553
        instId, err = m.InstanceId()
 
554
        c.Assert(err, gc.IsNil)
 
555
        c.Assert(string(instId), gc.Equals, "inst-id")
447
556
}
448
557
 
449
558
func (s *StateSuite) TestAddMachinesEnvironmentDying(c *gc.C) {
767
876
        s.assertMachineContainers(c, m0, []string{"0/lxc/0", "0/lxc/1"})
768
877
}
769
878
 
 
879
func (s *StateSuite) TestAddMachineCanOnlyAddStateServerForMachine0(c *gc.C) {
 
880
        template := state.MachineTemplate{
 
881
                Series: "quantal",
 
882
                Jobs:   []state.MachineJob{state.JobManageEnviron},
 
883
        }
 
884
        // Check that we can add the bootstrap machine.
 
885
        m, err := s.State.AddOneMachine(template)
 
886
        c.Assert(err, gc.IsNil)
 
887
        c.Assert(m.Id(), gc.Equals, "0")
 
888
        c.Assert(m.WantsVote(), jc.IsTrue)
 
889
        c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobManageEnviron})
 
890
 
 
891
        // Check that the state server information is correct.
 
892
        info, err := s.State.StateServerInfo()
 
893
        c.Assert(err, gc.IsNil)
 
894
        c.Assert(info.MachineIds, gc.DeepEquals, []string{"0"})
 
895
        c.Assert(info.VotingMachineIds, gc.DeepEquals, []string{"0"})
 
896
 
 
897
        const errCannotAdd = "cannot add a new machine: state server jobs specified without calling EnsureAvailability"
 
898
        m, err = s.State.AddOneMachine(template)
 
899
        c.Assert(err, gc.ErrorMatches, errCannotAdd)
 
900
 
 
901
        m, err = s.State.AddMachineInsideMachine(template, "0", instance.LXC)
 
902
        c.Assert(err, gc.ErrorMatches, errCannotAdd)
 
903
 
 
904
        m, err = s.State.AddMachineInsideNewMachine(template, template, instance.LXC)
 
905
        c.Assert(err, gc.ErrorMatches, errCannotAdd)
 
906
}
 
907
 
770
908
func (s *StateSuite) TestReadMachine(c *gc.C) {
771
909
        machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
772
910
        c.Assert(err, gc.IsNil)
2477
2615
        }
2478
2616
}
2479
2617
 
2480
 
func (s *StateSuite) TestStateServerMachineIds(c *gc.C) {
2481
 
        ids, err := state.StateServerMachineIds(s.State)
 
2618
func (s *StateSuite) TestStateServerInfo(c *gc.C) {
 
2619
        ids, err := s.State.StateServerInfo()
2482
2620
        c.Assert(err, gc.IsNil)
2483
 
        c.Assert(ids, gc.HasLen, 0)
 
2621
        c.Assert(ids.MachineIds, gc.HasLen, 0)
 
2622
        c.Assert(ids.VotingMachineIds, gc.HasLen, 0)
2484
2623
 
2485
2624
        // TODO(rog) more testing here when we can actually add
2486
2625
        // state servers.
2487
2626
}
2488
2627
 
2489
2628
func (s *StateSuite) TestOpenCreatesStateServersDoc(c *gc.C) {
2490
 
        _, err := s.State.AddMachine("quantal", state.JobHostUnits)
2491
 
        c.Assert(err, gc.IsNil)
2492
 
        m1, err := s.State.AddMachine("quantal", state.JobHostUnits, state.JobManageState)
2493
 
        c.Assert(err, gc.IsNil)
2494
 
        m2, err := s.State.AddMachine("quantal", state.JobManageEnviron, state.JobManageState)
 
2629
        m0, err := s.State.AddMachine("quantal", state.JobHostUnits, state.JobManageEnviron)
2495
2630
        c.Assert(err, gc.IsNil)
2496
2631
 
2497
2632
        // Delete the stateServers collection to pretend this
2501
2636
        c.Assert(err, gc.IsNil)
2502
2637
 
2503
2638
        // Sanity check that we have in fact deleted the right info.
2504
 
        ids, err := state.StateServerMachineIds(s.State)
 
2639
        info, err := s.State.StateServerInfo()
2505
2640
        c.Assert(err, gc.NotNil)
2506
 
        c.Assert(ids, gc.HasLen, 0)
2507
 
 
2508
 
        st, err := state.Open(state.TestingStateInfo(), state.TestingDialOpts())
2509
 
        c.Assert(err, gc.IsNil)
2510
 
        defer st.Close()
2511
 
 
2512
 
        expectIds := []string{m1.Id(), m2.Id()}
2513
 
        sort.Strings(expectIds)
2514
 
        ids, err = state.StateServerMachineIds(st)
2515
 
        c.Assert(err, gc.IsNil)
 
2641
        c.Assert(info, gc.IsNil)
 
2642
 
 
2643
        st, err := state.Open(state.TestingStateInfo(), state.TestingDialOpts())
 
2644
        c.Assert(err, gc.IsNil)
 
2645
        defer st.Close()
 
2646
 
 
2647
        expectIds := []string{m0.Id()}
 
2648
        expectStateServerInfo := &state.StateServerInfo{
 
2649
                MachineIds:       expectIds,
 
2650
                VotingMachineIds: expectIds,
 
2651
        }
 
2652
        info, err = st.StateServerInfo()
 
2653
        c.Assert(err, gc.IsNil)
 
2654
        c.Assert(info, gc.DeepEquals, expectStateServerInfo)
 
2655
}
 
2656
 
 
2657
func (s *StateSuite) TestReopenWithNoMachines(c *gc.C) {
 
2658
        info, err := s.State.StateServerInfo()
 
2659
        c.Assert(err, gc.IsNil)
 
2660
        c.Assert(info, jc.DeepEquals, &state.StateServerInfo{})
 
2661
 
 
2662
        st, err := state.Open(state.TestingStateInfo(), state.TestingDialOpts())
 
2663
        c.Assert(err, gc.IsNil)
 
2664
        defer st.Close()
 
2665
 
 
2666
        info, err = s.State.StateServerInfo()
 
2667
        c.Assert(err, gc.IsNil)
 
2668
        c.Assert(info, jc.DeepEquals, &state.StateServerInfo{})
 
2669
}
 
2670
 
 
2671
func (s *StateSuite) TestOpenReplacesOldStateServersDoc(c *gc.C) {
 
2672
        m0, err := s.State.AddMachine("quantal", state.JobHostUnits, state.JobManageEnviron)
 
2673
        c.Assert(err, gc.IsNil)
 
2674
 
 
2675
        // Clear the voting machine ids from the stateServers collection
 
2676
        // to pretend this is a semi-old environment that had
 
2677
        // created the collection but not the voting ids.
 
2678
        _, err = s.stateServers.UpdateAll(nil, bson.D{{
 
2679
                "$set",
 
2680
                bson.D{
 
2681
                        {"votingmachineids", nil},
 
2682
                        {"machineids", nil},
 
2683
                },
 
2684
        }})
 
2685
        c.Assert(err, gc.IsNil)
 
2686
 
 
2687
        // Sanity check that they have actually been removed.
 
2688
        info, err := s.State.StateServerInfo()
 
2689
        c.Assert(err, gc.IsNil)
 
2690
        c.Assert(info.MachineIds, gc.HasLen, 0)
 
2691
        c.Assert(info.VotingMachineIds, gc.HasLen, 0)
 
2692
 
 
2693
        st, err := state.Open(state.TestingStateInfo(), state.TestingDialOpts())
 
2694
        c.Assert(err, gc.IsNil)
 
2695
        defer st.Close()
 
2696
 
 
2697
        info, err = s.State.StateServerInfo()
 
2698
        c.Assert(err, gc.IsNil)
 
2699
        expectIds := []string{m0.Id()}
 
2700
        c.Assert(info, gc.DeepEquals, &state.StateServerInfo{
 
2701
                MachineIds:       expectIds,
 
2702
                VotingMachineIds: expectIds,
 
2703
        })
 
2704
}
 
2705
 
 
2706
func (s *StateSuite) TestEnsureAvailabilityFailsWithBadCount(c *gc.C) {
 
2707
        for _, n := range []int{-1, 0, 2, 6} {
 
2708
                err := s.State.EnsureAvailability(n, constraints.Value{}, "")
 
2709
                c.Assert(err, gc.ErrorMatches, "number of state servers must be odd and greater than zero")
 
2710
        }
 
2711
        err := s.State.EnsureAvailability(replicaset.MaxPeers+2, constraints.Value{}, "")
 
2712
        c.Assert(err, gc.ErrorMatches, `state server count is too large \(allowed \d+\)`)
 
2713
}
 
2714
 
 
2715
func (s *StateSuite) TestEnsureAvailabilityAddsNewMachines(c *gc.C) {
 
2716
        ids := make([]string, 3)
 
2717
        m0, err := s.State.AddMachine("quantal", state.JobHostUnits, state.JobManageEnviron)
 
2718
        c.Assert(err, gc.IsNil)
 
2719
        ids[0] = m0.Id()
 
2720
 
 
2721
        // Add a non-state-server machine just to make sure.
 
2722
        _, err = s.State.AddMachine("quantal", state.JobHostUnits)
 
2723
        c.Assert(err, gc.IsNil)
 
2724
 
 
2725
        info, err := s.State.StateServerInfo()
 
2726
        c.Assert(err, gc.IsNil)
 
2727
        c.Assert(info, gc.DeepEquals, &state.StateServerInfo{
 
2728
                MachineIds:       []string{m0.Id()},
 
2729
                VotingMachineIds: []string{m0.Id()},
 
2730
        })
 
2731
 
 
2732
        cons := constraints.Value{
 
2733
                Mem: newUint64(100),
 
2734
        }
 
2735
        err = s.State.EnsureAvailability(3, cons, "quantal")
 
2736
        c.Assert(err, gc.IsNil)
 
2737
 
 
2738
        for i := 1; i < 3; i++ {
 
2739
                m, err := s.State.Machine(fmt.Sprint(i + 1))
 
2740
                c.Assert(err, gc.IsNil)
 
2741
                c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{
 
2742
                        state.JobHostUnits,
 
2743
                        state.JobManageEnviron,
 
2744
                })
 
2745
                gotCons, err := m.Constraints()
 
2746
                c.Assert(err, gc.IsNil)
 
2747
                c.Assert(gotCons, gc.DeepEquals, cons)
 
2748
                c.Assert(m.WantsVote(), jc.IsTrue)
 
2749
                ids[i] = m.Id()
 
2750
        }
2516
2751
        sort.Strings(ids)
2517
 
        c.Assert(ids, gc.DeepEquals, expectIds)
2518
2752
 
2519
 
        // Check that it works with the original connection too.
2520
 
        ids, err = state.StateServerMachineIds(s.State)
 
2753
        info, err = s.State.StateServerInfo()
2521
2754
        c.Assert(err, gc.IsNil)
2522
 
        c.Assert(ids, gc.DeepEquals, expectIds)
 
2755
        sort.Strings(info.MachineIds)
 
2756
        sort.Strings(info.VotingMachineIds)
 
2757
        c.Assert(info, gc.DeepEquals, &state.StateServerInfo{
 
2758
                MachineIds:       ids,
 
2759
                VotingMachineIds: ids,
 
2760
        })
 
2761
}
 
2762
 
 
2763
func newUint64(i uint64) *uint64 {
 
2764
        return &i
2523
2765
}