1
# Copyright 2012 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Helpers for testing South database migrations.
6
Each Django application in MAAS tests the basic sanity of its own South
7
database migrations. To minimize repetition, this single module provides all
8
the code those tests need.
11
from __future__ import (
19
'detect_sequence_clashes',
22
from collections import Counter
25
from south.migration.base import Migrations
26
from south.utils import ask_for_it_by_name
29
def extract_number(migration_name):
30
"""Extract the sequence number from a migration module name."""
31
return int(re.match('([0-9]+)_', migration_name).group(1))
34
def get_duplicates(numbers):
35
"""Return set of those items that occur more than once."""
38
for numbers, count in Counter(numbers).items()
42
def list_migrations(app_name):
43
"""List schema migrations in the given app."""
44
app = ask_for_it_by_name(app_name)
45
return [migration.name() for migration in Migrations(app)]
48
def detect_sequence_clashes(app_name):
49
"""List numbering clashes among database migrations in given app.
51
:param app_name: Name of a MAAS Django application, e.g. "metadataserver"
52
:return: A sorted `list` of tuples `(number, name)` representing all
53
migration modules in the app that have clashing sequence numbers.
54
The `number` is as found in `name`, but in `int` form.
56
migrations = list_migrations(app_name)
57
numbers_and_names = [(extract_number(name), name) for name in migrations]
58
duplicates = get_duplicates(number for number, name in numbers_and_names)
61
for number, name in numbers_and_names
62
if number in duplicates)