Improve setting migration method matching

Avoid executing a migrations for settings with similar but
shorter names.

Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-12-04 23:05:50 -04:00
parent 5070a4fcd6
commit aa3495ff18
4 changed files with 73 additions and 11 deletions

View File

@@ -1,3 +1,8 @@
3.3.2 (2019-XX-XX)
==================
- Improve setting migration method matching. Avoid executing
a migrations for settings with similar but shorter names.
3.3.1 (2019-12-04)
==================
- Update Celery broker environment variable in the docker installer.

View File

@@ -5,6 +5,7 @@ import hashlib
from importlib import import_module
import logging
import os
import re
import sys
import yaml
@@ -122,12 +123,13 @@ class Namespace(object):
class NamespaceMigration(object):
@staticmethod
def get_method_name(setting):
return setting.global_name.lower()
def __init__(self, namespace):
self.namespace = namespace
def get_method_name(self, setting):
return setting.global_name.lower()
def get_method_name_full(self, setting, version):
return '{}_{}'.format(
self.get_method_name(setting=setting),
@@ -136,18 +138,20 @@ class NamespaceMigration(object):
def migrate(self, setting):
if self.namespace.get_config_version() != self.namespace.version:
method_name = self.get_method_name(setting=setting)
setting_method_name = NamespaceMigration.get_method_name(
setting=setting
)
# Get methods for this setting
setting_methods = [
method for method in dir(self) if method.startswith(
method_name
)
]
pattern = r'{}_\d{{4}}'.format(setting_method_name)
setting_methods = re.findall(
pattern=pattern, string='\n'.join(dir(self))
)
# Get order of execution of setting methods
versions = [
method.replace(
'{}_'.format(method_name), ''
'{}_'.format(setting_method_name), ''
) for method in setting_methods
]
try:

View File

@@ -14,3 +14,13 @@ class TestNamespaceMigrationTwo(NamespaceMigration):
def smart_settings_test_setting_0002(self, value):
return '{}_0002'.format(value)
class TestNamespaceMigrationInvalid(NamespaceMigration):
def smart_settings_test_setting(self, value):
return 'invalid migration'
class TestNamespaceMigrationInvalidDual(NamespaceMigration):
def smart_settings_test_setting_with_longer_name(self, value):
return 'invalid migration'

View File

@@ -17,7 +17,10 @@ from .literals import (
TEST_SETTING_INITIAL_VALUE, TEST_SETTING_VALUE
)
from .mixins import SmartSettingTestMixin
from .mocks import TestNamespaceMigrationOne, TestNamespaceMigrationTwo
from .mocks import (
TestNamespaceMigrationOne, TestNamespaceMigrationTwo,
TestNamespaceMigrationInvalid, TestNamespaceMigrationInvalidDual
)
class ClassesTestCase(EnvironmentTestCaseMixin, SmartSettingTestMixin, BaseTestCase):
@@ -116,3 +119,43 @@ class NamespaceMigrationTestCase(
self.assertEqual(
self.test_setting.value, '{}_0001_0002'.format(TEST_SETTING_VALUE)
)
def test_migration_invalid(self):
self._create_test_settings_namespace(
migration_class=TestNamespaceMigrationInvalid, version='0002'
)
self._create_test_setting()
with NamedTemporaryFile() as file_object:
settings.CONFIGURATION_FILEPATH = file_object.name
file_object.write(
force_bytes(
'{}: {}'.format(TEST_SETTING_GLOBAL_NAME, TEST_SETTING_VALUE)
)
)
file_object.seek(0)
Setting._config_file_cache = None
self.assertEqual(
self.test_setting.value, TEST_SETTING_VALUE
)
def test_migration_invalid_dual(self):
self._create_test_settings_namespace(
migration_class=TestNamespaceMigrationInvalidDual, version='0002'
)
self._create_test_setting()
with NamedTemporaryFile() as file_object:
settings.CONFIGURATION_FILEPATH = file_object.name
file_object.write(
force_bytes(
'{}: {}'.format(TEST_SETTING_GLOBAL_NAME, TEST_SETTING_VALUE)
)
)
file_object.seek(0)
Setting._config_file_cache = None
self.assertEqual(
self.test_setting.value, TEST_SETTING_VALUE
)