Merge lp:~hazmat/pyjuju/bool-and-validate-defaults into lp:pyjuju

Proposed by Kapil Thangavelu
Status: Merged
Approved by: Benjamin Saller
Approved revision: 449
Merged at revision: 473
Proposed branch: lp:~hazmat/pyjuju/bool-and-validate-defaults
Merge into: lp:pyjuju
Diff against target: 141 lines (+68/-7)
2 files modified
juju/charm/config.py (+16/-5)
juju/charm/tests/test_config.py (+52/-2)
To merge this branch: bzr merge lp:~hazmat/pyjuju/bool-and-validate-defaults
Reviewer Review Type Date Requested Status
Benjamin Saller (community) Approve
Jim Baker (community) Approve
Review via email: mp+89978@code.launchpad.net

Description of the change

Validate defaults and add a boolean config type

Defaults previously could be inconsistent to the schema without detection. Per
request also implement a boolean configuration type.

https://codereview.appspot.com/5572053/

To post a comment you must log in.
Revision history for this message
Kapil Thangavelu (hazmat) wrote :
Download full text (5.6 KiB)

Reviewers: mp+89978_code.launchpad.net,

Message:
Please take a look.

Description:
Defaults previously could be inconsistent to the schema without
detection. Per
request also implement a boolean configuration type.

https://code.launchpad.net/~hazmat/juju/bool-and-validate-defaults/+merge/89978

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/5572053/

Affected files:
   M juju/charm/config.py
   M juju/charm/tests/test_config.py

Index: juju/charm/config.py
=== <email address hidden> >
<email address hidden>
=== modified file 'juju/charm/config.py'
--- juju/charm/config.py 2011-12-07 02:32:07 +0000
+++ juju/charm/config.py 2012-01-24 18:10:19 +0000
@@ -13,6 +13,7 @@
          "type": OneOf(Constant("string"),
                        Constant("str"), # Obsolete
                        Constant("int"),
+ Constant("boolean"),
                        Constant("float")),
          "default": OneOf(String(), Int(), Float()),
          "description": String(),
@@ -91,6 +92,8 @@

          data = self.parse_serialization_data(raw_data, pathname)
          self._data = data
+ # validate defaults
+ self.get_defaults()

      def parse_serialization_data(self, data, pathname=None):
          """Verify we have sensible option metadata.
@@ -136,7 +139,7 @@

          if not valid:
              raise ServiceConfigValueError(
- "Invalid value for %s: %s" % (name, value))
+ "Invalid value for %s: %r" % (name, value))
          return value

      def get_defaults(self):
@@ -173,7 +176,9 @@

  # Validators return (type mapped value, valid boolean)
  def validate_str(value, options):
- return str(value), True
+ if isinstance(value, basestring):
+ return value, True
+ return value, False

  def validate_int(value, options):
@@ -184,10 +189,15 @@

  def validate_float(value, options):
- try:
+ if isinstance(value, (int, float)):
          return float(value), True
- except ValueError:
- return value, False
+ return value, False
+
+
+def validate_boolean(value, options):
+ if isinstance(value, bool):
+ return value, True
+ return value, False

  # maps service option types to callables
  validation_kinds = {
@@ -195,4 +205,5 @@
      "str": validate_str, # Obsolete
      "int": validate_int,
      "float": validate_float,
+ "boolean": validate_boolean,
      }

Index: juju/charm/tests/test_config.py
=== <email address hidden> >
<email address hidden>
=== modified file 'juju/charm/tests/test_config.py'
--- juju/charm/tests/test_config.py 2011-12-07 02:32:07 +0000
+++ juju/charm/tests/test_config.py 2012-01-24 18:42:22 +0000
@@ -78,6 +78,19 @@
          defaults = self.config.get_defaults()
          self.assertEqual(defaults, sample_config_defaults)

+ def test_defaults_validated(self):
+ e = self.assertRaises(
+ ServiceConfigValueError,
+ self.config.parse,
+ yaml.dump(
+ ...

Read more...

Revision history for this message
Jim Baker (jimbaker) wrote :

+1, another easy & small branch to review!

review: Approve
Revision history for this message
Benjamin Saller (bcsaller) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'juju/charm/config.py'
2--- juju/charm/config.py 2011-12-07 02:32:07 +0000
3+++ juju/charm/config.py 2012-01-24 19:02:27 +0000
4@@ -13,6 +13,7 @@
5 "type": OneOf(Constant("string"),
6 Constant("str"), # Obsolete
7 Constant("int"),
8+ Constant("boolean"),
9 Constant("float")),
10 "default": OneOf(String(), Int(), Float()),
11 "description": String(),
12@@ -91,6 +92,8 @@
13
14 data = self.parse_serialization_data(raw_data, pathname)
15 self._data = data
16+ # validate defaults
17+ self.get_defaults()
18
19 def parse_serialization_data(self, data, pathname=None):
20 """Verify we have sensible option metadata.
21@@ -136,7 +139,7 @@
22
23 if not valid:
24 raise ServiceConfigValueError(
25- "Invalid value for %s: %s" % (name, value))
26+ "Invalid value for %s: %r" % (name, value))
27 return value
28
29 def get_defaults(self):
30@@ -173,7 +176,9 @@
31
32 # Validators return (type mapped value, valid boolean)
33 def validate_str(value, options):
34- return str(value), True
35+ if isinstance(value, basestring):
36+ return value, True
37+ return value, False
38
39
40 def validate_int(value, options):
41@@ -184,10 +189,15 @@
42
43
44 def validate_float(value, options):
45- try:
46+ if isinstance(value, (int, float)):
47 return float(value), True
48- except ValueError:
49- return value, False
50+ return value, False
51+
52+
53+def validate_boolean(value, options):
54+ if isinstance(value, bool):
55+ return value, True
56+ return value, False
57
58 # maps service option types to callables
59 validation_kinds = {
60@@ -195,4 +205,5 @@
61 "str": validate_str, # Obsolete
62 "int": validate_int,
63 "float": validate_float,
64+ "boolean": validate_boolean,
65 }
66
67=== modified file 'juju/charm/tests/test_config.py'
68--- juju/charm/tests/test_config.py 2011-12-07 02:32:07 +0000
69+++ juju/charm/tests/test_config.py 2012-01-24 19:02:27 +0000
70@@ -78,6 +78,19 @@
71 defaults = self.config.get_defaults()
72 self.assertEqual(defaults, sample_config_defaults)
73
74+ def test_defaults_validated(self):
75+ e = self.assertRaises(
76+ ServiceConfigValueError,
77+ self.config.parse,
78+ yaml.dump(
79+ {"options": {
80+ "foobar": {
81+ "description": "beyond what?",
82+ "type": "string",
83+ "default": True}}}))
84+ self.assertEqual(
85+ str(e), "Invalid value for foobar: True")
86+
87 def test_as_dict(self):
88 # load valid data
89 filename = self.makeFile(sample_configuration)
90@@ -129,12 +142,49 @@
91 self.assertRaises(
92 ServiceConfigValueError, config.validate, sample_input)
93
94- def test_validate_types(self):
95+ def test_validate_float(self):
96+ self.config.parse(yaml.dump(
97+ {"options": {
98+ "score": {
99+ "description": "A number indicating score.",
100+ "type": "float"}}}))
101+ error = self.assertRaises(ServiceConfigValueError,
102+ self.config.validate, {"score": "82"})
103+ self.assertEquals(str(error), "Invalid value for score: '82'")
104+
105+ data = self.config.validate({"score": 82})
106+ self.assertEqual(data, {"score": 82})
107+
108+ def test_validate_string(self):
109+ self.config.parse(sample_configuration)
110+
111+ error = self.assertRaises(ServiceConfigValueError,
112+ self.config.validate, {"title": True})
113+ self.assertEquals(str(error), "Invalid value for title: True")
114+
115+ data = self.config.validate({"title": u"Good"})
116+ self.assertEqual(data, {"title": u"Good"})
117+
118+ def test_validate_boolean(self):
119+ self.config.parse(yaml.dump(
120+ {"options": {
121+ "active": {
122+ "description": "A boolean indicating activity.",
123+ "type": "boolean"}}}))
124+
125+ error = self.assertRaises(ServiceConfigValueError,
126+ self.config.validate, {"active": "True"})
127+ self.assertEquals(str(error), "Invalid value for active: 'True'")
128+
129+ data = self.config.validate({"active": False})
130+ self.assertEqual(data, {"active": False})
131+
132+ def test_validate_integer(self):
133 self.config.parse(sample_configuration)
134
135 error = self.assertRaises(ServiceConfigValueError,
136 self.config.validate, {"skill-level": "NaN"})
137- self.assertEquals(str(error), "Invalid value for skill-level: NaN")
138+ self.assertEquals(str(error), "Invalid value for skill-level: 'NaN'")
139
140 data = self.config.validate({"skill-level": "9001"})
141 # its over 9000!

Subscribers

People subscribed via source and target branches

to status/vote changes: