github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/add-metric_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc_test 5 6 import ( 7 "sort" 8 "time" 9 10 "github.com/juju/cmd/v3" 11 "github.com/juju/cmd/v3/cmdtesting" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/worker/uniter/runner/jujuc" 16 ) 17 18 type AddMetricSuite struct { 19 ContextSuite 20 } 21 22 var _ = gc.Suite(&AddMetricSuite{}) 23 24 func (s *AddMetricSuite) TestHelp(c *gc.C) { 25 hctx := s.GetHookContext(c, -1, "") 26 com, err := jujuc.NewCommand(hctx, "add-metric") 27 c.Assert(err, jc.ErrorIsNil) 28 ctx := cmdtesting.Context(c) 29 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, []string{"--help"}) 30 c.Assert(code, gc.Equals, 0) 31 c.Assert(bufferString(ctx.Stdout), gc.Equals, ` 32 Usage: add-metric [options] key1=value1 [key2=value2 ...] 33 34 Summary: 35 add metrics 36 37 Options: 38 -l, --labels (= "") 39 labels to be associated with metric values 40 `[1:]) 41 c.Assert(bufferString(ctx.Stderr), gc.Equals, "") 42 } 43 44 func (s *AddMetricSuite) TestAddMetric(c *gc.C) { 45 testCases := []struct { 46 about string 47 cmd []string 48 canAddMetrics bool 49 result int 50 stdout string 51 stderr string 52 expect []jujuc.Metric 53 }{ 54 { 55 "add single metric", 56 []string{"add-metric", "key=50"}, 57 true, 58 0, 59 "", 60 "", 61 []jujuc.Metric{{Key: "key", Value: "50", Time: time.Now()}}, 62 }, { 63 "no parameters error", 64 []string{"add-metric"}, 65 true, 66 2, 67 "", 68 "ERROR no metrics specified\n", 69 nil, 70 }, { 71 "invalid argument format", 72 []string{"add-metric", "key"}, 73 true, 74 2, 75 "", 76 "ERROR invalid metrics: expected \"key=value\", got \"key\"\n", 77 nil, 78 }, { 79 "invalid argument format", 80 []string{"add-metric", "=key"}, 81 true, 82 2, 83 "", 84 "ERROR invalid metrics: expected \"key=value\", got \"=key\"\n", 85 nil, 86 }, { 87 "invalid argument format, whitespace key", 88 []string{"add-metric", " =value"}, 89 true, 90 2, 91 "", 92 "ERROR invalid metrics: expected \"key=value\", got \"=value\"\n", 93 nil, 94 }, { 95 "invalid argument format, whitespace key and value", 96 []string{"add-metric", " \t = \n"}, 97 true, 98 2, 99 "", 100 "ERROR invalid metrics: expected \"key=value\", got \"=\"\n", 101 nil, 102 }, { 103 "invalid argument format, whitespace value", 104 []string{"add-metric", " key = "}, 105 true, 106 2, 107 "", 108 "ERROR invalid metrics: expected \"key=value\", got \"key=\"\n", 109 nil, 110 }, { 111 "multiple metrics", 112 []string{"add-metric", "key=60", "key2=50.4"}, 113 true, 114 0, 115 "", 116 "", 117 []jujuc.Metric{{ 118 Key: "key", 119 Value: "60", 120 Time: time.Now(), 121 }, { 122 Key: "key2", 123 Value: "50.4", 124 Time: time.Now(), 125 }}, 126 }, { 127 "multiple metrics, matching keys", 128 []string{"add-metric", "key=60", "key=50.4"}, 129 true, 130 2, 131 "", 132 "ERROR invalid metrics: key \"key\" specified more than once\n", 133 nil, 134 }, { 135 "newline in metric value", 136 []string{"add-metric", "key=60\n", "key2\t=\t30", "\tkey3 =\t15"}, 137 true, 138 0, 139 "", 140 "", 141 []jujuc.Metric{{ 142 Key: "key", Value: "60", Time: time.Now(), 143 }, { 144 Key: "key2", Value: "30", Time: time.Now(), 145 }, { 146 Key: "key3", Value: "15", Time: time.Now(), 147 }}, 148 }, { 149 "can't add metrics", 150 []string{"add-metric", "key=60", "key2=50.4"}, 151 false, 152 1, 153 "", 154 "ERROR cannot record metric: metrics disabled\n", 155 nil, 156 }, { 157 "cannot add builtin metric", 158 []string{"add-metric", "juju-key=50"}, 159 true, 160 1, 161 "", 162 "ERROR juju-key uses a reserved prefix\n", 163 nil, 164 }, { 165 "invalid label format", 166 []string{"add-metric", "--labels", "foo", "key=1"}, 167 true, 168 2, 169 "", 170 "ERROR invalid labels: expected \"key=value\", got \"foo\"\n", 171 nil, 172 }, { 173 "invalid label format", 174 []string{"add-metric", "--labels", "=bar", "key=1"}, 175 true, 176 2, 177 "", 178 "ERROR invalid labels: expected \"key=value\", got \"=bar\"\n", 179 nil, 180 }, { 181 "invalid label format, whitespace key", 182 []string{"add-metric", "--labels", " =bar", "key=1"}, 183 true, 184 2, 185 "", 186 "ERROR invalid labels: expected \"key=value\", got \"=bar\"\n", 187 nil, 188 }, { 189 "invalid label format, whitespace key and value", 190 []string{"add-metric", "--labels", " \t = \n", "key=1"}, 191 true, 192 2, 193 "", 194 "ERROR invalid labels: expected \"key=value\", got \"=\"\n", 195 nil, 196 }, { 197 "invalid label format, whitespace value", 198 []string{"add-metric", "--labels", " foo = ", "key=1"}, 199 true, 200 2, 201 "", 202 "ERROR invalid labels: expected \"key=value\", got \"foo=\"\n", 203 nil, 204 }, { 205 "add single metric with label", 206 []string{"add-metric", "--labels", "foo=bar", "key=50"}, 207 true, 208 0, 209 "", 210 "", 211 []jujuc.Metric{{ 212 Key: "key", Value: "50", Time: time.Now(), 213 Labels: map[string]string{"foo": "bar"}, 214 }}, 215 }, { 216 "add single metric with labels", 217 []string{"add-metric", "--labels", "foo=bar,baz=quux", "key=510"}, 218 true, 219 0, 220 "", 221 "", 222 []jujuc.Metric{{ 223 Key: "key", Value: "510", Time: time.Now(), 224 Labels: map[string]string{"foo": "bar", "baz": "quux"}, 225 }}, 226 }, { 227 "add single metric with labels, whitespace", 228 []string{"add-metric", "--labels", " foo = bar, baz = quux ", "key=510"}, 229 true, 230 0, 231 "", 232 "", 233 []jujuc.Metric{{ 234 Key: "key", Value: "510", Time: time.Now(), 235 Labels: map[string]string{"foo": "bar", "baz": "quux"}, 236 }}, 237 }, { 238 "add multiple metrics with labels", 239 []string{"add-metric", "--labels", "foo=bar,baz=quux", "a=1", "b=2"}, 240 true, 241 0, 242 "", 243 "", 244 []jujuc.Metric{{ 245 Key: "a", Value: "1", Time: time.Now(), 246 Labels: map[string]string{"foo": "bar", "baz": "quux"}, 247 }, { 248 Key: "b", Value: "2", Time: time.Now(), 249 Labels: map[string]string{"foo": "bar", "baz": "quux"}, 250 }}, 251 }, { 252 "can't add metrics with labels", 253 []string{"add-metric", "--labels", "foo=bar", "key=60", "key2=50.4"}, 254 false, 255 1, 256 "", 257 "ERROR cannot record metric: metrics disabled\n", 258 nil, 259 }, { 260 "cannot add builtin metric with labels", 261 []string{"add-metric", "--labels", "foo=bar", "juju-key=50"}, 262 true, 263 1, 264 "", 265 "ERROR juju-key uses a reserved prefix\n", 266 nil, 267 }} 268 for i, t := range testCases { 269 c.Logf("test %d: %s", i, t.about) 270 hctx := s.GetHookContext(c, -1, "") 271 hctx.canAddMetrics = t.canAddMetrics 272 com, err := jujuc.NewCommand(hctx, t.cmd[0]) 273 c.Assert(err, jc.ErrorIsNil) 274 ctx := cmdtesting.Context(c) 275 ret := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, t.cmd[1:]) 276 c.Check(ret, gc.Equals, t.result) 277 c.Check(bufferString(ctx.Stdout), gc.Equals, t.stdout) 278 c.Check(bufferString(ctx.Stderr), gc.Equals, t.stderr) 279 c.Check(hctx.metrics, gc.HasLen, len(t.expect)) 280 if len(hctx.metrics) != len(t.expect) { 281 continue 282 } 283 284 sort.Sort(SortedMetrics(hctx.metrics)) 285 sort.Sort(SortedMetrics(t.expect)) 286 287 for i, expected := range t.expect { 288 c.Check(expected.Key, gc.Equals, hctx.metrics[i].Key) 289 c.Check(expected.Value, gc.Equals, hctx.metrics[i].Value) 290 c.Check(expected.Labels, gc.DeepEquals, hctx.metrics[i].Labels) 291 } 292 } 293 } 294 295 type SortedMetrics []jujuc.Metric 296 297 func (m SortedMetrics) Len() int { return len(m) } 298 func (m SortedMetrics) Swap(i, j int) { m[i], m[j] = m[j], m[i] } 299 func (m SortedMetrics) Less(i, j int) bool { return m[i].Key < m[j].Key }