summaryrefslogtreecommitdiff
diff options
authorBilly Olsen <billy.olsen@canonical.com>2014-12-17 00:31:14 -0700
committerBilly Olsen <billy.olsen@canonical.com>2014-12-17 00:31:14 -0700
commit94e8c29812dd2086ce4a028945e6a316e3546c4d (patch)
tree7c982b1a9b4d09e430dced5a8cffffd0b986486e
parent37c13bbb3939e0c66e8c4c624fd2b20ce0e36ee8 (diff)
More unit tests, lint fixes
-rwxr-xr-xhooks/hooks.py49
-rw-r--r--unit_tests/test_hooks.py81
2 files changed, 95 insertions, 35 deletions
diff --git a/hooks/hooks.py b/hooks/hooks.py
index 8a105ee..84ffa9d 100755
--- a/hooks/hooks.py
+++ b/hooks/hooks.py
@@ -59,6 +59,7 @@ from charmhelpers.core.hookenv import (
open_port,
close_port,
Hooks,
+ DEBUG,
)
from charmhelpers.core.hookenv import log as juju_log
@@ -148,7 +149,7 @@ def regex_sub(pat_replace=None, data=None):
def update_file(filename=None, new_data=None, old_data=None):
- juju_log("update_file: %s" % filename, 'DEBUG')
+ juju_log("update_file: %s" % filename, DEBUG)
if filename is None or new_data is None:
retVal = False
try:
@@ -192,6 +193,7 @@ def process_check_pidfile(pidfile=None):
class TimeoutException(Exception):
pass
+
###############################################################################
# Charm support functions
###############################################################################
@@ -368,7 +370,7 @@ def mongo_client(host=None, command=None):
cmd_line = 'mongo'
cmd_line += ' --host %s' % host
cmd_line += ' --eval \'printjson(%s)\'' % command
- juju_log("Executing: %s" % cmd_line, 'DEBUG')
+ juju_log("Executing: %s" % cmd_line, DEBUG)
return(subprocess.call(cmd_line, shell=True) == 0)
@@ -389,7 +391,7 @@ def mongo_client_smart(host='localhost', command=None):
cmd_line.append(host)
cmd_line.append('--eval')
cmd_line.append('printjson(%s)' % command)
- juju_log("mongo_client_smart executing: %s" % str(cmd_line), 'DEBUG')
+ juju_log("mongo_client_smart executing: %s" % str(cmd_line), DEBUG)
for i in xrange(0, 10):
try:
@@ -401,11 +403,14 @@ def mongo_client_smart(host='localhost', command=None):
except subprocess.CalledProcessError as err:
juju_log('mongo_client_smart failed: %s' %
err.output,
- 'DEBUG')
+ DEBUG)
pass
finally:
time.sleep(1.5)
+ # At this point, the command failed
+ return False
+
def init_replset(master_node=None):
if master_node is None:
@@ -443,7 +448,7 @@ def init_replset(master_node=None):
finally:
time.sleep(1.5)
- juju_log("init_replset returns: %s" % retVal, 'DEBUG')
+ juju_log("init_replset returns: %s" % retVal, DEBUG)
return(retVal)
@@ -461,7 +466,7 @@ def join_replset(master_node=None, host=None):
retVal = False
else:
retVal = mongo_client_smart('localhost', "rs.add(\"%s\")" % host)
- juju_log("join_replset returns: %s" % retVal, 'DEBUG')
+ juju_log("join_replset returns: %s" % retVal, DEBUG)
return(retVal)
@@ -472,25 +477,25 @@ def leave_replset(master_node=None, host=None):
retVal = False
else:
retVal = mongo_client(master_node, "rs.remove(\"%s\")" % host)
- juju_log("leave_replset returns: %s" % retVal, 'DEBUG')
+ juju_log("leave_replset returns: %s" % retVal, DEBUG)
return(retVal)
def enable_replset(replicaset_name=None):
if replicaset_name is None:
- juju_log('enable_replset: replicaset_name is None, exiting', 'DEBUG')
+ juju_log('enable_replset: replicaset_name is None, exiting', DEBUG)
retVal = False
try:
juju_log('enable_replset: trying to get lock on: %s' %
default_mongodb_init_config)
with Lock(mongoinit_replset_lockfile, mode='a', timeout=100,
check_interval=.25, fail_when_locked=False):
- juju_log('enable_replset: lock acquired', 'DEBUG')
+ juju_log('enable_replset: lock acquired', DEBUG)
mongodb_init_config = open(default_mongodb_init_config).read()
if re.search(' --replSet %s ' % replicaset_name,
mongodb_init_config, re.MULTILINE) is None:
juju_log('enable_replset: --relset not preset, enabling',
- 'DEBUG')
+ DEBUG)
mongodb_init_config = regex_sub([(' -- ',
' -- --replSet %s ' %
replicaset_name)],
@@ -498,7 +503,7 @@ def enable_replset(replicaset_name=None):
update_file(default_mongodb_init_config, mongodb_init_config)
retVal = True
- juju_log('enable_replset will return: %s' % str(retVal), 'DEBUG')
+ juju_log('enable_replset will return: %s' % str(retVal), DEBUG)
except Exception, e:
juju_log(str(e), 'WARNING')
@@ -1059,7 +1064,7 @@ def replica_set_relation_joined():
# do not restart mongodb if config has not changed
if enable_replset(my_replset):
juju_log('Restarting mongodb after config change (enable replset)',
- 'DEBUG')
+ DEBUG)
restart_mongod()
relation_set(relation_id(), {
@@ -1113,20 +1118,14 @@ def get_replicaset_master():
def am_i_primary():
c = MongoClient('localhost')
- for i in xrange(1, 10):
+ for i in xrange(10):
try:
r = admin_command(c, 'replSetGetStatus')
juju_log('am_i_primary: replSetGetStatus returned: %s' % str(r),
- 'DEBUG')
- if r['myState'] == 1:
- juju_log('am_i_primary: myState says we are primary!', 'DEBUG')
- return True
- else:
- juju_log('am_i_primary: mystate says we are not primary...',
- 'DEBUG')
- return False
+ DEBUG)
+ return r['myState'] == 1
except OperationFailure as e:
- juju_log('am_i_primary: OperationError: %s' % str(e), 'DEBUG')
+ juju_log('am_i_primary: OperationError: %s' % str(e), DEBUG)
if 'replSetInitiate - should come online shortly' in str(e):
# replSet initialization in progress
continue
@@ -1137,7 +1136,7 @@ def am_i_primary():
raise
finally:
time.sleep(1.5)
-
+
# Raise an error if we exhausted the maximum amount of trials
raise TimeoutException('Unable to determine if local unit is primary')
@@ -1166,7 +1165,7 @@ def replica_set_relation_changed():
# add the rest
if oldest_peer(peer_units('replica-set')):
juju_log('Initializing replicaset via master: %s:%s' %
- (master_hostname, master_port), 'DEBUG')
+ (master_hostname, master_port), DEBUG)
init_replset("%s:%s" % (master_hostname, master_port))
unit = "%s:%s" % (unit_get('private-address'),
@@ -1177,7 +1176,7 @@ def replica_set_relation_changed():
# If this is primary, add joined unit to replicaset
if am_i_primary():
- juju_log('Adding new secondary... %s' % unit_remote, 'DEBUG')
+ juju_log('Adding new secondary... %s' % unit_remote, DEBUG)
join_replset(unit, unit_remote)
juju_log('replica_set_relation_changed-finish')
diff --git a/unit_tests/test_hooks.py b/unit_tests/test_hooks.py
index 4e40bdf..1aa2450 100644
--- a/unit_tests/test_hooks.py
+++ b/unit_tests/test_hooks.py
@@ -4,6 +4,7 @@ import hooks
from test_utils import CharmTestCase
from pymongo.errors import OperationFailure
+from subprocess import CalledProcessError
# Defines a set of functions to patch on the hooks object. Any of these
# methods will be patched by default on the default invocations of the
@@ -165,7 +166,7 @@ class MongoHooksTest(CharmTestCase):
def test_am_i_primary(self, mock_sleep, mock_mongo_client, mock_admin_cmd):
mock_admin_cmd.side_effect = [{'myState': x} for x in xrange(5)]
expected_results = [True if x == 1 else False for x in xrange(5)]
-
+
# Check expected return values each time...
for exp in expected_results:
rv = hooks.am_i_primary()
@@ -174,29 +175,31 @@ class MongoHooksTest(CharmTestCase):
@patch.object(hooks, 'admin_command')
@patch.object(hooks, 'MongoClient')
@patch('time.sleep')
- def test_am_i_primary_too_many_attempts(self, mock_sleep, mock_mongo_client,
- mock_admin_cmd):
+ def test_am_i_primary_too_many_attempts(self, mock_sleep,
+ mock_mongo_client, mock_admin_cmd):
msg = 'replSetInitiate - should come online shortly'
- mock_admin_cmd.side_effect = [OperationFailure(msg) for x in xrange(10)]
-
+ mock_admin_cmd.side_effect = [OperationFailure(msg)
+ for x in xrange(10)]
+
try:
- rv = hooks.am_i_primary()
+ hooks.am_i_primary()
self.assertTrue(False, 'Expected failure.')
except hooks.TimeoutException:
- self.assertEqual(mock_admin_cmd.call_count, 9)
+ self.assertEqual(mock_admin_cmd.call_count, 10)
pass
@patch.object(hooks, 'admin_command')
@patch.object(hooks, 'MongoClient')
@patch('time.sleep')
def test_am_i_primary_operation_failures(self, mock_sleep,
- mock_mongo_client, mock_admin_cmd):
+ mock_mongo_client,
+ mock_admin_cmd):
mock_admin_cmd.side_effect = OperationFailure('EMPTYCONFIG')
-
+
rv = hooks.am_i_primary()
mock_admin_cmd.assert_called()
self.assertFalse(rv)
-
+
mock_admin_cmd.reset_mock()
mock_admin_cmd.side_effect = OperationFailure('unexpected failure')
try:
@@ -204,3 +207,61 @@ class MongoHooksTest(CharmTestCase):
except OperationFailure:
mock_admin_cmd.assert_called()
+ @patch('time.sleep')
+ @patch('subprocess.check_output')
+ def test_mongo_client_smart_no_command(self, mock_check_output,
+ mock_sleep):
+ rv = hooks.mongo_client_smart()
+ self.assertFalse(rv)
+ self.assertEqual(0, mock_check_output.call_count)
+
+ mock_check_output.reset_mock()
+ mock_check_output.return_value = '{"ok": 1}'
+
+ rv = hooks.mongo_client_smart(command='fake-cmd')
+ self.assertTrue(rv)
+ mock_check_output.assert_called_once_with(['mongo', '--quiet',
+ '--host', 'localhost',
+ '--eval',
+ 'printjson(fake-cmd)'])
+
+ @patch('time.sleep')
+ @patch('subprocess.check_output')
+ def test_mongo_client_smart_error_cases(self, mock_ck_output, mock_sleep):
+ mock_ck_output.side_effect = [CalledProcessError(1, 'cmd',
+ output='fake-error')
+ for x in xrange(11)]
+ rv = hooks.mongo_client_smart(command='fake-cmd')
+ self.assertFalse(rv)
+
+ @patch('subprocess.call')
+ def test_mongo_client(self, mock_subprocess):
+ rv = hooks.mongo_client()
+ self.assertFalse(rv)
+ self.assertEqual(0, mock_subprocess.call_count)
+
+ mock_subprocess.reset_mock()
+ rv = hooks.mongo_client(host='fake-host')
+ self.assertFalse(rv)
+ self.assertEqual(0, mock_subprocess.call_count)
+
+ mock_subprocess.reset_mock()
+ rv = hooks.mongo_client(command='fake-command')
+ self.assertFalse(rv)
+ self.assertEqual(0, mock_subprocess.call_count)
+
+ mock_subprocess.reset_mock()
+ mock_subprocess.return_value = 0
+ rv = hooks.mongo_client(host='fake-host', command='fake-command')
+ expected_cmd = ("mongo --host %s --eval 'printjson(%s)'"
+ % ('fake-host', 'fake-command'))
+ mock_subprocess.assert_called_once_with(expected_cmd, shell=True)
+ self.assertTrue(rv)
+
+ mock_subprocess.reset_mock()
+ mock_subprocess.return_value = 1
+ rv = hooks.mongo_client(host='fake-host', command='fake-command')
+ expected_cmd = ("mongo --host %s --eval 'printjson(%s)'"
+ % ('fake-host', 'fake-command'))
+ mock_subprocess.assert_called_once_with(expected_cmd, shell=True)
+ self.assertFalse(rv)