def test_twistd_option_namespace(self): """ The twisted option namespace bridges argparse attribute access, to twisted dictionary access for cli options. """ options = TwistedOptionNamespace() options.x = 1 self.assertEqual(options["x"], 1) self.assertEqual(options.get("x"), 1) self.assertEqual(options.get("y"), None) self.assertRaises(KeyError, options.__getitem__, "y") options["y"] = 2 self.assertEqual(options.y, 2) self.assertTrue(options.has_key("y")) self.assertFalse(options.has_key("z"))
def test_agent_machine_id_environment_extraction(self): self.change_args("es-agent") parser = argparse.ArgumentParser() self.agent.setup_options(parser) config = parser.parse_args(namespace=TwistedOptionNamespace()) self.assertEqual(config["machine_id"], "0")
def test_agent_unit_name_cli_extraction(self): """The unit agent can parse its unit-name from the cli. """ self.change_args("unit-agent", "--unit-name", "rabbit/1") parser = argparse.ArgumentParser() self.agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) self.assertEqual(options["unit_name"], "rabbit/1")
def test_agent_unit_name_environment_extraction(self): """Verify extraction of unit name from the environment.""" self.change_args("unit-agent") self.change_environment(JUJU_UNIT_NAME="rabbit/1") parser = argparse.ArgumentParser() self.agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) self.assertEqual(options["unit_name"], "rabbit/1")
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_agent_machine_id_cli_extraction(self): """Command line passing of machine id works and has precedence over environment arg passing.""" self.change_environment(JUJU_MACHINE_ID=str(21)) self.change_args("es-agent", "--machine-id", "0") parser = argparse.ArgumentParser() self.agent.setup_options(parser) config = parser.parse_args(namespace=TwistedOptionNamespace()) self.assertEqual(config["machine_id"], "0")
def create_agent(self, agent_cls, path, **extra_options): agent = agent_cls() options = TwistedOptionNamespace() options["juju_directory"] = path options["zookeeper_servers"] = get_test_zookeeper_address() for k, v in extra_options.items(): options[k] = v agent.configure(options) agent.set_watch_enabled(False) agent.client = self.client yield agent.start() self.agents.append(agent)
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_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_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_unit_name_cli_extraction_error(self): """Failure to extract the unit name, results in a nice error message. """ # We don't want JUJU_UNIT_NAME set, so that the expected # JujuError will be raised self.change_environment(PATH=get_cli_environ_path()) self.change_args("unit-agent", "--juju-directory", self.makeDir(), "--zookeeper-servers", get_test_zookeeper_address()) parser = argparse.ArgumentParser() self.agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) e = self.assertRaises(JujuError, self.agent.configure, options) self.assertEquals( str(e), "--unit-name must be provided in the command line, or " "$JUJU_UNIT_NAME in the environment")
def test_agent_machine_id_cli_error(self): """ If the machine id can't be found, a detailed error message is given. """ # initially setup by get_agent_config in setUp self.change_environment(JUJU_MACHINE_ID="") self.change_args("es-agent", "--zookeeper-servers", get_test_zookeeper_address(), "--juju-directory", self.makeDir()) parser = argparse.ArgumentParser() self.agent.setup_options(parser) options = parser.parse_args(namespace=TwistedOptionNamespace()) e = self.assertRaises(JujuError, self.agent.configure, options) self.assertIn(("--machine-id must be provided in the command line," " or $JUJU_MACHINE_ID in the environment"), str(e))
def test_twistd_option_namespace(self): """ The twisted option namespace bridges argparse attribute access, to twisted dictionary access for cli options. """ options = TwistedOptionNamespace() options.x = 1 self.assertEqual(options['x'], 1) self.assertEqual(options.get('x'), 1) self.assertEqual(options.get('y'), None) self.assertRaises(KeyError, options.__getitem__, 'y') options['y'] = 2 self.assertEqual(options.y, 2) self.assertTrue(options.has_key('y')) self.assertFalse(options.has_key('z'))
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 get_agent_config(self): options = TwistedOptionNamespace() options["juju_directory"] = self.juju_directory options["zookeeper_servers"] = get_test_zookeeper_address() return succeed(options)
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_collect(self): yield self.build_topology(skip_unit_agents=("varnish/1", )) agent = MachineAgent() options = TwistedOptionNamespace() options["juju_directory"] = self.makeDir() options["zookeeper_servers"] = get_test_zookeeper_address() options["machine_id"] = "0" agent.configure(options) agent.set_watch_enabled(False) agent.client = self.client yield agent.start() # collect everything state = yield status.collect(None, self.provider, self.client, None) services = state["services"] self.assertIn("wordpress", services) self.assertIn("varnish", services) self.assertIn("mysql", services) # and verify the specifics of a single service self.assertTrue("mysql" in services) units = list(services["mysql"]["units"]) self.assertEqual(len(units), 2) self.assertEqual( state["machines"][0], { "instance-id": 0, "instance-state": "unknown", "dns-name": "steamcloud-1.com", "state": "running" }) self.assertEqual(services["mysql"]["relations"], {"db": "wordpress"}) self.assertEqual(services["wordpress"]["relations"], { "cache": "memcache", "db": "mysql", "proxy": "varnish" }) self.assertEqual( services["varnish"], { "units": { "varnish/1": { "machine": 4, "state": "down", "open-ports": ["80/tcp"], "public-address": "varnish-1.example.com", "relations": { "proxy": { "state": "up" } } }, "varnish/0": { "machine": 3, "state": "started", "public-address": "varnish-0.example.com", "open-ports": ["80/tcp"], "relations": { "proxy": { "state": "up" } } } }, "exposed": True, "charm": "local:series/varnish-1", "relations": { "proxy": "wordpress" } }) self.assertEqual( services["wordpress"], { "charm": "local:series/wordpress-3", "relations": { "cache": "memcache", "db": "mysql", "proxy": "varnish" }, "units": { "wordpress/0": { "machine": 0, "public-address": "wordpress-0.example.com", "relations": { "cache": { "state": "up" }, "db": { "state": "up" }, "proxy": { "state": "up" } }, "state": "started" } } }) self.assertEqual( services["memcache"], { "charm": "local:series/dummy-1", "relations": { "cache": "wordpress" }, "units": { "memcache/0": { "machine": 5, "public-address": "memcache-0.example.com", "relations": { "cache": { "state": "up" } }, "state": "pending" }, "memcache/1": { "machine": 6, "public-address": "memcache-1.example.com", "relations": { "cache": { "state": "down" } }, "state": "installed" } } })