Fix image import tests for read-only stores

In order to test with one or more read-only store (such as an http
type store), we must exclude those from our list of stores we expect
to see when doing an import. This fixes both the waiter for the
"all stores" case, as well as our specific-store test from choosing
those stores for the list.

Change-Id: I8dd5e3256339ab1483e909fb5207d0da856e467e
This commit is contained in:
Dan Smith
2022-10-10 15:25:39 -07:00
parent 6714b65a21
commit 466f706082
3 changed files with 51 additions and 5 deletions
+5 -3
View File
@@ -363,10 +363,12 @@ class MultiStoresImportImagesTest(base.BaseV2ImageTest):
if all_stores:
stores_list = ','.join([store['id']
for store in self.available_stores])
for store in self.available_stores
if store.get('read-only') != 'true'])
else:
stores = [store['id'] for store in self.available_stores]
stores_list = stores[::len(stores) - 1]
stores = [store['id'] for store in self.available_stores
if store.get('read-only') != 'true']
stores_list = stores[::max(1, len(stores) - 1)]
return body, stores_list
+20
View File
@@ -233,6 +233,26 @@ def wait_for_image_imported_to_stores(client, image_id, stores=None):
exc_cls = lib_exc.TimeoutException
start = int(time.time())
# NOTE(danms): Don't wait for stores that are read-only as those
# will never complete
try:
store_info = client.info_stores()['stores']
stores = ','.join(sorted([
store['id'] for store in store_info
if store.get('read-only') != 'true' and
(not stores or store['id'] in stores.split(','))]))
except lib_exc.NotFound:
# If multi-store is not enabled, then we can not resolve which
# ones are read-only, and stores must have been passed as None
# anyway for us to succeed. If not, then we should raise right
# now and avoid waiting since we will never see the stores
# appear.
if stores is not None:
raise lib_exc.TimeoutException(
'Image service has no store support; '
'cowardly refusing to wait for them.')
while int(time.time()) - start < client.build_timeout:
image = client.show_image(image_id)
if image['status'] == 'active' and (stores is None or
+26 -2
View File
@@ -59,11 +59,19 @@ class TestImageWaiters(base.TestCase):
def test_wait_for_image_imported_to_stores(self):
self.client.show_image.return_value = ({'status': 'active',
'stores': 'fake_store'})
self.client.info_stores.return_value = {
'stores': [{'id': 'fake_store',
'description': 'A writable store'},
{'id': 'another_fake_store',
'description': 'A read-only store',
'read-only': 'true'}]
}
start_time = int(time.time())
waiters.wait_for_image_imported_to_stores(
self.client, 'fake_image_id', 'fake_store')
self.client, 'fake_image_id', 'fake_store,another_fake_store')
end_time = int(time.time())
# Ensure waiter returns before build_timeout
# Ensure waiter returns before build_timeout, and did not wait
# for the read-only store
self.assertLess((end_time - start_time), 10)
def test_wait_for_image_imported_to_stores_failure(self):
@@ -95,6 +103,22 @@ class TestImageWaiters(base.TestCase):
waiters.wait_for_image_imported_to_stores,
client, 'fake_image_id', 'fake_store')
def test_wait_for_image_imported_to_stores_no_stores(self):
client = mock.MagicMock()
client.show_image.return_value = ({'status': 'active'})
client.info_stores.side_effect = lib_exc.NotFound
client.build_timeout = 2
start_time = time.time()
waiters.wait_for_image_imported_to_stores(
client, 'fake_image_id', None)
end_time = time.time()
self.assertLess(end_time - start_time, 10)
exc = self.assertRaises(lib_exc.TimeoutException,
waiters.wait_for_image_imported_to_stores,
client, 'fake_image_id', 'foo,bar')
self.assertIn('cowardly', str(exc))
def test_wait_for_image_copied_to_stores(self):
self.client.show_image.return_value = ({
'status': 'active',