Skip to content

Commit

Permalink
Lost patches and a bugfix
Browse files Browse the repository at this point in the history
* askbot/patches/__init__.py relied on some ancient method for
  obtaining the currently installed Django version => updated
* Missing change: use the exported instances from
  askbot.deployment.parameters instead of creating new instances all the
  time
* Missing change: add reset() to ConfigManger because for testing purposes
  we now need to reset ConfigManagers as we are not creating new instances
  for each test
* Bugfix: ConfigManager._order(unsorted_list) would not return the result
  of its ordering, but the original unsorted_list, making this method
  effectively a noop. It now returns an ordered list as intended.
  • Loading branch information
martin-bts committed Nov 16, 2019
1 parent d967fa5 commit 5cbf4e7
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 44 deletions.
4 changes: 2 additions & 2 deletions askbot/deployment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from askbot.deployment import path_utils
from askbot.utils.functions import generate_random_key
from askbot.deployment.template_loader import DeploymentTemplate
from askbot.deployment.parameters import ConfigManagerCollection
from askbot.deployment.parameters import askbotCollection
from askbot.deployment.base import ObjectWithOutput
from askbot.deployment.deployables.components import DeployableComponent
import askbot.deployment.deployables as deployable
Expand All @@ -24,7 +24,7 @@ def __init__(self, interactive=True, verbosity=-128):
super(AskbotSetup, self).__init__(verbosity=verbosity)
self.parser = ArgumentParser(description="Setup a Django project and app for Askbot")
self._todo = {}
self.configManagers = ConfigManagerCollection(interactive=interactive, verbosity=verbosity)
self.configManagers = askbotCollection
self.database_engines = self.configManagers.configManager(
'database').configField(
'database_engine').database_engines
Expand Down
9 changes: 8 additions & 1 deletion askbot/deployment/base/configmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def _order(self, keys):
if f in known_fields: # only fields the caller wants sorted
ordered_keys.append(f)
known_fields.remove(f) # avoid duplicates
return keys
return ordered_keys

def complete(self, collection):
"""Main method of this :class:ConfigManager.
Expand All @@ -139,6 +139,13 @@ def complete(self, collection):
contribution.setdefault(k, v)
collection.update(contribution)

def reset(self):
"""ConfigManagers may keep a state. This method shall be used to reset
the state to whatever that means for the specific config manager. This
implementation merely flushes the memory about completed work."""
self._managed_config = dict()



# one could make a case for not deriving ConfigManagerCollection from
# ConfigManager because the collection serves a different purpose than the
Expand Down
11 changes: 11 additions & 0 deletions askbot/deployment/parameters/configmanagers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,21 @@ def _remember(self, name, value):
self._catalog['cache_db'].defaultOk = False
self._catalog['cache_password'].defaultOk = False

def reset(self):
super(CacheConfigManager, self).reset()
self._catalog['cache_nodes'].defaultOk = False
self._catalog['cache_db'].defaultOk = True
self._catalog['cache_password'].defaultOk = True

class DbConfigManager(ConfigManager):
"""A config manager for validating setup parameters pertaining to
the database Askbot will use."""

def reset(self):
super(DbConfigManager, self).reset()
self._catalog['database_user'].defaultOk = False
self._catalog['database_password'].defaultOk = False

def _remember(self, name, value):
if name == 'database_engine':
value = int(value)
Expand Down
2 changes: 1 addition & 1 deletion askbot/deployment/parameters/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def acceptable(self, value):
self.print(f'DbEngine.complete called with {value} of type {type(value)}', 2)
try:
return value in [e[0] for e in self.database_engines]
finally:
except AttributeError:
return False

def ask_user(self, current_value, depth=0):
Expand Down
3 changes: 1 addition & 2 deletions askbot/patches/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
"""
import django
from askbot.patches import django_patches
from askbot.deployment import package_utils

def patch_django():
(major, minor, micro) = package_utils.get_django_version()
(major, minor, micro, _, __) = django.VERSION

if major == 1 and minor > 4:
# This shouldn't be required with django < 1.4.x
Expand Down
74 changes: 36 additions & 38 deletions askbot/tests/test_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_get_options(self):
default_dict = vars(default_opts)

def test_db_configmanager(self):
manager = DbConfigManager(interactive=False, verbosity=0)
manager = databaseManager
new_empty = lambda:dict([(k,None) for k in manager.keys])

parameters = new_empty() # includes ALL database parameters
Expand All @@ -54,29 +54,29 @@ class DatabaseEngineTest(AskbotTestCase):
def setUp(self):
self.installer = AskbotSetup()
self.parser = self.installer.parser
self.manager = databaseManager
self.manager.reset()

def test_database_engine(self):
manager = DbConfigManager(interactive=False, verbosity=0)
new_empty = lambda: dict([(k, None) for k in manager.keys])

new_empty = lambda: dict([(k, None) for k in self.manager.keys])

# DbConfigManager is supposed to test database_engine first
# here: engine is NOT acceptable and name is NOT acceptable
parameters = new_empty() # includes ALL database parameters
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as e:
self.assertIn('database_engine', str(e))

# With a database_engine set, users must provide a database_name
# here: engine is acceptable and name is NOT acceptable
engines = manager._catalog['database_engine'].database_engines
engines = self.manager._catalog['database_engine'].database_engines
parameters = {'database_engine': None, 'database_name': None}
caught_exceptions = 0
for db_type in [e[0] for e in engines]:
parameters['database_engine'] = db_type
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
caught_exceptions += 1
self.assertIn('database_name', str(ve))
Expand All @@ -86,45 +86,45 @@ def test_database_engine(self):
parameters = {'database_engine': None, 'database_name': 'acceptable_value'}
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
self.assertIn('database_engine', str(e))

# here: engine is acceptable and name is acceptable
acceptable_engine = manager._catalog['database_engine'].database_engines[0][0]
acceptable_engine = self.manager._catalog['database_engine'].database_engines[0][0]
parameters = {'database_engine': acceptable_engine, 'database_name': 'acceptable_value'}
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
self.assertIsNone(e)

# at the moment, the parameter parse does not have special code for
# mysql and oracle, so we do not provide dedicated tests for them
def test_database_postgres(self):
manager = DbConfigManager(interactive=False, verbosity=0)
new_empty = lambda: dict([(k, None) for k in manager.keys])
new_empty = lambda: dict([(k, None) for k in self.manager.keys])
parameters = new_empty()
parameters['database_engine'] = 1

acceptable_answers = {
'database_name': 'testDB',
'database_user': 'askbot',
'database_password': 'd34db33f',
}
expected_issues = acceptable_answers.keys()
ordered_acceptable_answers = (
('database_name', 'testDB'),
('database_user', 'askbot'),
('database_password', 'd34db33f'),
)

acceptable_answers = dict(ordered_acceptable_answers)
expected_issues = [item[0] for item in ordered_acceptable_answers]
met_issues = set()
for i in expected_issues:
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
matches = [issue for issue in expected_issues if issue in str(e)]
self.assertEqual(len(matches), 1, str(e))
self.assertIs(type(e), ValueError)

issue = matches[0]
cnt_old = len(met_issues)
Expand All @@ -135,14 +135,13 @@ def test_database_postgres(self):
self.assertEqual(len(expected_issues), len(met_issues))
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
self.assertIsNone(e)

def test_database_sqlite(self):
manager = DbConfigManager(interactive=False, verbosity=0)
new_empty = lambda: dict([(k, None) for k in manager.keys])
new_empty = lambda: dict([(k, None) for k in self.manager.keys])
parameters = new_empty()
parameters['database_engine'] = 2

Expand All @@ -154,7 +153,7 @@ def test_database_sqlite(self):
for i in expected_issues:
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
matches = [issue for issue in expected_issues if issue in str(e)]
Expand All @@ -170,7 +169,7 @@ def test_database_sqlite(self):
self.assertEqual(len(expected_issues), len(met_issues))
e = None
try:
manager.complete(parameters)
self.manager.complete(parameters)
except ValueError as ve:
e = ve
self.assertIsNone(e)
Expand All @@ -181,13 +180,13 @@ class CacheEngineTest(AskbotTestCase):
def setUp(self):
self.installer = AskbotSetup()
self.parser = self.installer.parser
self.manager = cacheManager
self.manager.reset()

@staticmethod
def _setUpTest():
manager = CacheConfigManager(interactive=False, verbosity=0)
engines = manager._catalog['cache_engine'].cache_engines
new_empty = lambda: dict([(k, None) for k in manager.keys])
return manager, engines, new_empty
def _setUpTest(self):
engines = self.manager._catalog['cache_engine'].cache_engines
new_empty = lambda: dict([(k, None) for k in self.manager.keys])
return self.manager, engines, new_empty

@staticmethod
def run_complete(manager, parameters):
Expand Down Expand Up @@ -325,12 +324,12 @@ class FilesystemTests(AskbotTestCase):
def setUp(self):
self.installer = AskbotSetup()
self.parser = self.installer.parser
self.manager = filesystemManager
self.manager.reset()

@staticmethod
def _setUpTest():
manager = FilesystemConfigManager(interactive=False, verbosity=0)
new_empty = lambda: dict([(k, None) for k in manager.keys])
return manager, new_empty
def _setUpTest(self):
new_empty = lambda: dict([(k, None) for k in self.manager.keys])
return self.manager, new_empty

@staticmethod
def run_complete(manager, parameters):
Expand Down Expand Up @@ -415,12 +414,11 @@ def __test_project_dir_interactive(self):
"""The console functions contain endless loops, which impedes
testability. If we mock the console functions, then there is no merrit
in testing interactively at all."""
manager = FilesystemConfigManager(interactive=True, verbosity=1)
parameters = {'dir_name': ''}

#with patch('askbot.utils.console.simple_dialog', return_value='validDeployment'), patch('askbot.utils.console.choice_dialog', return_value='yes'):
with patch('builtins.input', new=MockInput('martin', 'yes')):
e = self.run_complete(manager, parameters)
e = self.run_complete(self.manager, parameters)
self.assertIsNone(e)

class MainInstallerTests(AskbotTestCase):
Expand Down

0 comments on commit 5cbf4e7

Please sign in to comment.