github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/environs/simplestreams/fetchdata_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package simplestreams_test
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"io/ioutil"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/environs/simplestreams"
    15  	"github.com/juju/juju/environs/simplestreams/testing"
    16  	"github.com/juju/juju/juju/keys"
    17  )
    18  
    19  type fetchDataSuite struct {
    20  	requireSigned bool
    21  	source        *testing.StubDataSource
    22  
    23  	readerData, expectedData string
    24  	expectedCalls            []string
    25  }
    26  
    27  var _ = gc.Suite(&fetchDataSuite{})
    28  
    29  func (s *fetchDataSuite) SetUpTest(c *gc.C) {
    30  	s.source = testing.NewStubDataSource()
    31  }
    32  
    33  func (s *fetchDataSuite) TestFetchSignedDataWithRequireSignedDataSourceWithoutPublicKey(c *gc.C) {
    34  	s.requireSigned = true
    35  	s.expectedCalls = []string{"Fetch", "PublicSigningKey", "Description"}
    36  	s.readerData = signedData
    37  	s.expectedData = unsignedData[1:]
    38  	s.setupDataSource("")
    39  	s.assertFetchDataFail(c, `cannot read data for source "" at URL this.path.doesnt.matter.for.test.either: failed to parse public key: openpgp: invalid argument: no armored data found`)
    40  }
    41  
    42  func (s *fetchDataSuite) TestFetchSignedDataWithRequireSignedDataSourceWithWrongPublicKey(c *gc.C) {
    43  	s.requireSigned = true
    44  	s.expectedCalls = []string{"Fetch", "PublicSigningKey", "Description"}
    45  	s.readerData = signedData
    46  	s.expectedData = unsignedData[1:]
    47  	s.setupDataSource(keys.JujuPublicKey)
    48  	s.assertFetchDataFail(c, `cannot read data for source "" at URL this.path.doesnt.matter.for.test.either: openpgp: signature made by unknown entity`)
    49  }
    50  
    51  func (s *fetchDataSuite) TestFetchSignedDataWithRequireSignedDataSourceWithPublicKey(c *gc.C) {
    52  	s.requireSigned = true
    53  	s.expectedCalls = []string{"Fetch", "PublicSigningKey"}
    54  	s.readerData = signedData
    55  	s.expectedData = unsignedData[1:]
    56  	s.setupDataSource(testSigningKey)
    57  	s.assertFetchData(c)
    58  }
    59  
    60  func (s *fetchDataSuite) TestFetchSignedDataWithNotRequireSignedDataSourceWithPublicKey(c *gc.C) {
    61  	s.requireSigned = false
    62  	s.expectedCalls = []string{"Fetch"}
    63  	s.readerData = signedData
    64  	// Current implementation will return the full signed data
    65  	// without stripping signature prefix and suffix.
    66  	// In order to return strip signing information, we need to be able to detect if file
    67  	// contents are signed and act accordingly. We do not do this now, we hard-code "requireSigned".
    68  	s.expectedData = signedData
    69  	s.setupDataSource(testSigningKey)
    70  	s.assertFetchData(c)
    71  }
    72  
    73  func (s *fetchDataSuite) TestFetchSignedDataWithNotRequireSignedDataSourceWithoutPublicKey(c *gc.C) {
    74  	s.requireSigned = false
    75  	s.expectedCalls = []string{"Fetch"}
    76  	s.readerData = signedData
    77  	// Current implementation will return the full signed data
    78  	// without stripping signature prefix and suffix.
    79  	// In order to return strip signing information, we need to be able to detect if file
    80  	// contents are signed and act accordingly. We do not do this now, we hard-code "requireSigned".
    81  	s.expectedData = signedData
    82  	s.setupDataSource("")
    83  	s.assertFetchData(c)
    84  }
    85  
    86  func (s *fetchDataSuite) TestFetchUnsignedDataWithRequireSignedDataSourceWithoutPublicKey(c *gc.C) {
    87  	s.requireSigned = true
    88  	s.expectedCalls = []string{"Fetch", "PublicSigningKey", "Description"}
    89  	s.expectedData = unsignedData
    90  	s.readerData = unsignedData
    91  	s.setupDataSource("")
    92  	s.assertFetchDataFail(c, `cannot read data for source "" at URL this.path.doesnt.matter.for.test.either: no PGP signature embedded in plain text data`)
    93  }
    94  
    95  func (s *fetchDataSuite) TestFetchUnsignedDataWithRequireSignedDataSourceWithPublicKey(c *gc.C) {
    96  	s.requireSigned = true
    97  	s.expectedCalls = []string{"Fetch", "PublicSigningKey", "Description"}
    98  	s.expectedData = unsignedData
    99  	s.readerData = unsignedData
   100  	s.setupDataSource(testSigningKey)
   101  	s.assertFetchDataFail(c, `cannot read data for source "" at URL this.path.doesnt.matter.for.test.either: no PGP signature embedded in plain text data`)
   102  }
   103  
   104  func (s *fetchDataSuite) TestFetchUnsignedDataWithNotRequireSignedDataSourceWithPublicKey(c *gc.C) {
   105  	s.requireSigned = false
   106  	s.expectedCalls = []string{"Fetch"}
   107  	s.expectedData = unsignedData
   108  	s.readerData = unsignedData
   109  	s.setupDataSource(testSigningKey)
   110  	s.assertFetchData(c)
   111  }
   112  
   113  func (s *fetchDataSuite) TestFetchUnsignedDataWithNotRequireSignedDataSourceWithoutPublicKey(c *gc.C) {
   114  	s.requireSigned = false
   115  	s.expectedCalls = []string{"Fetch"}
   116  	s.readerData = unsignedData
   117  	s.expectedData = unsignedData
   118  	s.setupDataSource("")
   119  	s.assertFetchData(c)
   120  }
   121  
   122  func (s *fetchDataSuite) setupDataSource(key string) {
   123  	s.source = testing.NewStubDataSource()
   124  	s.source.FetchFunc = func(path string) (io.ReadCloser, string, error) {
   125  		r := bytes.NewReader([]byte(s.readerData))
   126  		return ioutil.NopCloser(r), path, nil
   127  	}
   128  	s.source.PublicSigningKeyFunc = func() string {
   129  		return key
   130  	}
   131  }
   132  
   133  func (s *fetchDataSuite) assertFetchData(c *gc.C) {
   134  	data, _, err := simplestreams.FetchData(s.source, "this.path.doesnt.matter.for.test.either", s.requireSigned)
   135  	c.Assert(err, jc.ErrorIsNil)
   136  	c.Assert([]byte(s.expectedData), gc.DeepEquals, data)
   137  	s.source.CheckCallNames(c, s.expectedCalls...)
   138  }
   139  
   140  func (s *fetchDataSuite) assertFetchDataFail(c *gc.C, msg string) {
   141  	data, _, err := simplestreams.FetchData(s.source, "this.path.doesnt.matter.for.test.either", s.requireSigned)
   142  	c.Assert(err, gc.ErrorMatches, msg)
   143  	c.Assert(data, gc.IsNil)
   144  	s.source.CheckCallNames(c, s.expectedCalls...)
   145  }