Skip to content

Commit e1120d6

Browse files
committed
test: write tests for stat exporter and span reporter
1 parent 982db73 commit e1120d6

File tree

6 files changed

+167
-20
lines changed

6 files changed

+167
-20
lines changed

config/dev.conf

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
[
2-
{opencensus, [
3-
{reporter, {oc_reporter_datadog, []}},
4-
{stat, [
5-
{exporters, [{oc_stat_exporter_datadog, []}]}
6-
]}
7-
]}
2+
{opencensus,
3+
[{reporter, {oc_reporter_datadog, []}},
4+
{stat, [{exporters, [{oc_stat_exporter_datadog, []}]}]}]}
85
].

rebar.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77

88
{shell, [{config, "config/dev.conf"}]}.
99

10+
{eunit_opts, [{report, {eunit_surefire, [{dir, "."}]}}]}.
11+
{ct_opts, [{ct_hooks, [{cth_surefire, [{path, "./report.xml"}]}]}]}.
12+
1013
% vi: ft=erlang syn=erlang

src/oc_reporter_datadog.erl

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,20 @@ init(Options) ->
3232
Port = proplists:get_value(port, Options, ?DEFAULT_PORT),
3333
Service = proplists:get_value(service, Options, ?DEFAULT_SERVICE),
3434
Type = proplists:get_value(type, Options, ?DEFAULT_TYPE),
35-
#{host => Host, port => Port, service => Service, type => Type}.
35+
Client = proplists:get_value(http_client, Options, fun default_client/3),
36+
#{host => Host,
37+
port => Port,
38+
service => Service,
39+
type => Type,
40+
client => Client}.
3641

3742
-spec report(nonempty_list(opencensus:span()), oc_reporter:opts()) -> ok.
3843
report(Spans, #{
3944
service := Service,
4045
host := Host,
4146
port := Port,
42-
type := Type}) ->
47+
type := Type,
48+
client := Client}) ->
4349
Sorted = lists:sort(fun(A, B) ->
4450
A#span.trace_id =< B#span.trace_id
4551
end, Spans),
@@ -55,15 +61,9 @@ report(Spans, #{
5561
{"Datadog-Meta-Lang-Interpreter", interpreter_version()},
5662
{"Datadog-Meta-Tracer-Version", ?TRACER_VERSION}
5763
],
58-
case httpc:request(
59-
put,
60-
{Address, Headers, "application/json", JSON},
61-
[],
62-
[]
63-
) of
64-
{ok, {{_, Code, _}, _, _}} when Code >= 200, Code =< 299 ->
65-
ok;
66-
{ok, {{_, Code, _}, _, Message}} ->
64+
case Client(Address, Headers, JSON) of
65+
ok -> ok;
66+
{error, {http_error, Code, Message}} ->
6767
?LOG_ERROR("DD: Unable to send spans,"
6868
" DD reported an error: ~p: ~p",
6969
[Code, Message]);
@@ -76,8 +76,23 @@ report(Spans, #{
7676
?LOG_ERROR("DD: Can't spans encode to json: ~p", [Error])
7777
end.
7878

79+
default_client(Address, Headers, JSON) ->
80+
case httpc:request(
81+
put,
82+
{Address, Headers, "application/json", JSON},
83+
[],
84+
[]
85+
) of
86+
{ok, {{_, Code, _}, _, _}} when Code >= 200, Code =< 299 ->
87+
ok;
88+
{ok, {{_, Code, _}, _, Body}} ->
89+
{error, {http_error, Code, Body}};
90+
{error, Reason} ->
91+
{error, Reason}
92+
end.
93+
7994
lang_version() ->
80-
erlang:system_info(otp_version).
95+
erlang:system_info(otp_release).
8196

8297
interpreter_version() ->
8398
io_lib:format('~s-~s', [erlang:system_info(version),

src/oc_stat_exporter_datadog.erl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ build_packet(#{name := Name,
4343
lists:join($\n, List).
4444

4545
build_tags(Tags, TagsV, CTags) ->
46-
build_tags(maps:merge(CTags, maps:from_list(lists:zip(Tags, TagsV)))).
46+
TagsMap = maps:merge(CTags, maps:from_list(lists:zip(Tags, TagsV))),
47+
TagsList = maps:to_list(TagsMap),
48+
Cleaned = [{Key, Value} || {Key, Value} <- TagsList, Value =/= undefined],
49+
build_tags(Cleaned).
4750

48-
build_tags(Map) when is_map(Map) -> build_tags(maps:to_list(Map));
4951
build_tags([]) -> [];
5052
build_tags(Tags) ->
5153
List = [[to_key(Key), $:, Value]

test/oc_reporter_datadog_SUITE.erl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-module(oc_reporter_datadog_SUITE).
2+
3+
-include_lib("opencensus/include/opencensus.hrl").
4+
-include_lib("common_test/include/ct.hrl").
5+
-include_lib("eunit/include/eunit.hrl").
6+
7+
-export([all/0, init_per_testcase/2]).
8+
-export([test_eunit/1, test_reports_spans/1]).
9+
10+
all() -> [test_eunit, test_reports_spans].
11+
12+
init_per_testcase(_, Config) ->
13+
Span = #span{
14+
name = <<"foo">>,
15+
trace_id = 1,
16+
span_id = 1,
17+
start_time = wts:timestamp(),
18+
end_time = wts:timestamp(),
19+
attributes = #{foo => "bar"}
20+
},
21+
Options = oc_reporter_datadog:init([{http_client, fun mock_client/3}]),
22+
[{span, Span}, {options, Options} | Config].
23+
24+
mock_client(Address, Headers, JSON) ->
25+
self() ! {http, lists:flatten(Address), Headers, JSON},
26+
ok.
27+
28+
test_reports_spans(Config) ->
29+
Options = ?config(options, Config),
30+
Span = ?config(span, Config),
31+
oc_reporter_datadog:report([Span], Options),
32+
receive
33+
{http, "http://localhost:8126/v0.3/traces", _, JSON} ->
34+
Data = jsx:decode(JSON, [return_maps]),
35+
[[RSpan]] = Data,
36+
#{<<"name">> := <<"foo">>,
37+
<<"trace_id">> := 1,
38+
<<"span_id">> := 1,
39+
<<"type">> := <<"custom">>,
40+
<<"duration">> := _,
41+
<<"meta">> := #{<<"foo">> := <<"bar">>}} = RSpan,
42+
ok;
43+
Msg ->
44+
ct:fail("Unknown message: ~p", [Msg])
45+
after
46+
1000 -> ct:fail("Didn't received message in 1s")
47+
end.
48+
49+
%% EUNIT TESTS =================================================================
50+
51+
test_eunit(_Config) -> eunit:test(?MODULE, []).
52+
53+
init_return_value_contains_needed_keys_test_() ->
54+
Opts = oc_reporter_datadog:init([]),
55+
{"test that init value contains needed keys", inparallel,
56+
[?_assert(maps:is_key(service, Opts)),
57+
?_assert(maps:is_key(host, Opts)),
58+
?_assert(maps:is_key(port, Opts)),
59+
?_assert(maps:is_key(type, Opts))]}.
60+
61+
init_sets_proper_fields_to_requested_values_test_() ->
62+
{"test that init sets proper fields in resulting map", inparallel,
63+
[init_sets(host, "foo"),
64+
init_sets(port, 6666),
65+
init_sets(service, "foo"),
66+
init_sets(type, "foo")]}.
67+
68+
init_sets(Key, Value) ->
69+
Opts = oc_reporter_datadog:init([{Key, Value}]),
70+
?_assertEqual(Value, maps:get(Key, Opts)).
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
-module(oc_stat_exporter_datadog_SUITE).
2+
3+
-include_lib("common_test/include/ct.hrl").
4+
-include_lib("eunit/include/eunit.hrl").
5+
6+
-export([all/0, init_per_testcase/2, end_per_testcase/2]).
7+
-export([test_eunit/1, test_export/1, test_export_with_tags/1]).
8+
9+
all() -> [test_eunit, test_export, test_export_with_tags].
10+
11+
init_per_testcase(test_eunit, Config) -> Config;
12+
init_per_testcase(_, Config) ->
13+
_ = application:ensure_all_started(oc_datadog),
14+
{ok, Socket} = gen_udp:open(8125, [{active, once}]),
15+
Measure = oc_stat_measure:new('datadog/test', "Test", foos),
16+
{ok, View} = oc_stat_view:subscribe(#{
17+
name => "datadog.test",
18+
measure => Measure,
19+
description => "Test",
20+
tags => [foo, bar],
21+
aggregation => oc_stat_aggregation_count}),
22+
[{udp, Socket}, {measure, Measure}, {view, View} | Config].
23+
24+
end_per_testcase(test_eunit, Config) -> Config;
25+
end_per_testcase(_, Config) ->
26+
Socket = ?config(udp, Config),
27+
View = ?config(view, Config),
28+
oc_stat_view:unsubscribe(View),
29+
oc_stat_view:deregister(View),
30+
gen_udp:close(Socket),
31+
Config.
32+
33+
test_eunit(_Config) -> eunit:test(?MODULE, []).
34+
35+
test_export(Config) ->
36+
_ = oc_stat:record(#{}, 'datadog/test', 1),
37+
View = ?config(view, Config),
38+
Data = oc_stat_view:export(View),
39+
oc_stat_exporter_datadog:export([Data], []),
40+
receive
41+
{udp, _, _, _, "datadog.test:1|g"} -> ok;
42+
Msg ->
43+
ct:fail("Unknown message: ~p", [Msg])
44+
after
45+
1000 -> ct:fail("Didn't received message in 1s")
46+
end.
47+
48+
test_export_with_tags(Config) ->
49+
_ = oc_stat:record(#{foo => "1", bar => "2"}, 'datadog/test', 1),
50+
View = ?config(view, Config),
51+
Data = oc_stat_view:export(View),
52+
oc_stat_exporter_datadog:export([Data], []),
53+
receive
54+
{udp, _, _, _, "datadog.test:1|g|#bar:2,foo:1"} -> ok;
55+
{udp, _, _, _, "datadog.test:1|g|#foo:1,bar:2"} -> ok;
56+
Msg ->
57+
ct:fail("Unknown message: ~p", [Msg])
58+
after
59+
1000 -> ct:fail("Didn't received message in 1s")
60+
end.

0 commit comments

Comments
 (0)