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)
Beispiel #3
0
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()
Beispiel #5
0
 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)
Beispiel #6
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #13
0
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)
Beispiel #14
0
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)
Beispiel #15
0
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()
Beispiel #16
0
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')
Beispiel #17
0
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()
Beispiel #20
0
    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)
Beispiel #22
0
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)
Beispiel #23
0
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()
Beispiel #25
0
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
Beispiel #26
0
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
Beispiel #28
0
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()
Beispiel #30
0
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)
Beispiel #31
0
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)
Beispiel #33
0
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)
Beispiel #34
0
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()
Beispiel #35
0
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)
Beispiel #36
0
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')
Beispiel #42
0
 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')
Beispiel #43
0
 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')
Beispiel #44
0
 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')
Beispiel #45
0
 def test_make_local_charm_1x(self):
     charm = 'mysql'
     path = local_charm_path(charm, '1.25.0')
     self.assertEqual(path, 'local:mysql')
Beispiel #46
0
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)