diff options
author | Pradyumna Sampath <pradyumna@hitachi.co.in> | 2014-11-20 01:33:33 -0800 |
---|---|---|
committer | Eoghan Glynn <eglynn@redhat.com> | 2014-12-02 11:25:54 +0000 |
commit | 37e593eb4df040cce83e9ccf381318e6df2d0faa (patch) | |
tree | 452c6e08028da23808bf83367cad4823aaecca49 | |
parent | 6eb39a9a2c76cefc5a2c1af071516a68f1e0672f (diff) | |
download | ceilometer-37e593eb4df040cce83e9ccf381318e6df2d0faa.tar.gz |
Validate AdvEnum & return an InvalidInput on error
Raise a relevant exception of InvalidInput while validating if
the input to AdvEnum is not one of what is expected.
Closes-bug: #1320430
Change-Id: I48f014cc09e7d88e9b0f02fb8e9cf45772178b2c
(cherry picked from commit 7cf60e2a3b54b7a763434f65cb045b80074addf1)
-rw-r--r-- | ceilometer/api/controllers/v2.py | 8 | ||||
-rw-r--r-- | ceilometer/tests/api/v2/test_alarm_scenarios.py | 154 | ||||
-rw-r--r-- | ceilometer/tests/api/v2/test_wsme_custom_type.py | 2 |
3 files changed, 159 insertions, 5 deletions
diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index 36f6bec5..0f28ed72 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -164,8 +164,12 @@ class AdvEnum(wtypes.wsproperty): return self._default def _set(self, parent, value): - if self.datatype.validate(value): - setattr(parent, self._name, value) + try: + if self.datatype.validate(value): + setattr(parent, self._name, value) + except ValueError as e: + raise wsme.exc.InvalidInput(self._name.replace('_advenum_', '', 1), + value, e) class CronType(wtypes.UserType): diff --git a/ceilometer/tests/api/v2/test_alarm_scenarios.py b/ceilometer/tests/api/v2/test_alarm_scenarios.py index 8ab13b75..87640df7 100644 --- a/ceilometer/tests/api/v2/test_alarm_scenarios.py +++ b/ceilometer/tests/api/v2/test_alarm_scenarios.py @@ -531,8 +531,158 @@ class TestAlarms(v2.FunctionalTest, 'statistic': 'magic', } } - self.post_json('/alarms', params=json, expect_errors=True, status=400, - headers=self.auth_headers) + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " statistic." + " Value: 'magic'." + " Value should be one of:" + " count, max, sum, avg, min") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_alarm_input_state(self): + json = { + 'name': 'alarm1', + 'state': 'bad_state', + 'type': 'threshold', + 'threshold_rule': { + 'meter_name': 'ameter', + 'comparison_operator': 'gt', + 'threshold': 50.0 + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute state." + " Value: 'bad_state'." + " Value should be one of:" + " alarm, ok, insufficient data") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_alarm_input_comparison_operator(self): + json = { + 'name': 'alarm2', + 'state': 'ok', + 'type': 'threshold', + 'threshold_rule': { + 'meter_name': 'ameter', + 'comparison_operator': 'bad_co', + 'threshold': 50.0 + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " comparison_operator." + " Value: 'bad_co'." + " Value should be one of:" + " gt, lt, ne, ge, le, eq") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_alarm_input_type(self): + json = { + 'name': 'alarm3', + 'state': 'ok', + 'type': 'bad_type', + 'threshold_rule': { + 'meter_name': 'ameter', + 'comparison_operator': 'gt', + 'threshold': 50.0 + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " type." + " Value: 'bad_type'." + " Value should be one of:" + " threshold, combination") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_alarm_input_enabled_str(self): + json = { + 'name': 'alarm5', + 'enabled': 'bad_enabled', + 'state': 'ok', + 'type': 'threshold', + 'threshold_rule': { + 'meter_name': 'ameter', + 'comparison_operator': 'gt', + 'threshold': 50.0 + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " enabled." + " Value: 'bad_enabled'." + " Wrong type. Expected '<type 'bool'>'," + " got '<type 'str'>'") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_alarm_input_enabled_int(self): + json = { + 'name': 'alarm6', + 'enabled': 0, + 'state': 'ok', + 'type': 'threshold', + 'threshold_rule': { + 'meter_name': 'ameter', + 'comparison_operator': 'gt', + 'threshold': 50.0 + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " enabled." + " Value: '0'." + " Wrong type. Expected '<type 'bool'>'," + " got '<type 'int'>'") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) + alarms = list(self.alarm_conn.get_alarms()) + self.assertEqual(4, len(alarms)) + + def test_post_invalid_combination_alarm_input_operator(self): + json = { + 'enabled': False, + 'name': 'alarm6', + 'state': 'ok', + 'type': 'combination', + 'ok_actions': ['http://something/ok'], + 'alarm_actions': ['http://something/alarm'], + 'insufficient_data_actions': ['http://something/no'], + 'repeat_actions': True, + 'combination_rule': { + 'alarm_ids': ['a', + 'b'], + 'operator': 'bad_operator', + } + } + resp = self.post_json('/alarms', params=json, expect_errors=True, + status=400, headers=self.auth_headers) + expected_err_msg = ("Invalid input for field/attribute" + " operator." + " Value: 'bad_operator'." + " Value should be one of: and, or") + self.assertEqual(expected_err_msg, + resp.json['error_message']['faultstring']) alarms = list(self.alarm_conn.get_alarms()) self.assertEqual(4, len(alarms)) diff --git a/ceilometer/tests/api/v2/test_wsme_custom_type.py b/ceilometer/tests/api/v2/test_wsme_custom_type.py index 6a80054b..230d4d9b 100644 --- a/ceilometer/tests/api/v2/test_wsme_custom_type.py +++ b/ceilometer/tests/api/v2/test_wsme_custom_type.py @@ -32,4 +32,4 @@ class TestWsmeCustomType(base.BaseTestCase): obj = dummybase(ae="one") self.assertEqual("one", obj.ae) - self.assertRaises(ValueError, dummybase, ae="not exists") + self.assertRaises(wsme.exc.InvalidInput, dummybase, ae="not exists") |