github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/environs/simplestreams/simplestreams_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package simplestreams_test
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/environs/simplestreams"
    15  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    16  )
    17  
    18  func Test(t *testing.T) {
    19  	registerSimpleStreamsTests()
    20  	gc.Suite(&jsonSuite{})
    21  	gc.TestingT(t)
    22  }
    23  
    24  func registerSimpleStreamsTests() {
    25  	gc.Suite(&simplestreamsSuite{
    26  		LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{
    27  			Source:         simplestreams.NewURLDataSource("test", "test:", utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, false),
    28  			RequireSigned:  false,
    29  			DataType:       "image-ids",
    30  			StreamsVersion: "v1",
    31  			ValidConstraint: sstesting.NewTestConstraint(simplestreams.LookupParams{
    32  				CloudSpec: simplestreams.CloudSpec{
    33  					Region:   "us-east-1",
    34  					Endpoint: "https://ec2.us-east-1.amazonaws.com",
    35  				},
    36  				Series: []string{"precise"},
    37  				Arches: []string{"amd64", "arm"},
    38  			}),
    39  		},
    40  	})
    41  }
    42  
    43  type simplestreamsSuite struct {
    44  	sstesting.TestDataSuite
    45  	sstesting.LocalLiveSimplestreamsSuite
    46  }
    47  
    48  func (s *simplestreamsSuite) SetUpSuite(c *gc.C) {
    49  	s.LocalLiveSimplestreamsSuite.SetUpSuite(c)
    50  	s.TestDataSuite.SetUpSuite(c)
    51  }
    52  
    53  func (s *simplestreamsSuite) TearDownSuite(c *gc.C) {
    54  	s.TestDataSuite.TearDownSuite(c)
    55  	s.LocalLiveSimplestreamsSuite.TearDownSuite(c)
    56  }
    57  
    58  func (s *simplestreamsSuite) TestGetProductsPath(c *gc.C) {
    59  	indexRef, err := s.GetIndexRef(sstesting.Index_v1)
    60  	c.Assert(err, jc.ErrorIsNil)
    61  	path, err := indexRef.GetProductsPath(s.ValidConstraint)
    62  	c.Assert(err, jc.ErrorIsNil)
    63  	c.Assert(path, gc.Equals, "streams/v1/image_metadata.json")
    64  }
    65  
    66  func (*simplestreamsSuite) TestExtractCatalogsForProductsAcceptsNil(c *gc.C) {
    67  	empty := simplestreams.CloudMetadata{}
    68  	c.Check(simplestreams.ExtractCatalogsForProducts(empty, nil), gc.HasLen, 0)
    69  }
    70  
    71  func (*simplestreamsSuite) TestExtractCatalogsForProductsReturnsMatch(c *gc.C) {
    72  	metadata := simplestreams.CloudMetadata{
    73  		Products: map[string]simplestreams.MetadataCatalog{
    74  			"foo": {},
    75  		},
    76  	}
    77  	c.Check(
    78  		simplestreams.ExtractCatalogsForProducts(metadata, []string{"foo"}),
    79  		gc.DeepEquals,
    80  		[]simplestreams.MetadataCatalog{metadata.Products["foo"]})
    81  }
    82  
    83  func (*simplestreamsSuite) TestExtractCatalogsForProductsIgnoresNonMatches(c *gc.C) {
    84  	metadata := simplestreams.CloudMetadata{
    85  		Products: map[string]simplestreams.MetadataCatalog{
    86  			"one-product": {},
    87  		},
    88  	}
    89  	absentProducts := []string{"another-product"}
    90  	c.Check(simplestreams.ExtractCatalogsForProducts(metadata, absentProducts), gc.HasLen, 0)
    91  }
    92  
    93  func (*simplestreamsSuite) TestExtractCatalogsForProductsPreservesOrder(c *gc.C) {
    94  	products := map[string]simplestreams.MetadataCatalog{
    95  		"1": {},
    96  		"2": {},
    97  		"3": {},
    98  		"4": {},
    99  	}
   100  
   101  	metadata := simplestreams.CloudMetadata{Products: products}
   102  
   103  	c.Check(
   104  		simplestreams.ExtractCatalogsForProducts(metadata, []string{"1", "3", "4", "2"}),
   105  		gc.DeepEquals,
   106  		[]simplestreams.MetadataCatalog{
   107  			products["1"],
   108  			products["3"],
   109  			products["4"],
   110  			products["2"],
   111  		})
   112  }
   113  
   114  func (*simplestreamsSuite) TestExtractIndexesAcceptsEmpty(c *gc.C) {
   115  	ind := simplestreams.Indices{}
   116  	c.Check(simplestreams.ExtractIndexes(ind, nil), gc.HasLen, 0)
   117  }
   118  
   119  func (*simplestreamsSuite) TestExtractIndexesReturnsIndex(c *gc.C) {
   120  	metadata := simplestreams.IndexMetadata{}
   121  	ind := simplestreams.Indices{Indexes: map[string]*simplestreams.IndexMetadata{"foo": &metadata}}
   122  	c.Check(simplestreams.ExtractIndexes(ind, nil), gc.DeepEquals, simplestreams.IndexMetadataSlice{&metadata})
   123  }
   124  
   125  func (*simplestreamsSuite) TestExtractIndexesReturnsAllIndexes(c *gc.C) {
   126  	ind := simplestreams.Indices{
   127  		Indexes: map[string]*simplestreams.IndexMetadata{
   128  			"foo": {},
   129  			"bar": {},
   130  		},
   131  	}
   132  
   133  	array := simplestreams.ExtractIndexes(ind, nil)
   134  
   135  	c.Assert(array, gc.HasLen, len(ind.Indexes))
   136  	c.Check(array[0], gc.NotNil)
   137  	c.Check(array[1], gc.NotNil)
   138  	c.Check(array[0], gc.Not(gc.Equals), array[1])
   139  	c.Check(
   140  		(array[0] == ind.Indexes["foo"]),
   141  		gc.Not(gc.Equals),
   142  		(array[1] == ind.Indexes["foo"]))
   143  	c.Check(
   144  		(array[0] == ind.Indexes["bar"]),
   145  		gc.Not(gc.Equals),
   146  		(array[1] == ind.Indexes["bar"]))
   147  }
   148  
   149  func (*simplestreamsSuite) TestExtractIndexesReturnsSpecifiedIndexes(c *gc.C) {
   150  	ind := simplestreams.Indices{
   151  		Indexes: map[string]*simplestreams.IndexMetadata{
   152  			"foo":    {},
   153  			"bar":    {},
   154  			"foobar": {},
   155  		},
   156  	}
   157  
   158  	array := simplestreams.ExtractIndexes(ind, []string{"foobar"})
   159  	c.Assert(array, gc.HasLen, 1)
   160  	c.Assert(array[0], gc.Equals, ind.Indexes["foobar"])
   161  }
   162  
   163  func (*simplestreamsSuite) TestHasCloudAcceptsNil(c *gc.C) {
   164  	metadata := simplestreams.IndexMetadata{Clouds: nil}
   165  	c.Check(simplestreams.HasCloud(metadata, simplestreams.CloudSpec{}), jc.IsTrue)
   166  }
   167  
   168  func (*simplestreamsSuite) TestHasCloudFindsMatch(c *gc.C) {
   169  	metadata := simplestreams.IndexMetadata{
   170  		Clouds: []simplestreams.CloudSpec{
   171  			{Region: "r1", Endpoint: "http://e1"},
   172  			{Region: "r2", Endpoint: "http://e2"},
   173  		},
   174  	}
   175  	c.Check(simplestreams.HasCloud(metadata, metadata.Clouds[1]), jc.IsTrue)
   176  }
   177  
   178  func (*simplestreamsSuite) TestHasCloudFindsMatchWithTrailingSlash(c *gc.C) {
   179  	metadata := simplestreams.IndexMetadata{
   180  		Clouds: []simplestreams.CloudSpec{
   181  			{Region: "r1", Endpoint: "http://e1/"},
   182  			{Region: "r2", Endpoint: "http://e2"},
   183  		},
   184  	}
   185  	spec := simplestreams.CloudSpec{Region: "r1", Endpoint: "http://e1"}
   186  	c.Check(simplestreams.HasCloud(metadata, spec), jc.IsTrue)
   187  	spec = simplestreams.CloudSpec{Region: "r1", Endpoint: "http://e1/"}
   188  	c.Check(simplestreams.HasCloud(metadata, spec), jc.IsTrue)
   189  	spec = simplestreams.CloudSpec{Region: "r2", Endpoint: "http://e2/"}
   190  	c.Check(simplestreams.HasCloud(metadata, spec), jc.IsTrue)
   191  }
   192  
   193  func (*simplestreamsSuite) TestHasCloudReturnsFalseIfCloudsDoNotMatch(c *gc.C) {
   194  	metadata := simplestreams.IndexMetadata{
   195  		Clouds: []simplestreams.CloudSpec{
   196  			{Region: "r1", Endpoint: "http://e1"},
   197  			{Region: "r2", Endpoint: "http://e2"},
   198  		},
   199  	}
   200  	otherCloud := simplestreams.CloudSpec{Region: "r9", Endpoint: "http://e9"}
   201  	c.Check(simplestreams.HasCloud(metadata, otherCloud), jc.IsFalse)
   202  }
   203  
   204  func (*simplestreamsSuite) TestHasCloudRequiresIdenticalRegion(c *gc.C) {
   205  	metadata := simplestreams.IndexMetadata{
   206  		Clouds: []simplestreams.CloudSpec{
   207  			{Region: "around", Endpoint: "http://nearby"},
   208  		},
   209  	}
   210  	similarCloud := metadata.Clouds[0]
   211  	similarCloud.Region = "elsewhere"
   212  	c.Assert(similarCloud, gc.Not(gc.Equals), metadata.Clouds[0])
   213  
   214  	c.Check(simplestreams.HasCloud(metadata, similarCloud), jc.IsFalse)
   215  }
   216  
   217  func (*simplestreamsSuite) TestHasCloudRequiresIdenticalEndpoint(c *gc.C) {
   218  	metadata := simplestreams.IndexMetadata{
   219  		Clouds: []simplestreams.CloudSpec{
   220  			{Region: "around", Endpoint: "http://nearby"},
   221  		},
   222  	}
   223  	similarCloud := metadata.Clouds[0]
   224  	similarCloud.Endpoint = "http://far"
   225  	c.Assert(similarCloud, gc.Not(gc.Equals), metadata.Clouds[0])
   226  
   227  	c.Check(simplestreams.HasCloud(metadata, similarCloud), jc.IsFalse)
   228  }
   229  
   230  func (*simplestreamsSuite) TestHasProductAcceptsNils(c *gc.C) {
   231  	metadata := simplestreams.IndexMetadata{}
   232  	c.Check(simplestreams.HasProduct(metadata, nil), jc.IsFalse)
   233  }
   234  
   235  func (*simplestreamsSuite) TestHasProductFindsMatchingProduct(c *gc.C) {
   236  	metadata := simplestreams.IndexMetadata{ProductIds: []string{"x", "y", "z"}}
   237  	c.Check(
   238  		simplestreams.HasProduct(metadata, []string{"a", "b", metadata.ProductIds[1]}),
   239  		gc.Equals,
   240  		true)
   241  }
   242  
   243  func (*simplestreamsSuite) TestHasProductReturnsFalseIfProductsDoNotMatch(c *gc.C) {
   244  	metadata := simplestreams.IndexMetadata{ProductIds: []string{"x", "y", "z"}}
   245  	c.Check(simplestreams.HasProduct(metadata, []string{"a", "b", "c"}), jc.IsFalse)
   246  }
   247  
   248  func (*simplestreamsSuite) TestFilterReturnsNothingForEmptyArray(c *gc.C) {
   249  	empty := simplestreams.IndexMetadataSlice{}
   250  	c.Check(
   251  		simplestreams.Filter(empty, func(*simplestreams.IndexMetadata) bool { return true }),
   252  		gc.HasLen,
   253  		0)
   254  }
   255  
   256  func (*simplestreamsSuite) TestFilterRemovesNonMatches(c *gc.C) {
   257  	array := simplestreams.IndexMetadataSlice{&simplestreams.IndexMetadata{}}
   258  	c.Check(
   259  		simplestreams.Filter(array, func(*simplestreams.IndexMetadata) bool { return false }),
   260  		gc.HasLen,
   261  		0)
   262  }
   263  
   264  func (*simplestreamsSuite) TestFilterIncludesMatches(c *gc.C) {
   265  	metadata := simplestreams.IndexMetadata{}
   266  	array := simplestreams.IndexMetadataSlice{&metadata}
   267  	c.Check(
   268  		simplestreams.Filter(array, func(*simplestreams.IndexMetadata) bool { return true }),
   269  		gc.DeepEquals,
   270  		simplestreams.IndexMetadataSlice{&metadata})
   271  }
   272  
   273  func (*simplestreamsSuite) TestFilterLeavesOriginalUnchanged(c *gc.C) {
   274  	item1 := simplestreams.IndexMetadata{CloudName: "aws"}
   275  	item2 := simplestreams.IndexMetadata{CloudName: "openstack"}
   276  	array := simplestreams.IndexMetadataSlice{&item1, &item2}
   277  
   278  	result := simplestreams.Filter(array, func(metadata *simplestreams.IndexMetadata) bool {
   279  		return metadata.CloudName == "aws"
   280  	})
   281  	// This exercises both the "leave out" and the "include" code paths.
   282  	c.Assert(result, gc.HasLen, 1)
   283  
   284  	// The original, however, has not changed.
   285  	c.Assert(array, gc.HasLen, 2)
   286  	c.Check(array, gc.DeepEquals, simplestreams.IndexMetadataSlice{&item1, &item2})
   287  }
   288  
   289  func (*simplestreamsSuite) TestFilterPreservesOrder(c *gc.C) {
   290  	array := simplestreams.IndexMetadataSlice{
   291  		&simplestreams.IndexMetadata{CloudName: "aws"},
   292  		&simplestreams.IndexMetadata{CloudName: "maas"},
   293  		&simplestreams.IndexMetadata{CloudName: "openstack"},
   294  	}
   295  
   296  	c.Check(
   297  		simplestreams.Filter(array, func(metadata *simplestreams.IndexMetadata) bool { return true }),
   298  		gc.DeepEquals,
   299  		array)
   300  }
   301  
   302  func (*simplestreamsSuite) TestFilterCombinesMatchesAndNonMatches(c *gc.C) {
   303  	array := simplestreams.IndexMetadataSlice{
   304  		&simplestreams.IndexMetadata{Format: "1.0"},
   305  		&simplestreams.IndexMetadata{Format: "1.1"},
   306  		&simplestreams.IndexMetadata{Format: "2.0"},
   307  		&simplestreams.IndexMetadata{Format: "2.1"},
   308  	}
   309  
   310  	dotOFormats := simplestreams.Filter(array, func(metadata *simplestreams.IndexMetadata) bool {
   311  		return strings.HasSuffix(metadata.Format, ".0")
   312  	})
   313  
   314  	c.Check(dotOFormats, gc.DeepEquals, simplestreams.IndexMetadataSlice{array[0], array[2]})
   315  }
   316  
   317  // countingSource is used to check that a DataSource has been queried.
   318  type countingSource struct {
   319  	simplestreams.DataSource
   320  	count int
   321  }
   322  
   323  func (s *countingSource) URL(path string) (string, error) {
   324  	s.count++
   325  	return s.DataSource.URL(path)
   326  }
   327  
   328  func (s *simplestreamsSuite) TestGetMetadataNoMatching(c *gc.C) {
   329  	source := &countingSource{
   330  		DataSource: simplestreams.NewURLDataSource(
   331  			"test",
   332  			"test:/daily",
   333  			utils.VerifySSLHostnames,
   334  			simplestreams.DEFAULT_CLOUD_DATA,
   335  			false,
   336  		),
   337  	}
   338  	sources := []simplestreams.DataSource{source, source, source}
   339  	constraint := sstesting.NewTestConstraint(simplestreams.LookupParams{
   340  		CloudSpec: simplestreams.CloudSpec{
   341  			Region:   "us-east-1",
   342  			Endpoint: "https://ec2.us-east-1.amazonaws.com",
   343  		},
   344  		Series: []string{"precise"},
   345  		Arches: []string{"not-a-real-arch"}, // never matches
   346  	})
   347  	params := simplestreams.GetMetadataParams{
   348  		StreamsVersion:   s.StreamsVersion,
   349  		LookupConstraint: constraint,
   350  		ValueParams:      simplestreams.ValueParams{DataType: "image-ids"},
   351  	}
   352  
   353  	items, resolveInfo, err := simplestreams.GetMetadata(sources, params)
   354  	c.Assert(err, jc.ErrorIsNil)
   355  	c.Assert(items, gc.HasLen, 0)
   356  	c.Assert(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{
   357  		Source:    "test",
   358  		Signed:    false,
   359  		IndexURL:  "test:/daily/streams/v1/index.json",
   360  		MirrorURL: "",
   361  	})
   362  
   363  	// There should be 4 calls to each data-source:
   364  	// one for .sjson, one for .json, repeated for legacy vs new index files.
   365  	c.Assert(source.count, gc.Equals, 4*len(sources))
   366  }
   367  
   368  func (s *simplestreamsSuite) TestMetadataCatalog(c *gc.C) {
   369  	metadata := s.AssertGetMetadata(c)
   370  	c.Check(len(metadata.Products), gc.Equals, 6)
   371  	c.Check(len(metadata.Aliases), gc.Equals, 1)
   372  	metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"]
   373  	c.Check(len(metadataCatalog.Items), gc.Equals, 2)
   374  	c.Check(metadataCatalog.Series, gc.Equals, "precise")
   375  	c.Check(metadataCatalog.Version, gc.Equals, "12.04")
   376  	c.Check(metadataCatalog.Arch, gc.Equals, "amd64")
   377  	c.Check(metadataCatalog.RegionName, gc.Equals, "au-east-1")
   378  	c.Check(metadataCatalog.Endpoint, gc.Equals, "https://somewhere")
   379  }
   380  
   381  func (s *simplestreamsSuite) TestItemCollection(c *gc.C) {
   382  	ic := s.AssertGetItemCollections(c, "20121218")
   383  	c.Check(ic.RegionName, gc.Equals, "au-east-2")
   384  	c.Check(ic.Endpoint, gc.Equals, "https://somewhere-else")
   385  	c.Assert(len(ic.Items) > 0, jc.IsTrue)
   386  	ti := ic.Items["usww2he"].(*sstesting.TestItem)
   387  	c.Check(ti.Id, gc.Equals, "ami-442ea674")
   388  	c.Check(ti.Storage, gc.Equals, "ebs")
   389  	c.Check(ti.VirtType, gc.Equals, "hvm")
   390  	c.Check(ti.RegionName, gc.Equals, "us-east-1")
   391  	c.Check(ti.Endpoint, gc.Equals, "https://ec2.us-east-1.amazonaws.com")
   392  }
   393  
   394  func (s *simplestreamsSuite) TestDenormalisationFromCollection(c *gc.C) {
   395  	ic := s.AssertGetItemCollections(c, "20121218")
   396  	ti := ic.Items["usww1pe"].(*sstesting.TestItem)
   397  	c.Check(ti.RegionName, gc.Equals, ic.RegionName)
   398  	c.Check(ti.Endpoint, gc.Equals, ic.Endpoint)
   399  }
   400  
   401  func (s *simplestreamsSuite) TestDenormalisationFromCatalog(c *gc.C) {
   402  	metadata := s.AssertGetMetadata(c)
   403  	metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"]
   404  	ic := metadataCatalog.Items["20111111"]
   405  	ti := ic.Items["usww3pe"].(*sstesting.TestItem)
   406  	c.Check(ti.RegionName, gc.Equals, metadataCatalog.RegionName)
   407  	c.Check(ti.Endpoint, gc.Equals, metadataCatalog.Endpoint)
   408  }
   409  
   410  func (s *simplestreamsSuite) TestDenormalisationFromTopLevel(c *gc.C) {
   411  	metadata := s.AssertGetMetadata(c)
   412  	metadataCatalog := metadata.Products["com.ubuntu.cloud:server:14.04:amd64"]
   413  	ic := metadataCatalog.Items["20140118"]
   414  	ti := ic.Items["nzww1pe"].(*sstesting.TestItem)
   415  	c.Check(ti.RegionName, gc.Equals, metadata.RegionName)
   416  	c.Check(ti.Endpoint, gc.Equals, metadata.Endpoint)
   417  }
   418  
   419  func (s *simplestreamsSuite) TestDealiasing(c *gc.C) {
   420  	metadata := s.AssertGetMetadata(c)
   421  	metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"]
   422  	ic := metadataCatalog.Items["20121218"]
   423  	ti := ic.Items["usww3he"].(*sstesting.TestItem)
   424  	c.Check(ti.RegionName, gc.Equals, "us-west-3")
   425  	c.Check(ti.Endpoint, gc.Equals, "https://ec2.us-west-3.amazonaws.com")
   426  }
   427  
   428  type storageVirtTest struct {
   429  	product, coll, item, storage, virt string
   430  }
   431  
   432  func (s *simplestreamsSuite) TestStorageVirtFromTopLevel(c *gc.C) {
   433  	s.assertImageMetadata(c,
   434  		storageVirtTest{"com.ubuntu.cloud:server:13.04:amd64", "20160318", "nzww1pe", "ebs", "pv"},
   435  	)
   436  }
   437  
   438  func (s *simplestreamsSuite) TestStorageVirtFromCatalog(c *gc.C) {
   439  	s.assertImageMetadata(c,
   440  		storageVirtTest{"com.ubuntu.cloud:server:14.10:amd64", "20160218", "nzww1pe", "ebs", "pv"},
   441  	)
   442  }
   443  
   444  func (s *simplestreamsSuite) TestStorageVirtFromCollection(c *gc.C) {
   445  	s.assertImageMetadata(c,
   446  		storageVirtTest{"com.ubuntu.cloud:server:12.10:amd64", "20160118", "nzww1pe", "ebs", "pv"},
   447  	)
   448  }
   449  
   450  func (s *simplestreamsSuite) TestStorageVirtFromItem(c *gc.C) {
   451  	s.assertImageMetadata(c,
   452  		storageVirtTest{"com.ubuntu.cloud:server:14.04:amd64", "20140118", "nzww1pe", "ssd", "hvm"},
   453  	)
   454  }
   455  
   456  func (s *simplestreamsSuite) assertImageMetadata(c *gc.C, one storageVirtTest) {
   457  	metadata := s.AssertGetMetadata(c)
   458  	metadataCatalog := metadata.Products[one.product]
   459  	ic := metadataCatalog.Items[one.coll]
   460  	ti := ic.Items[one.item].(*sstesting.TestItem)
   461  	c.Check(ti.Storage, gc.Equals, one.storage)
   462  	c.Check(ti.VirtType, gc.Equals, one.virt)
   463  }
   464  
   465  var getMirrorTests = []struct {
   466  	region    string
   467  	endpoint  string
   468  	err       string
   469  	mirrorURL string
   470  	path      string
   471  }{{
   472  	// defaults
   473  	mirrorURL: "http://some-mirror/",
   474  	path:      "com.ubuntu.juju:download.json",
   475  }, {
   476  	// default mirror index entry
   477  	region:    "some-region",
   478  	endpoint:  "https://some-endpoint.com",
   479  	mirrorURL: "http://big-mirror/",
   480  	path:      "big:download.json",
   481  }, {
   482  	// endpoint with trailing "/"
   483  	region:    "some-region",
   484  	endpoint:  "https://some-endpoint.com/",
   485  	mirrorURL: "http://big-mirror/",
   486  	path:      "big:download.json",
   487  }}
   488  
   489  func (s *simplestreamsSuite) TestGetMirrorMetadata(c *gc.C) {
   490  	for i, t := range getMirrorTests {
   491  		c.Logf("test %d", i)
   492  		if t.region == "" {
   493  			t.region = "us-east-2"
   494  		}
   495  		if t.endpoint == "" {
   496  			t.endpoint = "https://ec2.us-east-2.amazonaws.com"
   497  		}
   498  		cloud := simplestreams.CloudSpec{t.region, t.endpoint}
   499  		params := simplestreams.ValueParams{
   500  			DataType:        "content-download",
   501  			MirrorContentId: "com.ubuntu.juju:released:tools",
   502  		}
   503  		indexRef, err := simplestreams.GetIndexWithFormat(
   504  			s.Source, s.IndexPath(), sstesting.Index_v1,
   505  			simplestreams.MirrorsPath("v1"), s.RequireSigned, cloud, params)
   506  		if !c.Check(err, jc.ErrorIsNil) {
   507  			continue
   508  		}
   509  		if t.err != "" {
   510  			c.Check(err, gc.ErrorMatches, t.err)
   511  			continue
   512  		}
   513  		if !c.Check(err, jc.ErrorIsNil) {
   514  			continue
   515  		}
   516  		mirrorURL, err := indexRef.Source.URL("")
   517  		if !c.Check(err, jc.ErrorIsNil) {
   518  			continue
   519  		}
   520  		c.Check(mirrorURL, gc.Equals, t.mirrorURL)
   521  		c.Check(indexRef.MirroredProductsPath, gc.Equals, t.path)
   522  	}
   523  }