github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/resource/cmd/show_service_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cmd
     5  
     6  import (
     7  	"time"
     8  
     9  	jujucmd "github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/names"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  	charmresource "gopkg.in/juju/charm.v6-unstable/resource"
    16  
    17  	"github.com/juju/juju/resource"
    18  )
    19  
    20  var _ = gc.Suite(&ShowServiceSuite{})
    21  
    22  type ShowServiceSuite struct {
    23  	testing.IsolationSuite
    24  
    25  	stubDeps *stubShowServiceDeps
    26  }
    27  
    28  func (s *ShowServiceSuite) SetUpTest(c *gc.C) {
    29  	s.IsolationSuite.SetUpTest(c)
    30  
    31  	stub := &testing.Stub{}
    32  	s.stubDeps = &stubShowServiceDeps{
    33  		stub:   stub,
    34  		client: &stubServiceClient{stub: stub},
    35  	}
    36  }
    37  
    38  func (*ShowServiceSuite) TestInitEmpty(c *gc.C) {
    39  	s := ShowServiceCommand{}
    40  
    41  	err := s.Init([]string{})
    42  	c.Assert(err, jc.Satisfies, errors.IsBadRequest)
    43  }
    44  
    45  func (*ShowServiceSuite) TestInitGood(c *gc.C) {
    46  	s := ShowServiceCommand{}
    47  	err := s.Init([]string{"foo"})
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	c.Assert(s.target, gc.Equals, "foo")
    50  }
    51  
    52  func (*ShowServiceSuite) TestInitTooManyArgs(c *gc.C) {
    53  	s := ShowServiceCommand{}
    54  
    55  	err := s.Init([]string{"foo", "bar"})
    56  	c.Assert(err, jc.Satisfies, errors.IsBadRequest)
    57  }
    58  
    59  func (s *ShowServiceSuite) TestInfo(c *gc.C) {
    60  	var command ShowServiceCommand
    61  	info := command.Info()
    62  
    63  	c.Check(info, jc.DeepEquals, &jujucmd.Info{
    64  		Name:    "list-resources",
    65  		Aliases: []string{"resources"},
    66  		Args:    "service-or-unit",
    67  		Purpose: "show the resources for a service or unit",
    68  		Doc: `
    69  This command shows the resources required by and those in use by an existing
    70  service or unit in your model.  When run for a service, it will also show any
    71  updates available for resources from the charmstore.
    72  `,
    73  	})
    74  }
    75  
    76  func (s *ShowServiceSuite) TestRun(c *gc.C) {
    77  	data := []resource.ServiceResources{
    78  		{
    79  			Resources: []resource.Resource{
    80  				{
    81  					Resource: charmresource.Resource{
    82  						Meta: charmresource.Meta{
    83  							Name:        "openjdk",
    84  							Description: "the java runtime",
    85  						},
    86  						Origin:   charmresource.OriginStore,
    87  						Revision: 7,
    88  					},
    89  				},
    90  				{
    91  					Resource: charmresource.Resource{
    92  						Meta: charmresource.Meta{
    93  							Name:        "website",
    94  							Description: "your website data",
    95  						},
    96  						Origin: charmresource.OriginUpload,
    97  					},
    98  				},
    99  				{
   100  					Resource: charmresource.Resource{
   101  						Meta: charmresource.Meta{
   102  							Name:        "rsc1234",
   103  							Description: "a big description",
   104  						},
   105  						Origin:   charmresource.OriginStore,
   106  						Revision: 15,
   107  					},
   108  					Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   109  				},
   110  				{
   111  					Resource: charmresource.Resource{
   112  						Meta: charmresource.Meta{
   113  							Name:        "website2",
   114  							Description: "awesome data",
   115  						},
   116  						Origin: charmresource.OriginUpload,
   117  					},
   118  					Username:  "Bill User",
   119  					Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   120  				},
   121  			},
   122  			CharmStoreResources: []charmresource.Resource{
   123  				{
   124  					// This resource has a higher revision than the corresponding one
   125  					// above.
   126  					Meta: charmresource.Meta{
   127  						Name:        "openjdk",
   128  						Description: "the java runtime",
   129  						Type:        charmresource.TypeFile,
   130  						Path:        "foobar",
   131  					},
   132  					Revision: 10,
   133  					Origin:   charmresource.OriginStore,
   134  				},
   135  				{
   136  					// This resource is the same revision as the corresponding one
   137  					// above.
   138  					Meta: charmresource.Meta{
   139  						Name:        "rsc1234",
   140  						Description: "a big description",
   141  						Type:        charmresource.TypeFile,
   142  						Path:        "foobar",
   143  					},
   144  					Revision: 15,
   145  					Origin:   charmresource.OriginStore,
   146  				},
   147  				{
   148  					Meta: charmresource.Meta{
   149  						Name:        "website",
   150  						Description: "your website data",
   151  					},
   152  					Origin: charmresource.OriginUpload,
   153  				},
   154  				{
   155  					Meta: charmresource.Meta{
   156  						Name:        "website2",
   157  						Description: "awesome data",
   158  					},
   159  					Origin: charmresource.OriginUpload,
   160  				},
   161  			},
   162  		},
   163  	}
   164  	s.stubDeps.client.ReturnResources = data
   165  
   166  	cmd := &ShowServiceCommand{
   167  		deps: ShowServiceDeps{
   168  			NewClient: s.stubDeps.NewClient,
   169  		},
   170  	}
   171  
   172  	code, stdout, stderr := runCmd(c, cmd, "svc")
   173  	c.Check(code, gc.Equals, 0)
   174  	c.Check(stderr, gc.Equals, "")
   175  
   176  	c.Check(stdout, gc.Equals, `
   177  [Service]
   178  RESOURCE SUPPLIED BY REVISION
   179  openjdk  charmstore  7
   180  website  upload      -
   181  rsc1234  charmstore  15
   182  website2 Bill User   2012-12-12T12:12
   183  
   184  [Updates Available]
   185  RESOURCE REVISION
   186  openjdk  10
   187  
   188  `[1:])
   189  
   190  	s.stubDeps.stub.CheckCall(c, 1, "ListResources", []string{"svc"})
   191  }
   192  
   193  func (s *ShowServiceSuite) TestRunUnit(c *gc.C) {
   194  	data := []resource.ServiceResources{{
   195  		UnitResources: []resource.UnitResources{{
   196  			Tag: names.NewUnitTag("svc/0"),
   197  			Resources: []resource.Resource{
   198  				{
   199  					Resource: charmresource.Resource{
   200  						Meta: charmresource.Meta{
   201  							Name:        "rsc1234",
   202  							Description: "a big description",
   203  						},
   204  						Origin:   charmresource.OriginStore,
   205  						Revision: 15,
   206  					},
   207  					Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   208  				},
   209  				{
   210  					Resource: charmresource.Resource{
   211  						Meta: charmresource.Meta{
   212  							Name:        "website2",
   213  							Description: "awesome data",
   214  						},
   215  						Origin: charmresource.OriginUpload,
   216  						Size:   15,
   217  					},
   218  					Username:  "Bill User",
   219  					Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   220  				},
   221  			},
   222  			DownloadProgress: map[string]int64{
   223  				"website2": 12,
   224  			},
   225  		}},
   226  	}}
   227  	s.stubDeps.client.ReturnResources = data
   228  
   229  	cmd := &ShowServiceCommand{
   230  		deps: ShowServiceDeps{
   231  			NewClient: s.stubDeps.NewClient,
   232  		},
   233  	}
   234  
   235  	code, stdout, stderr := runCmd(c, cmd, "svc/0")
   236  	c.Assert(code, gc.Equals, 0)
   237  	c.Assert(stderr, gc.Equals, "")
   238  
   239  	c.Check(stdout, gc.Equals, `
   240  [Unit]
   241  RESOURCE REVISION
   242  rsc1234  15
   243  website2 2012-12-12T12:12
   244  
   245  `[1:])
   246  
   247  	s.stubDeps.stub.CheckCall(c, 1, "ListResources", []string{"svc"})
   248  }
   249  
   250  func (s *ShowServiceSuite) TestRunDetails(c *gc.C) {
   251  	data := []resource.ServiceResources{{
   252  		Resources: []resource.Resource{
   253  			{
   254  				Resource: charmresource.Resource{
   255  					Meta: charmresource.Meta{
   256  						Name:        "alpha",
   257  						Description: "a big comment",
   258  					},
   259  					Origin:   charmresource.OriginStore,
   260  					Revision: 15,
   261  					Size:     113,
   262  				},
   263  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   264  			},
   265  			{
   266  				Resource: charmresource.Resource{
   267  					Meta: charmresource.Meta{
   268  						Name:        "charlie",
   269  						Description: "awesome data",
   270  					},
   271  					Origin: charmresource.OriginUpload,
   272  					Size:   9835617,
   273  				},
   274  				Username:  "Bill User",
   275  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   276  			},
   277  			{
   278  				Resource: charmresource.Resource{
   279  					Meta: charmresource.Meta{
   280  						Name:        "beta",
   281  						Description: "more data",
   282  					},
   283  					Origin: charmresource.OriginUpload,
   284  				},
   285  				Username:  "Bill User",
   286  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   287  			},
   288  		},
   289  		CharmStoreResources: []charmresource.Resource{
   290  			{
   291  				Meta: charmresource.Meta{
   292  					Name:        "alpha",
   293  					Description: "a big comment",
   294  				},
   295  				Origin:   charmresource.OriginStore,
   296  				Revision: 15,
   297  			},
   298  			{
   299  				Meta: charmresource.Meta{
   300  					Name:        "charlie",
   301  					Description: "awesome data",
   302  				},
   303  				Origin: charmresource.OriginUpload,
   304  			},
   305  			{
   306  				Meta: charmresource.Meta{
   307  					Name:        "beta",
   308  					Description: "more data",
   309  				},
   310  				Origin: charmresource.OriginUpload,
   311  			},
   312  		},
   313  		UnitResources: []resource.UnitResources{
   314  			{
   315  				Tag: names.NewUnitTag("svc/10"),
   316  				Resources: []resource.Resource{
   317  					{
   318  						Resource: charmresource.Resource{
   319  							Meta: charmresource.Meta{
   320  								Name:        "alpha",
   321  								Description: "a big comment",
   322  							},
   323  							Origin:   charmresource.OriginStore,
   324  							Revision: 10, // note the reivision is different for this unit
   325  						},
   326  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   327  					},
   328  					{
   329  						Resource: charmresource.Resource{
   330  							Meta: charmresource.Meta{
   331  								Name:        "charlie",
   332  								Description: "awesome data",
   333  							},
   334  							Origin: charmresource.OriginUpload,
   335  						},
   336  						Username: "Bill User",
   337  						// note the different time
   338  						Timestamp: time.Date(2011, 11, 11, 11, 11, 11, 0, time.UTC),
   339  					},
   340  					// note we're missing the beta resource for this unit
   341  				},
   342  				DownloadProgress: map[string]int64{
   343  					"alpha":   17,
   344  					"charlie": 899937,
   345  				},
   346  			},
   347  			{
   348  				Tag: names.NewUnitTag("svc/5"),
   349  				Resources: []resource.Resource{
   350  					{
   351  						Resource: charmresource.Resource{
   352  							Meta: charmresource.Meta{
   353  								Name:        "alpha",
   354  								Description: "a big comment",
   355  							},
   356  							Origin:   charmresource.OriginStore,
   357  							Revision: 10, // note the reivision is different for this unit
   358  						},
   359  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   360  					},
   361  					{
   362  						Resource: charmresource.Resource{
   363  							Meta: charmresource.Meta{
   364  								Name:        "charlie",
   365  								Description: "awesome data",
   366  							},
   367  							Origin: charmresource.OriginUpload,
   368  						},
   369  						Username: "Bill User",
   370  						// note the different time
   371  						Timestamp: time.Date(2011, 11, 11, 11, 11, 11, 0, time.UTC),
   372  					},
   373  					{
   374  						Resource: charmresource.Resource{
   375  							Meta: charmresource.Meta{
   376  								Name:        "beta",
   377  								Description: "more data",
   378  							},
   379  							Origin: charmresource.OriginUpload,
   380  						},
   381  						Username:  "Bill User",
   382  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   383  					},
   384  				},
   385  				DownloadProgress: map[string]int64{
   386  					"charlie": 177331,
   387  				},
   388  			},
   389  		},
   390  	}}
   391  	s.stubDeps.client.ReturnResources = data
   392  
   393  	cmd := &ShowServiceCommand{
   394  		deps: ShowServiceDeps{
   395  			NewClient: s.stubDeps.NewClient,
   396  		},
   397  	}
   398  
   399  	code, stdout, stderr := runCmd(c, cmd, "svc", "--details")
   400  	c.Check(code, gc.Equals, 0)
   401  	c.Check(stderr, gc.Equals, "")
   402  
   403  	c.Check(stdout, gc.Equals, `
   404  [Units]
   405  UNIT RESOURCE REVISION         EXPECTED
   406  5    alpha    10               15
   407  5    beta     2012-12-12T12:12 2012-12-12T12:12
   408  5    charlie  2011-11-11T11:11 2012-12-12T12:12 (fetching: 2%)
   409  10   alpha    10               15 (fetching: 15%)
   410  10   beta     -                2012-12-12T12:12
   411  10   charlie  2011-11-11T11:11 2012-12-12T12:12 (fetching: 9%)
   412  
   413  `[1:])
   414  
   415  	s.stubDeps.stub.CheckCall(c, 1, "ListResources", []string{"svc"})
   416  }
   417  
   418  func (s *ShowServiceSuite) TestRunUnitDetails(c *gc.C) {
   419  	data := []resource.ServiceResources{{
   420  		Resources: []resource.Resource{
   421  			{
   422  				Resource: charmresource.Resource{
   423  					Meta: charmresource.Meta{
   424  						Name:        "alpha",
   425  						Description: "a big comment",
   426  					},
   427  					Origin:   charmresource.OriginStore,
   428  					Revision: 15,
   429  					Size:     113,
   430  				},
   431  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   432  			},
   433  			{
   434  				Resource: charmresource.Resource{
   435  					Meta: charmresource.Meta{
   436  						Name:        "charlie",
   437  						Description: "awesome data",
   438  					},
   439  					Origin: charmresource.OriginUpload,
   440  					Size:   9835617,
   441  				},
   442  				Username:  "Bill User",
   443  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   444  			},
   445  			{
   446  				Resource: charmresource.Resource{
   447  					Meta: charmresource.Meta{
   448  						Name:        "beta",
   449  						Description: "more data",
   450  					},
   451  					Origin: charmresource.OriginUpload,
   452  				},
   453  				Username:  "Bill User",
   454  				Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   455  			},
   456  		},
   457  		UnitResources: []resource.UnitResources{
   458  			{
   459  				Tag: names.NewUnitTag("svc/10"),
   460  				Resources: []resource.Resource{
   461  					{
   462  						Resource: charmresource.Resource{
   463  							Meta: charmresource.Meta{
   464  								Name:        "alpha",
   465  								Description: "a big comment",
   466  							},
   467  							Origin:   charmresource.OriginStore,
   468  							Revision: 10, // note the reivision is different for this unit
   469  						},
   470  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   471  					},
   472  					{
   473  						Resource: charmresource.Resource{
   474  							Meta: charmresource.Meta{
   475  								Name:        "charlie",
   476  								Description: "awesome data",
   477  							},
   478  							Origin: charmresource.OriginUpload,
   479  						},
   480  						Username: "Bill User",
   481  						// note the different time
   482  						Timestamp: time.Date(2011, 11, 11, 11, 11, 11, 0, time.UTC),
   483  					},
   484  					// note we're missing the beta resource for this unit
   485  				},
   486  				DownloadProgress: map[string]int64{
   487  					"charlie": 17,
   488  				},
   489  			},
   490  			{
   491  				Tag: names.NewUnitTag("svc/5"),
   492  				Resources: []resource.Resource{
   493  					{
   494  						Resource: charmresource.Resource{
   495  							Meta: charmresource.Meta{
   496  								Name:        "alpha",
   497  								Description: "a big comment",
   498  							},
   499  							Origin:   charmresource.OriginStore,
   500  							Revision: 10, // note the reivision is different for this unit
   501  						},
   502  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   503  					},
   504  					{
   505  						Resource: charmresource.Resource{
   506  							Meta: charmresource.Meta{
   507  								Name:        "charlie",
   508  								Description: "awesome data",
   509  							},
   510  							Origin: charmresource.OriginUpload,
   511  						},
   512  						Username: "Bill User",
   513  						// note the different time
   514  						Timestamp: time.Date(2011, 11, 11, 11, 11, 11, 0, time.UTC),
   515  					},
   516  					{
   517  						Resource: charmresource.Resource{
   518  							Meta: charmresource.Meta{
   519  								Name:        "beta",
   520  								Description: "more data",
   521  							},
   522  							Origin: charmresource.OriginUpload,
   523  						},
   524  						Username:  "Bill User",
   525  						Timestamp: time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC),
   526  					},
   527  				},
   528  			},
   529  		},
   530  	}}
   531  	s.stubDeps.client.ReturnResources = data
   532  
   533  	cmd := &ShowServiceCommand{
   534  		deps: ShowServiceDeps{
   535  			NewClient: s.stubDeps.NewClient,
   536  		},
   537  	}
   538  
   539  	code, stdout, stderr := runCmd(c, cmd, "svc/10", "--details")
   540  	c.Assert(code, gc.Equals, 0)
   541  	c.Assert(stderr, gc.Equals, "")
   542  
   543  	c.Check(stdout, gc.Equals, `
   544  [Unit]
   545  RESOURCE REVISION         EXPECTED
   546  alpha    10               15
   547  beta     -                2012-12-12T12:12
   548  charlie  2011-11-11T11:11 2012-12-12T12:12 (fetching: 0%)
   549  
   550  `[1:])
   551  
   552  	s.stubDeps.stub.CheckCall(c, 1, "ListResources", []string{"svc"})
   553  }
   554  
   555  type stubShowServiceDeps struct {
   556  	stub   *testing.Stub
   557  	client *stubServiceClient
   558  }
   559  
   560  func (s *stubShowServiceDeps) NewClient(c *ShowServiceCommand) (ShowServiceClient, error) {
   561  	s.stub.AddCall("NewClient", c)
   562  	if err := s.stub.NextErr(); err != nil {
   563  		return nil, errors.Trace(err)
   564  	}
   565  
   566  	return s.client, nil
   567  }
   568  
   569  type stubServiceClient struct {
   570  	stub            *testing.Stub
   571  	ReturnResources []resource.ServiceResources
   572  }
   573  
   574  func (s *stubServiceClient) ListResources(services []string) ([]resource.ServiceResources, error) {
   575  	s.stub.AddCall("ListResources", services)
   576  	if err := s.stub.NextErr(); err != nil {
   577  		return nil, errors.Trace(err)
   578  	}
   579  	return s.ReturnResources, nil
   580  }
   581  
   582  func (s *stubServiceClient) Close() error {
   583  	s.stub.AddCall("Close")
   584  	if err := s.stub.NextErr(); err != nil {
   585  		return errors.Trace(err)
   586  	}
   587  
   588  	return nil
   589  }