github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/environs/gui/simplestreams_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package gui_test
     5  
     6  import (
     7  	"net/http"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils"
    11  	"github.com/juju/version"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/environs/gui"
    15  	"github.com/juju/juju/environs/simplestreams"
    16  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    17  	"github.com/juju/juju/juju"
    18  	coretesting "github.com/juju/juju/testing"
    19  	jujuversion "github.com/juju/juju/version"
    20  )
    21  
    22  type simplestreamsSuite struct {
    23  	sstesting.LocalLiveSimplestreamsSuite
    24  }
    25  
    26  var _ = gc.Suite(&simplestreamsSuite{
    27  	LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{
    28  		Source:          simplestreams.NewURLDataSource("test", "test:", utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, false),
    29  		RequireSigned:   false,
    30  		DataType:        gui.DownloadType,
    31  		StreamsVersion:  gui.StreamsVersion,
    32  		ValidConstraint: gui.NewConstraint(gui.ReleasedStream, 2),
    33  	},
    34  })
    35  
    36  func (s *simplestreamsSuite) SetUpSuite(c *gc.C) {
    37  	s.LocalLiveSimplestreamsSuite.SetUpSuite(c)
    38  	sstesting.TestRoundTripper.Sub = coretesting.NewCannedRoundTripper(
    39  		guiData, map[string]int{"test://unauth": http.StatusUnauthorized})
    40  }
    41  
    42  func (s *simplestreamsSuite) TearDownSuite(c *gc.C) {
    43  	sstesting.TestRoundTripper.Sub = nil
    44  	s.LocalLiveSimplestreamsSuite.TearDownSuite(c)
    45  }
    46  
    47  func (s *simplestreamsSuite) TestNewDataSource(c *gc.C) {
    48  	source := gui.NewDataSource("https://1.2.3.4/streams")
    49  	c.Assert(source.Description(), gc.Equals, "gui simplestreams")
    50  
    51  	url, err := source.URL("/my/path")
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	c.Assert(url, gc.Equals, "https://1.2.3.4/streams//my/path")
    54  
    55  	c.Assert(source.RequireSigned(), jc.IsTrue)
    56  	c.Assert(source.PublicSigningKey(), gc.Equals, juju.JujuPublicKey)
    57  }
    58  
    59  var fetchMetadataTests = []struct {
    60  	// about describes the test.
    61  	about string
    62  	// stream holds the stream name to use for the test.
    63  	stream string
    64  	// jujuVersion holds the current Juju version to be used during the test.
    65  	jujuVersion string
    66  	// expectedMetadata holds the list of metadata information returned.
    67  	// The following fields are automatically pre-populated by the test:
    68  	// "FullPath", "Source", "StringVersion" and "JujuMajorVersion"
    69  	expectedMetadata []*gui.Metadata
    70  	// expectedError optionally holds the expected error returned while trying
    71  	// to retrieve GUI metadata information.
    72  	expectedError string
    73  }{{
    74  	about:       "released version 2",
    75  	stream:      gui.ReleasedStream,
    76  	jujuVersion: "2.0.0",
    77  	expectedMetadata: []*gui.Metadata{{
    78  		Version: version.MustParse("2.1.1"),
    79  		Path:    "gui/2.1.1/jujugui-2.1.1.tar.bz2",
    80  		Size:    6140774,
    81  		SHA256:  "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
    82  	}, {
    83  		Version: version.MustParse("2.1.0"),
    84  		Path:    "gui/2.1.0/jujugui-2.1.0.tar.bz2",
    85  		Size:    6098111,
    86  		SHA256:  "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
    87  	}},
    88  }, {
    89  	about:       "released version 2 beta",
    90  	stream:      gui.ReleasedStream,
    91  	jujuVersion: "2.0-beta1",
    92  	expectedMetadata: []*gui.Metadata{{
    93  		Version: version.MustParse("2.1.1"),
    94  		Path:    "gui/2.1.1/jujugui-2.1.1.tar.bz2",
    95  		Size:    6140774,
    96  		SHA256:  "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
    97  	}, {
    98  		Version: version.MustParse("2.1.0"),
    99  		Path:    "gui/2.1.0/jujugui-2.1.0.tar.bz2",
   100  		Size:    6098111,
   101  		SHA256:  "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   102  	}},
   103  }, {
   104  	about:       "released version 2.42",
   105  	stream:      gui.ReleasedStream,
   106  	jujuVersion: "2.42.0",
   107  	expectedMetadata: []*gui.Metadata{{
   108  		Version: version.MustParse("2.1.1"),
   109  		Path:    "gui/2.1.1/jujugui-2.1.1.tar.bz2",
   110  		Size:    6140774,
   111  		SHA256:  "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   112  	}, {
   113  		Version: version.MustParse("2.1.0"),
   114  		Path:    "gui/2.1.0/jujugui-2.1.0.tar.bz2",
   115  		Size:    6098111,
   116  		SHA256:  "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   117  	}},
   118  }, {
   119  	about:       "released version 3",
   120  	stream:      gui.ReleasedStream,
   121  	jujuVersion: "3.0.0",
   122  	expectedMetadata: []*gui.Metadata{{
   123  		Version: version.MustParse("3.0.0"),
   124  		Path:    "gui/3.0.0/jujugui-3.0.0.tar.bz2",
   125  		Size:    42424242,
   126  		SHA256:  "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   127  	}},
   128  }, {
   129  	about:       "released version 47",
   130  	stream:      gui.ReleasedStream,
   131  	jujuVersion: "47.0.0",
   132  }, {
   133  	about:       "devel version 2",
   134  	stream:      gui.DevelStream,
   135  	jujuVersion: "2.0.0",
   136  	expectedMetadata: []*gui.Metadata{{
   137  		Version: version.MustParse("2.4.0"),
   138  		Path:    "gui/2.4.0/jujugui-2.4.0.tar.bz2",
   139  		Size:    6098111,
   140  		SHA256:  "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   141  	}, {
   142  		Version: version.MustParse("2.1.1"),
   143  		Path:    "gui/2.1.1/jujugui-2.1.1.tar.bz2",
   144  		Size:    474747,
   145  		SHA256:  "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   146  	}},
   147  }, {
   148  	about:       "devel version 42",
   149  	stream:      gui.DevelStream,
   150  	jujuVersion: "42.0.0",
   151  }, {
   152  	about:         "error: invalid stream",
   153  	stream:        "invalid",
   154  	jujuVersion:   "2.0.0",
   155  	expectedError: `error fetching simplestreams metadata: cannot unmarshal JSON metadata at URL "test:/streams/v1/com.canonical.streams-invalid-gui.json": .*`,
   156  }, {
   157  	about:         "error: invalid metadata",
   158  	stream:        "errors",
   159  	jujuVersion:   "2.0.0",
   160  	expectedError: `error fetching simplestreams metadata: cannot parse metadata version: invalid version "bad-wolf"`,
   161  }, {
   162  	about:         "error: stream not found",
   163  	stream:        "no-stream",
   164  	jujuVersion:   "2.0.0",
   165  	expectedError: `error fetching simplestreams metadata: "content-download" data not found`,
   166  }, {
   167  	about:         "error: stream file not found",
   168  	stream:        "no-such",
   169  	jujuVersion:   "2.0.0",
   170  	expectedError: `error fetching simplestreams metadata: cannot read product data, invalid URL "test:/streams/v1/com.canonical.streams-no-such-gui.json" not found`,
   171  }}
   172  
   173  func (s *simplestreamsSuite) TestFetchMetadata(c *gc.C) {
   174  	for i, test := range fetchMetadataTests {
   175  		c.Logf("\ntest %d: %s", i, test.about)
   176  
   177  		// Patch the current Juju version.
   178  		jujuVersion := version.MustParse(test.jujuVersion)
   179  		s.PatchValue(&jujuversion.Current, jujuVersion)
   180  
   181  		// Add invalid datasource and check later that resolveInfo is correct.
   182  		invalidSource := simplestreams.NewURLDataSource(
   183  			"invalid", "file://invalid", utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, s.RequireSigned)
   184  
   185  		// Fetch the Juju GUI archives.
   186  		allMeta, err := gui.FetchMetadata(test.stream, invalidSource, s.Source)
   187  		for i, meta := range allMeta {
   188  			c.Logf("metadata %d:\n%#v", i, meta)
   189  		}
   190  		if test.expectedError != "" {
   191  			c.Assert(err, gc.ErrorMatches, test.expectedError)
   192  			c.Assert(allMeta, gc.IsNil)
   193  			continue
   194  		}
   195  
   196  		// Populate the expected metadata with missing fields.
   197  		for _, meta := range test.expectedMetadata {
   198  			meta.JujuMajorVersion = jujuVersion.Major
   199  			meta.FullPath = "test:/" + meta.Path
   200  			meta.Source = s.Source
   201  			meta.StringVersion = meta.Version.String()
   202  		}
   203  		c.Assert(err, jc.ErrorIsNil)
   204  		c.Assert(allMeta, jc.DeepEquals, test.expectedMetadata)
   205  	}
   206  }
   207  
   208  func (s *simplestreamsSuite) TestConstraint(c *gc.C) {
   209  	constraint := gui.NewConstraint("test-stream", 42)
   210  	c.Assert(constraint.IndexIds(), jc.DeepEquals, []string{"com.canonical.streams:test-stream:gui"})
   211  
   212  	ids, err := constraint.ProductIds()
   213  	c.Assert(err, jc.ErrorIsNil)
   214  	c.Assert(ids, jc.DeepEquals, []string{"com.canonical.streams:gui"})
   215  
   216  	c.Assert(constraint.Arches, jc.DeepEquals, []string{})
   217  	c.Assert(constraint.Series, jc.DeepEquals, []string{})
   218  
   219  	c.Assert(constraint.Endpoint, gc.Equals, "")
   220  	c.Assert(constraint.Region, gc.Equals, "")
   221  	c.Assert(constraint.Stream, gc.Equals, "test-stream")
   222  }
   223  
   224  var guiData = map[string]string{
   225  	"/streams/v1/index.json": `{
   226          "format": "index:1.0",
   227          "index": {
   228              "com.canonical.streams:devel:gui": {
   229                  "datatype": "content-download",
   230                  "format": "products:1.0",
   231                  "path": "streams/v1/com.canonical.streams-devel-gui.json",
   232                  "products": [
   233                      "com.canonical.streams:gui"
   234                  ],
   235                  "updated": "Tue, 05 Apr 2016 16:19:03 +0000"
   236              },
   237              "com.canonical.streams:released:gui": {
   238                  "datatype": "content-download",
   239                  "format": "products:1.0",
   240                  "path": "streams/v1/com.canonical.streams-released-gui.json",
   241                  "products": [
   242                      "com.canonical.streams:gui"
   243                  ],
   244                  "updated": "Fri, 01 Apr 2016 15:47:41 +0000"
   245              },
   246              "com.canonical.streams:invalid:gui": {
   247                  "datatype": "content-download",
   248                  "format": "products:1.0",
   249                  "path": "streams/v1/com.canonical.streams-invalid-gui.json",
   250                  "products": [
   251                      "com.canonical.streams:gui"
   252                  ],
   253                  "updated": "Fri, 01 Apr 2016 15:47:41 +0000"
   254              },
   255              "com.canonical.streams:errors:gui": {
   256                  "datatype": "content-download",
   257                  "format": "products:1.0",
   258                  "path": "streams/v1/com.canonical.streams-errors-gui.json",
   259                  "products": [
   260                      "com.canonical.streams:gui"
   261                  ],
   262                  "updated": "Fri, 01 Apr 2016 15:47:41 +0000"
   263              },
   264              "com.canonical.streams:no-such:gui": {
   265                  "datatype": "content-download",
   266                  "format": "products:1.0",
   267                  "path": "streams/v1/com.canonical.streams-no-such-gui.json",
   268                  "products": [
   269                      "com.canonical.streams:gui"
   270                  ],
   271                  "updated": "Fri, 01 Apr 2016 15:47:41 +0000"
   272              }
   273          },
   274      "updated": "Fri, 01 Apr 2016 15:47:41 +0000"
   275      }`,
   276  	"/streams/v1/com.canonical.streams-devel-gui.json": `{
   277          "content_id": "com.canonical.streams:devel:gui",
   278          "datatype": "content-download",
   279          "format": "products:1.0",
   280          "products": {
   281              "com.canonical.streams:gui": {
   282                  "format": "products:1.0",
   283                  "ftype": "tar.bz2",
   284                  "versions": {
   285                      "20160404": {
   286                          "items": {
   287                              "2.4.0": {
   288                                  "juju-version": 2,
   289                                  "md5": "5af3cb9f2625afbaff904cbd5c65772f",
   290                                  "path": "gui/2.4.0/jujugui-2.4.0.tar.bz2",
   291                                  "sha1": "b364a4236a132c75241a75d6ab1c96788c6f38b0",
   292                                  "sha256": "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   293                                  "size": 6098111,
   294                                  "version": "2.4.0"
   295                              },
   296                              "2.1.1": {
   297                                  "juju-version": 2,
   298                                  "md5": "c49f1707078347cab31b0ff98bfb8dca",
   299                                  "path": "gui/2.1.1/jujugui-2.1.1.tar.bz2",
   300                                  "sha1": "1300d555f79b3de3bf334702d027701f69563849",
   301                                  "sha256": "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   302                                  "size": 474747,
   303                                  "version": "2.1.1"
   304                              }
   305                          }
   306                      }
   307                  }
   308              }
   309          },
   310          "updated": "Mon, 04 Apr 2016 17:14:58 +0000"
   311      }`,
   312  	"/streams/v1/com.canonical.streams-released-gui.json": `{
   313          "content_id": "com.canonical.streams:released:gui",
   314          "datatype": "content-download",
   315          "format": "products:1.0",
   316          "products": {
   317              "com.canonical.streams:gui": {
   318                  "format": "products:1.0",
   319                  "ftype": "tar.bz2",
   320                  "versions": {
   321                      "20160404": {
   322                          "items": {
   323                              "2.1.0": {
   324                                  "juju-version": 2,
   325                                  "md5": "5af3cb9f2625afbaff904cbd5c65772f",
   326                                  "path": "gui/2.1.0/jujugui-2.1.0.tar.bz2",
   327                                  "sha1": "b364a4236a132c75241a75d6ab1c96788c6f38b0",
   328                                  "sha256": "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   329                                  "size": 6098111,
   330                                  "version": "2.1.0"
   331                              },
   332                              "2.1.1": {
   333                                  "juju-version": 2,
   334                                  "md5": "c49f1707078347cab31b0ff98bfb8dca",
   335                                  "path": "gui/2.1.1/jujugui-2.1.1.tar.bz2",
   336                                  "sha1": "1300d555f79b3de3bf334702d027701f69563849",
   337                                  "sha256": "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   338                                  "size": 6140774,
   339                                  "version": "2.1.1"
   340                              },
   341                              "3.0.0": {
   342                                  "juju-version": 3,
   343                                  "md5": "c49f1707078347cab31b0ff98bfb8dca",
   344                                  "path": "gui/3.0.0/jujugui-3.0.0.tar.bz2",
   345                                  "sha1": "1300d555f79b3de3bf334702d027701f69563849",
   346                                  "sha256": "5236f1b694a9a66dc4f86b740371408bf4ddf2354ebc6e5410587843a1e55743",
   347                                  "size": 42424242,
   348                                  "version": "3.0.0"
   349                              }
   350                          }
   351                      }
   352                  }
   353              }
   354          },
   355          "updated": "Mon, 04 Apr 2016 17:14:58 +0000"
   356      }`,
   357  	"/streams/v1/com.canonical.streams-invalid-gui.json": `
   358          bad: wolf
   359      `,
   360  	"/streams/v1/com.canonical.streams-errors-gui.json": `{
   361          "content_id": "com.canonical.streams:devel:gui",
   362          "datatype": "content-download",
   363          "format": "products:1.0",
   364          "products": {
   365              "com.canonical.streams:gui": {
   366                  "format": "products:1.0",
   367                  "ftype": "tar.bz2",
   368                  "versions": {
   369                      "20160404": {
   370                          "items": {
   371                              "2.0.0": {
   372                                  "juju-version": 2,
   373                                  "md5": "5af3cb9f2625afbaff904cbd5c65772f",
   374                                  "path": "gui/2.0.0/jujugui-2.0.0.tar.bz2",
   375                                  "sha1": "b364a4236a132c75241a75d6ab1c96788c6f38b0",
   376                                  "sha256": "6cec58b36969590d3ff56279a2c63b4f5faf277b0dbeefe1106f666582575894",
   377                                  "size": 6098111,
   378                                  "version": "bad-wolf"
   379                              }
   380                          }
   381                      }
   382                  }
   383              }
   384          },
   385          "updated": "Mon, 04 Apr 2016 17:14:58 +0000"
   386      }`,
   387  }