Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parametric: Add tests for OTEL #884

Merged
merged 56 commits into from Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
61f1eaa
added structures for otel apps in parametric tests
dianashevchenko Jan 27, 2023
34436e8
updated protos
dianashevchenko Jan 27, 2023
4c9fdfc
reformatted
dianashevchenko Jan 27, 2023
4536a19
added more methods / method properties
dianashevchenko Jan 30, 2023
c9518dc
Merge branch 'main' into shevchenko/otel-parametric
dianashevchenko Jan 31, 2023
65a1a30
added spancontext
dianashevchenko Jan 31, 2023
f783b48
combined otel and regular tests into one entity
dianashevchenko Feb 8, 2023
b68f88b
lint
dianashevchenko Feb 8, 2023
baf524f
added test cases on top of new otel parametric structure
lievan Feb 9, 2023
6605b5a
fixes to set status, flushing, isrecording
lievan Feb 9, 2023
9def536
set IsRoot default to false for starting span
lievan Feb 9, 2023
fac4129
fix lint
lievan Feb 9, 2023
9a751e2
cleaned up
dianashevchenko Feb 9, 2023
8aa1fec
Merge pull request #857 from DataDog/shevchenko/otel-parametric
dianashevchenko Feb 9, 2023
ad6b371
Merge branch 'shared/otel-parametric' into evan.li/otel-parametric-v2
dianashevchenko Feb 9, 2023
13eae88
refactored otel set attributes to allow for single-value attributes
lievan Feb 9, 2023
a59b251
check span resource name is the same as name
lievan Feb 9, 2023
d605e6d
added starting span with attributes
lievan Feb 10, 2023
43608cb
testing for tracer start options
lievan Feb 13, 2023
2fdf41d
implemented span timestamp end option, refactored test cases
lievan Feb 13, 2023
652cfb2
refactored tests to be more granular
lievan Feb 14, 2023
609419a
remove redundancy in otel helper methods
lievan Feb 14, 2023
96471dc
add clarifying comments and additional case to set status
lievan Feb 15, 2023
62d7263
Merged main into shared/otel-parametric
dianashevchenko Feb 18, 2023
11eff8f
Added otel span methods specific tests
dianashevchenko Feb 18, 2023
66bcd24
Merged shared/otel-parametric into shevchenko/otel-span-tests
dianashevchenko Feb 20, 2023
52905fb
fixed merge conflict
dianashevchenko Feb 20, 2023
cd1d830
fixed faulty merge conflicts
dianashevchenko Feb 22, 2023
5abcbef
Merge branch 'shared/otel-parametric' into shevchenko/otel-span-tests
dianashevchenko Feb 22, 2023
e572273
fixed more span methods
dianashevchenko Feb 22, 2023
ed3ba42
changed unix to unix micro in go code
dianashevchenko Mar 7, 2023
a75f7bc
Fix lint
ajgajg1134 Mar 9, 2023
df68533
WIP trying to get tests to pass
ajgajg1134 Mar 9, 2023
edc126a
WIP2: Fixing more tests
ajgajg1134 Mar 9, 2023
0806dcb
More WIP, bump dd-trace-go in parametric apps to include otel fixes
ajgajg1134 Mar 9, 2023
4008642
WIP: calling end span explicitly
ajgajg1134 Mar 10, 2023
1db32fa
unskip final otel tests for golang, fix expectation bugs
ajgajg1134 Mar 20, 2023
de1996e
Cleanup prints
ajgajg1134 Mar 20, 2023
9622ff1
Merged main into shevchenko/otel-span-tests
dianashevchenko Mar 21, 2023
5816cb9
removed env and srv from tracer test_library instance
dianashevchenko Mar 21, 2023
7106a91
Merge branch 'main' into shevchenko/otel-span-tests
dianashevchenko Mar 21, 2023
679539a
skipped a test
dianashevchenko Mar 21, 2023
1d36ec4
skipped a test
dianashevchenko Mar 21, 2023
1e478c6
Removed startTracer references
dianashevchenko Mar 21, 2023
82434ae
resolved go.mod conflict
dianashevchenko Mar 21, 2023
576a1fb
updated go.mod
dianashevchenko Mar 21, 2023
ad87121
addressed comments
dianashevchenko Mar 23, 2023
3c127a0
unskipped a test
dianashevchenko Mar 23, 2023
5a0eecb
Merge branch 'main' into shevchenko/otel-span-tests
dianashevchenko Mar 23, 2023
c8568e5
Merge branch 'main' into shevchenko/otel-span-tests
dianashevchenko Mar 23, 2023
b7a2aec
Merge branch 'main' into shevchenko/otel-span-tests
pawelchcki Mar 27, 2023
32f8e2c
added test skips for php
dianashevchenko Mar 27, 2023
1bfff04
added test skips for ruby
dianashevchenko Mar 27, 2023
4df396e
removed todos + renamed class method
dianashevchenko Mar 28, 2023
5dfbd78
Merge branch 'main' into shevchenko/otel-span-tests
dianashevchenko Mar 28, 2023
4d5953d
fixed naming : prefixed methods with otel_
dianashevchenko Mar 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions parametric/README.md
Expand Up @@ -33,6 +33,8 @@ def test_tracer_env_environment_variable(library_env, test_library, test_agent):

### Installation

Make sure you're in the `parametric` directory before running these commands.

The following dependencies are required to run the tests locally:

- Docker
Expand Down
156 changes: 154 additions & 2 deletions parametric/_library_client.py
@@ -1,7 +1,6 @@
import contextlib
import urllib.parse
import time

import urllib.parse
from typing import Generator
from typing import List
from typing import Optional
Expand All @@ -13,6 +12,8 @@

from parametric.protos import apm_test_client_pb2 as pb
from parametric.protos import apm_test_client_pb2_grpc
from parametric.spec.otel_trace import OtelSpanContext
from parametric.spec.otel_trace import convert_to_proto


class StartSpanResponse(TypedDict):
Expand All @@ -33,9 +34,39 @@ def trace_start_span(
) -> StartSpanResponse:
raise NotImplementedError

def trace_start_otel_span(
self,
name: str,
new_root: bool,
timestamp: int,
span_kind: int,
parent_id: int,
http_headers: List[Tuple[str, str]],
attributes: dict = None,
) -> StartSpanResponse:
raise NotImplementedError

def finish_span(self, span_id: int) -> None:
raise NotImplementedError

def otel_end_span(self, span_id: int, timestamp: int) -> None:
raise NotImplementedError

def otel_set_attributes(self, span_id: int, attributes) -> None:
raise NotImplementedError

def otel_set_name(self, span_id: int, name: str) -> None:
raise NotImplementedError

def otel_set_status(self, span_id: int, code: int, description: str) -> None:
raise NotImplementedError

def otel_is_recording(self, span_id: int) -> bool:
raise NotImplementedError

def get_otel_span_context(self, span_id: int):
raise NotImplementedError

def span_set_meta(self, span_id: int, key: str, value: str) -> None:
raise NotImplementedError

Expand All @@ -54,6 +85,9 @@ def trace_flush(self) -> None:
def trace_stop(self) -> None:
raise NotImplementedError

def flush_otel(self, timeout: int) -> bool:
dianashevchenko marked this conversation as resolved.
Show resolved Hide resolved
raise NotImplementedError


class APMLibraryClientHTTP(APMLibraryClient):
def __init__(self, url: str, timeout: int):
Expand Down Expand Up @@ -147,6 +181,37 @@ def finish(self):
self._client.finish_span(self.span_id)


class _TestOtelSpan:
def __init__(self, client: APMLibraryClient, span_id: int):
self._client = client
self.span_id = span_id

def set_attributes(self, attributes):
self._client.otel_set_attributes(self.span_id, attributes)

def set_name(self, name):
self._client.otel_set_name(self.span_id, name)

def set_status(self, code, description):
self._client.otel_set_status(self.span_id, code, description)

def otel_end_span(self, timestamp: int = 0):
dianashevchenko marked this conversation as resolved.
Show resolved Hide resolved
self._client.otel_end_span(self.span_id, timestamp)

def is_recording(self) -> bool:
return self._client.otel_is_recording(self.span_id)

def span_context(self) -> OtelSpanContext:
sctx = self._client.get_otel_span_context(self.span_id)
return OtelSpanContext(
trace_id=sctx.trace_id,
span_id=sctx.span_id,
trace_flags=sctx.trace_flags,
trace_state=sctx.trace_state,
remote=sctx.remote,
)


class APMLibraryClientGRPC:
def __init__(self, url: str, timeout: int):
channel = grpc.insecure_channel(url)
Expand Down Expand Up @@ -187,10 +252,43 @@ def trace_start_span(
"trace_id": resp.trace_id,
}

def trace_start_otel_span(
self,
name: str,
new_root: bool,
timestamp: int,
span_kind: int,
parent_id: int,
http_headers: List[Tuple[str, str]],
attributes: dict = None,
):
distributed_message = pb.DistributedHTTPHeaders()
for key, value in http_headers:
distributed_message.http_headers.append(pb.HeaderTuple(key=key, value=value))

resp = self._client.OtelStartSpan(
pb.OtelStartSpanArgs(
name=name,
new_root=new_root,
timestamp=timestamp,
span_kind=span_kind,
parent_id=parent_id,
attributes=convert_to_proto(attributes),
http_headers=distributed_message,
)
)
return {
"span_id": resp.span_id,
"trace_id": resp.trace_id,
}

def trace_flush(self):
self._client.FlushSpans(pb.FlushSpansArgs())
self._client.FlushTraceStats(pb.FlushTraceStatsArgs())

def flush_otel(self, timeout: int) -> bool:
return self._client.OtelFlushSpans(pb.OtelFlushSpansArgs(seconds=timeout)).success

def trace_inject_headers(self, span_id) -> List[Tuple[str, str]]:
resp = self._client.InjectHeaders(pb.InjectHeadersArgs(span_id=span_id,))
return [(header_tuple.key, header_tuple.value) for header_tuple in resp.http_headers.http_headers]
Expand All @@ -210,6 +308,26 @@ def span_set_error(self, span_id: int, typestr: str = "", message: str = "", sta
def finish_span(self, span_id: int):
self._client.FinishSpan(pb.FinishSpanArgs(id=span_id))

def otel_end_span(self, span_id: int, timestamp: int):
self._client.OtelEndSpan(pb.OtelEndSpanArgs(id=span_id, timestamp=timestamp))

def otel_set_attributes(self, span_id: int, attributes):
self._client.OtelSetAttributes(
pb.OtelSetAttributesArgs(span_id=span_id, attributes=convert_to_proto(attributes))
)

def otel_set_name(self, span_id: int, name: str):
self._client.OtelSetName(pb.OtelSetNameArgs(span_id=span_id, name=name))

def otel_set_status(self, span_id: int, code: int, description: str):
self._client.OtelSetStatus(pb.OtelSetStatusArgs(span_id=span_id, code=code, description=description))

def otel_is_recording(self, span_id: int) -> bool:
return self._client.OtelIsRecording(pb.OtelIsRecordingArgs(span_id=span_id)).is_recording

def get_otel_span_context(self, span_id: int):
return self._client.OtelSpanContext(pb.OtelSpanContextArgs(span_id=span_id))


class APMLibrary:
def __init__(self, client: APMLibraryClient):
Expand Down Expand Up @@ -247,8 +365,42 @@ def start_span(
yield span
span.finish()

@contextlib.contextmanager
def start_otel_span(
self,
name: str,
new_root: bool = False,
timestamp: int = 0,
span_kind: int = 0,
parent_id: int = 0,
attributes: dict = None,
http_headers: Optional[List[Tuple[str, str]]] = None,
) -> Generator[_TestOtelSpan, None, None]:
resp = self._client.trace_start_otel_span(
name=name,
new_root=new_root,
timestamp=timestamp,
span_kind=span_kind,
parent_id=parent_id,
attributes=attributes,
http_headers=http_headers if http_headers is not None else [],
)
span = _TestOtelSpan(self._client, resp["span_id"])
yield span

return {
"span_id": resp["span_id"],
"trace_id": resp["trace_id"],
}

def flush(self):
self._client.trace_flush()

def flush_otel(self, timeout_sec: int) -> bool:
return self._client.flush_otel(timeout_sec)

def inject_headers(self, span_id) -> List[Tuple[str, str]]:
return self._client.trace_inject_headers(span_id)

def stop(self):
return self._client.StopTracer(pb.StopTracerArgs())