github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/resource/api/client/client_upload_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package client_test
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"strings"
    11  
    12  	"github.com/juju/errors"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils"
    16  	gc "gopkg.in/check.v1"
    17  	"gopkg.in/juju/charm.v6"
    18  	charmresource "gopkg.in/juju/charm.v6/resource"
    19  
    20  	"github.com/juju/juju/charmstore"
    21  	"github.com/juju/juju/resource/api/client"
    22  )
    23  
    24  var _ = gc.Suite(&UploadSuite{})
    25  
    26  type UploadSuite struct {
    27  	BaseSuite
    28  }
    29  
    30  func (s *UploadSuite) TestOkay(c *gc.C) {
    31  	data := "<data>"
    32  	reader := &stubFile{stub: s.stub}
    33  	reader.returnRead = strings.NewReader(data)
    34  	cl := client.NewClient(s.facade, s, s.facade)
    35  
    36  	_, s.response.Resource = newResource(c, "spam", "a-user", data)
    37  
    38  	err := cl.Upload("a-application", "spam", "foo.zip", reader)
    39  	c.Assert(err, jc.ErrorIsNil)
    40  
    41  	fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
    42  	c.Assert(err, jc.ErrorIsNil)
    43  	req, err := http.NewRequest("PUT", "/applications/a-application/resources/spam", nil)
    44  	c.Assert(err, jc.ErrorIsNil)
    45  	req.Header.Set("Content-Type", "application/octet-stream")
    46  	req.Header.Set("Content-SHA384", fp.String())
    47  	req.Header.Set("Content-Length", fmt.Sprint(len(data)))
    48  	req.Header.Set("Content-Disposition", "form-data; filename=foo.zip")
    49  	req.ContentLength = int64(len(data))
    50  
    51  	s.stub.CheckCallNames(c, "Read", "Read", "Seek", "Do")
    52  	s.stub.CheckCall(c, 3, "Do", req, reader, s.response)
    53  }
    54  
    55  func (s *UploadSuite) TestBadService(c *gc.C) {
    56  	cl := client.NewClient(s.facade, s, s.facade)
    57  
    58  	err := cl.Upload("???", "spam", "file.zip", nil)
    59  
    60  	c.Check(err, gc.ErrorMatches, `.*invalid application.*`)
    61  	s.stub.CheckNoCalls(c)
    62  }
    63  
    64  func (s *UploadSuite) TestBadRequest(c *gc.C) {
    65  	reader := &stubFile{stub: s.stub}
    66  	cl := client.NewClient(s.facade, s, s.facade)
    67  	failure := errors.New("<failure>")
    68  	s.stub.SetErrors(failure)
    69  
    70  	err := cl.Upload("a-application", "spam", "file.zip", reader)
    71  
    72  	c.Check(errors.Cause(err), gc.Equals, failure)
    73  	s.stub.CheckCallNames(c, "Read")
    74  }
    75  
    76  func (s *UploadSuite) TestRequestFailed(c *gc.C) {
    77  	reader := &stubFile{stub: s.stub}
    78  	reader.returnRead = strings.NewReader("<data>")
    79  	cl := client.NewClient(s.facade, s, s.facade)
    80  	failure := errors.New("<failure>")
    81  	s.stub.SetErrors(nil, nil, nil, failure)
    82  
    83  	err := cl.Upload("a-application", "spam", "file.zip", reader)
    84  
    85  	c.Check(errors.Cause(err), gc.Equals, failure)
    86  	s.stub.CheckCallNames(c, "Read", "Read", "Seek", "Do")
    87  }
    88  
    89  func (s *UploadSuite) TestPendingResources(c *gc.C) {
    90  	res, apiResult := newResourceResult(c, "a-application", "spam")
    91  	resources := []charmresource.Resource{res[0].Resource}
    92  	uuid, err := utils.NewUUID()
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	expected := []string{uuid.String()}
    95  	s.response.Resource = apiResult.Resources[0]
    96  	s.facade.pendingIDs = expected
    97  	cURL := charm.MustParseURL("cs:~a-user/trusty/spam-5")
    98  	cl := client.NewClient(s.facade, s, s.facade)
    99  
   100  	pendingIDs, err := cl.AddPendingResources(client.AddPendingResourcesArgs{
   101  		ApplicationID: "a-application",
   102  		CharmID: charmstore.CharmID{
   103  			URL: cURL,
   104  		},
   105  		Resources: resources,
   106  	})
   107  	c.Assert(err, jc.ErrorIsNil)
   108  
   109  	s.stub.CheckCallNames(c, "FacadeCall")
   110  	//s.stub.CheckCall(c, 0, "FacadeCall", "AddPendingResources", args, result)
   111  	c.Check(pendingIDs, jc.DeepEquals, expected)
   112  }
   113  
   114  func (s *UploadSuite) TestPendingResourceOkay(c *gc.C) {
   115  	res, apiResult := newResourceResult(c, "a-application", "spam")
   116  	uuid, err := utils.NewUUID()
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	expected := uuid.String()
   119  	s.response.Resource = apiResult.Resources[0]
   120  	data := "<data>"
   121  	reader := &stubFile{stub: s.stub}
   122  	reader.returnRead = strings.NewReader(data)
   123  	s.facade.pendingIDs = []string{expected}
   124  	cl := client.NewClient(s.facade, s, s.facade)
   125  
   126  	uploadID, err := cl.UploadPendingResource("a-application", res[0].Resource, "file.zip", reader)
   127  	c.Assert(err, jc.ErrorIsNil)
   128  
   129  	s.stub.CheckCallNames(c,
   130  		"FacadeCall",
   131  		"Read",
   132  		"Read",
   133  		"Seek",
   134  		"Do",
   135  	)
   136  
   137  	fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
   138  	c.Assert(err, jc.ErrorIsNil)
   139  	req, err := http.NewRequest("PUT", "/applications/a-application/resources/spam", nil)
   140  	c.Assert(err, jc.ErrorIsNil)
   141  	req.Header.Set("Content-Type", "application/octet-stream")
   142  	req.Header.Set("Content-SHA384", fp.String())
   143  	req.Header.Set("Content-Length", fmt.Sprint(len(data)))
   144  	req.ContentLength = int64(len(data))
   145  	req.URL.RawQuery = "pendingid=" + expected
   146  	req.Header.Set("Content-Disposition", "form-data; filename=file.zip")
   147  
   148  	s.stub.CheckCall(c, 4, "Do", req, reader, s.response)
   149  	c.Check(uploadID, gc.Equals, expected)
   150  }
   151  
   152  func (s *UploadSuite) TestPendingResourceNoFile(c *gc.C) {
   153  	res, apiResult := newResourceResult(c, "a-application", "spam")
   154  	uuid, err := utils.NewUUID()
   155  	c.Assert(err, jc.ErrorIsNil)
   156  	expected := uuid.String()
   157  	s.response.Resource = apiResult.Resources[0]
   158  	s.facade.pendingIDs = []string{expected}
   159  	cl := client.NewClient(s.facade, s, s.facade)
   160  
   161  	uploadID, err := cl.UploadPendingResource("a-application", res[0].Resource, "file.zip", nil)
   162  	c.Assert(err, jc.ErrorIsNil)
   163  
   164  	s.stub.CheckCallNames(c,
   165  		"FacadeCall",
   166  	)
   167  	c.Check(uploadID, gc.Equals, expected)
   168  }
   169  
   170  func (s *UploadSuite) TestPendingResourceBadService(c *gc.C) {
   171  	res, _ := newResourceResult(c, "a-application", "spam")
   172  	s.facade.FacadeCallFn = nil
   173  	cl := client.NewClient(s.facade, s, s.facade)
   174  
   175  	_, err := cl.UploadPendingResource("???", res[0].Resource, "file.zip", nil)
   176  
   177  	c.Check(err, gc.ErrorMatches, `.*invalid application.*`)
   178  	s.stub.CheckNoCalls(c)
   179  }
   180  
   181  func (s *UploadSuite) TestPendingResourceBadRequest(c *gc.C) {
   182  	res, _ := newResource(c, "spam", "", "")
   183  	chRes := res.Resource
   184  	reader := &stubFile{stub: s.stub}
   185  	s.facade.pendingIDs = []string{"some-unique-id"}
   186  	cl := client.NewClient(s.facade, s, s.facade)
   187  	failure := errors.New("<failure>")
   188  	s.stub.SetErrors(nil, failure)
   189  
   190  	_, err := cl.UploadPendingResource("a-application", chRes, "file.zip", reader)
   191  
   192  	c.Check(errors.Cause(err), gc.Equals, failure)
   193  	s.stub.CheckCallNames(c, "FacadeCall", "Read")
   194  }
   195  
   196  func (s *UploadSuite) TestPendingResourceRequestFailed(c *gc.C) {
   197  	res, _ := newResourceResult(c, "a-application", "spam")
   198  	reader := &stubFile{stub: s.stub}
   199  	reader.returnRead = strings.NewReader("<data>")
   200  	s.facade.pendingIDs = []string{"some-unique-id"}
   201  	cl := client.NewClient(s.facade, s, s.facade)
   202  	failure := errors.New("<failure>")
   203  	s.stub.SetErrors(nil, nil, nil, nil, failure)
   204  
   205  	_, err := cl.UploadPendingResource("a-application", res[0].Resource, "file.zip", reader)
   206  
   207  	c.Check(errors.Cause(err), gc.Equals, failure)
   208  	s.stub.CheckCallNames(c,
   209  		"FacadeCall",
   210  		"Read",
   211  		"Read",
   212  		"Seek",
   213  		"Do",
   214  	)
   215  }
   216  
   217  type stubFile struct {
   218  	stub *testing.Stub
   219  
   220  	returnRead io.Reader
   221  	returnSeek int64
   222  }
   223  
   224  func (s *stubFile) Read(buf []byte) (int, error) {
   225  	s.stub.AddCall("Read", buf)
   226  	if err := s.stub.NextErr(); err != nil {
   227  		return 0, errors.Trace(err)
   228  	}
   229  
   230  	return s.returnRead.Read(buf)
   231  }
   232  
   233  func (s *stubFile) Seek(offset int64, whence int) (int64, error) {
   234  	s.stub.AddCall("Seek", offset, whence)
   235  	if err := s.stub.NextErr(); err != nil {
   236  		return 0, errors.Trace(err)
   237  	}
   238  
   239  	return s.returnSeek, nil
   240  }
   241  
   242  func (s *stubFile) Close() error {
   243  	s.stub.AddCall("Close")
   244  	if err := s.stub.NextErr(); err != nil {
   245  		return errors.Trace(err)
   246  	}
   247  
   248  	return nil
   249  }