~therve/pyjuju/validate-config-values

« back to all changes in this revision

Viewing changes to juju/machine/tests/test_constraints.py

  • Committer: William Reade
  • Author(s): William Reade
  • Date: 2012-04-11 15:43:50 UTC
  • mfrom: (520.3.2 constraints-compatibility)
  • Revision ID: fwereade@gmail.com-20120411154350-zihzhrwj6puzlfgt
Forward-compatibility fixes for Constraints

* Any constraint name can now be registered; no more global registry
* Unrecognised constraints are now ignored but persisted when introduced via
  ConstraintSet.load
* Unrecognised traits are now always errors when introduced via
  ConstraintSet.parse

R=hazmat
CC=
https://codereview.appspot.com/6001050

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
all_providers = ["dummy", "ec2", "orchestra"]
28
28
 
29
29
 
 
30
def _raiser(exc_type):
 
31
    def raise_(s):
 
32
        raise exc_type(s)
 
33
    return raise_
 
34
 
 
35
 
30
36
class ConstraintsTestCase(TestCase):
31
37
 
32
38
    def assert_error(self, message, *raises_args):
219
225
 
220
226
class ConstraintSetTest(TestCase):
221
227
 
222
 
    def allow_names(self, *names):
223
 
        all_names = ["ubuntu-series", "provider-type"]
224
 
        all_names.extend(names)
225
 
        from juju.machine import constraints
226
 
        self.patch(constraints, "ALL_NAMES", all_names)
227
 
 
228
 
    def test_register_unknown_name(self):
229
 
        e = self.assertRaises(
230
 
            AssertionError, ConstraintSet("provider").register, "nonsense")
231
 
        self.assertEquals(str(e), "please update ALL_NAMES")
232
 
 
233
 
    def test_register_known_names(self):
234
 
        self.allow_names("foo", "blob")
235
 
        cs = ConstraintSet("provider")
236
 
        cs.register("foo")
237
 
        cs.register("blob")
238
 
        c1 = cs.parse(["foo=bar"]).with_series("series")
239
 
        self.assertEquals(c1["foo"], "bar")
240
 
        self.assertEquals(c1["blob"], None)
241
 
        c2 = cs.parse(["foo=bar"]).with_series("series")
242
 
        self.assertTrue(c1.can_satisfy(c2))
243
 
        self.assertTrue(c2.can_satisfy(c1))
244
 
 
245
228
    def test_unregistered_name(self):
246
 
        self.allow_names("foo", "bar", "baz")
247
229
        cs = ConstraintSet("provider")
248
230
        cs.register("bar")
249
 
        output = self.capture_logging()
250
 
        constraints = cs.parse(["foo=1", "bar=2", "baz=3"])
251
 
        self.assertIn("ignored irrelevant 'foo' constraint", output.getvalue())
252
 
        self.assertIn("ignored irrelevant 'baz' constraint", output.getvalue())
253
 
        self.assertEquals(constraints["bar"], "2")
 
231
        e = self.assertRaises(ConstraintError, cs.parse, ["bar=2", "baz=3"])
 
232
        self.assertEquals(str(e), "Unknown constraint: 'baz'")
254
233
 
255
234
    def test_register_invisible(self):
256
 
        self.allow_names("foo")
257
235
        cs = ConstraintSet("provider")
258
236
        cs.register("foo", visible=False)
259
237
        e = self.assertRaises(ConstraintError, cs.parse, ["foo=bar"])
260
238
        self.assertEquals(str(e), "Cannot set computed constraint: 'foo'")
261
239
 
262
240
    def test_register_comparer(self):
263
 
        self.allow_names("foo")
264
241
        cs = ConstraintSet("provider")
265
242
        cs.register("foo", comparer=operator.ne)
266
243
        c1 = cs.parse(["foo=bar"]).with_series("series")
272
249
        self.assertTrue(c3.can_satisfy(c1))
273
250
 
274
251
    def test_register_default_and_converter(self):
275
 
        self.allow_names("foo")
276
252
        cs = ConstraintSet("provider")
277
253
        cs.register("foo", default="star", converter=lambda s: "death-" + s)
278
254
        c1 = cs.parse([])
281
257
        self.assertEquals(c1["foo"], "death-clock")
282
258
 
283
259
    def test_convert_wraps_ValueError(self):
284
 
        self.allow_names("foo", "bar")
285
 
 
286
 
        def raiser(e):
287
 
            raise e
288
260
        cs = ConstraintSet("provider")
289
 
        cs.register("foo", converter=lambda s: raiser(ValueError(s)))
290
 
        cs.register("bar", converter=lambda s: raiser(KeyError(s)))
 
261
        cs.register("foo", converter=_raiser(ValueError))
 
262
        cs.register("bar", converter=_raiser(KeyError))
291
263
        self.assertRaises(ConstraintError, cs.parse, ["foo=1"])
292
264
        self.assertRaises(KeyError, cs.parse, ["bar=1"])
293
265
 
294
266
    def test_register_conflicts(self):
295
 
        self.allow_names("foo", "bar", "baz", "qux")
296
267
        cs = ConstraintSet("provider")
297
268
        cs.register("foo")
298
269
        cs.register("bar")
394
365
        self.assertEquals(c8["mem"], 512.0)
395
366
        self.assertEquals(c8["instance-type"], None)
396
367
 
397
 
    def test_load_validates(self):
398
 
        self.allow_names("foo")
 
368
    def test_load_validates_known(self):
399
369
        cs = ConstraintSet("provider")
400
 
 
401
 
        def blam(s):
402
 
            raise ValueError(s)
403
 
 
404
 
        cs.register("foo", converter=blam)
 
370
        cs.register("foo", converter=_raiser(ValueError))
405
371
        e = self.assertRaises(ConstraintError, cs.load, {"foo": "bar"})
406
372
        self.assertEquals(str(e), "Bad 'foo' constraint 'bar': bar")
 
373
 
 
374
    def test_load_preserves_unknown(self):
 
375
        cs = ConstraintSet("provider")
 
376
        constraints = cs.load({"foo": "bar"})
 
377
        self.assertNotIn("foo", constraints)
 
378
        self.assertEquals(constraints.data, {"foo": "bar"})