github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/romulus/showbudget/show_budget_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.s
     3  
     4  package showbudget_test
     5  
     6  import (
     7  	"github.com/juju/cmd/cmdtesting"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/romulus/wireformat/budget"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/cmd/juju/romulus/showbudget"
    17  	coretesting "github.com/juju/juju/testing"
    18  )
    19  
    20  var _ = gc.Suite(&showBudgetSuite{})
    21  
    22  type showBudgetSuite struct {
    23  	coretesting.FakeJujuXDGDataHomeSuite
    24  	stub          *testing.Stub
    25  	mockBudgetAPI *mockBudgetAPI
    26  	mockAPI       *mockAPI
    27  }
    28  
    29  func (s *showBudgetSuite) SetUpTest(c *gc.C) {
    30  	s.CleanupSuite.SetUpTest(c)
    31  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    32  	s.stub = &testing.Stub{}
    33  	s.mockBudgetAPI = &mockBudgetAPI{s.stub}
    34  	s.mockAPI = &mockAPI{s.stub}
    35  	s.PatchValue(showbudget.NewBudgetAPIClient, showbudget.BudgetAPIClientFnc(s.mockBudgetAPI))
    36  	s.PatchValue(showbudget.NewAPIClient, showbudget.NewAPIClientFnc(s.mockAPI))
    37  }
    38  
    39  func (s *showBudgetSuite) TestShowBudgetCommand(c *gc.C) {
    40  	tests := []struct {
    41  		about      string
    42  		args       []string
    43  		err        string
    44  		budget     string
    45  		apierr     string
    46  		resolveerr string
    47  		output     string
    48  	}{{
    49  		about: "missing argument",
    50  		err:   `missing arguments`,
    51  	}, {
    52  		about: "unknown arguments",
    53  		args:  []string{"my-special-budget", "extra", "arguments"},
    54  		err:   `unrecognized args: \["extra" "arguments"\]`,
    55  	}, {
    56  		about:  "api error",
    57  		args:   []string{"personal"},
    58  		apierr: "well, this is embarrassing",
    59  		err:    "failed to retrieve the budget: well, this is embarrassing",
    60  	}, {
    61  		about:  "all ok",
    62  		args:   []string{"personal"},
    63  		budget: "personal",
    64  		output: "" +
    65  			"MODEL      \tSERVICES \tSPENT\tALLOCATED\tBY       \tUSAGE\n" +
    66  			"model.joe  \tmysql    \t  200\t     1200\tuser.joe \t  42%\n" +
    67  			"           \twordpress\t  300\t         \t         \n" +
    68  			"model.jess \tlandscape\t  600\t     1000\tuser.jess\t  60%\n" +
    69  			"uuid3      \tmysql    \t   10\t      100\tuser.bob \t  10%\n" +
    70  			"           \t         \t     \t         \t         \n" +
    71  			"TOTAL      \t         \t 1110\t     2300\t         \t  48%\n" +
    72  			"BUDGET     \t         \t     \t     4000\t         \n" +
    73  			"UNALLOCATED\t         \t     \t     1700\t         \n",
    74  	}, {
    75  		about:      "all ok",
    76  		args:       []string{"personal"},
    77  		budget:     "personal",
    78  		resolveerr: "test error",
    79  		output: "" +
    80  			"MODEL      \tSERVICES \tSPENT\tALLOCATED\tBY       \tUSAGE\n" +
    81  			"uuid1      \tmysql    \t  200\t     1200\tuser.joe \t  42%\n" +
    82  			"           \twordpress\t  300\t         \t         \n" +
    83  			"uuid2      \tlandscape\t  600\t     1000\tuser.jess\t  60%\n" +
    84  			"uuid3      \tmysql    \t   10\t      100\tuser.bob \t  10%\n" +
    85  			"           \t         \t     \t         \t         \n" +
    86  			"TOTAL      \t         \t 1110\t     2300\t         \t  48%\n" +
    87  			"BUDGET     \t         \t     \t     4000\t         \n" +
    88  			"UNALLOCATED\t         \t     \t     1700\t         \n",
    89  	},
    90  	}
    91  
    92  	for i, test := range tests {
    93  		c.Logf("running test %d: %v", i, test.about)
    94  		s.mockAPI.ResetCalls()
    95  
    96  		errs := []error{}
    97  		if test.apierr != "" {
    98  			errs = append(errs, errors.New(test.apierr))
    99  		} else {
   100  			errs = append(errs, nil)
   101  		}
   102  		if test.resolveerr != "" {
   103  			errs = append(errs, errors.New(test.resolveerr))
   104  		} else {
   105  			errs = append(errs, nil)
   106  		}
   107  		s.mockAPI.SetErrors(errs...)
   108  
   109  		showBudget := showbudget.NewShowBudgetCommand()
   110  
   111  		ctx, err := cmdtesting.RunCommand(c, showBudget, test.args...)
   112  		if test.err == "" {
   113  			c.Assert(err, jc.ErrorIsNil)
   114  			s.stub.CheckCalls(c, []testing.StubCall{
   115  				{"GetBudget", []interface{}{test.budget}},
   116  				{"ModelInfo", []interface{}{[]names.ModelTag{names.NewModelTag("uuid1"), names.NewModelTag("uuid2"), names.NewModelTag("uuid3")}}},
   117  			})
   118  			output := cmdtesting.Stdout(ctx)
   119  			c.Assert(output, gc.Equals, test.output)
   120  		} else {
   121  			c.Assert(err, gc.ErrorMatches, test.err)
   122  		}
   123  	}
   124  }
   125  
   126  type mockAPI struct {
   127  	*testing.Stub
   128  }
   129  
   130  func (api *mockAPI) ModelInfo(tags []names.ModelTag) ([]params.ModelInfoResult, error) {
   131  	api.AddCall("ModelInfo", tags)
   132  	return []params.ModelInfoResult{{
   133  		Result: &params.ModelInfo{
   134  			Name: "model.jess",
   135  			UUID: "uuid2",
   136  		},
   137  	}, {
   138  		Result: &params.ModelInfo{
   139  			Name: "model.joe",
   140  			UUID: "uuid1",
   141  		},
   142  	}, {
   143  		Error: &params.Error{
   144  			Message: "not found",
   145  		},
   146  	},
   147  	}, api.NextErr()
   148  }
   149  
   150  type mockBudgetAPI struct {
   151  	*testing.Stub
   152  }
   153  
   154  func (api *mockBudgetAPI) GetBudget(name string) (*budget.BudgetWithAllocations, error) {
   155  	api.AddCall("GetBudget", name)
   156  	return &budget.BudgetWithAllocations{
   157  		Limit: "4000",
   158  		Total: budget.BudgetTotals{
   159  			Allocated:   "2300",
   160  			Unallocated: "1700",
   161  			Available:   "1190",
   162  			Consumed:    "1110",
   163  			Usage:       "48%",
   164  		},
   165  		Allocations: []budget.Allocation{{
   166  			Owner:    "user.joe",
   167  			Limit:    "1200",
   168  			Consumed: "500",
   169  			Usage:    "42%",
   170  			Model:    "uuid1",
   171  			Services: map[string]budget.ServiceAllocation{
   172  				"wordpress": budget.ServiceAllocation{
   173  					Consumed: "300",
   174  				},
   175  				"mysql": budget.ServiceAllocation{
   176  					Consumed: "200",
   177  				},
   178  			},
   179  		}, {
   180  			Owner:    "user.jess",
   181  			Limit:    "1000",
   182  			Consumed: "600",
   183  			Usage:    "60%",
   184  			Model:    "uuid2",
   185  			Services: map[string]budget.ServiceAllocation{
   186  				"landscape": budget.ServiceAllocation{
   187  					Consumed: "600",
   188  				},
   189  			},
   190  		}, {
   191  			Owner:    "user.bob",
   192  			Limit:    "100",
   193  			Consumed: "10",
   194  			Usage:    "10%",
   195  			Model:    "uuid3",
   196  			Services: map[string]budget.ServiceAllocation{
   197  				"mysql": budget.ServiceAllocation{
   198  					Consumed: "10",
   199  				},
   200  			},
   201  		}}}, api.NextErr()
   202  }