Beispiel #1
0
def test_get_port_mappings():
    image_name = "registry.fedoraproject.org/fedora"
    image_tag = "27"
    image = DockerImage(image_name, image_tag)

    command = DockerRunBuilder(additional_opts=["-p", "321:123"])

    try:
        image.get_metadata()
    except Exception:
        image.pull()

    container = image.run_via_binary(command)
    try:
        mappings = container.get_port_mappings(123)

        assert len(mappings) == 1
        assert mappings == [{"HostIp": '0.0.0.0', "HostPort": '321'}]

        mappings = container.get_port_mappings()
        assert len(mappings) == 1
        assert mappings == {
            '123/tcp': [{
                'HostIp': '0.0.0.0',
                'HostPort': '321'
            }]
        }
    finally:
        container.stop()
        container.delete()

    command = DockerRunBuilder()
    container = image.run_via_binary(command)
    try:
        mappings = container.get_port_mappings(123)

        assert not mappings
    finally:
        container.stop()
        container.delete()
def test_docker_parameters():
    docker_run_builder = DockerRunBuilder(additional_opts=['-l', 'hello=there', '-l', 'oh=noo', '--name', 'test', '-d',
                                                           '--hostname', 'my_hostname',
                                                           '--rm', '--privileged', '--isolation', 'default',
                                                           '--mac-address', '92:d0:c6:0a:29:33',
                                                           '--memory', '1G', '--user', 'my_user',
                                                           '--workdir', '/tmp',
                                                           '--env', 'ENV1=my_env', '-p', '123:12345', '-p', '1444',
                                                           '-p', '10.0.0.1::150', '-p', '10.0.0.2:2345:7654',
                                                           '--cap-add', 'MKNOD', '--cap-add', 'SYS_ADMIN',
                                                           '--cap-drop', 'SYS_ADMIN', '--device', '/dev/sdc:/dev/xvdc',
                                                           '--dns', 'www.example.com', '--group-add', 'group1',
                                                           '--group-add', 'group2', '--mount', '/tmp',
                                                           '--volume', '/tmp:/tmp', '--no-healthcheck'],
                                          command=['sleep', '50'])

    parameters = docker_run_builder.get_parameters()

    assert parameters.labels == {'hello': 'there', 'oh': 'noo'}
    assert parameters.name == 'test'
    assert parameters.detach
    assert parameters.privileged
    assert parameters.hostname == 'my_hostname'
    assert parameters.remove
    assert parameters.isolation == 'default'
    assert parameters.mac_address == '92:d0:c6:0a:29:33'
    assert parameters.mem_limit == '1G'
    assert parameters.user == 'my_user'
    assert parameters.working_dir == '/tmp'
    assert 'ENV1=my_env' in parameters.env_variables
    assert parameters.port_mappings == {'12345': 123, '1444': None, '150': ('10.0.0.1', None), '7654': ('10.0.0.2', 2345)}
    assert parameters.cap_add == ['MKNOD', 'SYS_ADMIN']
    assert parameters.cap_drop == ['SYS_ADMIN']
    assert parameters.devices == ['/dev/sdc:/dev/xvdc']
    assert parameters.dns == ['www.example.com']
    assert parameters.group_add == ['group1', 'group2']
    assert parameters.mounts == ['/tmp']
    assert parameters.volumes == ['/tmp:/tmp']
    assert parameters.command == ['sleep', '50']
Beispiel #3
0
def test_nonblocking_execute():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        cmd = DockerRunBuilder(command=['sleep', 'infinity'])
        cont = image.run_via_binary(cmd)
        stream = cont.execute(["bash", "-c", "exit 0"], blocking=False)
        list(stream)
        gen = cont.execute(["printf", "asd"], blocking=False)
        assert [b"asd"] == list(gen)
        gen = cont.execute(["printf", "asd\nasd"], blocking=False)
        assert [b"asd\nasd"] == list(gen)
        cont.execute(["bash", "-c", "sleep 0.01; exit 110"], blocking=False)
Beispiel #4
0
def test_container_create_failed():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY, tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        # should raise an exc, there is no such command: waldo; we need to find waldo first
        with pytest.raises(ConuException):
            image.run_via_binary(
                command=["waldo"]
            )
        c = image.run_via_binary_in_foreground(
            DockerRunBuilder(command=["waldo"])
        )
        c.popen_instance.communicate()
        assert c.popen_instance.returncode > 0
Beispiel #5
0
def test_blocking_execute():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        cmd = DockerRunBuilder(command=['sleep', 'infinity'])
        cont = image.run_via_binary(cmd)
        cont.execute(["bash", "-c", "exit 0"])
        assert [b"asd"] == cont.execute(["printf", "asd"])
        assert [b"asd\nasd"] == cont.execute(["printf", "asd\nasd"])
        with pytest.raises(ConuException) as ex:
            cont.execute(["bash", "-c", "exit 110"])
            assert "exit code 110" in ex.value.message
            assert "bash" in ex.value.message
 def test_invoking_container(self):
     image = backend.ImageClass(image_name, tag=image_tag)
     c = image.run_via_binary(DockerRunBuilder(command=["bash", "-c", "ruby --version"]))
     try:
         c.wait()
         logs = list(c.logs())[0].decode("utf-8")
     finally:
         c.stop()
         c.wait()
         c.delete()
     assert "ruby " in logs
     if os.environ.get("VERSION", None):
         assert os.environ["VERSION"] in logs
Beispiel #7
0
def test_set_name():
    with DockerBackend() as backend:
        test_name = 'jondoe'
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG,
                                   pull_policy=DockerImagePullPolicy.NEVER)
        cont = image.run_via_binary()
        assert cont.name
        cont.delete(force=True)

        cont = image.run_via_binary_in_foreground()
        assert cont.name
        cont.delete(force=True)

        cmd = DockerRunBuilder(additional_opts=['--name', test_name])
        cont = image.run_via_binary(cmd)
        assert cont.name == test_name
        cont.delete(force=True)

        cmd = DockerRunBuilder(additional_opts=['--name', test_name])
        cont = image.run_via_binary_in_foreground(cmd)
        assert cont.name == test_name
        cont.delete(force=True)
Beispiel #8
0
def make_pg_client_request(container, pg_cmd, opts, expected_output=None):
    cmd = DockerRunBuilder(
        additional_opts = ["-e", "PGPASSWORD="******"psql",
                  "postgresql://" + opts['POSTGRESQL_USER'] + "@"
                  + container.get_IPv4s()[0] + ":5432/" + opts['POSTGRESQL_DATABASE'],
                  "-c", pg_cmd]
    )
    client_container = get_image().run_via_binary(cmd)
    assert not expected_output or client_container.logs() == expected_output
    client_container.wait(timeout=10)
    assert client_container.exit_code() == 0
    assert client_container.logs() == expected_output
    client_container.delete()
def e2e_case(i, results):
    # run master
    master = i.run_via_binary()
    master_started = master.is_running()
    add_result(master_started, 'It should be possible to start the master.')

    master.wait_for_port(8080, timeout=15)
    http_response = master.http_request(path='/json', port=8080)
    master_http_ok = http_response.ok
    add_result(master_http_ok, 'Master should start the web ui on port 8080')

    master_alive = 'ALIVE' in http_response.content.decode('utf-8')
    add_result(master_alive, 'Master should be alive.')

    if master_started and master.get_IPv4s():
        master_ip = master.get_IPv4s()[0]
        # run worker
        run_params_worker = DockerRunBuilder(additional_opts=[
            '-e', 'SPARK_MASTER_ADDRESS=' + master_ip +
            ':7077', '-e', 'SPARK_MASTER_UI_ADDRESS=http://' + master_ip +
            ':8080'
        ])
        worker = i.run_via_binary(run_params_worker)
        worker_started = worker.is_running()
        add_result(worker_started,
                   'It should be possible to start the worker.')
        worker.wait_for_port(8081, timeout=15)

        http_response = worker.http_request(path='/json', port=8081)
        worker_http_ok = http_response.ok
        add_result(worker_http_ok,
                   'Worker should start the web ui on port 8081')

        worker_registered_web_ui = 'spark://%s:7077' % master_ip in http_response.content.decode(
            'utf-8')
        add_result(worker_registered_web_ui,
                   "Worker web ui should contain the master's ip")

        worker_registered_logs = 'Registering worker' in (b'\n'.join(
            master.logs())).decode('utf-8')
        add_result(
            worker_registered_logs,
            "In the master's log file there should be worker registration message"
        )

        master_registered_logs = 'registered with master' in (b'\n'.join(
            worker.logs())).decode('utf-8')
        add_result(
            master_registered_logs,
            "In the worker's log file master registration should be mentioned")
Beispiel #10
0
def test_copy_from(tmpdir):
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        c = image.run_via_binary(
            DockerRunBuilder(command=["cat"], additional_opts=["-i", "-t"]))
        try:
            c.copy_from("/etc/fedora-release", str(tmpdir))
            with open(os.path.join(str(tmpdir), "fedora-release")) as fd:
                assert fd.read() == "Fedora release 26 (Twenty Six)\n"

            c.copy_from("/etc", str(tmpdir))
            os.path.exists(os.path.join(str(tmpdir), "passwd"))
        finally:
            c.delete(force=True)
Beispiel #11
0
def test_copy_to(tmpdir):
    content = b"gardener did it"
    p = tmpdir.join("secret")
    p.write(content)

    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        c = image.run_via_binary(
            DockerRunBuilder(command=["cat"], additional_opts=["-i", "-t"]))
        try:
            c.copy_to(str(p), "/")
            assert [content] == c.execute(["cat", "/secret"])
        finally:
            c.delete(force=True)
Beispiel #12
0
def test_s2i_extending(tmpdir):
    t = str(tmpdir)
    exec_path = os.path.join(t, "secret-executable")
    secret_message = "Can I have a cup of cocoa?"
    with open(exec_path, "w") as fd:
        fd.write("""\
        #!/bin/bash
        echo "%s"
        """ % secret_message)
    os.chmod(exec_path, 0o755)
    i = S2IDockerImage(S2I_IMAGE)
    ei = i.extend(t, "extended-punchbag")
    c = ei.run_via_binary(DockerRunBuilder())
    c.wait()
    assert c.logs().decode("utf-8").strip() == secret_message
Beispiel #13
0
def test_copy_to(tmpdir):
    content = b"gardener did it"
    p = tmpdir.join("secret")
    p.write(content)

    image = DockerImage(FEDORA_MINIMAL_REPOSITORY,
                        tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    c = image.run_via_binary(
        DockerRunBuilder(command=["cat"], additional_opts=["-i", "-t"]))
    try:
        c.copy_to(str(p), "/")
        assert content == c.execute(["cat", "/secret"])
    finally:
        c.stop()
        c.delete()
Beispiel #14
0
    def check(self, target):
        passed = self.all_must_be_present
        cleanup = False

        if target.target_type is TargetType.IMAGE:
            drb = DockerRunBuilder(command=["/bin/sleep", "infinity"],
                                   additional_opts=["--entrypoint="])
            cont = target.instance.run_via_binary(run_command_instance=drb)
            cleanup = True
        elif target.target_type is TargetType.CONTAINER:
            cont = target.instance
        else:
            return CheckResult(ok=False,
                               description=self.description,
                               message=self.message,
                               reference_url=self.reference_url,
                               check_name=self.name,
                               logs=[
                                   "Unsupported target, this check can "
                                   "process only containers and images"
                               ])
        logs = []
        try:
            for f in self.files:
                cmd = ["/bin/ls", "-1", f]
                try:
                    f_present = cont.execute(cmd)
                    logs.append("File '{}' is {}present.".format(
                        f, "" if f_present else "not "))
                except ConuException as ex:
                    logger.info("File %s is not present, ex: %s", f, ex)
                    f_present = False
                    logs.append("File {} is not present.".format(f))
                if self.all_must_be_present:
                    passed = f_present and passed
                else:
                    passed = f_present or passed

            return CheckResult(ok=passed,
                               description=self.description,
                               message=self.message,
                               reference_url=self.reference_url,
                               check_name=self.name,
                               logs=logs)
        finally:
            if cleanup:
                cont.stop()
                cont.delete()
Beispiel #15
0
def test_wait_for_status():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        cmd = DockerRunBuilder(command=['sleep', '2'])
        cont = image.run_via_binary(cmd)

        try:
            start = time.time()
            p = Probe(timeout=6, fnc=cont.get_status, expected_retval='exited')
            p.run()
            end = time.time() - start
            assert end > 2, "Probe should wait till container status is exited"
            assert end < 7, "Probe should end when container status is exited"
        finally:
            cont.delete(force=True)
Beispiel #16
0
def self_cleanup():
    import logging
    import pytest
    from conu import DockerBackend, DockerRunBuilder

    backend = DockerBackend(logging_level=logging.DEBUG)
    image = backend.ImageClass(IMAGE_NAME)

    # alternative of docker run --rm nginx
    run_params = DockerRunBuilder(additional_opts=['--rm'])
    container = image.run_via_binary(run_params)
    assert container.is_running()

    # check container is removed when stopped
    container.stop()
    with pytest.raises(Exception):
        container.inspect()
Beispiel #17
0
def test_container_logs():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        command = ["bash", "-c", "for x in `seq 1 5`; do echo $x; done"]
        r = DockerRunBuilder(command=command)
        cont = image.run_via_binary(r)
        try:
            Probe(timeout=5, fnc=cont.get_status,
                  expected_retval='exited').run()
            assert not cont.is_running()
            assert list(
                cont.logs()) == [b"1\n", b"2\n", b"3\n", b"4\n", b"5\n"]
            assert cont.logs_unicode() == "1\n2\n3\n4\n5\n"
            assert cont.logs_in_bytes() == b"1\n2\n3\n4\n5\n"
        finally:
            cont.delete(force=True)
Beispiel #18
0
def test_container():
    """
    Basic tests of interacting with a container
    """
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        c = image.run_via_binary(
            DockerRunBuilder(command=["cat"], additional_opts=["-i", "-t"]))
        try:
            assert "Config" in c.inspect()
            assert "Config" in c.inspect()
            assert c.get_id() == str(c)
            assert repr(c)
            assert isinstance(c.get_id(), string_types)
        finally:
            c.delete(force=True)
Beispiel #19
0
def test_http_client():
    image = DockerImage(FEDORA_REPOSITORY)
    c = image.run_via_binary(
        DockerRunBuilder(
            command=["python3", "-m", "http.server", "--bind", "0.0.0.0 8000"
                     ]))
    c.start()
    time.sleep(1)  # FIXME: replace by wait once available
    assert c.is_running()
    r = c.http_request(port="8000")
    assert "<!DOCTYPE HTML PUBLIC" in r.content.decode("utf-8")
    assert r.ok
    r2 = c.http_request(path="/etc", port="8000")
    assert "<!DOCTYPE HTML PUBLIC" in r2.content.decode("utf-8")
    assert "passwd" in r2.content.decode("utf-8")
    assert r2.ok
    c.stop()
    c.delete()
Beispiel #20
0
def test_cleanup_containers():
    backend = DockerBackend(logging_level=logging.DEBUG)

    # cleaning up from previous runs
    backend.cleanup_containers()

    client = get_client()
    container_sum = len(client.containers(all=True))
    image = DockerImage(FEDORA_MINIMAL_REPOSITORY,
                        tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    command = DockerRunBuilder(command=["ls"], additional_opts=["-i", "-t"])

    for i in range(3):
        image.run_via_binary(command)

    assert container_sum + 3 == len(client.containers(all=True))
    backend.cleanup_containers()
    assert container_sum == len(client.containers(all=True))
Beispiel #21
0
def check_output():
    import logging
    from conu import DockerBackend, DockerRunBuilder

    backend = DockerBackend(logging_level=logging.DEBUG)
    image = backend.ImageClass(IMAGE_NAME)

    # run own command in container
    message = 'Hello DevConf.cz 2018!'
    run_params = DockerRunBuilder(command=['echo', message])
    container = image.run_via_binary(run_params)

    # check it went ok
    assert container.logs().decode('utf-8') == message + '\n'
    print('Success!')

    # cleanup
    container.delete(force=True)
Beispiel #22
0
def test_http_client():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_REPOSITORY)
        c = image.run_via_binary(
            DockerRunBuilder(command=[
                "python3", "-m", "http.server", "--bind", "0.0.0.0 8000"
            ]))
        try:
            c.wait_for_port(8000)
            assert c.is_running()
            r = c.http_request(port="8000")
            assert "<!DOCTYPE HTML PUBLIC" in r.content.decode("utf-8")
            assert r.ok
            r2 = c.http_request(path="/etc", port="8000")
            assert "<!DOCTYPE HTML PUBLIC" in r2.content.decode("utf-8")
            assert "passwd" in r2.content.decode("utf-8")
            assert r2.ok
        finally:
            c.delete(force=True)
Beispiel #23
0
def test_interactive_container():
    with DockerBackend() as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                   tag=FEDORA_MINIMAL_REPOSITORY_TAG)
        command = ["bash"]
        r = DockerRunBuilder(command=command, additional_opts=["-i"])
        cont = image.run_via_binary_in_foreground(r,
                                                  popen_params={
                                                      "stdin": subprocess.PIPE,
                                                      "stdout": subprocess.PIPE
                                                  })
        try:
            assert "" == cont.logs_unicode()
            assert cont.is_running()
            time.sleep(0.1)
            cont.popen_instance.stdin.write(b"echo palacinky\n")
            cont.popen_instance.stdin.flush()
            time.sleep(0.2)
            assert b"palacinky" in cont.popen_instance.stdout.readline()
        finally:
            cont.delete(force=True)
def assert_container_creation_fails(opts, description):
    cmd = DockerRunBuilder(additional_opts=opts)
    image = get_image()
    cont = image.run_via_binary(cmd)

    p = Probe(timeout=9, fnc=cont.get_status, expected_retval='exited')
    try:
        p.run()
    except ProbeTimeout:
        actual_status = cont.get_status()
        cont.stop()
        cont.delete()
        if actual_status == 'running':
            raise RuntimeError("Container should fail with %s" % description)
        else:
            raise RuntimeError("Container reached unexpected status %s" %
                               actual_status)

    ec = cont.get_metadata()['State']['ExitCode']
    print(cont.logs())
    assert ec != 0, "Container should exit wit non-zero exit code when input is invalid"
    cont.delete()
def test_container_metadata():
    with DockerBackend(logging_level=10) as backend:
        image = backend.ImageClass(FEDORA_MINIMAL_REPOSITORY, tag=FEDORA_MINIMAL_REPOSITORY_TAG)

        c = image.run_via_binary(
            DockerRunBuilder(command=["cat"], additional_opts=['-i',
                                                               '-t',
                                                               '--name', 'my_container',
                                                               '-p', '1234:12345',
                                                               '-p', '123:12345',
                                                               '-p', '8080',
                                                               '--hostname', 'my_hostname',
                                                               '-e', 'ENV1=my_env',
                                                               '-e', 'ASD=',
                                                               '-e', 'A=B=C=D',
                                                               '-e', 'XYZ',
                                                               '-l', 'testlabel1=testvalue1'
                                                               ])
        )

        try:
            container_metadata = c.get_metadata()

            assert container_metadata.command == ["cat"]
            assert container_metadata.name == "my_container"
            assert container_metadata.env_variables["ENV1"] == "my_env"
            assert container_metadata.env_variables["ASD"] == ""
            assert container_metadata.env_variables["A"] == "B=C=D"
            assert container_metadata.hostname == "my_hostname"
            assert "XYZ" not in list(container_metadata.env_variables.keys())
            assert '12345/tcp' in container_metadata.port_mappings
            assert container_metadata.port_mappings['12345/tcp'] == [1234, 123]
            assert '8080/tcp' in container_metadata.port_mappings
            assert container_metadata.exposed_ports == ["12345/tcp", "8080/tcp"]
            assert container_metadata.labels["testlabel1"] == "testvalue1"
            assert container_metadata.status == ContainerStatus.RUNNING
        finally:
            c.delete(force=True)
Beispiel #26
0
def test_dr_command_class():
    simple = DockerRunBuilder()
    simple.image_name = "voodoo"
    assert ["docker", "run", "-l", CONU_ARTIFACT_TAG,
            "voodoo"] == simple.build()

    complex = DockerRunBuilder(additional_opts=["-a", "--foo"])
    complex.image_name = "voodoo"
    assert ["docker", "run", "-a", "--foo", "-l", CONU_ARTIFACT_TAG,
            "voodoo"] == complex.build()

    w_cmd = DockerRunBuilder(command=["x", "y"],
                             additional_opts=["-a", "--foo"])
    w_cmd.image_name = "voodoo"
    assert [
        "docker", "run", "-a", "--foo", "-l", CONU_ARTIFACT_TAG, "voodoo", "x",
        "y"
    ] == w_cmd.build()

    # test whether mutable params are not mutable across instances
    simple.options += ["spy"]
    assert "spy" not in DockerRunBuilder().options
Beispiel #27
0
    "POSTGRESQL_DATABASE=db"
]

with DockerBackend(logging_level=logging.DEBUG) as backend:
    image = backend.ImageClass('centos/postgresql-96-centos7')

    # create server
    additional_opts = environment
    dbcont = image.run_via_binary(additional_opts=additional_opts)

    # wait for server port to be ready
    dbcont.wait_for_port(5432)

    # prepare request
    endpoint = "postgresql://user@" + dbcont.get_IPv4s()[0] + ":5432/" + 'db'
    request_command = DockerRunBuilder(command=['psql', endpoint],
                                       additional_opts=['-i'])

    # create client
    clientcont = image.run_via_binary_in_foreground(
        request_command, popen_params={"stdin": subprocess.PIPE})

    # send requests
    clientcont.write_to_stdin(b'pass\n')
    # give postgres time to process
    time.sleep(0.1)
    clientcont.write_to_stdin(b'SELECT 1;\n')
    # give postgres time to process
    time.sleep(0.2)
    logs_bytes = clientcont.logs_in_bytes()
    expected_output = b'Password: \n ?column? \n----------\n        1\n(1 row)'
    try:
Beispiel #28
0
from conu import DockerImage, DockerContainer, DockerRunBuilder

image = DockerImage('centos/httpd-24-centos7')
image.pull()
command = DockerRunBuilder(additional_opts=["-p", "8080:8080"])
container = image.run_via_binary(command)
container.wait_for_port(port=8080, timeout=-1)

container.stop()
container.delete()
Beispiel #29
0
from conu import DockerImage, DockerRunBuilder

image = DockerImage('fedora', tag='26')
image.pull()
command = DockerRunBuilder(command=["ls"], additional_opts=["-i", "-t"])
container = image.run_via_binary(command)

container.stop()
container.delete()
Beispiel #30
0
image_tag = "27"

# we'll run our container using docker engine
backend = DockerBackend(logging_level=logging.DEBUG)
image = backend.ImageClass(image_name, tag=image_tag)

# is the image present? if not, pull it
try:
    image.get_metadata()
except Exception:
    image.pull()

# helper class to create `docker run ...` command -- we want to test the same
# experience as our users
b = DockerRunBuilder(
    # the command to run in a container
    command=["python3", "-m", "http.server", "--bind", "0.0.0.0", "%d" % port],
)
# let's run the container (in the background)
container = image.run_via_binary(run_command_instance=b)
try:
    # we need to wait for the webserver to start serving
    container.wait_for_port(port)
    # GET on /
    # this is standard `requests.Response`
    http_response = container.http_request(path="/", port=port)
    assert http_response.ok
    assert '<a href="etc/">etc/</a>' in http_response.content.decode("utf-8")
    # let's access /etc/passwd
    etc_passwd = container.http_request(path="/etc/passwd", port=port).content.decode("utf-8")
    assert 'root:x:0:0:root:/root:' in etc_passwd
    # we can also access it directly on disk and compare