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