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