Merge "Raise exception when adding an existed attribute while update bay"

This commit is contained in:
Jenkins 2015-11-04 05:14:23 +00:00 committed by Gerrit Code Review
commit 1bd78da9b4
7 changed files with 38 additions and 177 deletions

View File

@ -49,10 +49,15 @@ def validate_sort_dir(sort_dir):
def apply_jsonpatch(doc, patch):
for p in patch:
if p['op'] == 'add' and p['path'].count('/') == 1:
if p['path'].lstrip('/') not in doc:
msg = _('Adding a new attribute (%s) to the root of '
' the resource is not allowed')
raise wsme.exc.ClientSideError(msg % p['path'])
attr = p['path'].lstrip('/')
if attr not in doc:
msg = _("Adding a new attribute %s to the root of "
"the resource is not allowed.") % p['path']
raise wsme.exc.ClientSideError(msg)
if doc[attr] is not None:
msg = _("The attribute %s has existed, please use "
"'replace' operation instead.") % p['path']
raise wsme.exc.ClientSideError(msg)
return jsonpatch.apply_patch(doc, patch)

View File

@ -311,45 +311,6 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
def test_add_ok(self):
name = 'bay_example_B'
response = self.patch_json(
'/bays/%s' % self.bay.uuid,
[{'path': '/name', 'value': name, 'op': 'add'}])
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_int)
response = self.get_json('/bays/%s' % self.bay.uuid)
self.assertEqual(name, response['name'])
# Assert nothing else was changed
self.assertEqual(self.bay.uuid, response['uuid'])
self.assertEqual(self.bay.baymodel_id, response['baymodel_id'])
self.assertEqual(self.bay.node_count, response['node_count'])
def test_add_multi(self):
json = [
{
'path': '/name',
'value': 'bay_example_B',
'op': 'add'
},
{
'path': '/node_count',
'value': 33,
'op': 'add'
}
]
response = self.patch_json('/bays/%s' % self.bay.uuid, json)
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_code)
response = self.get_json('/bays/%s' % self.bay.uuid)
self.assertEqual('bay_example_B', response['name'])
self.assertEqual(33, response['node_count'])
# Assert nothing else was changed
self.assertEqual(self.bay.uuid, response['uuid'])
self.assertEqual(self.bay.baymodel_id, response['baymodel_id'])
def test_add_non_existent_property(self):
response = self.patch_json(
'/bays/%s' % self.bay.uuid,

View File

@ -367,30 +367,6 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual(400, response.status_code)
self.assertTrue(response.json['error_message'])
def test_add_root(self):
name = 'bay_model_example_B'
response = self.patch_json(
'/baymodels/%s' % self.baymodel.uuid,
[{'path': '/name', 'value': name, 'op': 'add'}])
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_int)
response = self.get_json('/baymodels/%s' % self.baymodel.uuid)
self.assertEqual(name, response['name'])
# Assert nothing else was changed
self.assertEqual(self.baymodel.uuid, response['uuid'])
self.assertEqual(self.baymodel.image_id, response['image_id'])
self.assertEqual(self.baymodel.apiserver_port,
response['apiserver_port'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.coe,
response['coe'])
self.assertEqual(self.baymodel.labels,
response['labels'])
def test_add_root_non_existent(self):
response = self.patch_json(
'/baymodels/%s' % self.baymodel.uuid,
@ -400,49 +376,6 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual(400, response.status_int)
self.assertTrue(response.json['error_message'])
def test_add_multi(self):
json = [
{
'path': '/name',
'value': 'bay_model_example_B',
'op': 'add'
},
{
'path': '/image_id',
'value': 'my-image',
'op': 'add'
}
]
response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, json)
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_code)
response = self.get_json('/baymodels/%s' % self.baymodel.uuid)
self.assertEqual('bay_model_example_B', response['name'])
self.assertEqual('my-image', response['image_id'])
# Assert nothing else was changed
self.assertEqual(self.baymodel.uuid, response['uuid'])
self.assertEqual(self.baymodel.apiserver_port,
response['apiserver_port'])
self.assertEqual(self.baymodel.fixed_network,
response['fixed_network'])
self.assertEqual(self.baymodel.network_driver,
response['network_driver'])
self.assertEqual(self.baymodel.docker_volume_size,
response['docker_volume_size'])
self.assertEqual(self.baymodel.ssh_authorized_key,
response['ssh_authorized_key'])
self.assertEqual(self.baymodel.coe,
response['coe'])
self.assertEqual(self.baymodel.http_proxy,
response['http_proxy'])
self.assertEqual(self.baymodel.https_proxy,
response['https_proxy'])
self.assertEqual(self.baymodel.no_proxy,
response['no_proxy'])
self.assertEqual(self.baymodel.labels,
response['labels'])
def test_remove_uuid(self):
response = self.patch_json('/baymodels/%s' % self.baymodel.uuid,
[{'path': '/uuid', 'op': 'remove'}],

View File

@ -175,17 +175,6 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
def test_add_ok(self):
new_image = 'Ubuntu'
response = self.patch_json(
'/nodes/%s' % self.node.uuid,
[{'path': '/image_id', 'value': new_image, 'op': 'add'}])
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_int)
response = self.get_json('/nodes/%s' % self.node.uuid)
self.assertEqual(new_image, response['image_id'])
def test_add_non_existent_property(self):
response = self.patch_json(
'/nodes/%s' % self.node.uuid,

View File

@ -260,48 +260,6 @@ class TestPatch(api_base.FunctionalTest):
parse_manifest.assert_called_once_with()
self.assertTrue(pod_update.is_called)
def test_add_ok(self):
new_desc = 'pod_example_B_desc'
response = self.patch_json(
'/pods/%s/%s' % (self.pod.uuid, self.pod.bay_uuid),
[{'path': '/desc', 'value': new_desc, 'op': 'add'}])
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_int)
response = self.get_json(
'/pods/%s/%s' % (self.pod.uuid, self.pod.bay_uuid))
self.assertEqual(new_desc, response['desc'])
def test_add_multi(self):
new_status = 'Stopped'
new_desc = 'pod_example_B_desc'
response = self.get_json(
'/pods/%s/%s' % (self.pod.uuid, self.pod.bay_uuid))
self.assertNotEqual(new_status, response['status'])
self.assertNotEqual(new_desc, response['desc'])
json = [
{
'path': '/status',
'value': new_status,
'op': 'add'
},
{
'path': '/desc',
'value': new_desc,
'op': 'add'
}
]
response = self.patch_json(
'/pods/%s/%s' % (self.pod.uuid, self.pod.bay_uuid), json)
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_code)
response = self.get_json(
'/pods/%s/%s' % (self.pod.uuid, self.pod.bay_uuid))
self.assertEqual(new_status, response['status'])
self.assertEqual(new_desc, response['desc'])
def test_add_non_existent_property(self):
response = self.patch_json(
'/pods/%s' % self.pod.uuid,

View File

@ -263,20 +263,6 @@ class TestPatch(api_base.FunctionalTest):
parse_manifest.assert_called_once_with()
self.assertTrue(rc_update.is_called)
def test_add_ok(self):
new_image = 'rc_example_B_image'
response = self.patch_json('/rcs/%s/%s' % (self.rc.uuid,
self.rc.bay_uuid),
[{'path': '/images/0',
'value': new_image,
'op': 'add'}])
self.assertEqual('application/json', response.content_type)
self.assertEqual(200, response.status_int)
response = self.get_json('/rcs/%s/%s' % (self.rc.uuid,
self.rc.bay_uuid))
self.assertEqual(new_image, response['images'][0])
def test_add_non_existent_property(self):
response = self.patch_json(
'/rcs/%s/%s' % (self.rc.uuid, self.rc.bay_uuid),

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import jsonpatch
import mock
import wsme
@ -121,3 +122,31 @@ class TestApiUtils(base.FunctionalTest):
self.assertRaises(exception.Conflict,
utils.get_openstack_resource,
fake_manager, 'fake_resource', 'fake_resource_type')
@mock.patch.object(jsonpatch, 'apply_patch')
def test_apply_jsonpatch(self, mock_jsonpatch):
doc = {'bay_uuid': 'id', 'node_count': 1}
patch = [{"path": "/node_count", "value": 2, "op": "replace"}]
utils.apply_jsonpatch(doc, patch)
mock_jsonpatch.assert_called_once_with(doc, patch)
def test_apply_jsonpatch_add_attr_not_exist(self):
doc = {'bay_uuid': 'id', 'node_count': 1}
patch = [{"path": "/fake", "value": 2, "op": "add"}]
exc = self.assertRaises(wsme.exc.ClientSideError,
utils.apply_jsonpatch,
doc, patch)
self.assertEqual(
"Adding a new attribute /fake to the root of the resource is "
"not allowed.", exc.message)
def test_apply_jsonpatch_add_attr_already_exist(self):
doc = {'bay_uuid': 'id', 'node_count': 1}
patch = [{"path": "/node_count", "value": 2, "op": "add"}]
exc = self.assertRaises(wsme.exc.ClientSideError,
utils.apply_jsonpatch,
doc, patch)
self.assertEqual(
"The attribute /node_count has existed, please use "
"'replace' operation instead.", exc.message)