github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/provisioner/broker_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner_test 5 6 import ( 7 "io/ioutil" 8 "net" 9 "path/filepath" 10 11 gitjujutesting "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils/arch" 14 "github.com/juju/version" 15 gc "gopkg.in/check.v1" 16 "gopkg.in/juju/names.v2" 17 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/cloudconfig/instancecfg" 20 "github.com/juju/juju/constraints" 21 "github.com/juju/juju/environs" 22 "github.com/juju/juju/instance" 23 instancetest "github.com/juju/juju/instance/testing" 24 jujutesting "github.com/juju/juju/juju/testing" 25 "github.com/juju/juju/network" 26 "github.com/juju/juju/status" 27 coretesting "github.com/juju/juju/testing" 28 coretools "github.com/juju/juju/tools" 29 "github.com/juju/juju/worker/provisioner" 30 ) 31 32 type fakeAddr struct{ value string } 33 34 func (f *fakeAddr) Network() string { return "net" } 35 func (f *fakeAddr) String() string { 36 if f.value != "" { 37 return f.value 38 } 39 return "fakeAddr" 40 } 41 42 var _ net.Addr = (*fakeAddr)(nil) 43 44 type fakeAPI struct { 45 *gitjujutesting.Stub 46 47 fakeContainerConfig params.ContainerConfig 48 fakeInterfaceInfo network.InterfaceInfo 49 } 50 51 var _ provisioner.APICalls = (*fakeAPI)(nil) 52 53 var fakeInterfaceInfo network.InterfaceInfo = network.InterfaceInfo{ 54 DeviceIndex: 0, 55 MACAddress: "aa:bb:cc:dd:ee:ff", 56 CIDR: "0.1.2.0/24", 57 InterfaceName: "dummy0", 58 Address: network.NewAddress("0.1.2.3"), 59 GatewayAddress: network.NewAddress("0.1.2.1"), 60 // Explicitly set only DNSServers, but not DNSSearchDomains to test this is 61 // detected and the latter populated by parsing the fake resolv.conf created 62 // by patchResolvConf(). See LP bug http://pad.lv/1575940 for more info. 63 DNSServers: network.NewAddresses("ns1.dummy"), 64 DNSSearchDomains: nil, 65 } 66 67 var fakeContainerConfig = params.ContainerConfig{ 68 UpdateBehavior: ¶ms.UpdateBehavior{true, true}, 69 ProviderType: "fake", 70 AuthorizedKeys: coretesting.FakeAuthKeys, 71 SSLHostnameVerification: true, 72 } 73 74 func NewFakeAPI() *fakeAPI { 75 return &fakeAPI{ 76 Stub: &gitjujutesting.Stub{}, 77 fakeContainerConfig: fakeContainerConfig, 78 fakeInterfaceInfo: fakeInterfaceInfo, 79 } 80 } 81 82 func (f *fakeAPI) ContainerConfig() (params.ContainerConfig, error) { 83 f.MethodCall(f, "ContainerConfig") 84 if err := f.NextErr(); err != nil { 85 return params.ContainerConfig{}, err 86 } 87 return f.fakeContainerConfig, nil 88 } 89 90 func (f *fakeAPI) PrepareContainerInterfaceInfo(tag names.MachineTag) ([]network.InterfaceInfo, error) { 91 f.MethodCall(f, "PrepareContainerInterfaceInfo", tag) 92 if err := f.NextErr(); err != nil { 93 return nil, err 94 } 95 return []network.InterfaceInfo{f.fakeInterfaceInfo}, nil 96 } 97 98 func (f *fakeAPI) GetContainerInterfaceInfo(tag names.MachineTag) ([]network.InterfaceInfo, error) { 99 f.MethodCall(f, "GetContainerInterfaceInfo", tag) 100 if err := f.NextErr(); err != nil { 101 return nil, err 102 } 103 return []network.InterfaceInfo{f.fakeInterfaceInfo}, nil 104 } 105 106 func (f *fakeAPI) ReleaseContainerAddresses(tag names.MachineTag) error { 107 f.MethodCall(f, "ReleaseContainerAddresses", tag) 108 if err := f.NextErr(); err != nil { 109 return err 110 } 111 return nil 112 } 113 114 type patcher interface { 115 PatchValue(destination, source interface{}) 116 } 117 118 func patchResolvConf(s patcher, c *gc.C) { 119 const fakeConf = ` 120 nameserver ns1.dummy 121 search dummy invalid 122 nameserver ns2.dummy 123 ` 124 125 fakeResolvConf := filepath.Join(c.MkDir(), "fakeresolv.conf") 126 err := ioutil.WriteFile(fakeResolvConf, []byte(fakeConf), 0644) 127 c.Assert(err, jc.ErrorIsNil) 128 s.PatchValue(provisioner.ResolvConf, fakeResolvConf) 129 } 130 131 func instancesFromResults(results ...*environs.StartInstanceResult) []instance.Instance { 132 instances := make([]instance.Instance, len(results)) 133 for i := range results { 134 instances[i] = results[i].Instance 135 } 136 return instances 137 } 138 139 func assertInstancesStarted(c *gc.C, broker environs.InstanceBroker, results ...*environs.StartInstanceResult) { 140 allInstances, err := broker.AllInstances() 141 c.Assert(err, jc.ErrorIsNil) 142 instancetest.MatchInstances(c, allInstances, instancesFromResults(results...)...) 143 } 144 145 func makeInstanceConfig(c *gc.C, s patcher, machineId string) *instancecfg.InstanceConfig { 146 machineNonce := "fake-nonce" 147 // To isolate the tests from the host's architecture, we override it here. 148 s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) 149 apiInfo := jujutesting.FakeAPIInfo(machineId) 150 instanceConfig, err := instancecfg.NewInstanceConfig(coretesting.ControllerTag, machineId, machineNonce, "released", "quantal", apiInfo) 151 c.Assert(err, jc.ErrorIsNil) 152 return instanceConfig 153 } 154 155 func makePossibleTools() coretools.List { 156 return coretools.List{&coretools.Tools{ 157 Version: version.MustParseBinary("2.3.4-quantal-amd64"), 158 URL: "http://tools.testing.invalid/2.3.4-quantal-amd64.tgz", 159 }, { 160 // non-host-arch tools should be filtered out by StartInstance 161 Version: version.MustParseBinary("2.3.4-quantal-arm64"), 162 URL: "http://tools.testing.invalid/2.3.4-quantal-arm64.tgz", 163 }} 164 } 165 166 func makeNoOpStatusCallback() func(settableStatus status.Status, info string, data map[string]interface{}) error { 167 return func(_ status.Status, _ string, _ map[string]interface{}) error { 168 return nil 169 } 170 } 171 172 func callStartInstance(c *gc.C, s patcher, broker environs.InstanceBroker, machineId string) *environs.StartInstanceResult { 173 result, err := broker.StartInstance(environs.StartInstanceParams{ 174 Constraints: constraints.Value{}, 175 Tools: makePossibleTools(), 176 InstanceConfig: makeInstanceConfig(c, s, machineId), 177 StatusCallback: makeNoOpStatusCallback(), 178 }) 179 c.Assert(err, jc.ErrorIsNil) 180 return result 181 } 182 183 func callMaintainInstance(c *gc.C, s patcher, broker environs.InstanceBroker, machineId string) { 184 err := broker.MaintainInstance(environs.StartInstanceParams{ 185 Constraints: constraints.Value{}, 186 Tools: makePossibleTools(), 187 InstanceConfig: makeInstanceConfig(c, s, machineId), 188 StatusCallback: makeNoOpStatusCallback(), 189 }) 190 c.Assert(err, jc.ErrorIsNil) 191 }