def deploy_dummy_stack(client, charm_series, use_charmstore=False): """"Deploy a dummy stack in the specified environment.""" # Centos requires specific machine configuration (i.e. network device # order). if charm_series.startswith("centos") and client.env.maas: client.set_model_constraints({'tags': 'MAAS_NIC_1'}) platform = 'ubuntu' if charm_series.startswith('win'): platform = 'win' elif charm_series.startswith('centos'): platform = 'centos' if use_charmstore: dummy_source = "cs:~juju-qa/dummy-source" dummy_sink = "cs:~juju-qa/dummy-sink" else: dummy_source = local_charm_path( charm='dummy-source', juju_ver=client.version, series=charm_series, platform=platform) dummy_sink = local_charm_path( charm='dummy-sink', juju_ver=client.version, series=charm_series, platform=platform) client.deploy(dummy_source, series=charm_series) client.deploy(dummy_sink, series=charm_series) client.juju('add-relation', ('dummy-source', 'dummy-sink')) client.juju('expose', ('dummy-sink',)) if client.env.kvm or client.env.maas: # A single virtual machine may need up to 30 minutes before # "apt-get update" and other initialisation steps are # finished; two machines initializing concurrently may # need even 40 minutes. In addition Windows image blobs or # any system deployment using MAAS requires extra time. client.wait_for_started(7200) else: client.wait_for_started(3600)
def assess_mixed_images(client): charm_path = local_charm_path(charm='dummy-sink', juju_ver=client.version, series='centos7', platform='centos') client.deploy(charm_path) charm_path = local_charm_path(charm='dummy-source', juju_ver=client.version, series='trusty') client.deploy(charm_path) client.juju('add-relation', ('dummy-source', 'dummy-sink')) # Wait for the deployment to finish. client.wait_for_started() assess_juju_relations(client)
def prepare_dummy_env(client): """Use a client to prepare a dummy environment.""" charm_source = local_charm_path( charm='dummy-source', juju_ver=client.version) client.deploy(charm_source) charm_sink = local_charm_path(charm='dummy-sink', juju_ver=client.version) client.deploy(charm_sink) token = get_random_string() client.set_config('dummy-source', {'token': token}) client.juju('add-relation', ('dummy-source', 'dummy-sink')) client.juju('expose', ('dummy-sink',)) return token
def push_resource(client, resource_name, finger_print, size, agent_timeout, resource_timeout, deploy=True, resource_file=None): charm_name = 'dummy-resource' charm_path = local_charm_path(charm=charm_name, juju_ver=client.version) if resource_file is None: resource_file = os.path.join(charm_path, '{}.txt'.format(resource_name)) else: resource_file = os.path.join(charm_path, resource_file) resource_arg = '{}={}'.format(resource_name, resource_file) log.info("Deploy charm with resource {} Size: {} File: {}".format( resource_name, size, resource_file)) if deploy: client.deploy(charm_path, resource=resource_arg) else: client.attach(charm_name, resource=resource_arg) client.wait_for_started(timeout=agent_timeout) resource_id = '{}/{}'.format(charm_name, resource_name) client.wait_for_resource(resource_id, charm_name, timeout=resource_timeout) status = client.list_resources(charm_name) verify_status(status, resource_id, resource_name, finger_print, size) client.show_status()
def iter_steps(self, client): yield self.prepare.as_result() with temp_dir() as temp_repository: charm = Charm('mycharm', 'Test charm', series=['trusty']) charm.metadata['description'] = 'Charm for industrial testing.' charm_root = charm.to_repo_dir(temp_repository) charm_path = local_charm_path( charm='mycharm', juju_ver=client.version, series='trusty', repository=os.path.dirname(charm_root)) client.deploy(charm_path, temp_repository) yield self.prepare.as_result() client.wait_for_started() yield self.prepare.as_result() charm.add_hook_script('config-changed', dedent("""\ #!/bin/sh open-port 34 """)) charm.add_hook_script('upgrade-charm', dedent("""\ #!/bin/sh open-port 42 """)) shutil.rmtree(charm_root) charm.to_repo_dir(temp_repository) yield self.prepare.as_result(True) yield self.upgrade.as_result() client.upgrade_charm('mycharm', charm_root) yield self.upgrade.as_result() for status in client.status_until(300): ports = status.get_open_ports('mycharm/0') if '42/tcp' in ports and '34/tcp' in ports: break else: raise Exception('42 and/or 34 not opened.') yield self.upgrade.as_result(True)
def assess_update_mongo(client, series, bootstrap_host): log.info('series={}, bootstrap_host={}'.format(series, bootstrap_host)) return_code = 1 charm = local_charm_path( charm='ubuntu', juju_ver=client.version, series=series) log.info("Setting up test.") client.deploy(charm, series=series) client.wait_for_started() log.info("Setup complete.") log.info("Test started.") # Instrument the case where Juju can install the new mongo packages from # Ubuntu. remote = remote_from_address(bootstrap_host, series=series) remote.run(DEP_SCRIPT) # upgrade-mongo returns 0 if all is well. status will work but not # explicitly show that mongo3 is running. client.upgrade_mongo() client.show_status() log.info("Checking bootstrap host for mongo3:") mongo_proc = remote.run(VERIFY_SCRIPT) log.info(mongo_proc) if '--port 37017' in mongo_proc and '--replSet juju' in mongo_proc: return_code = 0 log.info("Controller upgraded to MongoDB 3.") log.info("Test complete.") return return_code
def assess_update_mongo(client, series, bootstrap_host): log.info('series={}, bootstrap_host={}'.format(series, bootstrap_host)) return_code = 1 charm = local_charm_path(charm='ubuntu', juju_ver=client.version, series=series) log.info("Setting up test.") client.deploy(charm, series=series) client.wait_for_started() log.info("Setup complete.") log.info("Test started.") # Instrument the case where Juju can install the new mongo packages from # Ubuntu. remote = remote_from_address(bootstrap_host, series=series) remote.run(DEP_SCRIPT) # upgrade-mongo returns 0 if all is well. status will work but not # explicitly show that mongo3 is running. client.upgrade_mongo() client.show_status() log.info("Checking bootstrap host for mongo3:") mongo_proc = remote.run(VERIFY_SCRIPT) log.info(mongo_proc) if '--port 37017' in mongo_proc and '--replSet juju' in mongo_proc: return_code = 0 log.info("Controller upgraded to MongoDB 3.") log.info("Test complete.") return return_code
def assess_deploy_storage(client, charm_series, charm_name, provider_type, pool=None): """Set up the test for deploying charm with storage.""" if provider_type == "block": storage = { "disks": { "type": provider_type, "multiple": { "range": "0-10" } } } else: storage = {"data": {"type": provider_type, "location": "/srv/data"}} with temp_dir() as charm_dir: charm_root = create_storage_charm(charm_dir, charm_name, 'Test charm for storage', storage) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) deploy_storage(client, charm, charm_series, pool, "1G", charm_dir)
def assess_deploy_storage(client, charm_series, charm_name, provider_type, pool=None): """Set up the test for deploying charm with storage.""" if provider_type == "block": storage = { "disks": { "type": provider_type, "multiple": { "range": "0-10" } } } else: storage = { "data": { "type": provider_type, "location": "/srv/data" } } with temp_dir() as charm_dir: charm_root = create_storage_charm(charm_dir, charm_name, 'Test charm for storage', storage) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) deploy_storage(client, charm, charm_series, pool, "1G", charm_dir)
def deploy_dummy_source_to_new_model(client, model_name): new_model_client = client.add_model(client.env.clone(model_name)) charm_path = local_charm_path( charm='dummy-source', juju_ver=new_model_client.version) new_model_client.deploy(charm_path) new_model_client.wait_for_started() new_model_client.set_config('dummy-source', {'token': 'one'}) new_model_client.wait_for_workloads() return new_model_client
def deploy_dummy_source_to_new_model(client, model_name): new_model_client = client.add_model(client.env.clone(model_name)) charm_path = local_charm_path(charm='dummy-source', juju_ver=new_model_client.version) new_model_client.deploy(charm_path) new_model_client.wait_for_started() new_model_client.set_config('dummy-source', {'token': 'one'}) new_model_client.wait_for_workloads() return new_model_client
def assess_multi_series_charms(client, devel_series): """Assess multi series charms. :param client: Juju client. :param devel_series: The series to use for new and unsupported scenarios. :type client: jujupy.ModelClient :return: None """ tests = [ Test(series=devel_series, service='test0', force=False, success=False, machine=None, juju1x_supported=False), Test(series=None, service='test1', force=False, success=True, machine='0', juju1x_supported=True), Test(series="trusty", service='test2', force=False, success=True, machine='1', juju1x_supported=True), Test(series="xenial", service='test3', force=False, success=True, machine='2', juju1x_supported=False), Test(series=devel_series, service='test4', force=True, success=True, machine='3', juju1x_supported=False), ] with temp_dir() as repository: charm_name = 'dummy' charm = Charm(charm_name, 'Test charm', series=['trusty', 'xenial']) charm_dir = charm.to_repo_dir(repository) charm_path = local_charm_path(charm=charm_name, juju_ver=client.version, series='trusty', repository=os.path.dirname(charm_dir)) for test in tests: if client.is_juju1x() and not test.juju1x_supported: continue log.info( "Assessing multi series charms: test: {} charm_dir:{}".format( test, charm_path)) assert_deploy(client, test, charm_path, repository=repository) if test.machine: check_series(client, machine=test.machine, series=test.series)
def deploy_stack(environment, debug, machines, deploy_charm): """"Deploy a test stack in the specified environment. :param environment: The name of the desired environment. """ client = client_from_config(environment, None, debug=debug) running_domains = dict() if client.env.provider == 'maas': # Split the hypervisor_URI and machine name for machine in machines: name, URI = machine.split('@') # Record already running domains, so they can be left running, # if already running; otherwise start them. if verify_libvirt_domain(URI, name, LIBVIRT_DOMAIN_RUNNING): print("%s is already running" % name) running_domains = {machine: True} else: running_domains = {machine: False} print("Attempting to start %s at %s" % (name, URI)) status_msg = start_libvirt_domain(URI, name) print("%s" % status_msg) # Clean up any leftover junk client.destroy_environment() client.bootstrap() try: # wait for status info.... try: try: client.get_status() except CannotConnectEnv: print("Status got Unable to connect to env. Retrying...") client.get_status() client.wait_for_started() if deploy_charm: series = client.env.get_option('default-series', 'trusty') charm_path = local_charm_path('dummy-source', juju_ver=client.version, series=series) client.deploy(charm_path, series=series) client.wait_for_started() except subprocess.CalledProcessError as e: if getattr(e, 'stderr', None) is not None: sys.stderr.write(e.stderr) raise finally: client.destroy_environment() if client.env.provider == 'maas': sleep(90) for machine, running in running_domains.items(): name, URI = machine.split('@') if running: print("WARNING: %s at %s was running when deploy_job " "started. Shutting it down to ensure a clean " "environment." % (name, URI)) status_msg = stop_libvirt_domain(URI, name) print("%s" % status_msg)
def deploy_stack(environment, debug, machines, deploy_charm): """"Deploy a test stack in the specified environment. :param environment: The name of the desired environment. """ client = client_from_config(environment, None, debug=debug) running_domains = dict() if client.env.provider == 'maas': # Split the hypervisor_URI and machine name for machine in machines: name, URI = machine.split('@') # Record already running domains, so they can be left running, # if already running; otherwise start them. if verify_libvirt_domain(URI, name, LIBVIRT_DOMAIN_RUNNING): print("%s is already running" % name) running_domains = {machine: True} else: running_domains = {machine: False} print("Attempting to start %s at %s" % (name, URI)) status_msg = start_libvirt_domain(URI, name) print("%s" % status_msg) # Clean up any leftover junk client.destroy_environment() client.bootstrap() try: # wait for status info.... try: try: client.get_status() except CannotConnectEnv: print("Status got Unable to connect to env. Retrying...") client.get_status() client.wait_for_started() if deploy_charm: series = client.env.get_option('default-series', 'trusty') charm_path = local_charm_path( 'dummy-source', juju_ver=client.version, series=series) client.deploy(charm_path, series=series) client.wait_for_started() except subprocess.CalledProcessError as e: if getattr(e, 'stderr', None) is not None: sys.stderr.write(e.stderr) raise finally: client.destroy_environment() if client.env.provider == 'maas': sleep(90) for machine, running in running_domains.items(): name, URI = machine.split('@') if running: print("WARNING: %s at %s was running when deploy_job " "started. Shutting it down to ensure a clean " "environment." % (name, URI)) status_msg = stop_libvirt_domain(URI, name) print("%s" % status_msg)
def deploy_charm_with_subordinate_charm(client, series): """Deploy dummy-sink charm and dummy-subordinate charm :param client: ModelClient object :param series: String representing charm series """ token = "canonical" charm_sink = local_charm_path( charm='dummy-sink', series=series, juju_ver=client.version) client.deploy(charm_sink) client.wait_for_started() charm_subordinate = local_charm_path( charm='dummy-subordinate', series=series, juju_ver=client.version) client.deploy(charm_subordinate) client.wait_for_started() client.set_config('dummy-subordinate', {'token': token}) client.juju('add-relation', ('dummy-subordinate', 'dummy-sink')) client.juju('expose', ('dummy-sink',)) client.wait_for_workloads()
def assess_sla(client, series='xenial'): client.wait_for_started() dummy_source = local_charm_path(charm='dummy-source', juju_ver=client.version, series=series) client.deploy(charm=dummy_source) client.wait_for_workloads() # As we are unable to test supported models, for now, we only can assert # on the model shows correctly as unsupported assert_sla_state(client, 'unsupported')
def assess_sla(client, series='xenial'): client.wait_for_started() dummy_source = local_charm_path(charm='dummy-source', juju_ver=client.version, series=series) client.deploy(charm=dummy_source) client.wait_for_workloads() # As we are unable to test supported models, for now, we only can assert # on the model shows correctly as unsupported assert_sla_state(client, 'unsupported')
def ensure_can_push_and_list_charm_with_resources(charm_bin, cs_details): """Ensure that a charm can be pushed to a charm store with a resource. Checks that: - A charm can be pushed with a resource populated with a file - A charm can be updated (attach) after being pushed - A charms resources revision is updated after a push or attach """ charm_command = CharmCommand(charm_bin, cs_details.api_url) with charm_command.logged_in_user(cs_details.email, cs_details.password): charm_id = 'juju-qa-resources-{id}'.format(id=get_run_id()) # Only available for juju 2.x charm_path = local_charm_path('dummy-resource', '2.x') charm_url = 'cs:~{username}/{id}-0'.format( username=cs_details.username, id=charm_id) # Ensure we can publish a charm with a resource with NamedTemporaryFile(suffix='.txt') as temp_foo_resource: temp_foo = temp_foo_resource.name populate_file_data(temp_foo) push_charm_with_resource( charm_command, temp_foo, charm_id, charm_path, resource_name='foo') # Need to grant permissions so we can access details via the http # api. grant_everyone_access(charm_command, charm_url) expected_resource_details = {'foo': 0, 'bar': -1} check_resource_uploaded( charm_command, charm_url, 'foo', temp_foo, expected_resource_details) # Ensure we can attach a resource independently of pushing a charm. with NamedTemporaryFile(suffix='.txt') as temp_bar_resource: temp_bar = temp_bar_resource.name populate_file_data(temp_bar) output = attach_resource_to_charm( charm_command, temp_bar, charm_url, resource_name='bar') log.info(output) expected_resource_details = {'foo': 0, 'bar': 0} check_resource_uploaded( charm_command, charm_url, 'bar', temp_bar, expected_resource_details)
def deploy_charm_with_subordinate_charm(client, series): """Deploy dummy-sink charm and dummy-subordinate charm :param client: ModelClient object :param series: String representing charm series """ token = "canonical" charm_sink = local_charm_path(charm='dummy-sink', series=series, juju_ver=client.version) client.deploy(charm_sink) client.wait_for_started() charm_subordinate = local_charm_path(charm='dummy-subordinate', series=series, juju_ver=client.version) client.deploy(charm_subordinate) client.wait_for_started() client.set_config('dummy-subordinate', {'token': token}) client.juju('add-relation', ('dummy-subordinate', 'dummy-sink')) client.juju('expose', ('dummy-sink', )) client.wait_for_workloads()
def deploy_chaos_monkey(self): """Juju deploy chaos-monkey and add a relation. JUJU_REPOSITORY must be set in the OS environment so a local chaos-monkey charm can be found. """ if self.machine: logging.debug( 'Deploying ubuntu to machine {}.'.format(self.machine)) charm = local_charm_path( charm='ubuntu', juju_ver=self.client.version) self.client.deploy(charm, to=self.machine) logging.debug('Deploying local:chaos-monkey.') charm = local_charm_path( charm='chaos-monkey', juju_ver=self.client.version) self.client.deploy(charm) logging.debug('Relating chaos-monkey to {}.'.format(self.service)) self.client.juju('add-relation', (self.service, 'chaos-monkey')) logging.debug('Waiting for services to start.') self.client.wait_for_started() self.client.wait_for_subordinate_units(self.service, 'chaos-monkey')
def deploy_charm_constraint(client, constraints, charm_name, charm_series, charm_dir): """Create a charm with constraints and test deploying it.""" constraints_charm = Charm(charm_name, 'Test charm for constraints', series=[charm_series]) charm_root = constraints_charm.to_repo_dir(charm_dir) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) deploy_constraint(client, constraints, charm, charm_series, charm_dir)
def deploy_charm_constraint(client, constraints, charm_name, charm_series, charm_dir): """Create a charm with constraints and test deploying it.""" constraints_charm = Charm(charm_name, 'Test charm for constraints', series=[charm_series]) charm_root = constraints_charm.to_repo_dir(charm_dir) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) deploy_constraint(client, constraints, charm, charm_series, charm_dir)
def assess_model_change_watcher(client, charm_series, juju_bin): charm = local_charm_path( charm='dummy-source', juju_ver=client.version, series=charm_series, platform='ubuntu') client.deploy(charm) client.wait_for_started() loop, future = run_listener(client, is_config_change_in_event, juju_bin) logging.info("Making config change.") client.set_config('dummy-source', {'token': TOKEN}) loop.run_until_complete(future) result = future.result() if result is not True: raise JujuAssertionError("Config change event was not sent.") loop.close()
def assess_model_change_watcher(client, charm_series, juju_bin): charm = local_charm_path(charm='dummy-source', juju_ver=client.version, series=charm_series, platform='ubuntu') client.deploy(charm) client.wait_for_started() loop, future = run_listener(client, is_config_change_in_event, juju_bin) logging.info("Making config change.") client.set_config('dummy-source', {'token': TOKEN}) loop.run_until_complete(future) result = future.result() if result is not True: raise JujuAssertionError("Config change event was not sent.") loop.close()
def deploy_simple_resource_server(client, resource_contents=None): application_name = 'simple-resource-http' log.info('Deploying charm: '.format(application_name)) charm_path = local_charm_path( charm=application_name, juju_ver=client.version) # Create a temp file which we'll use as the resource. if resource_contents is not None: with temp_dir() as temp: index_file = os.path.join(temp, 'index.html') with open(index_file, 'wt') as f: f.write(resource_contents) client.deploy(charm_path, resource='index={}'.format(index_file)) else: client.deploy(charm_path) client.wait_for_started() client.wait_for_workloads() client.juju('expose', (application_name)) return application_name
def deploy_charm_and_verify(client, series="xenial", charm_app="dummy-source"): """ Deploy dummy charm from local repository and verify it uses the specified agent-metadata-url option :param client: Juju client :param series: The charm series to deploy :param charm_app: Juju charm application """ charm_source = local_charm_path( charm=charm_app, juju_ver=client.version, series=series) client.deploy(charm_source) client.wait_for_started() client.set_config(charm_app, {'token': 'one'}) client.wait_for_workloads() remote = remote_from_unit(client, "{}/0".format(charm_app)) verify_deployed_charm(client, remote) log.info( "Successfully deployed charm {} of series {} and verified".format( "dummy-source", series))
def deploy_simple_resource_server(client, resource_contents=None): application_name = 'simple-resource-http' log.info('Deploying charm: '.format(application_name)) charm_path = local_charm_path(charm=application_name, juju_ver=client.version) # Create a temp file which we'll use as the resource. if resource_contents is not None: with temp_dir() as temp: index_file = os.path.join(temp, 'index.html') with open(index_file, 'wt') as f: f.write(resource_contents) client.deploy(charm_path, resource='index={}'.format(index_file)) else: client.deploy(charm_path) client.wait_for_started() client.wait_for_workloads() client.juju('expose', (application_name)) return application_name
def ensure_storage_remains_after_application_removal(client): """Storage created during a deploy must persist after application removal. Steps taken to test: - Deploy the dummy storage charm - Set config and ensure data is stored on storage. - Remove application, taking note of the remaining storage name - Re-deploy new charm using persisted storage - Ensure data has remained. :param client: ModelClient object to deploy the charm on. """ random_token = get_random_string() expected_token_values = {'single-fs-token': random_token} charm_path = local_charm_path(charm='dummy-storage', juju_ver=client.version) client.deploy(charm_path, storage='single-fs=rootfs') client.wait_for_started() client.set_config('dummy-storage', {'single-fs-token': random_token}) client.wait_for_workloads() assert_storage_is_intact(client, expected_results=expected_token_values) try: single_filesystem_name = get_storage_filesystems(client, 'single-fs')[0] except IndexError: raise JujuAssertionError('Storage was not found.') client.remove_service('dummy-storage') # Wait for application to be removed then re-deploy with existing storage. storage_command = '--attach-storage single-fs={}'.format( single_filesystem_name) client.deploy(charm_path, alias=storage_command) client.wait_for_started() client.wait_for_workloads() assert_storage_is_intact(client, expected_token_values)
def assess_multiple_provider(client, charm_series, amount, charm_name, provider_1, provider_2, pool_1, pool_2): storage = {} for provider in [provider_1, provider_2]: if provider == "block": storage.update( {"disks": { "type": provider, "multiple": { "range": "0-10" } }}) else: storage.update( {"data": { "type": provider, "location": "/srv/data" }}) with temp_dir() as charm_dir: charm_root = create_storage_charm(charm_dir, charm_name, 'Test charm for storage', storage) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) if pool_1 == "loop": command = "disks=" + pool_1 + "," + amount else: command = "data=" + pool_1 + "," + amount if pool_2 == "loop": command = command + ",disks=" + pool_2 else: command = command + ",data=" + pool_2 client.deploy(charm, series=charm_series, repository=charm_dir, storage=command) client.wait_for_started()
def ensure_storage_remains_after_application_removal(client): """Storage created during a deploy must persist after application removal. Steps taken to test: - Deploy the dummy storage charm - Set config and ensure data is stored on storage. - Remove application, taking note of the remaining storage name - Re-deploy new charm using persisted storage - Ensure data has remained. :param client: ModelClient object to deploy the charm on. """ random_token = get_random_string() expected_token_values = {'single-fs-token': random_token} charm_path = local_charm_path( charm='dummy-storage', juju_ver=client.version) client.deploy(charm_path, storage='single-fs=rootfs') client.wait_for_started() client.set_config('dummy-storage', {'single-fs-token': random_token}) client.wait_for_workloads() assert_storage_is_intact(client, expected_results=expected_token_values) try: single_filesystem_name = get_storage_filesystems( client, 'single-fs')[0] except IndexError: raise JujuAssertionError('Storage was not found.') client.remove_service('dummy-storage') # Wait for application to be removed then re-deploy with existing storage. storage_command = '--attach-storage single-fs={}'.format( single_filesystem_name) client.deploy(charm_path, alias=storage_command) client.wait_for_started() client.wait_for_workloads() assert_storage_is_intact(client, expected_token_values)
def assess_multiple_provider(client, charm_series, amount, charm_name, provider_1, provider_2, pool_1, pool_2): storage = {} for provider in [provider_1, provider_2]: if provider == "block": storage.update({ "disks": { "type": provider, "multiple": { "range": "0-10" } } }) else: storage.update({ "data": { "type": provider, "location": "/srv/data" } }) with temp_dir() as charm_dir: charm_root = create_storage_charm(charm_dir, charm_name, 'Test charm for storage', storage) platform = 'ubuntu' charm = local_charm_path(charm=charm_name, juju_ver=client.version, series=charm_series, repository=os.path.dirname(charm_root), platform=platform) if pool_1 == "loop": command = "disks=" + pool_1 + "," + amount else: command = "data=" + pool_1 + "," + amount if pool_2 == "loop": command = command + ",disks=" + pool_2 else: command = command + ",data=" + pool_2 client.deploy(charm, series=charm_series, repository=charm_dir, storage=command) client.wait_for_started()
def main(): args = parse_args() client = make_client_from_args(args) with boot_context(args.temp_env_name, client, bootstrap_host=args.bootstrap_host, machines=args.machine, series=args.series, agent_url=args.agent_url, agent_stream=args.agent_stream, log_dir=args.logs, keep_env=args.keep_env, upload_tools=args.upload_tools, region=args.region): charm_path = local_charm_path(charm='fill-logs', juju_ver=client.version, series='trusty') client.deploy(charm_path) if args.agent == "unit": test_unit_rotation(client) if args.agent == "machine": assess_machine_rotation(client)
def ensure_multiple_models_forward_messages(rsyslog, dummy, unit_machine, remote_check_path): """Assert that logs of multiple models are forwarded. :raises JujuAssertionError: If the expected message does not appear in the given timeframe. :raises JujuAssertionError: If the log message check fails in an unexpected way. """ model1 = dummy.add_model('{}-{}'.format(dummy.env.environment, 'model1')) charm_path = local_charm_path(charm='dummy-source', juju_ver=model1.version) enable_log_forwarding(model1) model1.deploy(charm_path) model1.wait_for_started() model1_check_string = get_assert_regex(model1.get_model_uuid()) check_remote_log_for_content(rsyslog, unit_machine, model1_check_string, remote_check_path)
def push_resource(client, resource_name, finger_print, size, agent_timeout, resource_timeout, deploy=True, resource_file=None): charm_name = 'dummy-resource' charm_path = local_charm_path(charm=charm_name, juju_ver=client.version) if resource_file is None: resource_file = os.path.join( charm_path, '{}.txt'.format(resource_name)) else: resource_file = os.path.join(charm_path, resource_file) resource_arg = '{}={}'.format(resource_name, resource_file) log.info("Deploy charm with resource {} Size: {} File: {}".format( resource_name, size, resource_file)) if deploy: client.deploy(charm_path, resource=resource_arg) else: client.attach(charm_name, resource=resource_arg) client.wait_for_started(timeout=agent_timeout) resource_id = '{}/{}'.format(charm_name, resource_name) client.wait_for_resource( resource_id, charm_name, timeout=resource_timeout) status = client.list_resources(charm_name) verify_status(status, resource_id, resource_name, finger_print, size) client.show_status()
def ensure_multiple_models_forward_messages( rsyslog, dummy, unit_machine, remote_check_path): """Assert that logs of multiple models are forwarded. :raises JujuAssertionError: If the expected message does not appear in the given timeframe. :raises JujuAssertionError: If the log message check fails in an unexpected way. """ model1 = dummy.add_model('{}-{}'.format(dummy.env.environment, 'model1')) charm_path = local_charm_path( charm='dummy-source', juju_ver=model1.version) enable_log_forwarding(model1) model1.deploy(charm_path) model1.wait_for_started() model1_check_string = get_assert_regex(model1.get_model_uuid()) check_remote_log_for_content( rsyslog, unit_machine, model1_check_string, remote_check_path)
def assess_multi_series_charms(client, devel_series): """Assess multi series charms. :param client: Juju client. :param devel_series: The series to use for new and unsupported scenarios. :type client: jujupy.ModelClient :return: None """ tests = [ Test(series=devel_series, service='test0', force=False, success=False, machine=None, juju1x_supported=False), Test(series=None, service='test1', force=False, success=True, machine='0', juju1x_supported=True), Test(series="trusty", service='test2', force=False, success=True, machine='1', juju1x_supported=True), Test(series="xenial", service='test3', force=False, success=True, machine='2', juju1x_supported=False), Test(series=devel_series, service='test4', force=True, success=True, machine='3', juju1x_supported=False), ] with temp_dir() as repository: charm_name = 'dummy' charm = Charm(charm_name, 'Test charm', series=['trusty', 'xenial']) charm_dir = charm.to_repo_dir(repository) charm_path = local_charm_path( charm=charm_name, juju_ver=client.version, series='trusty', repository=os.path.dirname(charm_dir)) for test in tests: if client.is_juju1x() and not test.juju1x_supported: continue log.info( "Assessing multi series charms: test: {} charm_dir:{}".format( test, charm_path)) assert_deploy(client, test, charm_path, repository=repository) if test.machine: check_series(client, machine=test.machine, series=test.series)
def deploy_xplod_charm(client): charm_path = local_charm_path(charm='peer-xplod', juju_ver=client.version) client.deploy(charm_path, series='trusty') client.wait_for_started() client.wait_for_workloads()
def test_make_local_charm_2x_centos(self): charm = 'mysql' with temp_os_env('JUJU_REPOSITORY', '/home/foo/repository'): path = local_charm_path(charm, '2.0.0', platform='centos') self.assertEqual(path, '/home/foo/repository/charms-centos/mysql')
def test_make_local_charm_2x(self): charm = 'mysql' path = local_charm_path(charm, '2.0.0', repository='/tmp/charms') self.assertEqual(path, '/tmp/charms/mysql')
def test_make_local_charm_1x_series(self): charm = 'mysql' path = local_charm_path(charm, '1.25.0', series='trusty') self.assertEqual(path, 'local:trusty/mysql')
def test_make_local_charm_1x(self): charm = 'mysql' path = local_charm_path(charm, '1.25.0') self.assertEqual(path, 'local:mysql')
def test_make_local_charm_2x_centos(self): charm = 'mysql' with temp_os_env('JUJU_REPOSITORY', '/home/foo/repository'): path = local_charm_path(charm, '2.0.0', platform='centos') self.assertEqual(path, '/home/foo/repository/charms-centos/mysql')
def test_make_local_charm_2x(self): charm = 'mysql' path = local_charm_path(charm, '2.0.0', repository='/tmp/charms') self.assertEqual(path, '/tmp/charms/mysql')
def test_make_local_charm_1x_series(self): charm = 'mysql' path = local_charm_path(charm, '1.25.0', series='trusty') self.assertEqual(path, 'local:trusty/mysql')
def test_make_local_charm_1x(self): charm = 'mysql' path = local_charm_path(charm, '1.25.0') self.assertEqual(path, 'local:mysql')
def test_control_heterogeneous(bs_manager, other, upload_tools): """Test if one binary can control an environment set up by the other.""" initial = bs_manager.client released = bs_manager.tear_down_client with run_context(bs_manager, other, upload_tools): token = prepare_dummy_env(initial) initial.wait_for_started() if sys.platform != "win32": # Currently, juju ssh is not working on Windows. check_token(initial, token) check_series(other) other.juju('run', ('--all', 'uname -a')) other.get_config('dummy-source') other.get_model_config() other.juju('remove-relation', ('dummy-source', 'dummy-sink')) status = other.get_status() other.juju('unexpose', ('dummy-sink',)) status = other.get_status() if status.get_applications()['dummy-sink']['exposed']: raise AssertionError('dummy-sink is still exposed') status = other.get_status() charm_path = local_charm_path( charm='dummy-sink', juju_ver=other.version) juju_with_fallback(other, released, 'deploy', (charm_path, 'sink2')) other.wait_for_started() other.juju('add-relation', ('dummy-source', 'sink2')) status = other.get_status() other.juju('expose', ('sink2',)) status = other.get_status() if 'sink2' not in status.get_applications(): raise AssertionError('Sink2 missing') other.remove_service('sink2') for ignored in until_timeout(30): status = other.get_status() if 'sink2' not in status.get_applications(): break else: raise AssertionError('Sink2 not destroyed') other.juju('add-relation', ('dummy-source', 'dummy-sink')) status = other.get_status() relations = status.get_applications()['dummy-sink']['relations'] if not relations['source'] == ['dummy-source']: raise AssertionError('source is not dummy-source.') other.juju('expose', ('dummy-sink',)) status = other.get_status() if not status.get_applications()['dummy-sink']['exposed']: raise AssertionError('dummy-sink is not exposed') other.juju('add-unit', ('dummy-sink',)) if not has_agent(other, 'dummy-sink/1'): raise AssertionError('dummy-sink/1 was not added.') other.juju('remove-unit', ('dummy-sink/1',)) status = other.get_status() if has_agent(other, 'dummy-sink/1'): raise AssertionError('dummy-sink/1 was not removed.') container_type = other.preferred_container() other.juju('add-machine', (container_type,)) status = other.get_status() container_machine, = set(k for k, v in status.agent_items() if k.endswith('/{}/0'.format(container_type))) container_holder = container_machine.split('/')[0] other.remove_machine(container_machine) wait_until_removed(other, container_machine) other.remove_machine(container_holder) wait_until_removed(other, container_holder)