Fix 'project_share_type_quotas' DB table unique constraint
It should be possible to use share type quotas in each project/tenant. But we get error trying to set share types quota in second+ project for the same share type. It happens so due to the bug in DB schema, where we don't have 'project_id' in unique constraint. So, add new DB migration that fixes unique constraint and cover it with DB and tempest tests. Change-Id: I1405ced4e12b40904b7227c9f6285e2775005f8a Closes-Bug: #1722707
This commit is contained in:
parent
647147ba10
commit
7ba41320f3
@ -0,0 +1,45 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""Fix 'project_share_type_quotas' unique constraint
|
||||||
|
|
||||||
|
Revision ID: 829a09b0ddd4
|
||||||
|
Revises: b516de97bfee
|
||||||
|
Create Date: 2017-10-12 20:15:51.267488
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '829a09b0ddd4'
|
||||||
|
down_revision = 'b516de97bfee'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
TABLE_NAME = 'project_share_type_quotas'
|
||||||
|
UNIQUE_CONSTRAINT_NAME = 'uc_quotas_per_share_types'
|
||||||
|
ST_FK_NAME = 'share_type_id_fk'
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.drop_constraint(ST_FK_NAME, TABLE_NAME, type_='foreignkey')
|
||||||
|
op.drop_constraint(UNIQUE_CONSTRAINT_NAME, TABLE_NAME, type_='unique')
|
||||||
|
op.create_foreign_key(
|
||||||
|
ST_FK_NAME, TABLE_NAME, 'share_types', ['share_type_id'], ['id'])
|
||||||
|
op.create_unique_constraint(
|
||||||
|
UNIQUE_CONSTRAINT_NAME, TABLE_NAME,
|
||||||
|
['share_type_id', 'resource', 'deleted', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# NOTE(vponomaryov): no need to implement old behaviour as it was bug, and,
|
||||||
|
# moreover, not compatible with data from upgraded version.
|
||||||
|
pass
|
@ -2466,3 +2466,37 @@ class ProjectShareTypesQuotasChecks(BaseMigrationChecks):
|
|||||||
self.test_case.assertGreater(db_result.rowcount, 0)
|
self.test_case.assertGreater(db_result.rowcount, 0)
|
||||||
for row in db_result:
|
for row in db_result:
|
||||||
self.test_case.assertFalse(hasattr(row, 'share_type_id'))
|
self.test_case.assertFalse(hasattr(row, 'share_type_id'))
|
||||||
|
|
||||||
|
|
||||||
|
@map_to_migration('829a09b0ddd4')
|
||||||
|
class FixProjectShareTypesQuotasUniqueConstraintChecks(BaseMigrationChecks):
|
||||||
|
st_record_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
def setup_upgrade_data(self, engine):
|
||||||
|
# Create share type
|
||||||
|
self.st_data = {
|
||||||
|
'id': self.st_record_id,
|
||||||
|
'name': uuidutils.generate_uuid(),
|
||||||
|
'deleted': "False",
|
||||||
|
}
|
||||||
|
st_table = utils.load_table('share_types', engine)
|
||||||
|
engine.execute(st_table.insert(self.st_data))
|
||||||
|
|
||||||
|
def check_upgrade(self, engine, data):
|
||||||
|
for project_id in ('x' * 255, 'x'):
|
||||||
|
# Create share type quota
|
||||||
|
self.quota_data = {
|
||||||
|
'project_id': project_id,
|
||||||
|
'resource': 'y' * 255,
|
||||||
|
'hard_limit': 987654321,
|
||||||
|
'created_at': datetime.datetime(2017, 4, 11, 18, 5, 58),
|
||||||
|
'updated_at': None,
|
||||||
|
'deleted_at': None,
|
||||||
|
'deleted': 0,
|
||||||
|
'share_type_id': self.st_record_id,
|
||||||
|
}
|
||||||
|
new_table = utils.load_table('project_share_type_quotas', engine)
|
||||||
|
engine.execute(new_table.insert(self.quota_data))
|
||||||
|
|
||||||
|
def check_downgrade(self, engine):
|
||||||
|
pass
|
||||||
|
@ -247,6 +247,30 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
|
|||||||
for q in ('shares', 'gigabytes', 'snapshots', 'snapshot_gigabytes'):
|
for q in ('shares', 'gigabytes', 'snapshots', 'snapshot_gigabytes'):
|
||||||
self.assertEqual(int(quotas[q]) - 1, current_quotas[q])
|
self.assertEqual(int(quotas[q]) - 1, current_quotas[q])
|
||||||
|
|
||||||
|
@tc.attr(base.TAG_POSITIVE, base.TAG_API)
|
||||||
|
@base.skip_if_microversion_lt("2.39")
|
||||||
|
def test_update_share_type_quota_in_two_projects(self):
|
||||||
|
"""Regression test for bug/1722707"""
|
||||||
|
share_type = self._create_share_type()
|
||||||
|
client1 = self.get_client_with_isolated_creds(client_version='2')
|
||||||
|
client2 = self.get_client_with_isolated_creds(client_version='2')
|
||||||
|
|
||||||
|
for client in (client1, client2):
|
||||||
|
# Update quotas
|
||||||
|
for q in ('shares', 'gigabytes', 'snapshots',
|
||||||
|
'snapshot_gigabytes'):
|
||||||
|
# Set new quota
|
||||||
|
updated = client.update_quotas(
|
||||||
|
client.tenant_id, share_type=share_type['id'], **{q: 0})
|
||||||
|
self.assertEqual(0, int(updated[q]))
|
||||||
|
|
||||||
|
current_quotas = client.show_quotas(
|
||||||
|
client.tenant_id, share_type=share_type['id'])
|
||||||
|
|
||||||
|
for q in ('shares', 'gigabytes', 'snapshots',
|
||||||
|
'snapshot_gigabytes'):
|
||||||
|
self.assertEqual(0, int(current_quotas[q]))
|
||||||
|
|
||||||
@tc.attr(base.TAG_POSITIVE, base.TAG_API)
|
@tc.attr(base.TAG_POSITIVE, base.TAG_API)
|
||||||
def test_update_tenant_quota_snapshots(self):
|
def test_update_tenant_quota_snapshots(self):
|
||||||
# get current quotas
|
# get current quotas
|
||||||
|
Loading…
Reference in New Issue
Block a user