1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
package proxyupdater_test
9
jc "github.com/juju/testing/checkers"
10
gc "gopkg.in/check.v1"
11
"gopkg.in/juju/names.v2"
13
"github.com/juju/juju/apiserver/common"
14
"github.com/juju/juju/apiserver/params"
15
"github.com/juju/juju/apiserver/proxyupdater"
16
apiservertesting "github.com/juju/juju/apiserver/testing"
17
"github.com/juju/juju/environs/config"
18
"github.com/juju/juju/network"
19
"github.com/juju/juju/state"
20
coretesting "github.com/juju/juju/testing"
21
"github.com/juju/juju/worker/workertest"
22
"github.com/juju/testing"
25
type ProxyUpdaterSuite struct {
27
apiservertesting.StubNetwork
30
resources *common.Resources
31
authorizer apiservertesting.FakeAuthorizer
32
facade *proxyupdater.ProxyUpdaterAPI
36
var _ = gc.Suite(&ProxyUpdaterSuite{})
38
func (s *ProxyUpdaterSuite) SetUpSuite(c *gc.C) {
39
s.BaseSuite.SetUpSuite(c)
40
s.StubNetwork.SetUpSuite(c)
43
func (s *ProxyUpdaterSuite) SetUpTest(c *gc.C) {
44
s.BaseSuite.SetUpTest(c)
45
s.resources = common.NewResources()
46
s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
47
s.authorizer = apiservertesting.FakeAuthorizer{
48
Tag: names.NewMachineTag("1"),
49
EnvironManager: false,
51
s.tag = names.NewMachineTag("1")
52
s.state = &stubBackend{}
54
s.AddCleanup(func(_ *gc.C) { s.state.Kill() })
57
s.facade, err = proxyupdater.NewAPIWithBacking(s.state, s.resources, s.authorizer)
58
c.Assert(err, jc.ErrorIsNil)
59
c.Assert(s.facade, gc.NotNil)
61
// Shouldn't have any calls yet
62
apiservertesting.CheckMethodCalls(c, s.state.Stub)
65
func (s *ProxyUpdaterSuite) TestWatchForProxyConfigAndAPIHostPortChanges(c *gc.C) {
66
// WatchForProxyConfigAndAPIHostPortChanges combines WatchForModelConfigChanges
67
// and WatchAPIHostPorts. Check that they are both called and we get the
68
result := s.facade.WatchForProxyConfigAndAPIHostPortChanges(s.oneEntity())
69
c.Assert(result.Results, gc.HasLen, 1)
70
c.Assert(result.Results[0].Error, gc.IsNil)
72
s.state.Stub.CheckCallNames(c,
73
"WatchForModelConfigChanges",
77
// Verify the watcher resource was registered.
78
c.Assert(s.resources.Count(), gc.Equals, 1)
79
resource := s.resources.Get(result.Results[0].NotifyWatcherId)
80
watcher, ok := resource.(state.NotifyWatcher)
81
c.Assert(ok, jc.IsTrue)
83
// Verify the initial event was consumed.
85
case <-watcher.Changes():
86
c.Fatalf("initial event never consumed")
87
case <-time.After(coretesting.ShortWait):
91
func (s *ProxyUpdaterSuite) oneEntity() params.Entities {
92
entities := params.Entities{
93
make([]params.Entity, 1),
95
entities.Entities[0].Tag = s.tag.String()
99
func (s *ProxyUpdaterSuite) TestProxyConfig(c *gc.C) {
100
// Check that the ProxyConfig combines data from ModelConfig and APIHostPorts
101
cfg := s.facade.ProxyConfig(s.oneEntity())
103
s.state.Stub.CheckCallNames(c,
108
noProxy := "0.1.2.3,0.1.2.4,0.1.2.5"
110
r := params.ProxyConfigResult{
111
ProxySettings: params.ProxyConfig{
112
HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: noProxy},
113
APTProxySettings: params.ProxyConfig{
114
HTTP: "http://http proxy", HTTPS: "https://https proxy", FTP: "", NoProxy: ""},
116
c.Assert(cfg.Results[0], jc.DeepEquals, r)
119
func (s *ProxyUpdaterSuite) TestProxyConfigExtendsExisting(c *gc.C) {
120
// Check that the ProxyConfig combines data from ModelConfig and APIHostPorts
121
s.state.SetModelConfig(coretesting.Attrs{
122
"http-proxy": "http proxy",
123
"https-proxy": "https proxy",
124
"no-proxy": "9.9.9.9",
126
cfg := s.facade.ProxyConfig(s.oneEntity())
127
s.state.Stub.CheckCallNames(c,
132
expectedNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5,9.9.9.9"
134
c.Assert(cfg.Results[0], jc.DeepEquals, params.ProxyConfigResult{
135
ProxySettings: params.ProxyConfig{
136
HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedNoProxy},
137
APTProxySettings: params.ProxyConfig{
138
HTTP: "http://http proxy", HTTPS: "https://https proxy", FTP: "", NoProxy: ""},
142
func (s *ProxyUpdaterSuite) TestProxyConfigNoDuplicates(c *gc.C) {
143
// Check that the ProxyConfig combines data from ModelConfig and APIHostPorts
144
s.state.SetModelConfig(coretesting.Attrs{
145
"http-proxy": "http proxy",
146
"https-proxy": "https proxy",
147
"no-proxy": "0.1.2.3",
149
cfg := s.facade.ProxyConfig(s.oneEntity())
150
s.state.Stub.CheckCallNames(c,
155
expectedNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5"
157
c.Assert(cfg.Results[0], jc.DeepEquals, params.ProxyConfigResult{
158
ProxySettings: params.ProxyConfig{
159
HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedNoProxy},
160
APTProxySettings: params.ProxyConfig{
161
HTTP: "http://http proxy", HTTPS: "https://https proxy", FTP: "", NoProxy: ""},
165
type stubBackend struct {
168
EnvConfig *config.Config
170
configAttrs coretesting.Attrs
171
hpWatcher workertest.NotAWatcher
172
confWatcher workertest.NotAWatcher
175
func (sb *stubBackend) SetUp(c *gc.C) {
176
sb.Stub = &testing.Stub{}
178
sb.configAttrs = coretesting.Attrs{
179
"http-proxy": "http proxy",
180
"https-proxy": "https proxy",
182
sb.hpWatcher = workertest.NewFakeWatcher(1, 1)
183
sb.confWatcher = workertest.NewFakeWatcher(1, 1)
186
func (sb *stubBackend) Kill() {
188
sb.confWatcher.Kill()
191
func (sb *stubBackend) SetModelConfig(ca coretesting.Attrs) {
195
func (sb *stubBackend) ModelConfig() (*config.Config, error) {
196
sb.MethodCall(sb, "ModelConfig")
197
if err := sb.NextErr(); err != nil {
200
return coretesting.CustomModelConfig(sb.c, sb.configAttrs), nil
203
func (sb *stubBackend) APIHostPorts() ([][]network.HostPort, error) {
204
sb.MethodCall(sb, "APIHostPorts")
205
if err := sb.NextErr(); err != nil {
208
hps := [][]network.HostPort{
209
network.NewHostPorts(1234, "0.1.2.3"),
210
network.NewHostPorts(1234, "0.1.2.4"),
211
network.NewHostPorts(1234, "0.1.2.5"),
216
func (sb *stubBackend) WatchAPIHostPorts() state.NotifyWatcher {
217
sb.MethodCall(sb, "WatchAPIHostPorts")
221
func (sb *stubBackend) WatchForModelConfigChanges() state.NotifyWatcher {
222
sb.MethodCall(sb, "WatchForModelConfigChanges")
223
return sb.confWatcher