github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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/envcmd"
    19  	"github.com/juju/juju/environs/config"
    20  	"github.com/juju/juju/provider/dummy"
    21  	"github.com/juju/juju/testing"
    22  )
    23  
    24  type ImageMetadataSuite struct {
    25  	testing.FakeJujuHomeSuite
    26  	environ []string
    27  	dir     string
    28  }
    29  
    30  var _ = gc.Suite(&ImageMetadataSuite{})
    31  
    32  func (s *ImageMetadataSuite) SetUpSuite(c *gc.C) {
    33  	s.FakeJujuHomeSuite.SetUpSuite(c)
    34  	s.environ = os.Environ()
    35  }
    36  
    37  var testCert = `
    38  -----BEGIN PRIVATE KEY-----
    39  MIIBCgIBADANBgkqhkiG9w0BAQEFAASB9TCB8gIBAAIxAKQGQxP1i0VfCWn4KmMP
    40  taUFn8sMBKjP/9vHnUYdZRvvmoJCA1C6arBUDp8s2DNX+QIDAQABAjBLRqhwN4dU
    41  LfqHDKJ/Vg1aD8u3Buv4gYRBxdFR5PveyqHSt5eJ4g/x/4ndsvr2OqUCGQDNfNlD
    42  zxHCiEAwZZAPaAkn8jDkFupTljcCGQDMWCujiVZ1NNuBD/N32Yt8P9JDiNzZa08C
    43  GBW7VXLxbExpgnhb1V97vjQmTfthXQjYAwIYSTEjoFXm4+Bk5xuBh2IidgSeGZaC
    44  FFY9AhkAsteo31cyQw2xJ80SWrmsIw+ps7Cvt5W9
    45  -----END PRIVATE KEY-----
    46  -----BEGIN CERTIFICATE-----
    47  MIIBDzCByqADAgECAgkAgIBb3+lSwzEwDQYJKoZIhvcNAQEFBQAwFTETMBEGA1UE
    48  AxQKQEhvc3ROYW1lQDAeFw0xMzA3MTkxNjA1NTRaFw0yMzA3MTcxNjA1NTRaMBUx
    49  EzARBgNVBAMUCkBIb3N0TmFtZUAwTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEApAZD
    50  E/WLRV8JafgqYw+1pQWfywwEqM//28edRh1lG++agkIDULpqsFQOnyzYM1f5AgMB
    51  AAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADMQABKfn08tKfzzqMMD2w
    52  PI2fs3bw5bRH8tmGjrsJeEdp9crCBS8I3hKcxCkTTRTowdY=
    53  -----END CERTIFICATE-----
    54  `
    55  
    56  func (s *ImageMetadataSuite) SetUpTest(c *gc.C) {
    57  	s.FakeJujuHomeSuite.SetUpTest(c)
    58  	s.dir = c.MkDir()
    59  	// Create a fake certificate so azure test environment can be opened.
    60  	certfile, err := ioutil.TempFile(s.dir, "")
    61  	c.Assert(err, jc.ErrorIsNil)
    62  	filename := certfile.Name()
    63  	err = ioutil.WriteFile(filename, []byte(testCert), 0644)
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	envConfig := strings.Replace(metadataTestEnvConfig, "/home/me/azure.pem", filename, -1)
    66  	testing.WriteEnvironments(c, envConfig)
    67  	s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access")
    68  	s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret")
    69  }
    70  
    71  var seriesVersions map[string]string = map[string]string{
    72  	"precise": "12.04",
    73  	"raring":  "13.04",
    74  	"trusty":  "14.04",
    75  }
    76  
    77  type expectedMetadata struct {
    78  	series   string
    79  	arch     string
    80  	region   string
    81  	endpoint string
    82  	virtType string
    83  	storage  string
    84  }
    85  
    86  func (s *ImageMetadataSuite) assertCommandOutput(c *gc.C, expected expectedMetadata, errOut, indexFileName, imageFileName string) {
    87  	if expected.region == "" {
    88  		expected.region = "region"
    89  	}
    90  	if expected.endpoint == "" {
    91  		expected.endpoint = "endpoint"
    92  	}
    93  	strippedOut := strings.Replace(errOut, "\n", "", -1)
    94  	c.Check(strippedOut, gc.Matches, `Image metadata files have been written to.*`)
    95  	indexpath := filepath.Join(s.dir, "images", "streams", "v1", indexFileName)
    96  	data, err := ioutil.ReadFile(indexpath)
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	content := string(data)
    99  	var indices interface{}
   100  	err = json.Unmarshal(data, &indices)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	c.Assert(indices.(map[string]interface{})["format"], gc.Equals, "index:1.0")
   103  	prodId := fmt.Sprintf("com.ubuntu.cloud:server:%s:%s", seriesVersions[expected.series], expected.arch)
   104  	c.Assert(content, jc.Contains, prodId)
   105  	c.Assert(content, jc.Contains, fmt.Sprintf(`"region": %q`, expected.region))
   106  	c.Assert(content, jc.Contains, fmt.Sprintf(`"endpoint": %q`, expected.endpoint))
   107  	c.Assert(content, jc.Contains, fmt.Sprintf(`"path": "streams/v1/%s"`, imageFileName))
   108  
   109  	imagepath := filepath.Join(s.dir, "images", "streams", "v1", imageFileName)
   110  	data, err = ioutil.ReadFile(imagepath)
   111  	c.Assert(err, jc.ErrorIsNil)
   112  	content = string(data)
   113  	var images interface{}
   114  	err = json.Unmarshal(data, &images)
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	c.Assert(images.(map[string]interface{})["format"], gc.Equals, "products:1.0")
   117  	c.Assert(content, jc.Contains, prodId)
   118  	c.Assert(content, jc.Contains, `"id": "1234"`)
   119  	if expected.virtType != "" {
   120  		c.Assert(content, jc.Contains, fmt.Sprintf(`"virt": %q`, expected.virtType))
   121  	}
   122  	if expected.storage != "" {
   123  		c.Assert(content, jc.Contains, fmt.Sprintf(`"root_store": %q`, expected.storage))
   124  	}
   125  }
   126  
   127  const (
   128  	defaultIndexFileName = "index.json"
   129  	defaultImageFileName = "com.ubuntu.cloud-released-imagemetadata.json"
   130  )
   131  
   132  func (s *ImageMetadataSuite) TestImageMetadataFilesNoEnv(c *gc.C) {
   133  	ctx := testing.Context(c)
   134  	code := cmd.Main(
   135  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
   136  			"-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint", "-s", "raring", "--virt-type=pv", "--storage=root"})
   137  	c.Assert(code, gc.Equals, 0)
   138  	out := testing.Stdout(ctx)
   139  	expected := expectedMetadata{
   140  		series:   "raring",
   141  		arch:     "arch",
   142  		virtType: "pv",
   143  		storage:  "root",
   144  	}
   145  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   146  }
   147  
   148  func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultArch(c *gc.C) {
   149  	ctx := testing.Context(c)
   150  	code := cmd.Main(
   151  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
   152  			"-d", s.dir, "-i", "1234", "-r", "region", "-u", "endpoint", "-s", "raring"})
   153  	c.Assert(code, gc.Equals, 0)
   154  	out := testing.Stdout(ctx)
   155  	expected := expectedMetadata{
   156  		series: "raring",
   157  		arch:   "amd64",
   158  	}
   159  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   160  }
   161  
   162  func (s *ImageMetadataSuite) TestImageMetadataFilesLatestLts(c *gc.C) {
   163  	envConfig := strings.Replace(metadataTestEnvConfig, "default-series: precise", "", -1)
   164  	testing.WriteEnvironments(c, envConfig)
   165  	ctx := testing.Context(c)
   166  	code := cmd.Main(
   167  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
   168  			"-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint"})
   169  	c.Assert(code, gc.Equals, 0)
   170  	out := testing.Stdout(ctx)
   171  	expected := expectedMetadata{
   172  		series: config.LatestLtsSeries(),
   173  		arch:   "arch",
   174  	}
   175  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   176  }
   177  
   178  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnv(c *gc.C) {
   179  	ctx := testing.Context(c)
   180  	code := cmd.Main(
   181  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{"-d", s.dir, "-e", "ec2", "-i", "1234", "--virt-type=pv", "--storage=root"})
   182  	c.Assert(code, gc.Equals, 0)
   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 := testing.Context(c)
   197  	code := cmd.Main(
   198  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
   199  			"-d", s.dir, "-e", "ec2", "-r", "us-west-1", "-u", "https://ec2.us-west-1.amazonaws.com", "-i", "1234"})
   200  	c.Assert(code, gc.Equals, 0)
   201  	out := testing.Stdout(ctx)
   202  	expected := expectedMetadata{
   203  		series:   "precise",
   204  		arch:     "amd64",
   205  		region:   "us-west-1",
   206  		endpoint: "https://ec2.us-west-1.amazonaws.com",
   207  	}
   208  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   209  }
   210  
   211  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithNoHasRegion(c *gc.C) {
   212  	ctx := testing.Context(c)
   213  	code := cmd.Main(
   214  		envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
   215  			"-d", s.dir, "-e", "azure", "-r", "region", "-u", "endpoint", "-i", "1234"})
   216  	c.Assert(code, gc.Equals, 0)
   217  	out := testing.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 environment with no HasRegion interface
   246  		args: []string{"-i", "1234", "-e", "azure"},
   247  	},
   248  }
   249  
   250  func (s *ImageMetadataSuite) TestImageMetadataBadArgs(c *gc.C) {
   251  	testing.MakeSampleJujuHome(c)
   252  	s.AddCleanup(func(*gc.C) {
   253  		dummy.Reset()
   254  	})
   255  	for i, t := range errTests {
   256  		c.Logf("test: %d", i)
   257  		ctx := testing.Context(c)
   258  		code := cmd.Main(envcmd.Wrap(&ImageMetadataCommand{}), ctx, t.args)
   259  		c.Check(code, gc.Equals, 1)
   260  	}
   261  }