github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/ec2/image_test.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 import ( 7 jc "github.com/juju/testing/checkers" 8 "github.com/juju/utils/series" 9 gc "gopkg.in/check.v1" 10 11 "github.com/juju/juju/constraints" 12 "github.com/juju/juju/environs/imagemetadata" 13 imagetesting "github.com/juju/juju/environs/imagemetadata/testing" 14 "github.com/juju/juju/environs/instances" 15 sstesting "github.com/juju/juju/environs/simplestreams/testing" 16 "github.com/juju/juju/juju" 17 "github.com/juju/juju/testing" 18 ) 19 20 var _ = gc.Suite(&specSuite{}) 21 22 type specSuite struct { 23 testing.BaseSuite 24 sstesting.TestDataSuite 25 } 26 27 func (s *specSuite) SetUpSuite(c *gc.C) { 28 s.BaseSuite.SetUpSuite(c) 29 s.TestDataSuite.SetUpSuite(c) 30 31 imagetesting.PatchOfficialDataSources(&s.CleanupSuite, "test:") 32 s.PatchValue(&imagemetadata.SimplestreamsImagesPublicKey, sstesting.SignedMetadataPublicKey) 33 s.PatchValue(&juju.JujuPublicKey, sstesting.SignedMetadataPublicKey) 34 35 UseTestImageData(c, TestImagesData) 36 UseTestInstanceTypeData(TestInstanceTypeCosts) 37 UseTestRegionData(TestRegions) 38 } 39 40 func (s *specSuite) TearDownSuite(c *gc.C) { 41 UseTestInstanceTypeData(nil) 42 UseTestImageData(c, nil) 43 UseTestRegionData(nil) 44 s.TestDataSuite.TearDownSuite(c) 45 s.BaseSuite.TearDownSuite(c) 46 } 47 48 var findInstanceSpecTests = []struct { 49 series string 50 arches []string 51 cons string 52 itype string 53 image string 54 storage []string 55 }{ 56 { 57 series: testing.FakeDefaultSeries, 58 arches: both, 59 itype: "m3.medium", 60 image: "ami-00000033", 61 }, { 62 series: "quantal", 63 arches: []string{"i386"}, 64 itype: "c1.medium", 65 image: "ami-01000034", 66 }, { 67 series: testing.FakeDefaultSeries, 68 arches: both, 69 cons: "cpu-cores=4", 70 itype: "m3.xlarge", 71 image: "ami-00000033", 72 }, { 73 series: testing.FakeDefaultSeries, 74 arches: both, 75 cons: "cpu-cores=2 arch=i386", 76 itype: "c1.medium", 77 image: "ami-00000034", 78 }, { 79 series: testing.FakeDefaultSeries, 80 arches: both, 81 cons: "mem=10G", 82 itype: "m3.xlarge", 83 image: "ami-00000033", 84 }, { 85 series: testing.FakeDefaultSeries, 86 arches: both, 87 cons: "mem=", 88 itype: "m3.medium", 89 image: "ami-00000033", 90 }, { 91 series: testing.FakeDefaultSeries, 92 arches: both, 93 cons: "cpu-power=", 94 itype: "m3.medium", 95 image: "ami-00000033", 96 }, { 97 series: testing.FakeDefaultSeries, 98 arches: both, 99 cons: "cpu-power=800", 100 itype: "m3.xlarge", 101 image: "ami-00000033", 102 }, { 103 series: testing.FakeDefaultSeries, 104 arches: both, 105 cons: "cpu-power=500 arch=i386", 106 itype: "c1.medium", 107 image: "ami-00000034", 108 }, { 109 series: testing.FakeDefaultSeries, 110 arches: []string{"i386"}, 111 cons: "cpu-power=400", 112 itype: "c1.medium", 113 image: "ami-00000034", 114 }, { 115 series: "quantal", 116 arches: both, 117 cons: "arch=amd64", 118 itype: "cc2.8xlarge", 119 image: "ami-01000035", 120 }, { 121 series: "quantal", 122 arches: both, 123 cons: "instance-type=cc2.8xlarge", 124 itype: "cc2.8xlarge", 125 image: "ami-01000035", 126 }, { 127 series: testing.FakeDefaultSeries, 128 arches: []string{"i386"}, 129 cons: "instance-type=c1.medium", 130 itype: "c1.medium", 131 image: "ami-00000034", 132 }, { 133 series: testing.FakeDefaultSeries, 134 arches: []string{"amd64"}, 135 cons: "instance-type=m1.medium cpu-power=200", 136 itype: "m1.medium", 137 image: "ami-00000033", 138 }, { 139 series: testing.FakeDefaultSeries, 140 arches: both, 141 cons: "mem=2G root-disk=16384M", 142 itype: "m3.medium", 143 image: "ami-00000033", 144 }, { 145 series: testing.FakeDefaultSeries, 146 arches: both, 147 cons: "mem=4G root-disk=16384M", 148 itype: "m3.large", 149 storage: []string{"ssd", "ebs"}, 150 image: "ami-00000033", 151 }, { 152 series: testing.FakeDefaultSeries, 153 arches: both, 154 cons: "mem=4G root-disk=16384M", 155 itype: "m3.large", 156 storage: []string{"ebs", "ssd"}, 157 image: "ami-00000039", 158 }, { 159 series: testing.FakeDefaultSeries, 160 arches: both, 161 cons: "mem=4G root-disk=16384M", 162 itype: "m3.large", 163 storage: []string{"ebs"}, 164 image: "ami-00000039", 165 }, 166 } 167 168 func (s *specSuite) TestFindInstanceSpec(c *gc.C) { 169 for i, test := range findInstanceSpecTests { 170 c.Logf("\ntest %d: %q; %q; %q; %v", i, test.series, test.arches, test.cons, test.storage) 171 stor := test.storage 172 if len(stor) == 0 { 173 stor = []string{ssdStorage, ebsStorage} 174 } 175 // We need to filter the image metadata to the test's 176 // arches and series; the provisioner and bootstrap 177 // code will do this. 178 imageMetadata := filterImageMetadata( 179 c, TestImageMetadata, test.series, test.arches, 180 ) 181 spec, err := findInstanceSpec( 182 imageMetadata, 183 &instances.InstanceConstraint{ 184 Region: "test", 185 Series: test.series, 186 Arches: test.arches, 187 Constraints: constraints.MustParse(test.cons), 188 Storage: stor, 189 }) 190 c.Assert(err, jc.ErrorIsNil) 191 c.Check(spec.InstanceType.Name, gc.Equals, test.itype) 192 c.Check(spec.Image.Id, gc.Equals, test.image) 193 } 194 } 195 196 func (s *specSuite) TestFindInstanceSpecNotSetCpuPowerWhenInstanceTypeSet(c *gc.C) { 197 198 instanceConstraint := &instances.InstanceConstraint{ 199 Region: "test", 200 Series: testing.FakeDefaultSeries, 201 Constraints: constraints.MustParse("instance-type=t2.medium"), 202 } 203 204 c.Check(instanceConstraint.Constraints.CpuPower, gc.IsNil) 205 findInstanceSpec(TestImageMetadata, instanceConstraint) 206 207 c.Check(instanceConstraint.Constraints.CpuPower, gc.IsNil) 208 } 209 210 var findInstanceSpecErrorTests = []struct { 211 series string 212 arches []string 213 cons string 214 err string 215 }{ 216 { 217 series: testing.FakeDefaultSeries, 218 arches: []string{"arm"}, 219 err: `no "trusty" images in test with arches \[arm\]`, 220 }, { 221 series: "raring", 222 arches: both, 223 cons: "mem=4G", 224 err: `no "raring" images in test matching instance types \[m3.large m3.xlarge c1.xlarge m3.2xlarge cc2.8xlarge\]`, 225 }, { 226 series: testing.FakeDefaultSeries, 227 arches: both, 228 cons: "instance-type=m1.small mem=4G", 229 err: `no instance types in test matching constraints "instance-type=m1.small mem=4096M"`, 230 }, 231 } 232 233 func (s *specSuite) TestFindInstanceSpecErrors(c *gc.C) { 234 for i, t := range findInstanceSpecErrorTests { 235 c.Logf("test %d", i) 236 // We need to filter the image metadata to the test's 237 // arches and series; the provisioner and bootstrap 238 // code will do this. 239 imageMetadata := filterImageMetadata( 240 c, TestImageMetadata, t.series, t.arches, 241 ) 242 _, err := findInstanceSpec( 243 imageMetadata, 244 &instances.InstanceConstraint{ 245 Region: "test", 246 Series: t.series, 247 Arches: t.arches, 248 Constraints: constraints.MustParse(t.cons), 249 }) 250 c.Check(err, gc.ErrorMatches, t.err) 251 } 252 } 253 254 func filterImageMetadata( 255 c *gc.C, 256 in []*imagemetadata.ImageMetadata, 257 filterSeries string, filterArches []string, 258 ) []*imagemetadata.ImageMetadata { 259 var imageMetadata []*imagemetadata.ImageMetadata 260 for _, im := range in { 261 version, err := series.SeriesVersion(filterSeries) 262 c.Assert(err, jc.ErrorIsNil) 263 if im.Version != version { 264 continue 265 } 266 match := false 267 for _, arch := range filterArches { 268 match = match || im.Arch == arch 269 } 270 if match { 271 imageMetadata = append(imageMetadata, im) 272 } 273 } 274 return imageMetadata 275 } 276 277 func (*specSuite) TestFilterImagesAcceptsNil(c *gc.C) { 278 c.Check(filterImages(nil, nil), gc.HasLen, 0) 279 } 280 281 func (*specSuite) TestFilterImagesReturnsSelectively(c *gc.C) { 282 good := imagemetadata.ImageMetadata{Id: "good", Storage: "ebs"} 283 bad := imagemetadata.ImageMetadata{Id: "bad", Storage: "ftp"} 284 input := []*imagemetadata.ImageMetadata{&good, &bad} 285 expectation := []*imagemetadata.ImageMetadata{&good} 286 287 ic := &instances.InstanceConstraint{Storage: []string{"ebs"}} 288 c.Check(filterImages(input, ic), gc.DeepEquals, expectation) 289 } 290 291 func (*specSuite) TestFilterImagesMaintainsOrdering(c *gc.C) { 292 input := []*imagemetadata.ImageMetadata{ 293 {Id: "one", Storage: "ebs"}, 294 {Id: "two", Storage: "ebs"}, 295 {Id: "three", Storage: "ebs"}, 296 } 297 ic := &instances.InstanceConstraint{Storage: []string{"ebs"}} 298 c.Check(filterImages(input, ic), gc.DeepEquals, input) 299 }