~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package checkers_test
 
2
 
 
3
import (
 
4
        "fmt"
 
5
        "net"
 
6
        "time"
 
7
 
 
8
        jc "github.com/juju/testing/checkers"
 
9
        gc "gopkg.in/check.v1"
 
10
        "gopkg.in/errgo.v1"
 
11
        "gopkg.in/macaroon.v1"
 
12
 
 
13
        "gopkg.in/macaroon-bakery.v1/bakery"
 
14
        "gopkg.in/macaroon-bakery.v1/bakery/checkers"
 
15
)
 
16
 
 
17
type CheckersSuite struct{}
 
18
 
 
19
var _ = gc.Suite(&CheckersSuite{})
 
20
 
 
21
// Freeze time for the tests.
 
22
var now = func() time.Time {
 
23
        now, err := time.Parse(time.RFC3339Nano, "2006-01-02T15:04:05.123Z")
 
24
        if err != nil {
 
25
                panic(err)
 
26
        }
 
27
        *checkers.TimeNow = func() time.Time {
 
28
                return now
 
29
        }
 
30
        return now
 
31
}()
 
32
 
 
33
type checkTest struct {
 
34
        caveat      string
 
35
        expectError string
 
36
        expectCause func(err error) bool
 
37
}
 
38
 
 
39
var isCaveatNotRecognized = errgo.Is(checkers.ErrCaveatNotRecognized)
 
40
 
 
41
var checkerTests = []struct {
 
42
        about   string
 
43
        checker bakery.FirstPartyChecker
 
44
        checks  []checkTest
 
45
}{{
 
46
        about:   "empty MultiChecker",
 
47
        checker: checkers.New(),
 
48
        checks: []checkTest{{
 
49
                caveat:      "something",
 
50
                expectError: `caveat "something" not satisfied: caveat not recognized`,
 
51
                expectCause: isCaveatNotRecognized,
 
52
        }, {
 
53
                caveat:      "",
 
54
                expectError: `cannot parse caveat "": empty caveat`,
 
55
                expectCause: isCaveatNotRecognized,
 
56
        }, {
 
57
                caveat:      " hello",
 
58
                expectError: `cannot parse caveat " hello": caveat starts with space character`,
 
59
                expectCause: isCaveatNotRecognized,
 
60
        }},
 
61
}, {
 
62
        about: "MultiChecker with some values",
 
63
        checker: checkers.New(
 
64
                argChecker("a", "aval"),
 
65
                argChecker("b", "bval"),
 
66
        ),
 
67
        checks: []checkTest{{
 
68
                caveat: "a aval",
 
69
        }, {
 
70
                caveat: "b bval",
 
71
        }, {
 
72
                caveat:      "a wrong",
 
73
                expectError: `caveat "a wrong" not satisfied: wrong arg`,
 
74
                expectCause: errgo.Is(errWrongArg),
 
75
        }},
 
76
}, {
 
77
        about: "MultiChecker with several of the same condition",
 
78
        checker: checkers.New(
 
79
                argChecker("a", "aval"),
 
80
                argChecker("a", "bval"),
 
81
        ),
 
82
        checks: []checkTest{{
 
83
                caveat:      "a aval",
 
84
                expectError: `caveat "a aval" not satisfied: wrong arg`,
 
85
                expectCause: errgo.Is(errWrongArg),
 
86
        }, {
 
87
                caveat:      "a bval",
 
88
                expectError: `caveat "a bval" not satisfied: wrong arg`,
 
89
                expectCause: errgo.Is(errWrongArg),
 
90
        }},
 
91
}, {
 
92
        about: "nested MultiChecker",
 
93
        checker: checkers.New(
 
94
                argChecker("a", "aval"),
 
95
                argChecker("b", "bval"),
 
96
                checkers.New(
 
97
                        argChecker("c", "cval"),
 
98
                        checkers.New(
 
99
                                argChecker("d", "dval"),
 
100
                        ),
 
101
                        argChecker("e", "eval"),
 
102
                ),
 
103
        ),
 
104
        checks: []checkTest{{
 
105
                caveat: "a aval",
 
106
        }, {
 
107
                caveat: "b bval",
 
108
        }, {
 
109
                caveat: "c cval",
 
110
        }, {
 
111
                caveat: "d dval",
 
112
        }, {
 
113
                caveat: "e eval",
 
114
        }, {
 
115
                caveat:      "a wrong",
 
116
                expectError: `caveat "a wrong" not satisfied: wrong arg`,
 
117
                expectCause: errgo.Is(errWrongArg),
 
118
        }, {
 
119
                caveat:      "c wrong",
 
120
                expectError: `caveat "c wrong" not satisfied: wrong arg`,
 
121
                expectCause: errgo.Is(errWrongArg),
 
122
        }, {
 
123
                caveat:      "d wrong",
 
124
                expectError: `caveat "d wrong" not satisfied: wrong arg`,
 
125
                expectCause: errgo.Is(errWrongArg),
 
126
        }, {
 
127
                caveat:      "f something",
 
128
                expectError: `caveat "f something" not satisfied: caveat not recognized`,
 
129
                expectCause: isCaveatNotRecognized,
 
130
        }},
 
131
}, {
 
132
        about: "Map with no items",
 
133
        checker: checkers.New(
 
134
                checkers.Map{},
 
135
        ),
 
136
        checks: []checkTest{{
 
137
                caveat:      "a aval",
 
138
                expectError: `caveat "a aval" not satisfied: caveat not recognized`,
 
139
                expectCause: isCaveatNotRecognized,
 
140
        }},
 
141
}, {
 
142
        about: "Map with some values",
 
143
        checker: checkers.New(
 
144
                checkers.Map{
 
145
                        "a": argChecker("a", "aval").Check,
 
146
                        "b": argChecker("b", "bval").Check,
 
147
                },
 
148
        ),
 
149
        checks: []checkTest{{
 
150
                caveat: "a aval",
 
151
        }, {
 
152
                caveat: "b bval",
 
153
        }, {
 
154
                caveat:      "a wrong",
 
155
                expectError: `caveat "a wrong" not satisfied: wrong arg`,
 
156
                expectCause: errgo.Is(errWrongArg),
 
157
        }, {
 
158
                caveat:      "b wrong",
 
159
                expectError: `caveat "b wrong" not satisfied: wrong arg`,
 
160
                expectCause: errgo.Is(errWrongArg),
 
161
        }},
 
162
}, {
 
163
        about: "time within limit",
 
164
        checker: checkers.New(
 
165
                checkers.TimeBefore,
 
166
        ),
 
167
        checks: []checkTest{{
 
168
                caveat: checkers.TimeBeforeCaveat(now.Add(1)).Condition,
 
169
        }, {
 
170
                caveat:      checkers.TimeBeforeCaveat(now).Condition,
 
171
                expectError: `caveat "time-before 2006-01-02T15:04:05.123Z" not satisfied: macaroon has expired`,
 
172
        }, {
 
173
                caveat:      checkers.TimeBeforeCaveat(now.Add(-1)).Condition,
 
174
                expectError: `caveat "time-before 2006-01-02T15:04:05.122999999Z" not satisfied: macaroon has expired`,
 
175
        }, {
 
176
                caveat:      `time-before bad-date`,
 
177
                expectError: `caveat "time-before bad-date" not satisfied: parsing time "bad-date" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "bad-date" as "2006"`,
 
178
        }, {
 
179
                caveat:      checkers.TimeBeforeCaveat(now).Condition + " ",
 
180
                expectError: `caveat "time-before 2006-01-02T15:04:05.123Z " not satisfied: parsing time "2006-01-02T15:04:05.123Z ": extra text:  `,
 
181
        }},
 
182
}, {
 
183
        about:   "declared, no entries",
 
184
        checker: checkers.New(checkers.Declared{}),
 
185
        checks: []checkTest{{
 
186
                caveat:      checkers.DeclaredCaveat("a", "aval").Condition,
 
187
                expectError: `caveat "declared a aval" not satisfied: got a=null, expected "aval"`,
 
188
        }, {
 
189
                caveat:      checkers.CondDeclared,
 
190
                expectError: `caveat "declared" not satisfied: declared caveat has no value`,
 
191
        }},
 
192
}, {
 
193
        about: "declared, some entries",
 
194
        checker: checkers.New(checkers.Declared{
 
195
                "a":   "aval",
 
196
                "b":   "bval",
 
197
                "spc": " a b",
 
198
        }),
 
199
        checks: []checkTest{{
 
200
                caveat: checkers.DeclaredCaveat("a", "aval").Condition,
 
201
        }, {
 
202
                caveat: checkers.DeclaredCaveat("b", "bval").Condition,
 
203
        }, {
 
204
                caveat: checkers.DeclaredCaveat("spc", " a b").Condition,
 
205
        }, {
 
206
                caveat:      checkers.DeclaredCaveat("a", "bval").Condition,
 
207
                expectError: `caveat "declared a bval" not satisfied: got a="aval", expected "bval"`,
 
208
        }, {
 
209
                caveat:      checkers.DeclaredCaveat("a", " aval").Condition,
 
210
                expectError: `caveat "declared a  aval" not satisfied: got a="aval", expected " aval"`,
 
211
        }, {
 
212
                caveat:      checkers.DeclaredCaveat("spc", "a b").Condition,
 
213
                expectError: `caveat "declared spc a b" not satisfied: got spc=" a b", expected "a b"`,
 
214
        }, {
 
215
                caveat:      checkers.DeclaredCaveat("", "a b").Condition,
 
216
                expectError: `caveat "error invalid caveat 'declared' key \\"\\"" not satisfied: bad caveat`,
 
217
        }, {
 
218
                caveat:      checkers.DeclaredCaveat("a b", "a b").Condition,
 
219
                expectError: `caveat "error invalid caveat 'declared' key \\"a b\\"" not satisfied: bad caveat`,
 
220
        }},
 
221
}, {
 
222
        about:   "error caveat",
 
223
        checker: checkers.New(),
 
224
        checks: []checkTest{{
 
225
                caveat:      checkers.ErrorCaveatf("").Condition,
 
226
                expectError: `caveat "error " not satisfied: bad caveat`,
 
227
        }, {
 
228
                caveat:      checkers.ErrorCaveatf("something %d", 134).Condition,
 
229
                expectError: `caveat "error something 134" not satisfied: bad caveat`,
 
230
        }},
 
231
}, {
 
232
        about:   "error caveat overrides other",
 
233
        checker: checkers.New(argChecker("error", "something")),
 
234
        checks: []checkTest{{
 
235
                caveat:      checkers.ErrorCaveatf("something").Condition,
 
236
                expectError: `caveat "error something" not satisfied: bad caveat`,
 
237
        }},
 
238
}}
 
239
 
 
240
var errWrongArg = errgo.New("wrong arg")
 
241
 
 
242
func argChecker(expectCond, checkArg string) checkers.Checker {
 
243
        return checkers.CheckerFunc{
 
244
                Condition_: expectCond,
 
245
                Check_: func(cond, arg string) error {
 
246
                        if cond != expectCond {
 
247
                                panic(fmt.Errorf("got condition %q want %q", cond, expectCond))
 
248
                        }
 
249
                        if arg != checkArg {
 
250
                                return errWrongArg
 
251
                        }
 
252
                        return nil
 
253
                },
 
254
        }
 
255
}
 
256
 
 
257
func (s *CheckersSuite) TestCheckers(c *gc.C) {
 
258
        for i, test := range checkerTests {
 
259
                c.Logf("test %d: %s", i, test.about)
 
260
                for j, check := range test.checks {
 
261
                        c.Logf("\tcheck %d", j)
 
262
                        err := test.checker.CheckFirstPartyCaveat(check.caveat)
 
263
                        if check.expectError != "" {
 
264
                                c.Assert(err, gc.ErrorMatches, check.expectError)
 
265
                                if check.expectCause == nil {
 
266
                                        check.expectCause = errgo.Any
 
267
                                }
 
268
                                c.Assert(check.expectCause(errgo.Cause(err)), gc.Equals, true)
 
269
                        } else {
 
270
                                c.Assert(err, gc.IsNil)
 
271
                        }
 
272
                }
 
273
        }
 
274
}
 
275
 
 
276
func (s *CheckersSuite) TestClientIPAddrCaveat(c *gc.C) {
 
277
        cav := checkers.ClientIPAddrCaveat(net.IP{127, 0, 0, 1})
 
278
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
279
                Condition: "client-ip-addr 127.0.0.1",
 
280
        })
 
281
        cav = checkers.ClientIPAddrCaveat(net.ParseIP("2001:4860:0:2001::68"))
 
282
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
283
                Condition: "client-ip-addr 2001:4860:0:2001::68",
 
284
        })
 
285
        cav = checkers.ClientIPAddrCaveat(nil)
 
286
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
287
                Condition: "error bad IP address []",
 
288
        })
 
289
        cav = checkers.ClientIPAddrCaveat(net.IP{123, 3})
 
290
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
291
                Condition: "error bad IP address [123 3]",
 
292
        })
 
293
}
 
294
 
 
295
func (s *CheckersSuite) TestClientOriginCaveat(c *gc.C) {
 
296
        cav := checkers.ClientOriginCaveat("")
 
297
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
298
                Condition: "origin ",
 
299
        })
 
300
        cav = checkers.ClientOriginCaveat("somewhere")
 
301
        c.Assert(cav, gc.Equals, checkers.Caveat{
 
302
                Condition: "origin somewhere",
 
303
        })
 
304
}
 
305
 
 
306
var inferDeclaredTests = []struct {
 
307
        about   string
 
308
        caveats [][]checkers.Caveat
 
309
        expect  checkers.Declared
 
310
}{{
 
311
        about:  "no macaroons",
 
312
        expect: checkers.Declared{},
 
313
}, {
 
314
        about: "single macaroon with one declaration",
 
315
        caveats: [][]checkers.Caveat{{{
 
316
                Condition: "declared foo bar",
 
317
        }}},
 
318
        expect: checkers.Declared{
 
319
                "foo": "bar",
 
320
        },
 
321
}, {
 
322
        about: "only one argument to declared",
 
323
        caveats: [][]checkers.Caveat{{{
 
324
                Condition: "declared foo",
 
325
        }}},
 
326
        expect: checkers.Declared{},
 
327
}, {
 
328
        about: "spaces in value",
 
329
        caveats: [][]checkers.Caveat{{{
 
330
                Condition: "declared foo bar bloggs",
 
331
        }}},
 
332
        expect: checkers.Declared{
 
333
                "foo": "bar bloggs",
 
334
        },
 
335
}, {
 
336
        about: "attribute with declared prefix",
 
337
        caveats: [][]checkers.Caveat{{{
 
338
                Condition: "declaredccf foo",
 
339
        }}},
 
340
        expect: checkers.Declared{},
 
341
}, {
 
342
        about: "several macaroons with different declares",
 
343
        caveats: [][]checkers.Caveat{{
 
344
                checkers.DeclaredCaveat("a", "aval"),
 
345
                checkers.DeclaredCaveat("b", "bval"),
 
346
        }, {
 
347
                checkers.DeclaredCaveat("c", "cval"),
 
348
                checkers.DeclaredCaveat("d", "dval"),
 
349
        }},
 
350
        expect: checkers.Declared{
 
351
                "a": "aval",
 
352
                "b": "bval",
 
353
                "c": "cval",
 
354
                "d": "dval",
 
355
        },
 
356
}, {
 
357
        about: "duplicate values",
 
358
        caveats: [][]checkers.Caveat{{
 
359
                checkers.DeclaredCaveat("a", "aval"),
 
360
                checkers.DeclaredCaveat("a", "aval"),
 
361
                checkers.DeclaredCaveat("b", "bval"),
 
362
        }, {
 
363
                checkers.DeclaredCaveat("a", "aval"),
 
364
                checkers.DeclaredCaveat("b", "bval"),
 
365
                checkers.DeclaredCaveat("c", "cval"),
 
366
                checkers.DeclaredCaveat("d", "dval"),
 
367
        }},
 
368
        expect: checkers.Declared{
 
369
                "a": "aval",
 
370
                "b": "bval",
 
371
                "c": "cval",
 
372
                "d": "dval",
 
373
        },
 
374
}, {
 
375
        about: "conflicting values",
 
376
        caveats: [][]checkers.Caveat{{
 
377
                checkers.DeclaredCaveat("a", "aval"),
 
378
                checkers.DeclaredCaveat("a", "conflict"),
 
379
                checkers.DeclaredCaveat("b", "bval"),
 
380
        }, {
 
381
                checkers.DeclaredCaveat("a", "conflict"),
 
382
                checkers.DeclaredCaveat("b", "another conflict"),
 
383
                checkers.DeclaredCaveat("c", "cval"),
 
384
                checkers.DeclaredCaveat("d", "dval"),
 
385
        }},
 
386
        expect: checkers.Declared{
 
387
                "c": "cval",
 
388
                "d": "dval",
 
389
        },
 
390
}, {
 
391
        about: "third party caveats ignored",
 
392
        caveats: [][]checkers.Caveat{{{
 
393
                Condition: "declared a no conflict",
 
394
                Location:  "location",
 
395
        },
 
396
                checkers.DeclaredCaveat("a", "aval"),
 
397
        }},
 
398
        expect: checkers.Declared{
 
399
                "a": "aval",
 
400
        },
 
401
}, {
 
402
        about: "unparseable caveats ignored",
 
403
        caveats: [][]checkers.Caveat{{{
 
404
                Condition: " bad",
 
405
        },
 
406
                checkers.DeclaredCaveat("a", "aval"),
 
407
        }},
 
408
        expect: checkers.Declared{
 
409
                "a": "aval",
 
410
        },
 
411
}}
 
412
 
 
413
func (*CheckersSuite) TestInferDeclared(c *gc.C) {
 
414
        for i, test := range inferDeclaredTests {
 
415
                c.Logf("test %d: %s", i, test.about)
 
416
                ms := make(macaroon.Slice, len(test.caveats))
 
417
                for i, caveats := range test.caveats {
 
418
                        m, err := macaroon.New(nil, fmt.Sprint(i), "")
 
419
                        c.Assert(err, gc.IsNil)
 
420
                        for _, cav := range caveats {
 
421
                                if cav.Location == "" {
 
422
                                        m.AddFirstPartyCaveat(cav.Condition)
 
423
                                } else {
 
424
                                        m.AddThirdPartyCaveat(nil, cav.Condition, cav.Location)
 
425
                                }
 
426
                        }
 
427
                        ms[i] = m
 
428
                }
 
429
                c.Assert(checkers.InferDeclared(ms), jc.DeepEquals, test.expect)
 
430
        }
 
431
}
 
432
 
 
433
var operationCheckerTests = []struct {
 
434
        about       string
 
435
        caveat      checkers.Caveat
 
436
        oc          checkers.OperationChecker
 
437
        expectError string
 
438
}{{
 
439
        about:  "allowed operation",
 
440
        caveat: checkers.AllowCaveat("op1", "op2", "op3"),
 
441
        oc:     checkers.OperationChecker("op1"),
 
442
}, {
 
443
        about:  "not denied oc",
 
444
        caveat: checkers.DenyCaveat("op1", "op2", "op3"),
 
445
        oc:     checkers.OperationChecker("op4"),
 
446
}, {
 
447
        about:       "not allowed oc",
 
448
        caveat:      checkers.AllowCaveat("op1", "op2", "op3"),
 
449
        oc:          checkers.OperationChecker("op4"),
 
450
        expectError: "op4 not allowed",
 
451
}, {
 
452
        about:       "denied oc",
 
453
        caveat:      checkers.DenyCaveat("op1", "op2", "op3"),
 
454
        oc:          checkers.OperationChecker("op1"),
 
455
        expectError: "op1 not allowed",
 
456
}, {
 
457
        about:       "unrecognised caveat",
 
458
        caveat:      checkers.ErrorCaveatf("unrecognized"),
 
459
        oc:          checkers.OperationChecker("op1"),
 
460
        expectError: "caveat not recognized",
 
461
}, {
 
462
        about:  "empty deny caveat",
 
463
        caveat: checkers.DenyCaveat(),
 
464
        oc:     checkers.OperationChecker("op1"),
 
465
}}
 
466
 
 
467
func (*CheckersSuite) TestOperationChecker(c *gc.C) {
 
468
        for i, test := range operationCheckerTests {
 
469
                c.Logf("%d: %s", i, test.about)
 
470
                cond, arg, err := checkers.ParseCaveat(test.caveat.Condition)
 
471
                c.Assert(err, gc.IsNil)
 
472
                c.Assert(test.oc.Condition(), gc.Equals, "")
 
473
                err = test.oc.Check(cond, arg)
 
474
                if test.expectError == "" {
 
475
                        c.Assert(err, gc.IsNil)
 
476
                        continue
 
477
                }
 
478
                c.Assert(err, gc.ErrorMatches, test.expectError)
 
479
        }
 
480
}
 
481
 
 
482
var operationsCheckerTests = []struct {
 
483
        about       string
 
484
        caveat      checkers.Caveat
 
485
        oc          checkers.OperationsChecker
 
486
        expectError string
 
487
}{{
 
488
        about:  "all allowed",
 
489
        caveat: checkers.AllowCaveat("op1", "op2", "op4", "op3"),
 
490
        oc:     checkers.OperationsChecker{"op1", "op3", "op2"},
 
491
}, {
 
492
        about:  "none denied",
 
493
        caveat: checkers.DenyCaveat("op1", "op2"),
 
494
        oc:     checkers.OperationsChecker{"op3", "op4"},
 
495
}, {
 
496
        about:       "one not allowed",
 
497
        caveat:      checkers.AllowCaveat("op1", "op2"),
 
498
        oc:          checkers.OperationsChecker{"op1", "op3"},
 
499
        expectError: `op3 not allowed`,
 
500
}, {
 
501
        about:       "one denied",
 
502
        caveat:      checkers.DenyCaveat("op1", "op2"),
 
503
        oc:          checkers.OperationsChecker{"op4", "op5", "op2"},
 
504
        expectError: `op2 not allowed`,
 
505
}, {
 
506
        about:       "no operations, allow caveat",
 
507
        caveat:      checkers.AllowCaveat("op1"),
 
508
        oc:          checkers.OperationsChecker{},
 
509
        expectError: `op1 not allowed`,
 
510
}, {
 
511
        about:  "no operations, deny caveat",
 
512
        caveat: checkers.DenyCaveat("op1"),
 
513
        oc:     checkers.OperationsChecker{},
 
514
}, {
 
515
        about: "no operations, empty allow caveat",
 
516
        caveat: checkers.Caveat{
 
517
                Condition: checkers.CondAllow,
 
518
        },
 
519
        oc:          checkers.OperationsChecker{},
 
520
        expectError: `no operations allowed`,
 
521
}}
 
522
 
 
523
func (*CheckersSuite) TestOperationsChecker(c *gc.C) {
 
524
        for i, test := range operationsCheckerTests {
 
525
                c.Logf("%d: %s", i, test.about)
 
526
                cond, arg, err := checkers.ParseCaveat(test.caveat.Condition)
 
527
                c.Assert(err, gc.IsNil)
 
528
                c.Assert(test.oc.Condition(), gc.Equals, "")
 
529
                err = test.oc.Check(cond, arg)
 
530
                if test.expectError == "" {
 
531
                        c.Assert(err, gc.IsNil)
 
532
                        continue
 
533
                }
 
534
                c.Assert(err, gc.ErrorMatches, test.expectError)
 
535
        }
 
536
}
 
537
 
 
538
var operationErrorCaveatTests = []struct {
 
539
        about           string
 
540
        caveat          checkers.Caveat
 
541
        expectCondition string
 
542
}{{
 
543
        about:           "empty allow",
 
544
        caveat:          checkers.AllowCaveat(),
 
545
        expectCondition: "error no operations allowed",
 
546
}, {
 
547
        about:           "allow: invalid operation name",
 
548
        caveat:          checkers.AllowCaveat("op1", "operation number 2"),
 
549
        expectCondition: `error invalid operation name "operation number 2"`,
 
550
}, {
 
551
        about:           "deny: invalid operation name",
 
552
        caveat:          checkers.DenyCaveat("op1", "operation number 2"),
 
553
        expectCondition: `error invalid operation name "operation number 2"`,
 
554
}}
 
555
 
 
556
func (*CheckersSuite) TestOperationErrorCaveatTest(c *gc.C) {
 
557
        for i, test := range operationErrorCaveatTests {
 
558
                c.Logf("%d: %s", i, test.about)
 
559
                c.Assert(test.caveat.Condition, gc.Matches, test.expectCondition)
 
560
        }
 
561
}