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