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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package api_test
     5  
     6  import (
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	charmresource "gopkg.in/juju/charm.v6/resource"
    15  	"gopkg.in/juju/names.v2"
    16  
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/resource"
    19  	"github.com/juju/juju/resource/api"
    20  	"github.com/juju/juju/resource/resourcetesting"
    21  )
    22  
    23  const fingerprint = "123456789012345678901234567890123456789012345678"
    24  
    25  type HelpersSuite struct {
    26  	testing.IsolationSuite
    27  }
    28  
    29  var _ = gc.Suite(&HelpersSuite{})
    30  
    31  func (HelpersSuite) TestResource2API(c *gc.C) {
    32  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
    33  	c.Assert(err, jc.ErrorIsNil)
    34  	now := time.Now()
    35  	res := resource.Resource{
    36  		Resource: charmresource.Resource{
    37  			Meta: charmresource.Meta{
    38  				Name:        "spam",
    39  				Type:        charmresource.TypeFile,
    40  				Path:        "spam.tgz",
    41  				Description: "you need it",
    42  			},
    43  			Origin:      charmresource.OriginUpload,
    44  			Revision:    1,
    45  			Fingerprint: fp,
    46  			Size:        10,
    47  		},
    48  		ID:            "a-application/spam",
    49  		PendingID:     "some-unique-ID",
    50  		ApplicationID: "a-application",
    51  		Username:      "a-user",
    52  		Timestamp:     now,
    53  	}
    54  	err = res.Validate()
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	apiRes := api.Resource2API(res)
    57  
    58  	c.Check(apiRes, jc.DeepEquals, params.Resource{
    59  		CharmResource: params.CharmResource{
    60  			Name:        "spam",
    61  			Type:        "file",
    62  			Path:        "spam.tgz",
    63  			Description: "you need it",
    64  			Origin:      "upload",
    65  			Revision:    1,
    66  			Fingerprint: []byte(fingerprint),
    67  			Size:        10,
    68  		},
    69  		ID:            "a-application/spam",
    70  		PendingID:     "some-unique-ID",
    71  		ApplicationID: "a-application",
    72  		Username:      "a-user",
    73  		Timestamp:     now,
    74  	})
    75  }
    76  
    77  func (HelpersSuite) TestAPIResult2ApplicationResourcesOkay(c *gc.C) {
    78  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	now := time.Now()
    81  	expected := resource.Resource{
    82  		Resource: charmresource.Resource{
    83  			Meta: charmresource.Meta{
    84  				Name:        "spam",
    85  				Type:        charmresource.TypeFile,
    86  				Path:        "spam.tgz",
    87  				Description: "you need it",
    88  			},
    89  			Origin:      charmresource.OriginUpload,
    90  			Revision:    1,
    91  			Fingerprint: fp,
    92  			Size:        10,
    93  		},
    94  		ID:            "a-application/spam",
    95  		PendingID:     "some-unique-ID",
    96  		ApplicationID: "a-application",
    97  		Username:      "a-user",
    98  		Timestamp:     now,
    99  	}
   100  	err = expected.Validate()
   101  	c.Assert(err, jc.ErrorIsNil)
   102  
   103  	unitExpected := resource.Resource{
   104  		Resource: charmresource.Resource{
   105  			Meta: charmresource.Meta{
   106  				Name:        "unitspam",
   107  				Type:        charmresource.TypeFile,
   108  				Path:        "unitspam.tgz",
   109  				Description: "you need it",
   110  			},
   111  			Origin:      charmresource.OriginUpload,
   112  			Revision:    1,
   113  			Fingerprint: fp,
   114  			Size:        10,
   115  		},
   116  		ID:            "a-application/spam",
   117  		PendingID:     "some-unique-ID",
   118  		ApplicationID: "a-application",
   119  		Username:      "a-user",
   120  		Timestamp:     now,
   121  	}
   122  	err = unitExpected.Validate()
   123  	c.Assert(err, jc.ErrorIsNil)
   124  
   125  	apiRes := params.Resource{
   126  		CharmResource: params.CharmResource{
   127  			Name:        "spam",
   128  			Type:        "file",
   129  			Path:        "spam.tgz",
   130  			Description: "you need it",
   131  			Origin:      "upload",
   132  			Revision:    1,
   133  			Fingerprint: []byte(fingerprint),
   134  			Size:        10,
   135  		},
   136  		ID:            "a-application/spam",
   137  		PendingID:     "some-unique-ID",
   138  		ApplicationID: "a-application",
   139  		Username:      "a-user",
   140  		Timestamp:     now,
   141  	}
   142  
   143  	unitRes := params.Resource{
   144  		CharmResource: params.CharmResource{
   145  			Name:        "unitspam",
   146  			Type:        "file",
   147  			Path:        "unitspam.tgz",
   148  			Description: "you need it",
   149  			Origin:      "upload",
   150  			Revision:    1,
   151  			Fingerprint: []byte(fingerprint),
   152  			Size:        10,
   153  		},
   154  		ID:            "a-application/spam",
   155  		PendingID:     "some-unique-ID",
   156  		ApplicationID: "a-application",
   157  		Username:      "a-user",
   158  		Timestamp:     now,
   159  	}
   160  
   161  	fp2, err := charmresource.GenerateFingerprint(strings.NewReader("boo!"))
   162  	c.Assert(err, jc.ErrorIsNil)
   163  
   164  	chRes := params.CharmResource{
   165  		Name:        "unitspam2",
   166  		Type:        "file",
   167  		Path:        "unitspam.tgz2",
   168  		Description: "you need it2",
   169  		Origin:      "upload",
   170  		Revision:    2,
   171  		Fingerprint: fp2.Bytes(),
   172  		Size:        11,
   173  	}
   174  
   175  	chExpected := charmresource.Resource{
   176  		Meta: charmresource.Meta{
   177  			Name:        "unitspam2",
   178  			Type:        charmresource.TypeFile,
   179  			Path:        "unitspam.tgz2",
   180  			Description: "you need it2",
   181  		},
   182  		Origin:      charmresource.OriginUpload,
   183  		Revision:    2,
   184  		Fingerprint: fp2,
   185  		Size:        11,
   186  	}
   187  
   188  	resources, err := api.APIResult2ApplicationResources(params.ResourcesResult{
   189  		Resources: []params.Resource{
   190  			apiRes,
   191  		},
   192  		CharmStoreResources: []params.CharmResource{
   193  			chRes,
   194  		},
   195  		UnitResources: []params.UnitResources{
   196  			{
   197  				Entity: params.Entity{
   198  					Tag: "unit-foo-0",
   199  				},
   200  				Resources: []params.Resource{
   201  					unitRes,
   202  				},
   203  				DownloadProgress: map[string]int64{
   204  					unitRes.Name: 8,
   205  				},
   206  			},
   207  		},
   208  	})
   209  	c.Assert(err, jc.ErrorIsNil)
   210  
   211  	serviceResource := resource.ApplicationResources{
   212  		Resources: []resource.Resource{
   213  			expected,
   214  		},
   215  		CharmStoreResources: []charmresource.Resource{
   216  			chExpected,
   217  		},
   218  		UnitResources: []resource.UnitResources{
   219  			{
   220  				Tag: names.NewUnitTag("foo/0"),
   221  				Resources: []resource.Resource{
   222  					unitExpected,
   223  				},
   224  				DownloadProgress: map[string]int64{
   225  					unitRes.Name: 8,
   226  				},
   227  			},
   228  		},
   229  	}
   230  
   231  	c.Check(resources, jc.DeepEquals, serviceResource)
   232  }
   233  
   234  func (HelpersSuite) TestAPIResult2ApplicationResourcesBadUnitTag(c *gc.C) {
   235  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
   236  	c.Assert(err, jc.ErrorIsNil)
   237  	now := time.Now()
   238  	expected := resource.Resource{
   239  		Resource: charmresource.Resource{
   240  			Meta: charmresource.Meta{
   241  				Name:        "spam",
   242  				Type:        charmresource.TypeFile,
   243  				Path:        "spam.tgz",
   244  				Description: "you need it",
   245  			},
   246  			Origin:      charmresource.OriginUpload,
   247  			Revision:    1,
   248  			Fingerprint: fp,
   249  			Size:        10,
   250  		},
   251  		ID:            "a-application/spam",
   252  		PendingID:     "some-unique-ID",
   253  		ApplicationID: "a-application",
   254  		Username:      "a-user",
   255  		Timestamp:     now,
   256  	}
   257  	err = expected.Validate()
   258  	c.Assert(err, jc.ErrorIsNil)
   259  
   260  	unitExpected := resource.Resource{
   261  		Resource: charmresource.Resource{
   262  			Meta: charmresource.Meta{
   263  				Name:        "unitspam",
   264  				Type:        charmresource.TypeFile,
   265  				Path:        "unitspam.tgz",
   266  				Description: "you need it",
   267  			},
   268  			Origin:      charmresource.OriginUpload,
   269  			Revision:    1,
   270  			Fingerprint: fp,
   271  			Size:        10,
   272  		},
   273  		ID:            "a-application/spam",
   274  		PendingID:     "some-unique-ID",
   275  		ApplicationID: "a-application",
   276  		Username:      "a-user",
   277  		Timestamp:     now,
   278  	}
   279  	err = unitExpected.Validate()
   280  	c.Assert(err, jc.ErrorIsNil)
   281  
   282  	apiRes := params.Resource{
   283  		CharmResource: params.CharmResource{
   284  			Name:        "spam",
   285  			Type:        "file",
   286  			Path:        "spam.tgz",
   287  			Description: "you need it",
   288  			Origin:      "upload",
   289  			Revision:    1,
   290  			Fingerprint: []byte(fingerprint),
   291  			Size:        10,
   292  		},
   293  		ID:            "a-application/spam",
   294  		PendingID:     "some-unique-ID",
   295  		ApplicationID: "a-application",
   296  		Username:      "a-user",
   297  		Timestamp:     now,
   298  	}
   299  
   300  	unitRes := params.Resource{
   301  		CharmResource: params.CharmResource{
   302  			Name:        "unitspam",
   303  			Type:        "file",
   304  			Path:        "unitspam.tgz",
   305  			Description: "you need it",
   306  			Origin:      "upload",
   307  			Revision:    1,
   308  			Fingerprint: []byte(fingerprint),
   309  			Size:        10,
   310  		},
   311  		ID:            "a-application/spam",
   312  		PendingID:     "some-unique-ID",
   313  		ApplicationID: "a-application",
   314  		Username:      "a-user",
   315  		Timestamp:     now,
   316  	}
   317  
   318  	_, err = api.APIResult2ApplicationResources(params.ResourcesResult{
   319  		Resources: []params.Resource{
   320  			apiRes,
   321  		},
   322  		UnitResources: []params.UnitResources{
   323  			{
   324  				Entity: params.Entity{
   325  					Tag: "THIS IS NOT A GOOD UNIT TAG",
   326  				},
   327  				Resources: []params.Resource{
   328  					unitRes,
   329  				},
   330  			},
   331  		},
   332  	})
   333  	c.Assert(err, gc.ErrorMatches, ".*got bad data from server.*")
   334  }
   335  
   336  func (HelpersSuite) TestAPIResult2ApplicationResourcesFailure(c *gc.C) {
   337  	apiRes := params.Resource{
   338  		CharmResource: params.CharmResource{
   339  			Name:        "spam",
   340  			Type:        "file",
   341  			Path:        "spam.tgz",
   342  			Origin:      "upload",
   343  			Revision:    1,
   344  			Fingerprint: []byte(fingerprint),
   345  			Size:        10,
   346  		},
   347  		ID:            "a-application/spam",
   348  		ApplicationID: "a-application",
   349  	}
   350  	failure := errors.New("<failure>")
   351  
   352  	_, err := api.APIResult2ApplicationResources(params.ResourcesResult{
   353  		ErrorResult: params.ErrorResult{
   354  			Error: &params.Error{
   355  				Message: failure.Error(),
   356  			},
   357  		},
   358  		Resources: []params.Resource{
   359  			apiRes,
   360  		},
   361  	})
   362  
   363  	c.Check(err, gc.ErrorMatches, "<failure>")
   364  	c.Check(errors.Cause(err), gc.Not(gc.Equals), failure)
   365  }
   366  
   367  func (HelpersSuite) TestAPIResult2ApplicationResourcesNotFound(c *gc.C) {
   368  	apiRes := params.Resource{
   369  		CharmResource: params.CharmResource{
   370  			Name:        "spam",
   371  			Type:        "file",
   372  			Path:        "spam.tgz",
   373  			Origin:      "upload",
   374  			Revision:    1,
   375  			Fingerprint: []byte(fingerprint),
   376  			Size:        10,
   377  		},
   378  		ID:            "a-application/spam",
   379  		ApplicationID: "a-application",
   380  	}
   381  
   382  	_, err := api.APIResult2ApplicationResources(params.ResourcesResult{
   383  		ErrorResult: params.ErrorResult{
   384  			Error: &params.Error{
   385  				Message: `application "a-application" not found`,
   386  				Code:    params.CodeNotFound,
   387  			},
   388  		},
   389  		Resources: []params.Resource{
   390  			apiRes,
   391  		},
   392  	})
   393  
   394  	c.Check(err, jc.Satisfies, errors.IsNotFound)
   395  }
   396  
   397  func (HelpersSuite) TestAPI2Resource(c *gc.C) {
   398  	now := time.Now()
   399  	res, err := api.API2Resource(params.Resource{
   400  		CharmResource: params.CharmResource{
   401  			Name:        "spam",
   402  			Type:        "file",
   403  			Path:        "spam.tgz",
   404  			Description: "you need it",
   405  			Origin:      "upload",
   406  			Revision:    1,
   407  			Fingerprint: []byte(fingerprint),
   408  			Size:        10,
   409  		},
   410  		ID:            "a-application/spam",
   411  		PendingID:     "some-unique-ID",
   412  		ApplicationID: "a-application",
   413  		Username:      "a-user",
   414  		Timestamp:     now,
   415  	})
   416  	c.Assert(err, jc.ErrorIsNil)
   417  
   418  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
   419  	c.Assert(err, jc.ErrorIsNil)
   420  	expected := resource.Resource{
   421  		Resource: charmresource.Resource{
   422  			Meta: charmresource.Meta{
   423  				Name:        "spam",
   424  				Type:        charmresource.TypeFile,
   425  				Path:        "spam.tgz",
   426  				Description: "you need it",
   427  			},
   428  			Origin:      charmresource.OriginUpload,
   429  			Revision:    1,
   430  			Fingerprint: fp,
   431  			Size:        10,
   432  		},
   433  		ID:            "a-application/spam",
   434  		PendingID:     "some-unique-ID",
   435  		ApplicationID: "a-application",
   436  		Username:      "a-user",
   437  		Timestamp:     now,
   438  	}
   439  	err = expected.Validate()
   440  	c.Assert(err, jc.ErrorIsNil)
   441  
   442  	c.Check(res, jc.DeepEquals, expected)
   443  }
   444  
   445  func (HelpersSuite) TestCharmResource2API(c *gc.C) {
   446  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
   447  	c.Assert(err, jc.ErrorIsNil)
   448  	res := charmresource.Resource{
   449  		Meta: charmresource.Meta{
   450  			Name:        "spam",
   451  			Type:        charmresource.TypeFile,
   452  			Path:        "spam.tgz",
   453  			Description: "you need it",
   454  		},
   455  		Origin:      charmresource.OriginUpload,
   456  		Revision:    1,
   457  		Fingerprint: fp,
   458  		Size:        10,
   459  	}
   460  	err = res.Validate()
   461  	c.Assert(err, jc.ErrorIsNil)
   462  	apiInfo := api.CharmResource2API(res)
   463  
   464  	c.Check(apiInfo, jc.DeepEquals, params.CharmResource{
   465  		Name:        "spam",
   466  		Type:        "file",
   467  		Path:        "spam.tgz",
   468  		Description: "you need it",
   469  		Origin:      "upload",
   470  		Revision:    1,
   471  		Fingerprint: []byte(fingerprint),
   472  		Size:        10,
   473  	})
   474  }
   475  
   476  func (HelpersSuite) TestAPI2CharmResource(c *gc.C) {
   477  	res, err := api.API2CharmResource(params.CharmResource{
   478  		Name:        "spam",
   479  		Type:        "file",
   480  		Path:        "spam.tgz",
   481  		Description: "you need it",
   482  		Origin:      "upload",
   483  		Revision:    1,
   484  		Fingerprint: []byte(fingerprint),
   485  		Size:        10,
   486  	})
   487  	c.Assert(err, jc.ErrorIsNil)
   488  
   489  	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
   490  	c.Assert(err, jc.ErrorIsNil)
   491  	expected := charmresource.Resource{
   492  		Meta: charmresource.Meta{
   493  			Name:        "spam",
   494  			Type:        charmresource.TypeFile,
   495  			Path:        "spam.tgz",
   496  			Description: "you need it",
   497  		},
   498  		Origin:      charmresource.OriginUpload,
   499  		Revision:    1,
   500  		Fingerprint: fp,
   501  		Size:        10,
   502  	}
   503  	err = expected.Validate()
   504  	c.Assert(err, jc.ErrorIsNil)
   505  
   506  	c.Check(res, jc.DeepEquals, expected)
   507  }
   508  
   509  func (HelpersSuite) TestServiceResources2API(c *gc.C) {
   510  	res1 := resourcetesting.NewResource(c, nil, "res1", "a-application", "data").Resource
   511  	res2 := resourcetesting.NewResource(c, nil, "res2", "a-application", "data2").Resource
   512  
   513  	tag0 := names.NewUnitTag("a-application/0")
   514  	tag1 := names.NewUnitTag("a-application/1")
   515  
   516  	chres1 := res1.Resource
   517  	chres2 := res2.Resource
   518  	chres1.Revision++
   519  	chres2.Revision++
   520  
   521  	svcRes := resource.ApplicationResources{
   522  		Resources: []resource.Resource{
   523  			res1,
   524  			res2,
   525  		},
   526  		UnitResources: []resource.UnitResources{
   527  			{
   528  				Tag: tag0,
   529  				Resources: []resource.Resource{
   530  					res1,
   531  					res2,
   532  				},
   533  				DownloadProgress: map[string]int64{
   534  					res2.Name: 2,
   535  				},
   536  			},
   537  			{
   538  				Tag: tag1,
   539  			},
   540  		},
   541  		CharmStoreResources: []charmresource.Resource{
   542  			chres1,
   543  			chres2,
   544  		},
   545  	}
   546  
   547  	result := api.ApplicationResources2APIResult(svcRes)
   548  
   549  	apiRes1 := api.Resource2API(res1)
   550  	apiRes2 := api.Resource2API(res2)
   551  
   552  	apiChRes1 := api.CharmResource2API(chres1)
   553  	apiChRes2 := api.CharmResource2API(chres2)
   554  
   555  	c.Check(result, jc.DeepEquals, params.ResourcesResult{
   556  		Resources: []params.Resource{
   557  			apiRes1,
   558  			apiRes2,
   559  		},
   560  		UnitResources: []params.UnitResources{
   561  			{
   562  				Entity: params.Entity{
   563  					Tag: "unit-a-application-0",
   564  				},
   565  				Resources: []params.Resource{
   566  					apiRes1,
   567  					apiRes2,
   568  				},
   569  				DownloadProgress: map[string]int64{
   570  					res2.Name: 2,
   571  				},
   572  			},
   573  			{
   574  				// we should have a listing for every unit, even if they
   575  				// have no resources.
   576  				Entity: params.Entity{
   577  					Tag: "unit-a-application-1",
   578  				},
   579  			},
   580  		},
   581  		CharmStoreResources: []params.CharmResource{
   582  			apiChRes1,
   583  			apiChRes2,
   584  		},
   585  	})
   586  }