...

Text file src/github.com/datawire/ambassador/v2/python/tests/unit/test_tracing.py

Documentation: github.com/datawire/ambassador/v2/python/tests/unit

     1import logging
     2from typing import TYPE_CHECKING, Optional
     3
     4import pytest
     5
     6from tests.selfsigned import TLSCerts
     7from tests.utils import (
     8    assert_valid_envoy_config,
     9    econf_foreach_cluster,
    10    module_and_mapping_manifests,
    11)
    12
    13logging.basicConfig(
    14    level=logging.INFO,
    15    format="%(asctime)s test %(levelname)s: %(message)s",
    16    datefmt="%Y-%m-%d %H:%M:%S",
    17)
    18
    19logger = logging.getLogger("ambassador")
    20
    21from ambassador import IR, Config
    22from ambassador.envoy import 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, version="V2"):
    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, version)
    59
    60
    61def lightstep_tracing_service_manifest():
    62    return """
    63---
    64apiVersion: getambassador.io/v3alpha1
    65kind: TracingService
    66metadata:
    67  name: tracing
    68  namespace: ambassador
    69spec:
    70  service: lightstep:80
    71  driver: lightstep
    72  config:
    73    access_token_file: /lightstep-credentials/access-token
    74    propagation_modes: ["ENVOY", "TRACE_CONTEXT"]
    75"""
    76
    77
    78@pytest.mark.compilertest
    79def test_tracing_config_v3():
    80    aconf = Config()
    81
    82    yaml = module_and_mapping_manifests(None, []) + "\n" + lightstep_tracing_service_manifest()
    83    fetcher = ResourceFetcher(logger, aconf)
    84    fetcher.parse_yaml(yaml, k8s=True)
    85
    86    aconf.load_all(fetcher.sorted())
    87
    88    secret_handler = MockSecretHandler(logger, "mockery", "/tmp/ambassador/snapshots", "v1")
    89    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
    90
    91    assert ir
    92
    93    econf = EnvoyConfig.generate(ir, "V3")
    94
    95    bootstrap_config, ads_config, _ = econf.split_config()
    96    assert "tracing" in bootstrap_config
    97    assert bootstrap_config["tracing"] == {
    98        "http": {
    99            "name": "envoy.lightstep",
   100            "typed_config": {
   101                "@type": "type.googleapis.com/envoy.config.trace.v3.LightstepConfig",
   102                "access_token_file": "/lightstep-credentials/access-token",
   103                "collector_cluster": "cluster_tracing_lightstep_80_ambassador",
   104                "propagation_modes": ["ENVOY", "TRACE_CONTEXT"],
   105            },
   106        }
   107    }
   108
   109    ads_config.pop("@type", None)
   110    assert_valid_envoy_config(ads_config)
   111    assert_valid_envoy_config(bootstrap_config)
   112
   113
   114@pytest.mark.compilertest
   115def test_tracing_config_v2():
   116    aconf = Config()
   117
   118    yaml = module_and_mapping_manifests(None, []) + "\n" + lightstep_tracing_service_manifest()
   119    fetcher = ResourceFetcher(logger, aconf)
   120    fetcher.parse_yaml(yaml, k8s=True)
   121
   122    aconf.load_all(fetcher.sorted())
   123
   124    secret_handler = MockSecretHandler(logger, "mockery", "/tmp/ambassador/snapshots", "v1")
   125    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
   126
   127    assert ir
   128
   129    econf = EnvoyConfig.generate(ir, "V2")
   130
   131    bootstrap_config, ads_config, _ = econf.split_config()
   132    assert "tracing" in bootstrap_config
   133    assert bootstrap_config["tracing"] == {
   134        "http": {
   135            "name": "envoy.lightstep",
   136            "typed_config": {
   137                "@type": "type.googleapis.com/envoy.config.trace.v2.LightstepConfig",
   138                "access_token_file": "/lightstep-credentials/access-token",
   139                "collector_cluster": "cluster_tracing_lightstep_80_ambassador",
   140                "propagation_modes": ["ENVOY", "TRACE_CONTEXT"],
   141            },
   142        }
   143    }
   144
   145    ads_config.pop("@type", None)
   146    assert_valid_envoy_config(ads_config, v2=True)
   147    assert_valid_envoy_config(bootstrap_config, v2=True)
   148
   149
   150@pytest.mark.compilertest
   151def test_tracing_zipkin_defaults_v3_config():
   152
   153    yaml = """
   154---
   155apiVersion: getambassador.io/v3alpha1
   156kind: TracingService
   157metadata:
   158    name: myts
   159    namespace: default
   160spec:
   161    service: zipkin-test:9411
   162    driver: zipkin
   163"""
   164
   165    econf = _get_envoy_config(yaml, version="V3")
   166
   167    bootstrap_config, _, _ = econf.split_config()
   168    assert "tracing" in bootstrap_config
   169
   170    assert bootstrap_config["tracing"] == {
   171        "http": {
   172            "name": "envoy.zipkin",
   173            "typed_config": {
   174                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
   175                "collector_endpoint": "/api/v2/spans",
   176                "collector_endpoint_version": "HTTP_JSON",
   177                "trace_id_128bit": True,
   178                "collector_cluster": "cluster_tracing_zipkin_test_9411_default",
   179            },
   180        }
   181    }
   182
   183
   184def test_tracing_zipkin_defaults_v2_config():
   185
   186    yaml = """
   187---
   188apiVersion: getambassador.io/v3alpha1
   189kind: TracingService
   190metadata:
   191    name: myts
   192    namespace: default
   193spec:
   194    service: zipkin-test:9411
   195    driver: zipkin
   196"""
   197
   198    econf = _get_envoy_config(yaml, version="V2")
   199
   200    bootstrap_config, _, _ = econf.split_config()
   201    assert "tracing" in bootstrap_config
   202
   203    assert bootstrap_config["tracing"] == {
   204        "http": {
   205            "name": "envoy.zipkin",
   206            "typed_config": {
   207                "@type": "type.googleapis.com/envoy.config.trace.v2.ZipkinConfig",
   208                "collector_endpoint": "/api/v2/spans",
   209                "collector_endpoint_version": "HTTP_JSON",
   210                "trace_id_128bit": True,
   211                "collector_cluster": "cluster_tracing_zipkin_test_9411_default",
   212            },
   213        }
   214    }
   215
   216
   217@pytest.mark.compilertest
   218def test_tracing_cluster_fields_v2_config():
   219
   220    yaml = """
   221---
   222apiVersion: getambassador.io/v3alpha1
   223kind: TracingService
   224metadata:
   225    name: myts
   226    namespace: default
   227spec:
   228    service: zipkin-test:9411
   229    driver: zipkin
   230    stats_name: tracingservice
   231"""
   232
   233    econf = _get_envoy_config(yaml, version="V2")
   234
   235    bootstrap_config, _, _ = econf.split_config()
   236    assert "tracing" in bootstrap_config
   237
   238    cluster_name = "cluster_tracing_zipkin_test_9411_default"
   239    assert bootstrap_config["tracing"] == {
   240        "http": {
   241            "name": "envoy.zipkin",
   242            "typed_config": {
   243                "@type": "type.googleapis.com/envoy.config.trace.v2.ZipkinConfig",
   244                "collector_endpoint": "/api/v2/spans",
   245                "collector_endpoint_version": "HTTP_JSON",
   246                "trace_id_128bit": True,
   247                "collector_cluster": cluster_name,
   248            },
   249        }
   250    }
   251
   252    def check_fields(cluster):
   253        assert cluster["alt_stat_name"] == "tracingservice"
   254
   255    econf_foreach_cluster(econf.as_dict(), check_fields, name=cluster_name)
   256
   257
   258@pytest.mark.compilertest
   259def test_tracing_cluster_fields_v3_config():
   260
   261    yaml = """
   262---
   263apiVersion: getambassador.io/v3alpha1
   264kind: TracingService
   265metadata:
   266    name: myts
   267    namespace: default
   268spec:
   269    service: zipkin-test:9411
   270    driver: zipkin
   271    stats_name: tracingservice
   272"""
   273
   274    econf = _get_envoy_config(yaml, version="V3")
   275
   276    bootstrap_config, _, _ = econf.split_config()
   277    assert "tracing" in bootstrap_config
   278
   279    cluster_name = "cluster_tracing_zipkin_test_9411_default"
   280    assert bootstrap_config["tracing"] == {
   281        "http": {
   282            "name": "envoy.zipkin",
   283            "typed_config": {
   284                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
   285                "collector_endpoint": "/api/v2/spans",
   286                "collector_endpoint_version": "HTTP_JSON",
   287                "trace_id_128bit": True,
   288                "collector_cluster": cluster_name,
   289            },
   290        }
   291    }
   292
   293    def check_fields(cluster):
   294        assert cluster["alt_stat_name"] == "tracingservice"
   295
   296    econf_foreach_cluster(econf.as_dict(), check_fields, name=cluster_name)

View as plain text