OLD | NEW |
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package main | 4 package main |
5 | 5 |
6 import ( | 6 import ( |
| 7 "bytes" |
| 8 "encoding/json" |
7 "fmt" | 9 "fmt" |
8 | 10 |
9 jc "github.com/juju/testing/checkers" | 11 jc "github.com/juju/testing/checkers" |
10 gc "launchpad.net/gocheck" | 12 gc "launchpad.net/gocheck" |
| 13 "launchpad.net/goyaml" |
11 | 14 |
| 15 "launchpad.net/juju-core/cmd" |
12 "launchpad.net/juju-core/cmd/envcmd" | 16 "launchpad.net/juju-core/cmd/envcmd" |
13 "launchpad.net/juju-core/constraints" | 17 "launchpad.net/juju-core/constraints" |
14 jujutesting "launchpad.net/juju-core/juju/testing" | 18 jujutesting "launchpad.net/juju-core/juju/testing" |
15 "launchpad.net/juju-core/state" | 19 "launchpad.net/juju-core/state" |
16 "launchpad.net/juju-core/state/presence" | 20 "launchpad.net/juju-core/state/presence" |
17 coretesting "launchpad.net/juju-core/testing" | 21 coretesting "launchpad.net/juju-core/testing" |
18 ) | 22 ) |
19 | 23 |
20 type EnsureAvailabilitySuite struct { | 24 type EnsureAvailabilitySuite struct { |
21 jujutesting.RepoSuite | 25 jujutesting.RepoSuite |
(...skipping 20 matching lines...) Expand all Loading... |
42 func (s *EnsureAvailabilitySuite) TearDownTest(c *gc.C) { | 46 func (s *EnsureAvailabilitySuite) TearDownTest(c *gc.C) { |
43 // We have to Kill the Pinger before TearDownTest, otherwise the State | 47 // We have to Kill the Pinger before TearDownTest, otherwise the State |
44 // connection is already closed. | 48 // connection is already closed. |
45 if s.machine0Pinger != nil { | 49 if s.machine0Pinger != nil { |
46 s.machine0Pinger.Kill() | 50 s.machine0Pinger.Kill() |
47 s.machine0Pinger = nil | 51 s.machine0Pinger = nil |
48 } | 52 } |
49 s.RepoSuite.TearDownTest(c) | 53 s.RepoSuite.TearDownTest(c) |
50 } | 54 } |
51 | 55 |
52 func runEnsureAvailability(c *gc.C, args ...string) error { | 56 func runEnsureAvailability(c *gc.C, args ...string) (*cmd.Context, error) { |
53 » _, err := coretesting.RunCommand(c, envcmd.Wrap(&EnsureAvailabilityComma
nd{}), args...) | 57 » return coretesting.RunCommand(c, envcmd.Wrap(&EnsureAvailabilityCommand{
}), args...) |
54 » return err | 58 } |
| 59 |
| 60 func stdout(ctx *cmd.Context) string { |
| 61 » return ctx.Stdout.(*bytes.Buffer).String() |
55 } | 62 } |
56 | 63 |
57 func (s *EnsureAvailabilitySuite) TestEnsureAvailability(c *gc.C) { | 64 func (s *EnsureAvailabilitySuite) TestEnsureAvailability(c *gc.C) { |
58 » err := runEnsureAvailability(c, "-n", "1") | 65 » ctx, err := runEnsureAvailability(c, "-n", "1") |
59 c.Assert(err, gc.IsNil) | 66 c.Assert(err, gc.IsNil) |
| 67 c.Assert(stdout(ctx), gc.Equals, "maintaining machines: \"0\"\n\n") |
| 68 |
60 m, err := s.State.Machine("0") | 69 m, err := s.State.Machine("0") |
61 c.Assert(err, gc.IsNil) | 70 c.Assert(err, gc.IsNil) |
62 c.Assert(m.Life(), gc.Equals, state.Alive) | 71 c.Assert(m.Life(), gc.Equals, state.Alive) |
63 c.Assert(m.Series(), gc.DeepEquals, "precise") | 72 c.Assert(m.Series(), gc.DeepEquals, "precise") |
64 mcons, err := m.Constraints() | 73 mcons, err := m.Constraints() |
65 c.Assert(err, gc.IsNil) | 74 c.Assert(err, gc.IsNil) |
66 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) | 75 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) |
67 } | 76 } |
68 | 77 |
| 78 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityFormats(c *gc.C) { |
| 79 type formatTest struct { |
| 80 Name string |
| 81 Unmarshal func(in []byte, out interface{}) (err error) |
| 82 } |
| 83 formats := []formatTest{ |
| 84 formatTest{ |
| 85 Name: "yaml", |
| 86 Unmarshal: goyaml.Unmarshal, |
| 87 }, |
| 88 formatTest{ |
| 89 Name: "json", |
| 90 Unmarshal: json.Unmarshal, |
| 91 }, |
| 92 } |
| 93 |
| 94 expected := map[string][]string{ |
| 95 "maintained": []string{"0"}, |
| 96 } |
| 97 |
| 98 for _, format := range formats { |
| 99 c.Logf("testing format: %s", format.Name) |
| 100 |
| 101 ctx, err := runEnsureAvailability(c, "-n", "1", "--format", form
at.Name) |
| 102 c.Assert(err, gc.IsNil) |
| 103 |
| 104 var result map[string][]string |
| 105 err = format.Unmarshal(ctx.Stdout.(*bytes.Buffer).Bytes(), &resu
lt) |
| 106 c.Assert(err, gc.IsNil) |
| 107 c.Assert(result, gc.DeepEquals, expected) |
| 108 } |
| 109 } |
| 110 |
69 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithSeries(c *gc.C) { | 111 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithSeries(c *gc.C) { |
70 » err := runEnsureAvailability(c, "--series", "series", "-n", "3") | 112 » ctx, err := runEnsureAvailability(c, "--series", "series", "-n", "3") |
71 c.Assert(err, gc.IsNil) | 113 c.Assert(err, gc.IsNil) |
| 114 c.Assert(stdout(ctx), gc.Equals, |
| 115 "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
| 116 |
72 m, err := s.State.Machine("1") | 117 m, err := s.State.Machine("1") |
73 c.Assert(err, gc.IsNil) | 118 c.Assert(err, gc.IsNil) |
74 c.Assert(m.Series(), gc.DeepEquals, "series") | 119 c.Assert(m.Series(), gc.DeepEquals, "series") |
75 } | 120 } |
76 | 121 |
77 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithConstraints(c *gc.C)
{ | 122 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithConstraints(c *gc.C)
{ |
78 » err := runEnsureAvailability(c, "--constraints", "mem=4G", "-n", "3") | 123 » ctx, err := runEnsureAvailability(c, "--constraints", "mem=4G", "-n", "3
") |
79 c.Assert(err, gc.IsNil) | 124 c.Assert(err, gc.IsNil) |
| 125 c.Assert(stdout(ctx), gc.Equals, |
| 126 "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
| 127 |
80 m, err := s.State.Machine("1") | 128 m, err := s.State.Machine("1") |
81 c.Assert(err, gc.IsNil) | 129 c.Assert(err, gc.IsNil) |
82 mcons, err := m.Constraints() | 130 mcons, err := m.Constraints() |
83 c.Assert(err, gc.IsNil) | 131 c.Assert(err, gc.IsNil) |
84 expectedCons := constraints.MustParse("mem=4G") | 132 expectedCons := constraints.MustParse("mem=4G") |
85 c.Assert(mcons, gc.DeepEquals, expectedCons) | 133 c.Assert(mcons, gc.DeepEquals, expectedCons) |
86 } | 134 } |
87 | 135 |
88 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityIdempotent(c *gc.C) { | 136 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityIdempotent(c *gc.C) { |
89 for i := 0; i < 2; i++ { | 137 for i := 0; i < 2; i++ { |
90 » » err := runEnsureAvailability(c, "-n", "1") | 138 » » _, err := runEnsureAvailability(c, "-n", "1") |
91 c.Assert(err, gc.IsNil) | 139 c.Assert(err, gc.IsNil) |
92 } | 140 } |
93 machines, err := s.State.AllMachines() | 141 machines, err := s.State.AllMachines() |
94 c.Assert(err, gc.IsNil) | 142 c.Assert(err, gc.IsNil) |
95 c.Assert(machines, gc.HasLen, 1) | 143 c.Assert(machines, gc.HasLen, 1) |
96 m, err := s.State.Machine("0") | 144 m, err := s.State.Machine("0") |
97 c.Assert(err, gc.IsNil) | 145 c.Assert(err, gc.IsNil) |
98 mcons, err := m.Constraints() | 146 mcons, err := m.Constraints() |
99 c.Assert(err, gc.IsNil) | 147 c.Assert(err, gc.IsNil) |
100 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) | 148 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) |
101 | 149 |
102 // Running ensure-availability with constraints or series | 150 // Running ensure-availability with constraints or series |
103 // will have no effect unless new machines are | 151 // will have no effect unless new machines are |
104 // created. | 152 // created. |
105 » err = runEnsureAvailability(c, "-n", "1", "--constraints", "mem=4G") | 153 » ctx, err := runEnsureAvailability(c, "-n", "1", "--constraints", "mem=4G
") |
| 154 » c.Assert(stdout(ctx), gc.Equals, |
| 155 » » "maintaining machines: \"0\"\n\n") |
| 156 |
106 c.Assert(err, gc.IsNil) | 157 c.Assert(err, gc.IsNil) |
107 m, err = s.State.Machine("0") | 158 m, err = s.State.Machine("0") |
108 c.Assert(err, gc.IsNil) | 159 c.Assert(err, gc.IsNil) |
109 mcons, err = m.Constraints() | 160 mcons, err = m.Constraints() |
110 c.Assert(err, gc.IsNil) | 161 c.Assert(err, gc.IsNil) |
111 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) | 162 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) |
112 } | 163 } |
113 | 164 |
114 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityMultiple(c *gc.C) { | 165 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityMultiple(c *gc.C) { |
115 » err := runEnsureAvailability(c, "-n", "3", "--constraints", "mem=4G") | 166 » ctx, err := runEnsureAvailability(c, "-n", "3", "--constraints", "mem=4G
") |
116 c.Assert(err, gc.IsNil) | 167 c.Assert(err, gc.IsNil) |
| 168 c.Assert(stdout(ctx), gc.Equals, |
| 169 "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
117 | 170 |
118 machines, err := s.State.AllMachines() | 171 machines, err := s.State.AllMachines() |
119 c.Assert(err, gc.IsNil) | 172 c.Assert(err, gc.IsNil) |
120 c.Assert(machines, gc.HasLen, 3) | 173 c.Assert(machines, gc.HasLen, 3) |
121 mcons, err := machines[0].Constraints() | 174 mcons, err := machines[0].Constraints() |
122 c.Assert(err, gc.IsNil) | 175 c.Assert(err, gc.IsNil) |
123 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) | 176 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) |
124 for i := 1; i < 3; i++ { | 177 for i := 1; i < 3; i++ { |
125 mcons, err := machines[i].Constraints() | 178 mcons, err := machines[i].Constraints() |
126 c.Assert(err, gc.IsNil) | 179 c.Assert(err, gc.IsNil) |
127 expectedCons := constraints.MustParse("mem=4G") | 180 expectedCons := constraints.MustParse("mem=4G") |
128 c.Assert(mcons, gc.DeepEquals, expectedCons) | 181 c.Assert(mcons, gc.DeepEquals, expectedCons) |
129 } | 182 } |
130 } | 183 } |
131 | 184 |
132 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityErrors(c *gc.C) { | 185 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityErrors(c *gc.C) { |
133 for _, n := range []int{-1, 2} { | 186 for _, n := range []int{-1, 2} { |
134 » » err := runEnsureAvailability(c, "-n", fmt.Sprint(n)) | 187 » » _, err := runEnsureAvailability(c, "-n", fmt.Sprint(n)) |
135 c.Assert(err, gc.ErrorMatches, "must specify a number of state s
ervers odd and non-negative") | 188 c.Assert(err, gc.ErrorMatches, "must specify a number of state s
ervers odd and non-negative") |
136 } | 189 } |
137 » err := runEnsureAvailability(c, "-n", "3") | 190 » ctx, err := runEnsureAvailability(c, "-n", "3") |
138 c.Assert(err, gc.IsNil) | 191 c.Assert(err, gc.IsNil) |
139 » err = runEnsureAvailability(c, "-n", "1") | 192 » c.Assert(stdout(ctx), gc.Equals, |
| 193 » » "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
| 194 |
| 195 » _, err = runEnsureAvailability(c, "-n", "1") |
140 c.Assert(err, gc.ErrorMatches, "cannot reduce state server count") | 196 c.Assert(err, gc.ErrorMatches, "cannot reduce state server count") |
141 } | 197 } |
142 | 198 |
143 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityAllows0(c *gc.C) { | 199 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityAllows0(c *gc.C) { |
144 » err := runEnsureAvailability(c, "-n", "0") | 200 » ctx, err := runEnsureAvailability(c, "-n", "0") |
145 c.Assert(err, gc.IsNil) | 201 c.Assert(err, gc.IsNil) |
| 202 c.Assert(stdout(ctx), gc.Equals, |
| 203 "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
| 204 |
146 machines, err := s.State.AllMachines() | 205 machines, err := s.State.AllMachines() |
147 c.Assert(err, gc.IsNil) | 206 c.Assert(err, gc.IsNil) |
148 c.Assert(machines, gc.HasLen, 3) | 207 c.Assert(machines, gc.HasLen, 3) |
149 } | 208 } |
150 | 209 |
151 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityDefaultsTo3(c *gc.C) { | 210 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityDefaultsTo3(c *gc.C) { |
152 » err := runEnsureAvailability(c) | 211 » ctx, err := runEnsureAvailability(c) |
153 c.Assert(err, gc.IsNil) | 212 c.Assert(err, gc.IsNil) |
| 213 c.Assert(stdout(ctx), gc.Equals, |
| 214 "maintaining machines: \"0\"\nadding machines: \"1\", \"2\"\n\n"
) |
| 215 |
154 machines, err := s.State.AllMachines() | 216 machines, err := s.State.AllMachines() |
155 c.Assert(err, gc.IsNil) | 217 c.Assert(err, gc.IsNil) |
156 c.Assert(machines, gc.HasLen, 3) | 218 c.Assert(machines, gc.HasLen, 3) |
157 } | 219 } |
OLD | NEW |