github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/cmd/plugins/juju-metadata/imagemetadata_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "strings" 13 14 "github.com/juju/cmd" 15 jc "github.com/juju/testing/checkers" 16 "github.com/juju/utils/series" 17 gc "gopkg.in/check.v1" 18 19 "github.com/juju/juju/cmd/modelcmd" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/jujuclient" 22 "github.com/juju/juju/jujuclient/jujuclienttesting" 23 "github.com/juju/juju/provider/dummy" 24 "github.com/juju/juju/testing" 25 ) 26 27 type ImageMetadataSuite struct { 28 testing.FakeJujuXDGDataHomeSuite 29 environ []string 30 dir string 31 store *jujuclienttesting.MemStore 32 } 33 34 var _ = gc.Suite(&ImageMetadataSuite{}) 35 36 func (s *ImageMetadataSuite) SetUpSuite(c *gc.C) { 37 s.FakeJujuXDGDataHomeSuite.SetUpSuite(c) 38 s.environ = os.Environ() 39 } 40 41 func (s *ImageMetadataSuite) SetUpTest(c *gc.C) { 42 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 43 s.dir = c.MkDir() 44 45 s.store = jujuclienttesting.NewMemStore() 46 cacheTestEnvConfig(c, s.store) 47 48 s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") 49 s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") 50 } 51 52 func runImageMetadata(c *gc.C, store jujuclient.ClientStore, args ...string) (*cmd.Context, error) { 53 cmd := &imageMetadataCommand{} 54 cmd.SetClientStore(store) 55 return testing.RunCommand(c, modelcmd.Wrap(cmd), args...) 56 } 57 58 var seriesVersions map[string]string = map[string]string{ 59 "precise": "12.04", 60 "raring": "13.04", 61 "trusty": "14.04", 62 "xenial": "16.04", 63 } 64 65 type expectedMetadata struct { 66 series string 67 arch string 68 region string 69 endpoint string 70 virtType string 71 storage string 72 } 73 74 func (s *ImageMetadataSuite) assertCommandOutput(c *gc.C, expected expectedMetadata, errOut, indexFileName, imageFileName string) { 75 if expected.region == "" { 76 expected.region = "region" 77 } 78 if expected.endpoint == "" { 79 expected.endpoint = "endpoint" 80 } 81 strippedOut := strings.Replace(errOut, "\n", "", -1) 82 c.Check(strippedOut, gc.Matches, `Image metadata files have been written to.*`) 83 indexpath := filepath.Join(s.dir, "images", "streams", "v1", indexFileName) 84 data, err := ioutil.ReadFile(indexpath) 85 c.Assert(err, jc.ErrorIsNil) 86 content := string(data) 87 var indices interface{} 88 err = json.Unmarshal(data, &indices) 89 c.Assert(err, jc.ErrorIsNil) 90 c.Assert(indices.(map[string]interface{})["format"], gc.Equals, "index:1.0") 91 prodId := fmt.Sprintf("com.ubuntu.cloud:server:%s:%s", seriesVersions[expected.series], expected.arch) 92 c.Assert(content, jc.Contains, prodId) 93 c.Assert(content, jc.Contains, fmt.Sprintf(`"region": %q`, expected.region)) 94 c.Assert(content, jc.Contains, fmt.Sprintf(`"endpoint": %q`, expected.endpoint)) 95 c.Assert(content, jc.Contains, fmt.Sprintf(`"path": "streams/v1/%s"`, imageFileName)) 96 97 imagepath := filepath.Join(s.dir, "images", "streams", "v1", imageFileName) 98 data, err = ioutil.ReadFile(imagepath) 99 c.Assert(err, jc.ErrorIsNil) 100 content = string(data) 101 var images interface{} 102 err = json.Unmarshal(data, &images) 103 c.Assert(err, jc.ErrorIsNil) 104 c.Assert(images.(map[string]interface{})["format"], gc.Equals, "products:1.0") 105 c.Assert(content, jc.Contains, prodId) 106 c.Assert(content, jc.Contains, `"id": "1234"`) 107 if expected.virtType != "" { 108 c.Assert(content, jc.Contains, fmt.Sprintf(`"virt": %q`, expected.virtType)) 109 } 110 if expected.storage != "" { 111 c.Assert(content, jc.Contains, fmt.Sprintf(`"root_store": %q`, expected.storage)) 112 } 113 } 114 115 const ( 116 defaultIndexFileName = "index.json" 117 defaultImageFileName = "com.ubuntu.cloud-released-imagemetadata.json" 118 ) 119 120 func (s *ImageMetadataSuite) TestImageMetadataFilesNoEnv(c *gc.C) { 121 ctx, err := runImageMetadata(c, s.store, 122 "-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint", 123 "-s", "raring", "--virt-type=pv", "--storage=root", 124 ) 125 c.Assert(err, jc.ErrorIsNil) 126 out := testing.Stdout(ctx) 127 expected := expectedMetadata{ 128 series: "raring", 129 arch: "arch", 130 virtType: "pv", 131 storage: "root", 132 } 133 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 134 } 135 136 func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultArch(c *gc.C) { 137 ctx, err := runImageMetadata(c, s.store, 138 "-d", s.dir, "-i", "1234", "-r", "region", "-u", "endpoint", "-s", "raring", 139 ) 140 c.Assert(err, jc.ErrorIsNil) 141 out := testing.Stdout(ctx) 142 expected := expectedMetadata{ 143 series: "raring", 144 arch: "amd64", 145 } 146 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 147 } 148 149 func (s *ImageMetadataSuite) TestImageMetadataFilesLatestLts(c *gc.C) { 150 ec2Config, err := config.New(config.UseDefaults, map[string]interface{}{ 151 "name": "ec2-latest-lts", 152 "type": "ec2", 153 "uuid": testing.ModelTag.Id(), 154 "controller-uuid": testing.ModelTag.Id(), 155 "region": "us-east-1", 156 }) 157 c.Assert(err, jc.ErrorIsNil) 158 s.store.BootstrapConfig["ec2-controller"] = jujuclient.BootstrapConfig{ 159 Cloud: "ec2", 160 CloudRegion: "us-east-1", 161 Config: ec2Config.AllAttrs(), 162 } 163 164 ctx, err := runImageMetadata(c, s.store, 165 "-m", "ec2-controller:ec2-latest-lts", 166 "-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint", 167 ) 168 c.Assert(err, jc.ErrorIsNil) 169 out := testing.Stdout(ctx) 170 expected := expectedMetadata{ 171 series: series.LatestLts(), 172 arch: "arch", 173 } 174 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 175 } 176 177 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnv(c *gc.C) { 178 ctx, err := runImageMetadata(c, s.store, 179 "-d", s.dir, "-m", "ec2-controller:ec2", "-i", "1234", "--virt-type=pv", "--storage=root", 180 ) 181 c.Assert(err, jc.ErrorIsNil) 182 out := testing.Stdout(ctx) 183 expected := expectedMetadata{ 184 series: "precise", 185 arch: "amd64", 186 region: "us-east-1", 187 endpoint: "https://ec2.us-east-1.amazonaws.com", 188 virtType: "pv", 189 storage: "root", 190 } 191 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 192 } 193 194 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithRegionOverride(c *gc.C) { 195 ctx, err := runImageMetadata(c, s.store, 196 "-d", s.dir, "-m", "ec2-controller:ec2", "-r", "us-west-1", "-u", "https://ec2.us-west-1.amazonaws.com", "-i", "1234", 197 ) 198 c.Assert(err, jc.ErrorIsNil) 199 out := testing.Stdout(ctx) 200 expected := expectedMetadata{ 201 series: "precise", 202 arch: "amd64", 203 region: "us-west-1", 204 endpoint: "https://ec2.us-west-1.amazonaws.com", 205 } 206 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 207 } 208 209 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithNoHasRegion(c *gc.C) { 210 ctx, err := runImageMetadata(c, s.store, 211 "-d", s.dir, "-m", "azure-controller:azure", "-r", "region", "-u", "endpoint", "-i", "1234", 212 ) 213 c.Assert(err, jc.ErrorIsNil) 214 out := testing.Stdout(ctx) 215 expected := expectedMetadata{ 216 series: "raring", 217 arch: "amd64", 218 region: "region", 219 endpoint: "endpoint", 220 } 221 s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) 222 } 223 224 type errTestParams struct { 225 args []string 226 } 227 228 var errTests = []errTestParams{ 229 { 230 // Missing image id 231 args: []string{"-r", "region", "-a", "arch", "-u", "endpoint", "-s", "precise"}, 232 }, 233 { 234 // Missing region 235 args: []string{"-i", "1234", "-a", "arch", "-u", "endpoint", "-s", "precise"}, 236 }, 237 { 238 // Missing endpoint 239 args: []string{"-i", "1234", "-u", "endpoint", "-a", "arch", "-s", "precise"}, 240 }, 241 { 242 // Missing endpoint/region for model with no HasRegion interface 243 args: []string{"-i", "1234", "-m", "azure-controller:azure"}, 244 }, 245 } 246 247 func (s *ImageMetadataSuite) TestImageMetadataBadArgs(c *gc.C) { 248 for i, t := range errTests { 249 c.Logf("test: %d", i) 250 _, err := runImageMetadata(c, s.store, t.args...) 251 c.Check(err, gc.NotNil, gc.Commentf("test %d: %s", i, t.args)) 252 dummy.Reset(c) 253 } 254 }