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 }