Esempio n. 1
0
def test_verify_data_prevents_unwanted_loss():
    cfg = hint_deploy.HintConfig("config")
    cfg.protect_data = True
    msg = "Cannot remove volumes with this configuration"
    with mock.patch('src.hint_cli.prompt_yes_no') as prompt:
        with pytest.raises(Exception, match=msg):
            hint_cli.verify_data_loss("stop", {"remove_volumes": True}, cfg)
Esempio n. 2
0
def test_load_config_sets_branch_refs():
    path = "config"
    config = "production"
    options = {"hint": {"tag": "mrc-123"}, "hintr": {"tag": "mrc-456"}}
    cfg = hint_deploy.HintConfig(path, config, options=options)
    assert cfg.hint_tag == "mrc-123"
    assert cfg.hintr_tag == "mrc-456"
Esempio n. 3
0
def test_verify_data_loss_warns_if_loss():
    cfg = hint_deploy.HintConfig("config")
    f = io.StringIO()
    with redirect_stdout(f):
        with mock.patch('src.hint_cli.prompt_yes_no') as prompt:
            prompt.return_value = True
            hint_cli.verify_data_loss("stop", {"remove_volumes": True}, cfg)

    assert prompt.called
    assert "WARNING! PROBABLE IRREVERSIBLE DATA LOSS!" in f.getvalue()
Esempio n. 4
0
def test_verify_data_loss_silent_if_no_loss():
    cfg = hint_deploy.HintConfig("config")
    f = io.StringIO()
    with redirect_stdout(f):
        with mock.patch('src.hint_cli.prompt_yes_no') as prompt:
            prompt.return_value = True
            hint_cli.verify_data_loss("start", {}, cfg)
            hint_cli.verify_data_loss("stop", {"remove_volumes": False}, cfg)

    assert not prompt.called
    assert f.getvalue() == ""
Esempio n. 5
0
def test_load_and_reload_config():
    path = "config"
    config = "production"
    cfg = hint_deploy.HintConfig(path, config)
    cfg.hint_tag = "develop"
    hint_cli.save_config(path, config, cfg)

    hint_cli.read_config(path)

    config_name, config_value = hint_cli.load_config(path, None)
    assert config_value.hint_tag == "master"
    assert config_name == "production"
    hint_cli.remove_config(path)
Esempio n. 6
0
def test_start_pulls_db_migrate():
    cfg = hint_deploy.HintConfig("config")
    obj = hint_deploy.hint_constellation(cfg)

    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_start(obj, cfg, {"pull_images": True})
    p = f.getvalue()

    assert "Pulling docker image db-migrate" in p

    obj.destroy()

    # Start without --pull doesn't pull migrate image
    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_start(obj, cfg, {"pull_images": False})
    p = f.getvalue()

    assert "Pulling docker image db-migrate" not in p

    obj.destroy()
Esempio n. 7
0
def test_configure_proxy():
    cfg = hint_deploy.HintConfig("config", "staging")
    cl = docker.client.from_env()
    args = ["localhost:80", "localhost", "80", "443"]
    container = cl.containers.run("reside/proxy-nginx:master",
                                  args,
                                  detach=True,
                                  auto_remove=False)
    args = [
        "self-signed-certificate", "/tmp", "GB", "London", "IC", "reside",
        cfg.proxy_host
    ]
    docker_util.exec_safely(container, args)
    cert = docker_util.string_from_container(container, "/tmp/certificate.pem")
    key = docker_util.string_from_container(container, "/tmp/key.pem")
    cfg.proxy_ssl_certificate = cert
    cfg.proxy_ssl_key = key
    hint_deploy.proxy_configure(container, cfg)
    assert docker_util.string_from_container(
        container, "/run/proxy/certificate.pem") == cert
    assert docker_util.string_from_container(container,
                                             "/run/proxy/key.pem") == key
    container.kill()
Esempio n. 8
0
def test_start_hint():
    cfg = hint_deploy.HintConfig("config")
    obj = hint_deploy.hint_constellation(cfg)
    obj.status()
    obj.start()

    res = requests.get("http://localhost:8080")

    assert res.status_code == 200
    assert "Naomi" in res.content.decode("UTF-8")

    res = requests.get("http://localhost:8888")

    assert res.status_code == 200

    assert docker_util.network_exists("hint_nw")
    assert docker_util.volume_exists("hint_db_data")
    assert docker_util.volume_exists("hint_uploads")
    assert docker_util.volume_exists("hint_results")
    assert docker_util.volume_exists("hint_prerun")
    assert docker_util.container_exists("hint_db")
    assert docker_util.container_exists("hint_redis")
    assert docker_util.container_exists("hint_hintr")
    assert docker_util.container_exists("hint_hint")
    assert len(docker_util.containers_matching("hint_worker_", False)) == 2
    assert len(docker_util.containers_matching("hint_calibrate_worker_",
                                               False)) == 1

    # Some basic user management
    user = "******"
    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_user(cfg, "add-user", user, True, "password")

    p = f.getvalue()
    assert "Adding user {}".format(user) in p
    assert p.strip().split("\n")[-1] == "OK"

    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_user(cfg, "user-exists", user, False)

    assert f.getvalue() == "Checking if user exists: {}\ntrue\n".format(user)

    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_user(cfg, "add-user", user, True, "password")

    p = f.getvalue()
    assert "Not adding user {} as they already exist".format(user) in p

    f = io.StringIO()
    with redirect_stdout(f):
        hint_deploy.hint_user(cfg, "remove-user", user, False)

    assert f.getvalue() == "Removing user {}\nOK\n".format(user)

    # Confirm we have brought up exactly two workers (none in the
    # hintr container itself)
    script = 'message(httr::content(httr::GET(' + \
             '"http://localhost:8888/hintr/worker/status"),' + \
             '"text", encoding="UTF-8"))'
    args = ["Rscript", "-e", script]
    hintr = obj.containers.get("hintr", obj.prefix)
    result = docker_util.exec_safely(hintr, args).output
    logs = result.decode("UTF-8")
    data = json.loads(logs)["data"]
    assert len(data.keys()) == 3

    obj.destroy()

    assert not docker_util.network_exists("hint_nw")
    assert not docker_util.volume_exists("hint_db_data")
    assert not docker_util.volume_exists("hint_uploads")
    assert not docker_util.volume_exists("hint_results")
    assert not docker_util.volume_exists("hint_prerun")
    assert not docker_util.container_exists("hint_db")
    assert not docker_util.container_exists("hint_redis")
    assert not docker_util.container_exists("hint_hintr")
    assert not docker_util.container_exists("hint_hint")
    assert len(docker_util.containers_matching("hint_worker_", False)) == 0
    assert len(docker_util.containers_matching("hint_calibrate_worker_",
                                               False)) == 0
Esempio n. 9
0
def test_update_hintr_and_all():
    hint_cli.main(["start"])

    f = io.StringIO()
    with redirect_stdout(f):
        hint_cli.main(["upgrade", "hintr"])

    p = f.getvalue()
    assert "Pulling docker image hintr" in p
    assert "Pulling docker image db-migrate" not in p
    assert "Stopping previous hintr and workers" in p
    assert "Starting hintr" in p
    assert "Starting *service* calibrate_worker" in p
    assert "Starting *service* worker" in p

    assert docker_util.network_exists("hint_nw")
    assert docker_util.volume_exists("hint_db_data")
    assert docker_util.volume_exists("hint_uploads")
    assert docker_util.volume_exists("hint_results")
    assert docker_util.volume_exists("hint_prerun")
    assert docker_util.container_exists("hint_db")
    assert docker_util.container_exists("hint_redis")
    assert docker_util.container_exists("hint_hintr")
    assert docker_util.container_exists("hint_hint")
    assert len(docker_util.containers_matching("hint_worker_", False)) == 2
    assert len(docker_util.containers_matching("hint_worker_", True)) == 4
    assert len(docker_util.containers_matching("hint_calibrate_worker",
                                               False)) == 1
    assert len(docker_util.containers_matching("hint_calibrate_worker",
                                               True)) == 2

    # We are going to write some data into redis here and later check
    # that it survived the upgrade.
    cfg = hint_deploy.HintConfig("config")
    obj = hint_deploy.hint_constellation(cfg)
    args_set = ["redis-cli", "SET", "data_persists", "yes"]
    redis = obj.containers.get("redis", obj.prefix)
    docker_util.exec_safely(redis, args_set)

    f = io.StringIO()
    with redirect_stdout(f):
        hint_cli.main(["upgrade", "all"])

    p = f.getvalue()
    assert "Pulling docker image db" in p
    assert "Pulling docker image db-migrate" in p
    assert "Stop 'redis'" in p
    assert "Removing 'redis'" in p
    assert "Starting redis" in p
    assert "[redis] Waiting for redis to come up" in p

    assert docker_util.network_exists("hint_nw")
    assert docker_util.volume_exists("hint_db_data")
    assert docker_util.volume_exists("hint_uploads")
    assert docker_util.volume_exists("hint_results")
    assert docker_util.volume_exists("hint_prerun")
    assert docker_util.container_exists("hint_db")
    assert docker_util.container_exists("hint_redis")
    assert docker_util.container_exists("hint_hintr")
    assert docker_util.container_exists("hint_hint")
    assert len(docker_util.containers_matching("hint_worker_", False)) == 2
    assert len(docker_util.containers_matching("hint_calibrate_worker_",
                                               False)) == 1

    redis = obj.containers.get("redis", obj.prefix)
    args_get = ["redis-cli", "GET", "data_persists"]
    result = docker_util.exec_safely(redis, args_get).output.decode("UTF-8")
    assert "yes" in result

    obj.destroy()
Esempio n. 10
0
def test_real_adr_optional():
    cfg = hint_deploy.HintConfig("config")
    assert cfg.hint_adr_url is None
Esempio n. 11
0
def test_production_uses_real_adr():
    cfg = hint_deploy.HintConfig("config", "production")
    assert cfg.hint_adr_url == "https://adr.unaids.org/"
Esempio n. 12
0
def test_base_uses_fake_email_configuration():
    cfg = hint_deploy.HintConfig("config")
    assert cfg.hint_email_mode == "disk"
Esempio n. 13
0
def test_production_and_staging_use_real_email_configuration():
    cfg = hint_deploy.HintConfig("config", "production")
    assert cfg.hint_email_mode == "real"
    cfg = hint_deploy.HintConfig("config", "staging")
    assert cfg.hint_email_mode == "real"
Esempio n. 14
0
def test_verify_data_loss_throws_if_loss():
    cfg = hint_deploy.HintConfig("config")
    with mock.patch('src.hint_cli.prompt_yes_no') as prompt:
        prompt.return_value = False
        with pytest.raises(Exception, match="Not continuing"):
            hint_cli.verify_data_loss("stop", {"remove_volumes": True}, cfg)