~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/modelcmd/apiopener_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package modelcmd_test
 
5
 
 
6
import (
 
7
        "time"
 
8
 
 
9
        "github.com/juju/errors"
 
10
        jc "github.com/juju/testing/checkers"
 
11
        "github.com/juju/utils/clock"
 
12
        gc "gopkg.in/check.v1"
 
13
 
 
14
        "github.com/juju/juju/api"
 
15
        "github.com/juju/juju/cmd/modelcmd"
 
16
        "github.com/juju/juju/jujuclient"
 
17
)
 
18
 
 
19
type APIOpenerSuite struct {
 
20
        // Don't need any base suites
 
21
}
 
22
 
 
23
var _ = gc.Suite(&APIOpenerSuite{})
 
24
 
 
25
func (*APIOpenerSuite) TestPassthrough(c *gc.C) {
 
26
        var controllerName, modelName string
 
27
        open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
 
28
                controllerName = controllerNameArg
 
29
                modelName = modelNameArg
 
30
                // Lets do the bad thing and return both a connection instance
 
31
                // and an error to check they both come through.
 
32
                return &mockConnection{}, errors.New("boom")
 
33
        }
 
34
        opener := modelcmd.OpenFunc(open)
 
35
        conn, err := opener.Open(nil, "a-name", "b-name")
 
36
        c.Assert(err, gc.ErrorMatches, "boom")
 
37
        c.Assert(conn, gc.NotNil)
 
38
        c.Assert(controllerName, gc.Equals, "a-name")
 
39
        c.Assert(modelName, gc.Equals, "b-name")
 
40
}
 
41
 
 
42
func (*APIOpenerSuite) TestTimoutSuccess(c *gc.C) {
 
43
        var controllerName, modelName string
 
44
        open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
 
45
                controllerName = controllerNameArg
 
46
                modelName = modelNameArg
 
47
                return &mockConnection{}, nil
 
48
        }
 
49
        opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock.WallClock, 10*time.Second)
 
50
        conn, err := opener.Open(nil, "a-name", "b-name")
 
51
        c.Assert(err, jc.ErrorIsNil)
 
52
        c.Assert(conn, gc.NotNil)
 
53
        c.Assert(controllerName, gc.Equals, "a-name")
 
54
        c.Assert(modelName, gc.Equals, "b-name")
 
55
}
 
56
 
 
57
func (*APIOpenerSuite) TestTimoutErrors(c *gc.C) {
 
58
        var controllerName, modelName string
 
59
        open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
 
60
                controllerName = controllerNameArg
 
61
                modelName = modelNameArg
 
62
                return nil, errors.New("boom")
 
63
        }
 
64
        opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock.WallClock, 10*time.Second)
 
65
        conn, err := opener.Open(nil, "a-name", "b-name")
 
66
        c.Assert(err, gc.ErrorMatches, "boom")
 
67
        c.Assert(conn, gc.IsNil)
 
68
        c.Assert(controllerName, gc.Equals, "a-name")
 
69
        c.Assert(modelName, gc.Equals, "b-name")
 
70
}
 
71
 
 
72
func (*APIOpenerSuite) TestTimoutClosesAPIOnTimeout(c *gc.C) {
 
73
        var controllerName, modelName string
 
74
        finished := make(chan struct{})
 
75
        mockConn := &mockConnection{closed: make(chan struct{})}
 
76
        open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
 
77
                <-finished
 
78
                controllerName = controllerNameArg
 
79
                modelName = modelNameArg
 
80
                return mockConn, nil
 
81
        }
 
82
        // have the mock clock only wait a microsecond
 
83
        clock := &mockClock{wait: time.Microsecond}
 
84
        // but tell it to wait five seconds
 
85
        opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock, 5*time.Second)
 
86
        conn, err := opener.Open(nil, "a-name", "b-name")
 
87
        c.Assert(errors.Cause(err), gc.Equals, modelcmd.ErrConnTimedOut)
 
88
        c.Assert(conn, gc.IsNil)
 
89
        // check it was told to wait for 5 seconds
 
90
        c.Assert(clock.duration, gc.Equals, 5*time.Second)
 
91
        // tell the open func to continue now we have timed out
 
92
        close(finished)
 
93
        // wait until the connection has been closed
 
94
        select {
 
95
        case <-mockConn.closed:
 
96
                // continue
 
97
        case <-time.After(5 * time.Second):
 
98
                c.Error("API connection was not closed.")
 
99
        }
 
100
        c.Assert(controllerName, gc.Equals, "a-name")
 
101
        c.Assert(modelName, gc.Equals, "b-name")
 
102
}
 
103
 
 
104
// mockConnection will panic if anything but close is called.
 
105
type mockConnection struct {
 
106
        api.Connection
 
107
 
 
108
        closed chan struct{}
 
109
}
 
110
 
 
111
func (m *mockConnection) Close() error {
 
112
        close(m.closed)
 
113
        return nil
 
114
}
 
115
 
 
116
// mockClock will panic if anything but After is called
 
117
type mockClock struct {
 
118
        clock.Clock
 
119
 
 
120
        wait     time.Duration
 
121
        duration time.Duration
 
122
}
 
123
 
 
124
func (m *mockClock) After(duration time.Duration) <-chan time.Time {
 
125
        m.duration = duration
 
126
        return time.After(m.wait)
 
127
}