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: ¶ms.ModelInfo{ 134 Name: "model.jess", 135 UUID: "uuid2", 136 }, 137 }, { 138 Result: ¶ms.ModelInfo{ 139 Name: "model.joe", 140 UUID: "uuid1", 141 }, 142 }, { 143 Error: ¶ms.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 }