Exemplo n.º 1
0
def test_scout():
    test_status = False

    with open('/tmp/test_scout_output', 'w') as logfile:
        if not DockerImage:
            logfile.write('No $AMBASSADOR_DOCKER_IMAGE??\n')
        else:
            # Telepresence interferes with the docker network we set up, so stop it before running this test.
            # Any test that depends on telepresence should correctly run `telepresence connect` anyway.
            run_and_assert(['telepresence', 'quit'])

            # Sleep to make sure telepresence exited gracefully etc...
            time.sleep(10)

            if docker_start(logfile):
                if wait_for_diagd(logfile) and check_chimes(logfile):
                    test_status = True

                docker_kill(logfile)

    if not test_status:
        with open('/tmp/test_scout_output', 'r') as logfile:
            for line in logfile:
                print(line.rstrip())

    assert test_status, 'test failed'
Exemplo n.º 2
0
    def test_rapid_additions_and_deletions(self):
        namespace = 'watt-rapid'

        # Make sure telepresence is connected. Do this early on in the test to give the TP daemon plenty of
        # time to do its thing while we wait for other k8 resources to reconcile.
        run_with_retry(['telepresence', 'connect'])

        # Install Ambassador
        install_ambassador(namespace=namespace)

        # Install QOTM
        apply_kube_artifacts(namespace=namespace, artifacts=qotm_manifests)

        # Install QOTM Ambassador manifests
        self.apply_qotm_endpoint_manifests(namespace=namespace)

        # Now let's wait for ambassador and QOTM pods to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=ambassador', '-n', namespace
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=qotm', '-n', namespace
        ])

        # Assume we can reach Ambassador through telepresence
        qotm_host = "ambassador." + namespace
        qotm_url = f"http://{qotm_host}/qotm/"

        # Assert 200 OK at /qotm/ endpoint
        qotm_ready = False

        loop_limit = 60
        while not qotm_ready:
            assert loop_limit > 0, "QOTM is not ready yet, aborting..."
            try:
                qotm_http_code = get_code_with_retry(qotm_url)
                assert qotm_http_code == 200, f"Expected 200 OK, got {qotm_http_code}"
                print(f"{qotm_url} is ready")
                qotm_ready = True

            except Exception as e:
                print(f"Error: {e}")
                print(f"{qotm_url} not ready yet, trying again...")
                time.sleep(1)
                loop_limit -= 1

        # Try to mess up Ambassador by applying and deleting QOTM mapping over and over
        for i in range(10):
            self.delete_qotm_mapping(namespace=namespace)
            self.create_qotm_mapping(namespace=namespace)

        # Let's give Ambassador a few seconds to register the changes...
        time.sleep(5)

        # Assert 200 OK at /qotm/ endpoint
        qotm_http_code = get_code_with_retry(qotm_url)
        assert qotm_http_code == 200, f"Expected 200 OK, got {qotm_http_code}"
Exemplo n.º 3
0
    def test_rapid_additions_and_deletions(self):
        namespace = 'watt-rapid'

        # Install Ambassador
        install_ambassador(namespace=namespace)

        # Install QOTM
        apply_kube_artifacts(namespace=namespace, artifacts=qotm_manifests)

        # Install QOTM Ambassador manifests
        self.apply_qotm_endpoint_manifests(namespace=namespace)

        # Now let's wait for ambassador and QOTM pods to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=ambassador', '-n', namespace
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=qotm', '-n', namespace
        ])

        # Let's port-forward ambassador service to talk to QOTM
        port_forward_port = 6000
        port_forward_command = [
            'kubectl', 'port-forward', '--namespace', namespace,
            'service/ambassador', f'{port_forward_port}:80'
        ]
        run_and_assert(port_forward_command, communicate=False)
        qotm_url = f'http://localhost:{port_forward_port}/qotm/'

        # Assert 200 OK at /qotm/ endpoint
        qotm_ready = False

        loop_limit = 60
        while not qotm_ready:
            assert loop_limit > 0, "QOTM is not ready yet, aborting..."
            try:
                qotm_http_code = get_code_with_retry(qotm_url)
                assert qotm_http_code == 200, f"Expected 200 OK, got {qotm_http_code}"
                print(f"{qotm_url} is ready")
                qotm_ready = True

            except Exception as e:
                print(f"Error: {e}")
                print(f"{qotm_url} not ready yet, trying again...")
                time.sleep(1)
                loop_limit -= 1

        # Try to mess up Ambassador by applying and deleting QOTM mapping over and over
        for i in range(10):
            self.delete_qotm_mapping(namespace=namespace)
            self.create_qotm_mapping(namespace=namespace)

        # Let's give Ambassador a few seconds to register the changes...
        time.sleep(5)

        # Assert 200 OK at /qotm/ endpoint
        qotm_http_code = get_code_with_retry(qotm_url)
        assert qotm_http_code == 200, f"Expected 200 OK, got {qotm_http_code}"
Exemplo n.º 4
0
    def test_header_case_overrides(self):
        # Is there any reason not to use the default namespace?
        namespace = 'header-case-overrides'

        # Install Ambassador
        install_ambassador(namespace=namespace)

        # Install httpbin
        apply_kube_artifacts(namespace=namespace, artifacts=httpbin_manifests)

        # Install headerecho
        apply_kube_artifacts(namespace=namespace, artifacts=headerecho_manifests)

        # Install module
        self.create_module(namespace)

        # Install httpbin mapping
        create_httpbin_mapping(namespace=namespace)

        # Install headerecho mapping
        create_headerecho_mapping(namespace=namespace)

        # Now let's wait for ambassador and httpbin pods to become ready
        run_and_assert(['kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod', '-l', 'service=ambassador', '-n', namespace])
        run_and_assert(['kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod', '-l', 'service=httpbin', '-n', namespace])

        # Let's port-forward ambassador service to talk to Ambassador.
        # IMPORTANT: We _must_ choose a unique port_forward_port so long as test_watt.py,
        # test_knative.py, and others like it, run in the same environment as this test.
        # Otherwise we get port collisions and it's madness.
        port_forward_port = 6123
        port_forward_command = ['kubectl', 'port-forward', '--namespace', namespace, 'service/ambassador', f'{port_forward_port}:80']
        run_and_assert(port_forward_command, communicate=False)

        print("Waiting 5 seconds, just because...")
        time.sleep(2)

        # Assert 200 OK at httpbin/status/200 endpoint
        ready = False
        httpbin_url = f'http://localhost:{port_forward_port}/httpbin/status/200'
        headerecho_url = f'http://localhost:{port_forward_port}/headerecho/'

        loop_limit = 10
        while not ready:
            assert loop_limit > 0, "httpbin is not ready yet, aborting..."
            try:
                print(f"trying {httpbin_url}...")
                resp = requests.get(httpbin_url, timeout=5)
                code = resp.status_code
                assert code == 200, f"Expected 200 OK, got {code}"
                resp.close()
                print(f"{httpbin_url} is ready")

                print(f"trying {headerecho_url}...")
                resp = requests.get(headerecho_url, timeout=5)
                code = resp.status_code
                assert code == 200, f"Expected 200 OK, got {code}"
                resp.close()
                print(f"{headerecho_url} is ready")

                ready = True

            except Exception as e:
                print(f"Error: {e}")
                print(f"{httpbin_url} not ready yet, trying again...")
                time.sleep(1)
                loop_limit -= 1

        assert ready

        httpbin_url = f'http://localhost:{port_forward_port}/httpbin/response-headers?x-Hello=1&X-foo-Bar=1&x-Lowercase1=1&x-lowercase2=1'
        resp = requests.get(httpbin_url, timeout=5)
        code = resp.status_code
        assert code == 200, f"Expected 200 OK, got {code}"

        # First, test that the response headers have the correct case.

        # Very important: this test relies on matching case sensitive header keys.
        # Fortunately it appears that we can convert resp.headers, a case insensitive
        # dictionary, into a list of case sensitive keys.
        keys = [ h for h in resp.headers.keys() ]
        for k in keys:
            print(f"header key: {k}")

        assert 'x-hello' not in keys
        assert 'X-HELLO' in keys
        assert 'x-foo-bar' not in keys
        assert 'X-FOO-Bar' in keys
        assert 'x-lowercase1' in keys
        assert 'x-Lowercase1' not in keys
        assert 'x-lowercase2' in keys
        resp.close()

        # Second, test that the request headers sent to the headerecho server
        # have the correct case.

        headers = {
            'x-Hello': '1',
            'X-foo-Bar': '1',
            'x-Lowercase1': '1',
            'x-lowercase2': '1'
        }
        resp = requests.get(headerecho_url, headers=headers, timeout=5)
        code = resp.status_code
        assert code == 200, f"Expected 200 OK, got {code}"

        response_obj = json.loads(resp.text)
        print(f"response_obj = {response_obj}")
        assert response_obj
        assert 'headers' in response_obj

        hdrs = response_obj['headers']
        assert 'x-hello' not in hdrs
        assert 'X-HELLO' in hdrs
        assert 'x-foo-bar' not in hdrs
        assert 'X-FOO-Bar' in hdrs
        assert 'x-lowercase1' in hdrs
        assert 'x-Lowercase1' not in hdrs
        assert 'x-lowercase2' in hdrs
Exemplo n.º 5
0
    def test_knative(self):
        namespace = 'knative-testing'

        # Install Knative
        apply_kube_artifacts(namespace=None,
                             artifacts=load_manifest("knative_serving_crds"))
        apply_kube_artifacts(namespace='knative-serving',
                             artifacts=load_manifest("knative_serving_0.18.0"))
        run_and_assert([
            'kubectl', 'patch', 'configmap/config-network', '--type', 'merge',
            '--patch',
            r'{"data": {"ingress.class": "ambassador.ingress.networking.knative.dev"}}',
            '-n', 'knative-serving'
        ])

        # Wait for Knative to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=activator', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=controller', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=webhook', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=autoscaler', '-n', 'knative-serving'
        ])

        # Install Ambassador
        install_ambassador(namespace=namespace,
                           envs=[{
                               'name': 'AMBASSADOR_KNATIVE_SUPPORT',
                               'value': 'true'
                           }])

        # Install QOTM
        apply_kube_artifacts(namespace=namespace, artifacts=qotm_manifests)
        create_qotm_mapping(namespace=namespace)

        # Now let's wait for ambassador and QOTM pods to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=ambassador', '-n', namespace
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=qotm', '-n', namespace
        ])

        # Create kservice
        apply_kube_artifacts(namespace=namespace,
                             artifacts=knative_service_example)

        # Let's port-forward ambassador service to talk to QOTM
        port_forward_port = 7000
        port_forward_command = [
            'kubectl', 'port-forward', '--namespace', namespace,
            'service/ambassador', f'{port_forward_port}:80'
        ]
        run_and_assert(port_forward_command, communicate=False)

        # Assert 200 OK at /qotm/ endpoint
        qotm_url = f'http://localhost:{port_forward_port}/qotm/'
        code = get_code_with_retry(qotm_url)
        assert code == 200, f"Expected 200 OK, got {code}"
        print(f"{qotm_url} is ready")

        # Assert 200 OK at / with Knative Host header and 404 with other/no header
        kservice_url = f'http://localhost:{port_forward_port}/'

        code = get_code_with_retry(kservice_url)
        assert code == 404, f"Expected 404, got {code}"
        print(f"{kservice_url} returns 404 with no host")

        code = get_code_with_retry(kservice_url,
                                   headers={'Host': 'random.host.whatever'})
        assert code == 404, f"Expected 404, got {code}"
        print(f"{kservice_url} returns 404 with a random host")

        # Wait for kservice
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready',
            'ksvc', 'helloworld-go', '-n', namespace
        ])

        # kservice pod takes some time to spin up, so let's try a few times
        code = 000
        host = f'helloworld-go.{namespace}.example.com'
        for _ in range(5):
            code = get_code_with_retry(kservice_url, headers={'Host': host})
            if code == 200:
                break

        assert code == 200, f"Expected 200, got {code}"
        print(
            f"{kservice_url} returns 200 OK with host helloworld-go.{namespace}.example.com"
        )
    def test_knative(self):
        namespace = 'knative-testing'

        # Make sure telepresence is connected. Do this early on in the test to give the TP daemon plenty of
        # time to do its thing while we wait for other k8 resources to reconcile.
        run_with_retry(['telepresence', 'connect'])

        # Install Knative
        apply_kube_artifacts(namespace=None,
                             artifacts=load_manifest("knative_serving_crds"))
        apply_kube_artifacts(namespace='knative-serving',
                             artifacts=load_manifest("knative_serving_0.18.0"))
        run_and_assert([
            'kubectl', 'patch', 'configmap/config-network', '--type', 'merge',
            '--patch',
            r'{"data": {"ingress.class": "ambassador.ingress.networking.knative.dev"}}',
            '-n', 'knative-serving'
        ])

        # Wait for Knative to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=activator', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=controller', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=webhook', '-n', 'knative-serving'
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'app=autoscaler', '-n', 'knative-serving'
        ])

        # Install Ambassador
        install_ambassador(namespace=namespace,
                           envs=[{
                               'name': 'AMBASSADOR_KNATIVE_SUPPORT',
                               'value': 'true'
                           }])

        # Install QOTM
        apply_kube_artifacts(namespace=namespace, artifacts=qotm_manifests)
        create_qotm_mapping(namespace=namespace)

        # Now let's wait for ambassador and QOTM pods to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=ambassador', '-n', namespace
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=qotm', '-n', namespace
        ])

        # Create kservice
        apply_kube_artifacts(namespace=namespace,
                             artifacts=knative_service_example)

        # Assume we can reach Ambassador through telepresence
        qotm_host = "ambassador." + namespace

        # Assert 200 OK at /qotm/ endpoint
        qotm_url = f'http://{qotm_host}/qotm/'
        code = get_code_with_retry(qotm_url)
        assert code == 200, f"Expected 200 OK, got {code}"
        print(f"{qotm_url} is ready")

        # Assert 200 OK at / with Knative Host header and 404 with other/no header
        kservice_url = f'http://{qotm_host}/'

        code = get_code_with_retry(kservice_url)
        assert code == 404, f"Expected 404, got {code}"
        print(f"{kservice_url} returns 404 with no host")

        code = get_code_with_retry(kservice_url,
                                   headers={'Host': 'random.host.whatever'})
        assert code == 404, f"Expected 404, got {code}"
        print(f"{kservice_url} returns 404 with a random host")

        # Wait for kservice
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready',
            'ksvc', 'helloworld-go', '-n', namespace
        ])

        # kservice pod takes some time to spin up, so let's try a few times
        code = 000
        host = f'helloworld-go.{namespace}.example.com'
        for _ in range(5):
            code = get_code_with_retry(kservice_url, headers={'Host': host})
            if code == 200:
                break

        assert code == 200, f"Expected 200, got {code}"
        print(
            f"{kservice_url} returns 200 OK with host helloworld-go.{namespace}.example.com"
        )
    def test_header_case_overrides(self):
        # Is there any reason not to use the default namespace?
        namespace = 'header-case-overrides'

        # Make sure telepresence is connected. Do this early on in the test to give the TP daemon plenty of
        # time to do its thing while we wait for other k8 resources to reconcile.
        run_with_retry(['telepresence', 'connect'])

        # Install Ambassador
        install_ambassador(namespace=namespace)

        # Install httpbin
        apply_kube_artifacts(namespace=namespace, artifacts=httpbin_manifests)

        # Install headerecho
        apply_kube_artifacts(namespace=namespace,
                             artifacts=headerecho_manifests)

        # Install module
        self.create_module(namespace)

        # Install httpbin mapping
        create_httpbin_mapping(namespace=namespace)

        # Install headerecho mapping
        create_headerecho_mapping(namespace=namespace)

        # Now let's wait for ambassador and httpbin pods to become ready
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=ambassador', '-n', namespace
        ])
        run_and_assert([
            'kubectl', 'wait', '--timeout=90s', '--for=condition=Ready', 'pod',
            '-l', 'service=httpbin', '-n', namespace
        ])

        # Assume we can reach Ambassador through telepresence
        ambassador_host = "ambassador." + namespace

        # Assert 200 OK at httpbin/status/200 endpoint
        ready = False
        httpbin_url = f'http://{ambassador_host}/httpbin/status/200'
        headerecho_url = f'http://{ambassador_host}/headerecho/'

        loop_limit = 10
        while not ready:
            assert loop_limit > 0, "httpbin is not ready yet, aborting..."
            try:
                print(f"trying {httpbin_url}...")
                resp = requests.get(httpbin_url, timeout=5)
                code = resp.status_code
                assert code == 200, f"Expected 200 OK, got {code}"
                resp.close()
                print(f"{httpbin_url} is ready")

                print(f"trying {headerecho_url}...")
                resp = requests.get(headerecho_url, timeout=5)
                code = resp.status_code
                assert code == 200, f"Expected 200 OK, got {code}"
                resp.close()
                print(f"{headerecho_url} is ready")

                ready = True

            except Exception as e:
                print(f"Error: {e}")
                print(f"{httpbin_url} not ready yet, trying again...")
                time.sleep(1)
                loop_limit -= 1

        assert ready

        httpbin_url = f'http://{ambassador_host}/httpbin/response-headers?x-Hello=1&X-foo-Bar=1&x-Lowercase1=1&x-lowercase2=1'
        resp = requests.get(httpbin_url, timeout=5)
        code = resp.status_code
        assert code == 200, f"Expected 200 OK, got {code}"

        # First, test that the response headers have the correct case.

        # Very important: this test relies on matching case sensitive header keys.
        # Fortunately it appears that we can convert resp.headers, a case insensitive
        # dictionary, into a list of case sensitive keys.
        keys = [h for h in resp.headers.keys()]
        for k in keys:
            print(f"header key: {k}")

        assert 'x-hello' not in keys
        assert 'X-HELLO' in keys
        assert 'x-foo-bar' not in keys
        assert 'X-FOO-Bar' in keys
        assert 'x-lowercase1' in keys
        assert 'x-Lowercase1' not in keys
        assert 'x-lowercase2' in keys
        resp.close()

        # Second, test that the request headers sent to the headerecho server
        # have the correct case.

        headers = {
            'x-Hello': '1',
            'X-foo-Bar': '1',
            'x-Lowercase1': '1',
            'x-lowercase2': '1'
        }
        resp = requests.get(headerecho_url, headers=headers, timeout=5)
        code = resp.status_code
        assert code == 200, f"Expected 200 OK, got {code}"

        response_obj = json.loads(resp.text)
        print(f"response_obj = {response_obj}")
        assert response_obj
        assert 'headers' in response_obj

        hdrs = response_obj['headers']
        assert 'x-hello' not in hdrs
        assert 'X-HELLO' in hdrs
        assert 'x-foo-bar' not in hdrs
        assert 'X-FOO-Bar' in hdrs
        assert 'x-lowercase1' in hdrs
        assert 'x-Lowercase1' not in hdrs
        assert 'x-lowercase2' in hdrs