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  }