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)
|
||||
for row in db_result:
|
||||
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'):
|
||||
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)
|
||||
def test_update_tenant_quota_snapshots(self):
|
||||
# get current quotas
|
||||
|
Loading…
Reference in New Issue
Block a user