Added fix for Bug #813291: POST to /images setting x-image-meta-id to an already existing image id causes a 500 error.
I came up with about 3 or 4 different ways of resolving this bug, and all tests pass. Let me know if you think this should be resolved in a different way. This branch also includes a test in tests/functional/test_httplib2_api.py that shows the 500 error.
This commit is contained in:
commit
bd96e2043c
@ -24,6 +24,7 @@ Defines interface for DB access
|
||||
import logging
|
||||
|
||||
from sqlalchemy import asc, create_engine, desc
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import exc
|
||||
from sqlalchemy.orm import joinedload
|
||||
@ -273,7 +274,11 @@ def _image_update(context, values, image_id, purge_props=False):
|
||||
# idiotic.
|
||||
validate_image(image_ref.to_dict())
|
||||
|
||||
image_ref.save(session=session)
|
||||
try:
|
||||
image_ref.save(session=session)
|
||||
except IntegrityError, e:
|
||||
raise exception.Duplicate("Image ID %s already exists!"
|
||||
% values['id'])
|
||||
|
||||
_set_properties_for_image(context, image_ref, properties, purge_props,
|
||||
session)
|
||||
|
@ -1029,3 +1029,50 @@ class TestApiHttplib2(functional.FunctionalTest):
|
||||
self.assertEqual(data['images'][2]['id'], 2)
|
||||
|
||||
self.stop_servers()
|
||||
|
||||
def test_duplicate_image_upload(self):
|
||||
"""
|
||||
Upload initial image, then attempt to upload duplicate image
|
||||
"""
|
||||
self.cleanup()
|
||||
self.start_servers()
|
||||
|
||||
# 0. GET /images
|
||||
# Verify no public images
|
||||
path = "http://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(content, '{"images": []}')
|
||||
|
||||
# 1. POST /images with public image named Image1
|
||||
headers = {'Content-Type': 'application/octet-stream',
|
||||
'X-Image-Meta-Name': 'Image1',
|
||||
'X-Image-Meta-Status': 'active',
|
||||
'X-Image-Meta-Container-Format': 'ovf',
|
||||
'X-Image-Meta-Disk-Format': 'vdi',
|
||||
'X-Image-Meta-Size': '19',
|
||||
'X-Image-Meta-Is-Public': 'True'}
|
||||
path = "http://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'POST', headers=headers)
|
||||
self.assertEqual(response.status, 201)
|
||||
|
||||
# 2. POST /images with public image named Image1, and ID: 1
|
||||
headers = {'Content-Type': 'application/octet-stream',
|
||||
'X-Image-Meta-Name': 'Image1 Update',
|
||||
'X-Image-Meta-Status': 'active',
|
||||
'X-Image-Meta-Container-Format': 'ovf',
|
||||
'X-Image-Meta-Disk-Format': 'vdi',
|
||||
'X-Image-Meta-Size': '19',
|
||||
'X-Image-Meta-Id': '1',
|
||||
'X-Image-Meta-Is-Public': 'True'}
|
||||
path = "http://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'POST', headers=headers)
|
||||
self.assertEqual(response.status, 409)
|
||||
expected = "An image with identifier 1 already exists"
|
||||
self.assertTrue(expected in content,
|
||||
"Could not find '%s' in '%s'" % (expected, content))
|
||||
|
||||
self.stop_servers()
|
||||
|
Loading…
x
Reference in New Issue
Block a user