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

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/state/apiserver/client/api_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012, 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package client_test
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        . "launchpad.net/gocheck"
 
9
        "launchpad.net/juju-core/constraints"
 
10
        "launchpad.net/juju-core/environs/config"
 
11
        "launchpad.net/juju-core/errors"
 
12
        "launchpad.net/juju-core/instance"
 
13
        "launchpad.net/juju-core/juju/testing"
 
14
        "launchpad.net/juju-core/state"
 
15
        "launchpad.net/juju-core/state/api"
 
16
        "launchpad.net/juju-core/state/api/params"
 
17
        coretesting "launchpad.net/juju-core/testing"
 
18
        "launchpad.net/juju-core/testing/checkers"
 
19
        stdtesting "testing"
 
20
        "time"
 
21
)
 
22
 
 
23
func TestAll(t *stdtesting.T) {
 
24
        coretesting.MgoTestPackage(t)
 
25
}
 
26
 
 
27
type baseSuite struct {
 
28
        testing.JujuConnSuite
 
29
}
 
30
 
 
31
var _ = Suite(&baseSuite{})
 
32
 
 
33
func chanReadEmpty(c *C, ch <-chan struct{}, what string) bool {
 
34
        select {
 
35
        case _, ok := <-ch:
 
36
                return ok
 
37
        case <-time.After(10 * time.Second):
 
38
                c.Fatalf("timed out reading from %s", what)
 
39
        }
 
40
        panic("unreachable")
 
41
}
 
42
 
 
43
func chanReadStrings(c *C, ch <-chan []string, what string) ([]string, bool) {
 
44
        select {
 
45
        case changes, ok := <-ch:
 
46
                return changes, ok
 
47
        case <-time.After(10 * time.Second):
 
48
                c.Fatalf("timed out reading from %s", what)
 
49
        }
 
50
        panic("unreachable")
 
51
}
 
52
 
 
53
func chanReadConfig(c *C, ch <-chan *config.Config, what string) (*config.Config, bool) {
 
54
        select {
 
55
        case envConfig, ok := <-ch:
 
56
                return envConfig, ok
 
57
        case <-time.After(10 * time.Second):
 
58
                c.Fatalf("timed out reading from %s", what)
 
59
        }
 
60
        panic("unreachable")
 
61
}
 
62
 
 
63
func removeServiceAndUnits(c *C, service *state.Service) {
 
64
        // Destroy all units for the service.
 
65
        units, err := service.AllUnits()
 
66
        c.Assert(err, IsNil)
 
67
        for _, unit := range units {
 
68
                err = unit.EnsureDead()
 
69
                c.Assert(err, IsNil)
 
70
                err = unit.Remove()
 
71
                c.Assert(err, IsNil)
 
72
        }
 
73
        err = service.Destroy()
 
74
        c.Assert(err, IsNil)
 
75
 
 
76
        err = service.Refresh()
 
77
        c.Assert(err, checkers.Satisfies, errors.IsNotFoundError)
 
78
}
 
79
 
 
80
// apiAuthenticator represents a simple authenticator object with only the
 
81
// SetPassword and Tag methods.  This will fit types from both the state
 
82
// and api packages, as those in the api package do not have PasswordValid().
 
83
type apiAuthenticator interface {
 
84
        state.Tagger
 
85
        SetPassword(string) error
 
86
}
 
87
 
 
88
func setDefaultPassword(c *C, e apiAuthenticator) {
 
89
        err := e.SetPassword(defaultPassword(e))
 
90
        c.Assert(err, IsNil)
 
91
}
 
92
 
 
93
func defaultPassword(e apiAuthenticator) string {
 
94
        return e.Tag() + " password"
 
95
}
 
96
 
 
97
type setStatuser interface {
 
98
        SetStatus(status params.Status, info string) error
 
99
}
 
100
 
 
101
func setDefaultStatus(c *C, entity setStatuser) {
 
102
        err := entity.SetStatus(params.StatusStarted, "")
 
103
        c.Assert(err, IsNil)
 
104
}
 
105
 
 
106
func (s *baseSuite) tryOpenState(c *C, e apiAuthenticator, password string) error {
 
107
        stateInfo := s.StateInfo(c)
 
108
        stateInfo.Tag = e.Tag()
 
109
        stateInfo.Password = password
 
110
        st, err := state.Open(stateInfo, state.DialOpts{
 
111
                Timeout: 25 * time.Millisecond,
 
112
        })
 
113
        if err == nil {
 
114
                st.Close()
 
115
        }
 
116
        return err
 
117
}
 
118
 
 
119
// openAs connects to the API state as the given entity
 
120
// with the default password for that entity.
 
121
func (s *baseSuite) openAs(c *C, tag string) *api.State {
 
122
        _, info, err := s.APIConn.Environ.StateInfo()
 
123
        c.Assert(err, IsNil)
 
124
        info.Tag = tag
 
125
        info.Password = fmt.Sprintf("%s password", tag)
 
126
        c.Logf("opening state; entity %q; password %q", info.Tag, info.Password)
 
127
        st, err := api.Open(info, api.DialOpts{})
 
128
        c.Assert(err, IsNil)
 
129
        c.Assert(st, NotNil)
 
130
        return st
 
131
}
 
132
 
 
133
// scenarioStatus describes the expected state
 
134
// of the juju environment set up by setUpScenario.
 
135
var scenarioStatus = &api.Status{
 
136
        Machines: map[string]api.MachineInfo{
 
137
                "0": {
 
138
                        InstanceId: "i-machine-0",
 
139
                },
 
140
                "1": {
 
141
                        InstanceId: "i-machine-1",
 
142
                },
 
143
                "2": {
 
144
                        InstanceId: "i-machine-2",
 
145
                },
 
146
        },
 
147
}
 
148
 
 
149
// setUpScenario makes an environment scenario suitable for
 
150
// testing most kinds of access scenario. It returns
 
151
// a list of all the entities in the scenario.
 
152
//
 
153
// When the scenario is initialized, we have:
 
154
// user-admin
 
155
// user-other
 
156
// machine-0
 
157
//  instance-id="i-machine-0"
 
158
//  nonce="fake_nonce"
 
159
//  jobs=manage-environ
 
160
//  status=started, info=""
 
161
// machine-1
 
162
//  instance-id="i-machine-1"
 
163
//  nonce="fake_nonce"
 
164
//  jobs=host-units
 
165
//  status=started, info=""
 
166
//  constraints=mem=1G
 
167
// machine-2
 
168
//  instance-id="i-machine-2"
 
169
//  nonce="fake_nonce"
 
170
//  jobs=host-units
 
171
//  status=started, info=""
 
172
// service-wordpress
 
173
// service-logging
 
174
// unit-wordpress-0
 
175
//     deployer-name=machine-1
 
176
// unit-logging-0
 
177
//  deployer-name=unit-wordpress-0
 
178
// unit-wordpress-1
 
179
//     deployer-name=machine-2
 
180
// unit-logging-1
 
181
//  deployer-name=unit-wordpress-1
 
182
//
 
183
// The passwords for all returned entities are
 
184
// set to the entity name with a " password" suffix.
 
185
//
 
186
// Note that there is nothing special about machine-0
 
187
// here - it's the environment manager in this scenario
 
188
// just because machine 0 has traditionally been the
 
189
// environment manager (bootstrap machine), so is
 
190
// hopefully easier to remember as such.
 
191
func (s *baseSuite) setUpScenario(c *C) (entities []string) {
 
192
        add := func(e state.Tagger) {
 
193
                entities = append(entities, e.Tag())
 
194
        }
 
195
        u, err := s.State.User("admin")
 
196
        c.Assert(err, IsNil)
 
197
        setDefaultPassword(c, u)
 
198
        add(u)
 
199
 
 
200
        u, err = s.State.AddUser("other", "")
 
201
        c.Assert(err, IsNil)
 
202
        setDefaultPassword(c, u)
 
203
        add(u)
 
204
 
 
205
        m, err := s.State.AddMachine("series", state.JobManageEnviron)
 
206
        c.Assert(err, IsNil)
 
207
        c.Assert(m.Tag(), Equals, "machine-0")
 
208
        err = m.SetProvisioned(instance.Id("i-"+m.Tag()), "fake_nonce", nil)
 
209
        c.Assert(err, IsNil)
 
210
        setDefaultPassword(c, m)
 
211
        setDefaultStatus(c, m)
 
212
        add(m)
 
213
 
 
214
        _, err = s.State.AddService("mysql", s.AddTestingCharm(c, "mysql"))
 
215
        c.Assert(err, IsNil)
 
216
 
 
217
        wordpress, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "wordpress"))
 
218
        c.Assert(err, IsNil)
 
219
 
 
220
        _, err = s.State.AddService("logging", s.AddTestingCharm(c, "logging"))
 
221
        c.Assert(err, IsNil)
 
222
 
 
223
        eps, err := s.State.InferEndpoints([]string{"logging", "wordpress"})
 
224
        c.Assert(err, IsNil)
 
225
        rel, err := s.State.AddRelation(eps...)
 
226
        c.Assert(err, IsNil)
 
227
 
 
228
        for i := 0; i < 2; i++ {
 
229
                wu, err := wordpress.AddUnit()
 
230
                c.Assert(err, IsNil)
 
231
                c.Assert(wu.Tag(), Equals, fmt.Sprintf("unit-wordpress-%d", i))
 
232
                setDefaultPassword(c, wu)
 
233
                add(wu)
 
234
 
 
235
                m, err := s.State.AddMachine("series", state.JobHostUnits)
 
236
                c.Assert(err, IsNil)
 
237
                c.Assert(m.Tag(), Equals, fmt.Sprintf("machine-%d", i+1))
 
238
                if i == 1 {
 
239
                        err = m.SetConstraints(constraints.MustParse("mem=1G"))
 
240
                        c.Assert(err, IsNil)
 
241
                }
 
242
                err = m.SetProvisioned(instance.Id("i-"+m.Tag()), "fake_nonce", nil)
 
243
                c.Assert(err, IsNil)
 
244
                setDefaultPassword(c, m)
 
245
                setDefaultStatus(c, m)
 
246
                add(m)
 
247
 
 
248
                err = wu.AssignToMachine(m)
 
249
                c.Assert(err, IsNil)
 
250
 
 
251
                deployer, ok := wu.DeployerTag()
 
252
                c.Assert(ok, Equals, true)
 
253
                c.Assert(deployer, Equals, fmt.Sprintf("machine-%d", i+1))
 
254
 
 
255
                wru, err := rel.Unit(wu)
 
256
                c.Assert(err, IsNil)
 
257
 
 
258
                // Create the subordinate unit as a side-effect of entering
 
259
                // scope in the principal's relation-unit.
 
260
                err = wru.EnterScope(nil)
 
261
                c.Assert(err, IsNil)
 
262
 
 
263
                lu, err := s.State.Unit(fmt.Sprintf("logging/%d", i))
 
264
                c.Assert(err, IsNil)
 
265
                c.Assert(lu.IsPrincipal(), Equals, false)
 
266
                deployer, ok = lu.DeployerTag()
 
267
                c.Assert(ok, Equals, true)
 
268
                c.Assert(deployer, Equals, fmt.Sprintf("unit-wordpress-%d", i))
 
269
                setDefaultPassword(c, lu)
 
270
                add(lu)
 
271
        }
 
272
        return
 
273
}