diff options
| author | Billy Olsen <billy.olsen@canonical.com> | 2014-12-17 00:31:14 -0700 | 
|---|---|---|
| committer | Billy Olsen <billy.olsen@canonical.com> | 2014-12-17 00:31:14 -0700 | 
| commit | 94e8c29812dd2086ce4a028945e6a316e3546c4d (patch) | |
| tree | 7c982b1a9b4d09e430dced5a8cffffd0b986486e | |
| parent | 37c13bbb3939e0c66e8c4c624fd2b20ce0e36ee8 (diff) | |
More unit tests, lint fixes
| -rwxr-xr-x | hooks/hooks.py | 49 | ||||
| -rw-r--r-- | unit_tests/test_hooks.py | 81 | 
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) | 
