github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/metricsdebug/collectmetrics_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package metricsdebug_test 5 6 import ( 7 "github.com/juju/cmd/cmdtesting" 8 "github.com/juju/errors" 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/juju/charm.v6" 13 "gopkg.in/juju/names.v2" 14 15 "github.com/juju/juju/api" 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/cmd/juju/action" 18 "github.com/juju/juju/cmd/juju/metricsdebug" 19 "github.com/juju/juju/cmd/modelcmd" 20 coretesting "github.com/juju/juju/testing" 21 ) 22 23 type collectMetricsSuite struct { 24 coretesting.FakeJujuXDGDataHomeSuite 25 } 26 27 var ( 28 _ = gc.Suite(&collectMetricsSuite{}) 29 30 actionTag1 = names.NewActionTag("01234567-89ab-cdef-0123-456789abcdef") 31 actionTag2 = names.NewActionTag("11234567-89ab-cdef-0123-456789abcdef") 32 33 tests = []struct { 34 about string 35 args []string 36 stdout string 37 results [][]params.ActionResult 38 actionMap map[string]params.ActionResult 39 err string 40 }{{ 41 about: "missing args", 42 err: "you need to specify a unit or application.", 43 }, { 44 about: "invalid application name", 45 args: []string{"application_1-0"}, 46 err: `"application_1-0" is not a valid unit or application`, 47 }, { 48 about: "all is well", 49 args: []string{"uptime"}, 50 results: [][]params.ActionResult{ 51 {{ 52 Action: ¶ms.Action{ 53 Tag: actionTag1.String(), 54 }, 55 }}, 56 {{ 57 Action: ¶ms.Action{ 58 Tag: actionTag2.String(), 59 }, 60 }}, 61 }, 62 actionMap: map[string]params.ActionResult{ 63 actionTag1.Id(): { 64 Action: ¶ms.Action{ 65 Tag: actionTag1.String(), 66 Receiver: "unit-uptime-0", 67 }, 68 Output: map[string]interface{}{ 69 "Stdout": "ok", 70 "Stderr": "", 71 }, 72 }, 73 actionTag2.Id(): { 74 Action: ¶ms.Action{ 75 Tag: actionTag2.String(), 76 }, 77 Output: map[string]interface{}{ 78 "Stdout": "ok", 79 "Stderr": "", 80 }, 81 }, 82 }, 83 }, { 84 about: "invalid tag returned", 85 args: []string{"uptime"}, 86 results: [][]params.ActionResult{ 87 {{ 88 Action: ¶ms.Action{ 89 Tag: "invalid", 90 }, 91 }}, 92 }, 93 stdout: `failed to collect metrics: "invalid" is not a valid tag\n`, 94 }, { 95 about: "no action found", 96 args: []string{"uptime"}, 97 results: [][]params.ActionResult{ 98 {{ 99 Action: ¶ms.Action{ 100 Tag: actionTag1.String(), 101 }, 102 }}, 103 }, 104 stdout: "failed to collect metrics: plm\n", 105 }, { 106 about: "fail to parse result", 107 args: []string{"uptime"}, 108 results: [][]params.ActionResult{ 109 {{ 110 Action: ¶ms.Action{ 111 Tag: actionTag1.String(), 112 }, 113 }}, 114 }, 115 actionMap: map[string]params.ActionResult{ 116 actionTag1.Id(): {}, 117 }, 118 stdout: "failed to collect metrics: could not read stdout\n", 119 }, { 120 about: "no results on sendResults", 121 args: []string{"uptime"}, 122 results: [][]params.ActionResult{ 123 {{ 124 Action: ¶ms.Action{ 125 Tag: actionTag1.String(), 126 }, 127 }}, 128 }, 129 actionMap: map[string]params.ActionResult{ 130 actionTag1.Id(): { 131 Action: ¶ms.Action{ 132 Tag: actionTag2.String(), 133 Receiver: "unit-uptime-0", 134 }, 135 Output: map[string]interface{}{ 136 "Stdout": "ok", 137 "Stderr": "", 138 }, 139 }, 140 }, 141 stdout: "failed to send metrics for unit uptime/0: no results\n", 142 }, { 143 about: "too many sendResults", 144 args: []string{"uptime"}, 145 results: [][]params.ActionResult{ 146 {{ 147 Action: ¶ms.Action{ 148 Tag: actionTag1.String(), 149 }, 150 }}, 151 {{ 152 Action: ¶ms.Action{ 153 Tag: actionTag1.String(), 154 }, 155 }, { 156 Action: ¶ms.Action{ 157 Tag: actionTag2.String(), 158 }, 159 }}, 160 }, 161 actionMap: map[string]params.ActionResult{ 162 actionTag1.Id(): { 163 Action: ¶ms.Action{ 164 Tag: actionTag2.String(), 165 Receiver: "unit-uptime-0", 166 }, 167 Output: map[string]interface{}{ 168 "Stdout": "ok", 169 "Stderr": "", 170 }, 171 }, 172 }, 173 stdout: "failed to send metrics for unit uptime/0\n", 174 }, { 175 about: "sendResults error", 176 args: []string{"uptime"}, 177 results: [][]params.ActionResult{ 178 {{ 179 Action: ¶ms.Action{ 180 Tag: actionTag1.String(), 181 }, 182 }}, 183 {{ 184 Error: ¶ms.Error{ 185 Message: "permission denied", 186 }, 187 }}, 188 }, 189 actionMap: map[string]params.ActionResult{ 190 actionTag1.Id(): { 191 Action: ¶ms.Action{ 192 Tag: actionTag2.String(), 193 Receiver: "unit-uptime-0", 194 }, 195 Output: map[string]interface{}{ 196 "Stdout": "ok", 197 "Stderr": "", 198 }, 199 }, 200 }, 201 stdout: "failed to send metrics for unit uptime/0: permission denied\n", 202 }, { 203 about: "couldn't get sendResults action", 204 args: []string{"uptime"}, 205 results: [][]params.ActionResult{ 206 {{ 207 Action: ¶ms.Action{ 208 Tag: actionTag1.String(), 209 }, 210 }}, 211 {{ 212 Action: ¶ms.Action{ 213 Tag: actionTag2.String(), 214 }, 215 }}, 216 }, 217 actionMap: map[string]params.ActionResult{ 218 actionTag1.Id(): { 219 Action: ¶ms.Action{ 220 Tag: actionTag2.String(), 221 Receiver: "unit-uptime-0", 222 }, 223 Output: map[string]interface{}{ 224 "Stdout": "ok", 225 "Stderr": "", 226 }, 227 }, 228 }, 229 stdout: "failed to send metrics for unit uptime/0: plm\n", 230 }, { 231 about: "couldn't parse sendResults action", 232 args: []string{"uptime"}, 233 results: [][]params.ActionResult{ 234 {{ 235 Action: ¶ms.Action{ 236 Tag: actionTag1.String(), 237 }, 238 }}, 239 {{ 240 Action: ¶ms.Action{ 241 Tag: actionTag2.String(), 242 }, 243 }}, 244 }, 245 actionMap: map[string]params.ActionResult{ 246 actionTag1.Id(): { 247 Action: ¶ms.Action{ 248 Tag: actionTag2.String(), 249 Receiver: "unit-uptime-0", 250 }, 251 Output: map[string]interface{}{ 252 "Stdout": "ok", 253 "Stderr": "", 254 }, 255 }, 256 actionTag2.Id(): {}, 257 }, 258 stdout: "failed to send metrics for unit uptime/0: could not read stdout\n", 259 }, { 260 about: "sendResults action stderr", 261 args: []string{"uptime"}, 262 results: [][]params.ActionResult{ 263 {{ 264 Action: ¶ms.Action{ 265 Tag: actionTag1.String(), 266 }, 267 }}, 268 {{ 269 Action: ¶ms.Action{ 270 Tag: actionTag2.String(), 271 }, 272 }}, 273 }, 274 actionMap: map[string]params.ActionResult{ 275 actionTag1.Id(): { 276 Action: ¶ms.Action{ 277 Tag: actionTag2.String(), 278 Receiver: "unit-uptime-0", 279 }, 280 Output: map[string]interface{}{ 281 "Stdout": "ok", 282 "Stderr": "", 283 }, 284 }, 285 actionTag2.Id(): { 286 Action: ¶ms.Action{ 287 Tag: actionTag2.String(), 288 Receiver: "unit-uptime-0", 289 }, 290 Output: map[string]interface{}{ 291 "Stdout": "garbage", 292 "Stderr": "kek", 293 }, 294 }, 295 }, 296 stdout: "failed to send metrics for unit uptime/0: kek\n", 297 }} 298 ) 299 300 func (s *collectMetricsSuite) TestCollectMetricsLocal(c *gc.C) { 301 runClient := &testRunClient{} 302 applicationClient := &testApplicationClient{} 303 applicationClient.charmURL = "local:quantal/charm" 304 s.PatchValue(metricsdebug.NewAPIConn, noConn) 305 s.PatchValue(metricsdebug.NewRunClient, metricsdebug.NewRunClientFnc(runClient)) 306 307 for i, test := range tests { 308 c.Logf("running test %d: %v", i, test.about) 309 runClient.reset() 310 if test.results != nil { 311 runClient.results = test.results 312 } 313 metricsdebug.PatchGetActionResult(s.PatchValue, test.actionMap) 314 ctx, err := cmdtesting.RunCommand(c, metricsdebug.NewCollectMetricsCommandForTest(), test.args...) 315 if test.err != "" { 316 c.Assert(err, gc.ErrorMatches, test.err) 317 } else { 318 c.Assert(err, jc.ErrorIsNil) 319 c.Assert(cmdtesting.Stdout(ctx), gc.Matches, test.stdout) 320 } 321 } 322 } 323 324 func (s *collectMetricsSuite) TestCollectMetricsRemote(c *gc.C) { 325 runClient := &testRunClient{} 326 applicationClient := &testApplicationClient{} 327 applicationClient.charmURL = "quantal/charm" 328 s.PatchValue(metricsdebug.NewAPIConn, noConn) 329 s.PatchValue(metricsdebug.NewRunClient, metricsdebug.NewRunClientFnc(runClient)) 330 331 for i, test := range tests { 332 c.Logf("running test %d: %v", i, test.about) 333 runClient.reset() 334 if test.results != nil { 335 runClient.results = test.results 336 } 337 metricsdebug.PatchGetActionResult(s.PatchValue, test.actionMap) 338 ctx, err := cmdtesting.RunCommand(c, metricsdebug.NewCollectMetricsCommandForTest(), test.args...) 339 if test.err != "" { 340 c.Assert(err, gc.ErrorMatches, test.err) 341 } else { 342 c.Assert(err, jc.ErrorIsNil) 343 c.Assert(cmdtesting.Stdout(ctx), gc.Matches, test.stdout) 344 } 345 } 346 } 347 348 type testRunClient struct { 349 action.APIClient 350 testing.Stub 351 352 results [][]params.ActionResult 353 err string 354 } 355 356 // Run implements the runClient interface. 357 func (t *testRunClient) Run(run params.RunParams) ([]params.ActionResult, error) { 358 t.AddCall("Run", run) 359 if t.err != "" { 360 return nil, errors.New(t.err) 361 } 362 if len(t.results) == 0 { 363 return nil, errors.New("no results") 364 } 365 r := t.results[0] 366 t.results = t.results[1:] 367 return r, nil 368 } 369 370 // Close implements the runClient interface. 371 func (t *testRunClient) Close() error { 372 t.AddCall("Close") 373 return nil 374 } 375 376 func (t *testRunClient) reset() { 377 t.ResetCalls() 378 t.results = nil 379 t.err = "" 380 } 381 382 type testApplicationClient struct { 383 testing.Stub 384 charmURL string 385 } 386 387 func (t *testApplicationClient) GetCharmURL(service string) (*charm.URL, error) { 388 url := charm.MustParseURL(t.charmURL) 389 return url, t.NextErr() 390 } 391 392 func (t *testApplicationClient) Close() error { 393 return t.NextErr() 394 } 395 396 func noConn(_ modelcmd.ModelCommandBase) (api.Connection, error) { 397 return nil, nil 398 }