launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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  	gc "launchpad.net/gocheck"
    15  
    16  	"launchpad.net/juju-core/cmd"
    17  	"launchpad.net/juju-core/testing"
    18  	jc "launchpad.net/juju-core/testing/checkers"
    19  	"launchpad.net/juju-core/testing/testbase"
    20  )
    21  
    22  type ImageMetadataSuite struct {
    23  	testbase.LoggingSuite
    24  	environ []string
    25  	home    *testing.FakeHome
    26  	dir     string
    27  }
    28  
    29  var _ = gc.Suite(&ImageMetadataSuite{})
    30  
    31  func (s *ImageMetadataSuite) SetUpSuite(c *gc.C) {
    32  	s.LoggingSuite.SetUpSuite(c)
    33  	s.environ = os.Environ()
    34  }
    35  
    36  func (s *ImageMetadataSuite) SetUpTest(c *gc.C) {
    37  	s.LoggingSuite.SetUpTest(c)
    38  	os.Clearenv()
    39  	s.dir = c.MkDir()
    40  	// Create a fake certificate so azure test environment can be opened.
    41  	certfile, err := ioutil.TempFile(s.dir, "")
    42  	c.Assert(err, gc.IsNil)
    43  	filename := certfile.Name()
    44  	err = ioutil.WriteFile(filename, []byte("test certificate"), 0644)
    45  	c.Assert(err, gc.IsNil)
    46  	envConfig := strings.Replace(metadataTestEnvConfig, "/home/me/azure.pem", filename, -1)
    47  	s.home = testing.MakeFakeHome(c, envConfig)
    48  	s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access")
    49  	s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret")
    50  }
    51  
    52  func (s *ImageMetadataSuite) TearDownTest(c *gc.C) {
    53  	for _, envstring := range s.environ {
    54  		kv := strings.SplitN(envstring, "=", 2)
    55  		os.Setenv(kv[0], kv[1])
    56  	}
    57  	s.home.Restore()
    58  	s.LoggingSuite.TearDownTest(c)
    59  }
    60  
    61  var seriesVersions map[string]string = map[string]string{
    62  	"precise": "12.04",
    63  	"raring":  "13.04",
    64  }
    65  
    66  type expectedMetadata struct {
    67  	series   string
    68  	arch     string
    69  	region   string
    70  	endpoint 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, gc.IsNil)
    85  	content := string(data)
    86  	var indices interface{}
    87  	err = json.Unmarshal(data, &indices)
    88  	c.Assert(err, gc.IsNil)
    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, gc.IsNil)
    99  	content = string(data)
   100  	var images interface{}
   101  	err = json.Unmarshal(data, &images)
   102  	c.Assert(err, gc.IsNil)
   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  }
   107  
   108  const (
   109  	defaultIndexFileName = "index.json"
   110  	defaultImageFileName = "com.ubuntu.cloud:released:imagemetadata.json"
   111  )
   112  
   113  func (s *ImageMetadataSuite) TestImageMetadataFilesNoEnv(c *gc.C) {
   114  	ctx := testing.Context(c)
   115  	code := cmd.Main(
   116  		&ImageMetadataCommand{}, ctx, []string{
   117  			"-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint", "-s", "raring"})
   118  	c.Assert(code, gc.Equals, 0)
   119  	out := testing.Stdout(ctx)
   120  	expected := expectedMetadata{
   121  		series: "raring",
   122  		arch:   "arch",
   123  	}
   124  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   125  }
   126  
   127  func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultArch(c *gc.C) {
   128  	ctx := testing.Context(c)
   129  	code := cmd.Main(
   130  		&ImageMetadataCommand{}, ctx, []string{
   131  			"-d", s.dir, "-i", "1234", "-r", "region", "-u", "endpoint", "-s", "raring"})
   132  	c.Assert(code, gc.Equals, 0)
   133  	out := testing.Stdout(ctx)
   134  	expected := expectedMetadata{
   135  		series: "raring",
   136  		arch:   "amd64",
   137  	}
   138  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   139  }
   140  
   141  func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultSeries(c *gc.C) {
   142  	ctx := testing.Context(c)
   143  	code := cmd.Main(
   144  		&ImageMetadataCommand{}, ctx, []string{
   145  			"-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint"})
   146  	c.Assert(code, gc.Equals, 0)
   147  	out := testing.Stdout(ctx)
   148  	expected := expectedMetadata{
   149  		series: "precise",
   150  		arch:   "arch",
   151  	}
   152  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   153  }
   154  
   155  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnv(c *gc.C) {
   156  	ctx := testing.Context(c)
   157  	code := cmd.Main(
   158  		&ImageMetadataCommand{}, ctx, []string{"-d", s.dir, "-e", "ec2", "-i", "1234"})
   159  	c.Assert(code, gc.Equals, 0)
   160  	out := testing.Stdout(ctx)
   161  	expected := expectedMetadata{
   162  		series:   "precise",
   163  		arch:     "amd64",
   164  		region:   "us-east-1",
   165  		endpoint: "https://ec2.us-east-1.amazonaws.com",
   166  	}
   167  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   168  }
   169  
   170  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithRegionOverride(c *gc.C) {
   171  	ctx := testing.Context(c)
   172  	code := cmd.Main(
   173  		&ImageMetadataCommand{}, ctx, []string{
   174  			"-d", s.dir, "-e", "ec2", "-r", "us-west-1", "-u", "https://ec2.us-west-1.amazonaws.com", "-i", "1234"})
   175  	c.Assert(code, gc.Equals, 0)
   176  	out := testing.Stdout(ctx)
   177  	expected := expectedMetadata{
   178  		series:   "precise",
   179  		arch:     "amd64",
   180  		region:   "us-west-1",
   181  		endpoint: "https://ec2.us-west-1.amazonaws.com",
   182  	}
   183  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   184  }
   185  
   186  func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithNoHasRegion(c *gc.C) {
   187  	ctx := testing.Context(c)
   188  	code := cmd.Main(
   189  		&ImageMetadataCommand{}, ctx, []string{
   190  			"-d", s.dir, "-e", "azure", "-r", "region", "-u", "endpoint", "-i", "1234"})
   191  	c.Assert(code, gc.Equals, 0)
   192  	out := testing.Stdout(ctx)
   193  	expected := expectedMetadata{
   194  		series:   "raring",
   195  		arch:     "amd64",
   196  		region:   "region",
   197  		endpoint: "endpoint",
   198  	}
   199  	s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName)
   200  }
   201  
   202  type errTestParams struct {
   203  	args []string
   204  }
   205  
   206  var errTests = []errTestParams{
   207  	{
   208  		// Missing image id
   209  		args: []string{"-r", "region", "-a", "arch", "-u", "endpoint", "-s", "precise"},
   210  	},
   211  	{
   212  		// Missing region
   213  		args: []string{"-i", "1234", "-a", "arch", "-u", "endpoint", "-s", "precise"},
   214  	},
   215  	{
   216  		// Missing endpoint
   217  		args: []string{"-i", "1234", "-u", "endpoint", "-a", "arch", "-s", "precise"},
   218  	},
   219  	{
   220  		// Missing endpoint/region for environment with no HasRegion interface
   221  		args: []string{"-i", "1234", "-e", "azure"},
   222  	},
   223  }
   224  
   225  func (s *ImageMetadataSuite) TestImageMetadataBadArgs(c *gc.C) {
   226  	defer testing.MakeEmptyFakeHome(c).Restore()
   227  	for i, t := range errTests {
   228  		c.Logf("test: %d", i)
   229  		ctx := testing.Context(c)
   230  		code := cmd.Main(&ImageMetadataCommand{}, ctx, t.args)
   231  		c.Check(code, gc.Equals, 2)
   232  	}
   233  }