github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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.ControllerTag.Id(),
   155  		"region":          "us-east-1",
   156  	})
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	s.store.BootstrapConfig["ec2-controller"] = jujuclient.BootstrapConfig{
   159  		ControllerConfig: testing.FakeControllerConfig(),
   160  		Cloud:            "ec2",
   161  		CloudRegion:      "us-east-1",
   162  		Config:           ec2Config.AllAttrs(),
   163  	}
   164  
   165  	ctx, err := runImageMetadata(c, s.store,
   166  		"-m", "ec2-controller:ec2-latest-lts",
   167  		"-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint",
   168  	)
   169  	c.Assert(err, jc.ErrorIsNil)
   170  	out := testing.Stdout(ctx)
   171  	expected := expectedMetadata{
   172  		series: series.LatestLts(),
   173  		arch:   "arch",
   174  	}
   175  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   176  }
   177  
   178  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnv(c *gc.C) {
   179  	ctx, err := runImageMetadata(c, s.store,
   180  		"-d", s.dir, "-m", "ec2-controller:ec2", "-i", "1234", "--virt-type=pv", "--storage=root",
   181  	)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	out := testing.Stdout(ctx)
   184  	expected := expectedMetadata{
   185  		series:   "precise",
   186  		arch:     "amd64",
   187  		region:   "us-east-1",
   188  		endpoint: "https://ec2.us-east-1.amazonaws.com",
   189  		virtType: "pv",
   190  		storage:  "root",
   191  	}
   192  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   193  }
   194  
   195  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithRegionOverride(c *gc.C) {
   196  	ctx, err := runImageMetadata(c, s.store,
   197  		"-d", s.dir, "-m", "ec2-controller:ec2", "-r", "us-west-1", "-u", "https://ec2.us-west-1.amazonaws.com", "-i", "1234",
   198  	)
   199  	c.Assert(err, jc.ErrorIsNil)
   200  	out := testing.Stdout(ctx)
   201  	expected := expectedMetadata{
   202  		series:   "precise",
   203  		arch:     "amd64",
   204  		region:   "us-west-1",
   205  		endpoint: "https://ec2.us-west-1.amazonaws.com",
   206  	}
   207  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   208  }
   209  
   210  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithNoHasRegion(c *gc.C) {
   211  	ctx, err := runImageMetadata(c, s.store,
   212  		"-d", s.dir, "-m", "azure-controller:azure", "-r", "region", "-u", "endpoint", "-i", "1234",
   213  	)
   214  	c.Assert(err, jc.ErrorIsNil)
   215  	out := testing.Stdout(ctx)
   216  	expected := expectedMetadata{
   217  		series:   "raring",
   218  		arch:     "amd64",
   219  		region:   "region",
   220  		endpoint: "endpoint",
   221  	}
   222  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   223  }
   224  
   225  type errTestParams struct {
   226  	args []string
   227  }
   228  
   229  var errTests = []errTestParams{
   230  	{
   231  		// Missing image id
   232  		args: []string{"-r", "region", "-a", "arch", "-u", "endpoint", "-s", "precise"},
   233  	},
   234  	{
   235  		// Missing region
   236  		args: []string{"-i", "1234", "-a", "arch", "-u", "endpoint", "-s", "precise"},
   237  	},
   238  	{
   239  		// Missing endpoint
   240  		args: []string{"-i", "1234", "-u", "endpoint", "-a", "arch", "-s", "precise"},
   241  	},
   242  	{
   243  		// Missing endpoint/region for model with no HasRegion interface
   244  		args: []string{"-i", "1234", "-m", "azure-controller:azure"},
   245  	},
   246  }
   247  
   248  func (s *ImageMetadataSuite) TestImageMetadataBadArgs(c *gc.C) {
   249  	for i, t := range errTests {
   250  		c.Logf("test: %d", i)
   251  		_, err := runImageMetadata(c, s.store, t.args...)
   252  		c.Check(err, gc.NotNil, gc.Commentf("test %d: %s", i, t.args))
   253  		dummy.Reset(c)
   254  	}
   255  }