...

Text file src/github.com/emissary-ingress/emissary/v3/python/tests/unit/test_tracing.py

Documentation: github.com/emissary-ingress/emissary/v3/python/tests/unit

     1import logging
     2from pathlib import Path
     3from typing import TYPE_CHECKING, Optional
     4
     5import pytest
     6
     7from tests.selfsigned import TLSCerts
     8from tests.utils import (
     9    assert_valid_envoy_config,
    10    econf_foreach_cluster,
    11    module_and_mapping_manifests,
    12)
    13
    14logging.basicConfig(
    15    level=logging.INFO,
    16    format="%(asctime)s test %(levelname)s: %(message)s",
    17    datefmt="%Y-%m-%d %H:%M:%S",
    18)
    19
    20logger = logging.getLogger("ambassador")
    21
    22from ambassador import IR, Config, EnvoyConfig
    23from ambassador.fetch import ResourceFetcher
    24from ambassador.utils import NullSecretHandler, SecretHandler, SecretInfo
    25from tests.utils import default_listener_manifests
    26
    27if TYPE_CHECKING:
    28    from ambassador.ir.irresource import IRResource  # pragma: no cover
    29
    30
    31class MockSecretHandler(SecretHandler):
    32    def load_secret(
    33        self, resource: "IRResource", secret_name: str, namespace: str
    34    ) -> Optional[SecretInfo]:
    35        return SecretInfo(
    36            "fallback-self-signed-cert",
    37            "ambassador",
    38            "mocked-fallback-secret",
    39            TLSCerts["acook"].pubcert,
    40            TLSCerts["acook"].privkey,
    41            decode_b64=False,
    42        )
    43
    44
    45def _get_envoy_config(yaml):
    46
    47    aconf = Config()
    48    fetcher = ResourceFetcher(logger, aconf)
    49    fetcher.parse_yaml(default_listener_manifests() + yaml, k8s=True)
    50
    51    aconf.load_all(fetcher.sorted())
    52
    53    secret_handler = NullSecretHandler(logger, None, None, "0")
    54
    55    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
    56
    57    assert ir
    58    return EnvoyConfig.generate(ir)
    59
    60
    61@pytest.mark.compilertest
    62def test_tracing_config_v3(tmp_path: Path):
    63
    64    aconf = Config()
    65
    66    yaml = (
    67        module_and_mapping_manifests(None, [])
    68        + "\n"
    69        + """
    70---
    71apiVersion: getambassador.io/v3alpha1
    72kind: TracingService
    73metadata:
    74    name: myts
    75    namespace: default
    76spec:
    77    service: zipkin-test:9411
    78    driver: zipkin
    79    custom_tags:
    80    - tag: ltag
    81      literal:
    82        value: avalue
    83    - tag: etag
    84      environment:
    85        name: UNKNOWN_ENV_VAR
    86        default_value: efallback
    87    - tag: htag
    88      request_header:
    89        name: x-does-not-exist
    90        default_value: hfallback
    91"""
    92    )
    93
    94    fetcher = ResourceFetcher(logger, aconf)
    95    fetcher.parse_yaml(yaml, k8s=True)
    96
    97    aconf.load_all(fetcher.sorted())
    98
    99    secret_handler = MockSecretHandler(
   100        logger, "mockery", str(tmp_path / "ambassador" / "snapshots"), "v1"
   101    )
   102    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
   103
   104    assert ir
   105
   106    econf = EnvoyConfig.generate(ir)
   107
   108    # check if custom_tags are added
   109    assert econf.as_dict()["static_resources"]["listeners"][0]["filter_chains"][0]["filters"][0][
   110        "typed_config"
   111    ]["tracing"] == {
   112        "custom_tags": [
   113            {"literal": {"value": "avalue"}, "tag": "ltag"},
   114            {
   115                "environment": {"default_value": "efallback", "name": "UNKNOWN_ENV_VAR"},
   116                "tag": "etag",
   117            },
   118            {
   119                "request_header": {"default_value": "hfallback", "name": "x-does-not-exist"},
   120                "tag": "htag",
   121            },
   122        ]
   123    }
   124
   125    bootstrap_config, ads_config, _ = econf.split_config()
   126    assert "tracing" in bootstrap_config
   127    assert bootstrap_config["tracing"] == {
   128        "http": {
   129            "name": "envoy.zipkin",
   130            "typed_config": {
   131                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
   132                "collector_endpoint": "/api/v2/spans",
   133                "collector_endpoint_version": "HTTP_JSON",
   134                "trace_id_128bit": True,
   135                "collector_cluster": "cluster_tracing_zipkin_test_9411_default",
   136            },
   137        }
   138    }
   139
   140    ads_config.pop("@type", None)
   141    assert_valid_envoy_config(ads_config, extra_dirs=[str(tmp_path / "ambassador" / "snapshots")])
   142    assert_valid_envoy_config(
   143        bootstrap_config, extra_dirs=[str(tmp_path / "ambassador" / "snapshots")]
   144    )
   145
   146
   147@pytest.mark.compilertest
   148def test_tracing_zipkin_defaults():
   149
   150    yaml = """
   151---
   152apiVersion: getambassador.io/v3alpha1
   153kind: TracingService
   154metadata:
   155    name: myts
   156    namespace: default
   157spec:
   158    service: zipkin-test:9411
   159    driver: zipkin
   160"""
   161
   162    econf = _get_envoy_config(yaml)
   163
   164    bootstrap_config, _, _ = econf.split_config()
   165    assert "tracing" in bootstrap_config
   166
   167    assert bootstrap_config["tracing"] == {
   168        "http": {
   169            "name": "envoy.zipkin",
   170            "typed_config": {
   171                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
   172                "collector_endpoint": "/api/v2/spans",
   173                "collector_endpoint_version": "HTTP_JSON",
   174                "trace_id_128bit": True,
   175                "collector_cluster": "cluster_tracing_zipkin_test_9411_default",
   176            },
   177        }
   178    }
   179
   180
   181@pytest.mark.compilertest
   182def test_tracing_cluster_fields():
   183
   184    yaml = """
   185---
   186apiVersion: getambassador.io/v3alpha1
   187kind: TracingService
   188metadata:
   189    name: myts
   190    namespace: default
   191spec:
   192    service: zipkin-test:9411
   193    driver: zipkin
   194    stats_name: tracingservice
   195"""
   196
   197    econf = _get_envoy_config(yaml)
   198
   199    bootstrap_config, _, _ = econf.split_config()
   200    assert "tracing" in bootstrap_config
   201
   202    cluster_name = "cluster_tracing_zipkin_test_9411_default"
   203    assert bootstrap_config["tracing"] == {
   204        "http": {
   205            "name": "envoy.zipkin",
   206            "typed_config": {
   207                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
   208                "collector_endpoint": "/api/v2/spans",
   209                "collector_endpoint_version": "HTTP_JSON",
   210                "trace_id_128bit": True,
   211                "collector_cluster": cluster_name,
   212            },
   213        }
   214    }
   215
   216    def check_fields(cluster):
   217        assert cluster["alt_stat_name"] == "tracingservice"
   218
   219    econf_foreach_cluster(econf.as_dict(), check_fields, name=cluster_name)
   220
   221
   222@pytest.mark.compilertest
   223def test_tracing_zipkin_invalid_collector_version():
   224    """test to ensure that providing an improper value will result in an error and the tracer not included"""
   225
   226    yaml = """
   227---
   228apiVersion: getambassador.io/v3alpha1
   229kind: TracingService
   230metadata:
   231    name: myts
   232    namespace: default
   233spec:
   234    service: zipkin-test:9411
   235    driver: zipkin
   236    config:
   237        collector_endpoint_version: "HTTP_JSON_V1"
   238"""
   239
   240    econf = _get_envoy_config(yaml)
   241
   242    bootstrap_config, _, _ = econf.split_config()
   243    assert "tracing" not in bootstrap_config
   244
   245
   246@pytest.mark.compilertest
   247def test_lightstep_not_supported(tmp_path: Path):
   248
   249    yaml = """
   250---
   251apiVersion: getambassador.io/v3alpha1
   252kind: TracingService
   253metadata:
   254  name: tracing
   255  namespace: ambassador
   256spec:
   257  service: lightstep:80
   258  driver: lightstep
   259  custom_tags:
   260  - tag: ltag
   261    literal:
   262      value: avalue
   263  - tag: etag
   264    environment:
   265      name: UNKNOWN_ENV_VAR
   266      default_value: efallback
   267  - tag: htag
   268    request_header:
   269      name: x-does-not-exist
   270      default_value: hfallback
   271  config:
   272    access_token_file: /lightstep-credentials/access-token
   273    propagation_modes: ["ENVOY", "TRACE_CONTEXT"]
   274"""
   275    econf = _get_envoy_config(yaml)
   276    assert "ir.tracing" in econf.ir.aconf.errors
   277
   278    tracing_error = econf.ir.aconf.errors["ir.tracing"][0]["error"]
   279    assert "'lightstep' driver is no longer supported" in tracing_error
   280
   281    bootstrap_config, _, _ = econf.split_config()
   282    assert "tracing" not in bootstrap_config

View as plain text