def test_stop_service_stub_closes_agent(self): """The base class agent, stopService will the stop method. Additionally it will close the agent's zookeeper client if the client is still connected. """ mock_agent = self.mocker.patch(BaseAgent) mock_client = self.mocker.mock(ZookeeperClient) # connection is closed after agent.stop invoked. with self.mocker.order(): mock_agent.stop() self.mocker.passthrough() # client existence check mock_agent.client self.mocker.result(mock_client) # client connected check mock_agent.client self.mocker.result(mock_client) mock_client.connected self.mocker.result(True) # client close mock_agent.client self.mocker.result(mock_client) mock_client.close() self.mocker.replay() agent = BaseAgent() return agent.stopService()
def test_twistd_default_options(self): """The agent cli parsing, populates standard twistd options.""" parser = argparse.ArgumentParser() BaseAgent.setup_options(parser) # Daemon group self.assertEqual(parser.get_default("logfile"), "%s.log" % BaseAgent.name) self.assertEqual(parser.get_default("pidfile"), "%s.pid" % BaseAgent.name) self.assertEqual(parser.get_default("loglevel"), "DEBUG") self.assertTrue(parser.get_default("nodaemon")) self.assertEqual(parser.get_default("rundir"), ".") self.assertEqual(parser.get_default("chroot"), None) self.assertEqual(parser.get_default("umask"), None) self.assertEqual(parser.get_default("uid"), None) self.assertEqual(parser.get_default("gid"), None) self.assertEqual(parser.get_default("euid"), None) self.assertEqual(parser.get_default("prefix"), BaseAgent.name) self.assertEqual(parser.get_default("syslog"), False) # Development Group self.assertFalse(parser.get_default("debug")) self.assertFalse(parser.get_default("profile")) self.assertFalse(parser.get_default("savestats")) self.assertEqual(parser.get_default("profiler"), "cprofile") # Hidden defaults self.assertEqual(parser.get_default("reactor"), "epoll") self.assertEqual(parser.get_default("originalname"), None) # Agent options self.assertEqual(parser.get_default("principals"), []) self.assertEqual(parser.get_default("zookeeper_servers"), "")
def test_stop_service_stub_ignores_disconnected_agent(self): """The base class agent, stopService will the stop method. If the client is not connected then no attempt is made to close it. """ mock_agent = self.mocker.patch(BaseAgent) mock_client = self.mocker.mock(ZookeeperClient) # connection is closed after agent.stop invoked. with self.mocker.order(): mock_agent.stop() # client existence check mock_agent.client self.mocker.result(mock_client) # client connected check mock_agent.client self.mocker.result(mock_client) mock_client.connected self.mocker.result(False) self.mocker.replay() agent = BaseAgent() return agent.stopService()
def test_stop_service_stub_ignores_disconnected_agent(self): """The base class agent, stopService will the stop method. If the client is not connected then no attempt is made to close it. """ mock_agent = self.mocker.patch(BaseAgent) mock_client = self.mocker.mock(ZookeeperClient) session_file = self.makeFile() # connection is closed after agent.stop invoked. with self.mocker.order(): mock_agent.stop() # client existence check mock_agent.client self.mocker.result(mock_client) # client connected check mock_agent.client self.mocker.result(mock_client) mock_client.connected self.mocker.result(False) mock_agent.config self.mocker.result({"session_file": session_file}) self.mocker.replay() agent = BaseAgent() yield agent.stopService() self.assertFalse(os.path.exists(session_file))
def test_twistd_flags_correspond(self): parser = argparse.ArgumentParser() BaseAgent.setup_options(parser) args = ["--profile", "--savestats", "--daemon"] options = parser.parse_args(args, namespace=TwistedOptionNamespace()) self.assertEqual(options.get("savestats"), True) self.assertEqual(options.get("nodaemon"), False) self.assertEqual(options.get("profile"), True)
def test_directory_cli_option(self): """The juju directory can be configured on the cli.""" juju_directory = self.makeDir() self.change_args( "es-agent", "--zookeeper-servers", get_test_zookeeper_address(), "--juju-directory", juju_directory ) agent = BaseAgent() parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) agent.configure(options) self.assertEqual(agent.config["juju_directory"], juju_directory)
def test_run_base_raises_error(self): """The base class agent, raises a notimplemented error when started.""" client = self.mocker.patch(ZookeeperClient) client.connect(get_test_zookeeper_address()) client_mock = self.mocker.mock() self.mocker.result(succeed(client_mock)) self.mocker.replay() agent = BaseAgent() agent.configure({"zookeeper_servers": get_test_zookeeper_address(), "juju_directory": self.makeDir()}) d = agent.startService() self.failUnlessFailure(d, NotImplementedError) return d
def test_connect_cli_option(self): """The zookeeper server can be passed via cli argument.""" mock_client = self.mocker.mock() client = self.mocker.patch(ZookeeperClient) client.connect("x2.example.com") self.mocker.result(succeed(mock_client)) self.mocker.replay() agent = BaseAgent() agent.configure({"zookeeper_servers": "x2.example.com", "juju_directory": self.makeDir()}) result = agent.connect() self.assertEqual(result.result, mock_client) self.assertEqual(agent.client, mock_client)
def test_directory_env(self): """The juju directory passed via environment.""" self.change_args("es-agent") juju_directory = self.makeDir() self.change_environment(JUJU_HOME=juju_directory, JUJU_ZOOKEEPER=get_test_zookeeper_address()) agent = BaseAgent() parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) agent.configure(options) self.assertEqual(agent.config["juju_directory"], juju_directory)
def test_agent_logger(self): parser = argparse.ArgumentParser() BaseAgent.setup_options(parser) log_file_path = self.makeFile() options = parser.parse_args( ["--logfile", log_file_path, "--session-file", self.makeFile()], namespace=TwistedOptionNamespace()) def match_observer(observer): return isinstance(observer.im_self, log.PythonLoggingObserver) def cleanup(observer): # post test cleanup of global state. log.removeObserver(observer) logging.getLogger().handlers = [] original_log_with_observer = log.startLoggingWithObserver def _start_log_with_observer(observer): self.addCleanup(cleanup, observer) # by default logging will replace stdout/stderr return original_log_with_observer(observer, 0) app = self.mocker.mock() app.getComponent(log.ILogObserver, None) self.mocker.result(None) start_log_with_observer = self.mocker.replace( log.startLoggingWithObserver) start_log_with_observer(MATCH(match_observer)) self.mocker.call(_start_log_with_observer) self.mocker.replay() agent_logger = AgentLogger(options) agent_logger.start(app) # We suppress twisted messages below the error level. output = open(log_file_path).read() self.assertFalse(output) # also verify we didn't mess with the app logging. app_log = logging.getLogger() app_log.info("Good") # and that twisted errors still go through. log.err("Something bad happened") output = open(log_file_path).read() self.assertIn("Good", output) self.assertIn("Something bad happened", output)
def test_connect_env(self): """Zookeeper connection information can be passed via environment.""" self.change_args("es-agent") self.change_environment( JUJU_HOME=self.makeDir(), JUJU_ZOOKEEPER="x1.example.com", JUJU_PRINCIPALS="admin:abc agent:xyz") client = self.mocker.patch(ZookeeperClient) client.connect("x1.example.com") self.mocker.result(succeed(client)) client.client_id self.mocker.result((123, "abc")) client.add_auth("digest", "admin:abc") client.add_auth("digest", "agent:xyz") client.exists("/") self.mocker.replay() agent = BaseAgent() agent.set_watch_enabled(False) parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args( ["--session-file", self.makeFile()], namespace=TwistedOptionNamespace()) agent.configure(options) d = agent.startService() self.failUnlessFailure(d, NotImplementedError) return d
def test_connect_handles_nonsense_session(self): self.change_args("es-agent") self.change_environment( JUJU_HOME=self.makeDir(), JUJU_ZOOKEEPER="x1.example.com") session_file = self.makeFile() with open(session_file, "w") as f: f.write(yaml.dump("cheesy wotsits")) client = self.mocker.patch(ZookeeperClient) client.connect("x1.example.com", client_id="cheesy wotsits") self.mocker.result(fail(zookeeper.ZooKeeperException())) mock_client = self.mocker.mock() client.connect("x1.example.com") self.mocker.result(succeed(mock_client)) mock_client.client_id self.mocker.result((456, "def")) self.mocker.replay() agent = BaseAgent() agent.set_watch_enabled(False) parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args( ["--session-file", session_file], namespace=TwistedOptionNamespace()) agent.configure(options) d = agent.startService() self.failUnlessFailure(d, NotImplementedError) return d
def test_agent_logger(self): parser = argparse.ArgumentParser() BaseAgent.setup_options(parser) log_file_path = self.makeFile() options = parser.parse_args(["--logfile", log_file_path], namespace=TwistedOptionNamespace()) def match_observer(observer): return isinstance(observer.im_self, log.PythonLoggingObserver) def cleanup(observer): # post test cleanup of global state. log.removeObserver(observer) logging.getLogger().handlers = [] original_log_with_observer = log.startLoggingWithObserver def _start_log_with_observer(observer): self.addCleanup(cleanup, observer) # by default logging will replace stdout/stderr return original_log_with_observer(observer, 0) app = self.mocker.mock() app.getComponent(log.ILogObserver, None) self.mocker.result(None) start_log_with_observer = self.mocker.replace( log.startLoggingWithObserver) start_log_with_observer(MATCH(match_observer)) self.mocker.call(_start_log_with_observer) self.mocker.replay() agent_logger = AgentLogger(options) agent_logger.start(app) # We suppress twisted messages below the error level. output = open(log_file_path).read() self.assertFalse(output) # also verify we didn't mess with the app logging. app_log = logging.getLogger() app_log.info("Good") # and that twisted errors still go through. log.err("Something bad happened") output = open(log_file_path).read() self.assertIn("Good", output) self.assertIn("Something bad happened", output)
def test_connect_cli_option(self): """The zookeeper server can be passed via cli argument.""" mock_client = self.mocker.mock() client = self.mocker.patch(ZookeeperClient) client.connect("x2.example.com") self.mocker.result(succeed(mock_client)) self.mocker.replay() agent = BaseAgent() agent.configure({ "zookeeper_servers": "x2.example.com", "juju_directory": self.makeDir() }) result = agent.connect() self.assertEqual(result.result, mock_client) self.assertEqual(agent.client, mock_client)
def test_as_app(self): """The agent class can be accessed as an application.""" app = BaseAgent().as_app() multi_service = IService(app, None) self.assertTrue(IServiceCollection.providedBy(multi_service)) services = list(multi_service) self.assertEqual(len(services), 1)
def test_run_base_raises_error(self): """The base class agent, raises a notimplemented error when started.""" client = self.mocker.patch(ZookeeperClient) client.connect(get_test_zookeeper_address()) client_mock = self.mocker.mock() self.mocker.result(succeed(client_mock)) self.mocker.replay() agent = BaseAgent() agent.configure({ "zookeeper_servers": get_test_zookeeper_address(), "juju_directory": self.makeDir() }) d = agent.startService() self.failUnlessFailure(d, NotImplementedError) return d
def test_run(self): """Invokes the run class method on an agent. This will create an agent instance, parse the cli args, passes them to the agent, and starts the agent runner. """ self.change_args("es-agent", "--zookeeper-servers", get_test_zookeeper_address()) runner = self.mocker.patch(AgentRunner) runner.run() mock_agent = self.mocker.patch(BaseAgent) def match_args(config): self.assertEqual(config["zookeeper_servers"], get_test_zookeeper_address()) return True mock_agent.configure(MATCH(match_args)) self.mocker.passthrough() self.mocker.replay() BaseAgent.run()
def test_non_existant_directory(self): """If the juju directory does not exist an error should be raised. """ juju_directory = self.makeDir() os.rmdir(juju_directory) data = { "zookeeper_servers": get_test_zookeeper_address(), "juju_directory": juju_directory } agent = BaseAgent() self.assertRaises(JujuError, agent.configure, data)
def test_stop_service_stub_closes_agent(self): """The base class agent, stopService will the stop method. Additionally it will close the agent's zookeeper client if the client is still connected. """ mock_agent = self.mocker.patch(BaseAgent) mock_client = self.mocker.mock(ZookeeperClient) session_file = self.makeFile() # connection is closed after agent.stop invoked. with self.mocker.order(): mock_agent.stop() self.mocker.passthrough() # client existence check mock_agent.client self.mocker.result(mock_client) # client connected check mock_agent.client self.mocker.result(mock_client) mock_client.connected self.mocker.result(True) # client close mock_agent.client self.mocker.result(mock_client) mock_client.close() # delete session file mock_agent.config self.mocker.result({"session_file": session_file}) self.mocker.replay() agent = BaseAgent() yield agent.stopService() self.assertFalse(os.path.exists(session_file))
def test_directory_cli_option(self): """The juju directory can be configured on the cli.""" juju_directory = self.makeDir() self.change_args("es-agent", "--zookeeper-servers", get_test_zookeeper_address(), "--juju-directory", juju_directory) agent = BaseAgent() parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) agent.configure(options) self.assertEqual(agent.config["juju_directory"], juju_directory)
def test_connect_env(self): """Zookeeper connection information can be passed via environment.""" self.change_args("es-agent") self.change_environment(JUJU_HOME=self.makeDir(), JUJU_ZOOKEEPER="x1.example.com", JUJU_PRINCIPALS="admin:abc agent:xyz") client = self.mocker.patch(ZookeeperClient) client.connect("x1.example.com") self.mocker.result(succeed(client)) client.add_auth("digest", "admin:abc") client.add_auth("digest", "agent:xyz") client.exists("/") self.mocker.replay() agent = BaseAgent() parser = argparse.ArgumentParser() agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) agent.configure(options) d = agent.startService() self.failUnlessFailure(d, NotImplementedError) return d
def test_zookeeper_hosts_not_configured(self): """a NoConnection error is raised if no zookeeper host is specified.""" agent = BaseAgent() self.assertRaises(NoConnection, agent.configure, {"zookeeper_servers": None})
def test_custom_log_level(self): parser = argparse.ArgumentParser() BaseAgent.setup_options(parser) options = parser.parse_args(["--loglevel", "INFO"], namespace=TwistedOptionNamespace()) self.assertEqual(options.loglevel, "INFO")
def test_watch_enabled_accessors(self): agent = BaseAgent() self.assertTrue(agent.get_watch_enabled()) agent.set_watch_enabled(False) self.assertFalse(agent.get_watch_enabled())