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

Fix SpanCaptureReporter test spillage (#22) #25

Merged
merged 1 commit into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ if Mix.env() == :test do

config :opencensus,
reporters: [{Opencensus.TestSupport.SpanCaptureReporter, []}],
send_interval_ms: 0
send_interval_ms: 100
end
6 changes: 6 additions & 0 deletions lib/opencensus/span.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ defmodule Opencensus.Span do
def load(span_ctx) when is_tuple(span_ctx) do
span_ctx |> SpanContext.from() |> Map.get(:span_id) |> load()
end

@doc false
def began_monotonic(record) when Record.is_record(record, :span) do
{native_time, _native_offset} = span(record, :start_time)
native_time
end
end
41 changes: 34 additions & 7 deletions lib/opencensus/test_support/span_capture_reporter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Opencensus.TestSupport.SpanCaptureReporter do
```elixir
if Mix.env() == :test do
config :opencensus,
send_interval_ms: 1,
send_interval_ms: 100,
reporters: [{Opencensus.TestSupport.SpanCaptureReporter, []}]
end
```
Expand Down Expand Up @@ -52,25 +52,52 @@ defmodule Opencensus.TestSupport.SpanCaptureReporter do
end

@doc false
def handler([__MODULE__], %{}, %{spans: spans}, pid), do: send(pid, {:spans, spans})
def handler([__MODULE__], %{}, %{spans: spans}, {pid, attached_monotonic}) do
started_after_attach? = fn span -> span |> Span.began_monotonic() >= attached_monotonic end
filtered = spans |> Enum.filter(started_after_attach?)
send(pid, {:spans, filtered})
end

@doc "Attach the reporter to deliver spans to your process inbox."
def attach, do: :telemetry.attach(__MODULE__, [__MODULE__], &handler/4, self())
def attach do
:telemetry.attach(__MODULE__, [__MODULE__], &handler/4, {self(), :erlang.monotonic_time()})
end

@doc """
Detach the reporter to stop delivering spans to your process inbox.

If still attached, triggers span delivery before detaching.
"""
def detach do
if handler_attached?(), do: trigger_and_wait_for_span_delivery()
:telemetry.detach(__MODULE__)
end

@doc "Detach the reporter to stop delivering spans to your process inbox."
def detach, do: :telemetry.detach(__MODULE__)
@doc """
Collect spans from your process inbox.

@doc "Collect spans from your process inbox."
If still attached, triggers span delivery before collection.
"""
@spec collect() :: list(%Span{})
def collect do
if handler_attached?(), do: trigger_and_wait_for_span_delivery()
collect_span_records([]) |> Enum.map(&Span.from/1)
end

defp trigger_and_wait_for_span_delivery do
send(:oc_reporter, :report_spans)
:timer.sleep(1)
end

defp handler_attached? do
:telemetry.list_handlers([__MODULE__]) != []
end

defp collect_span_records(acc) when is_list(acc) do
receive do
{:spans, spans} -> collect_span_records(acc ++ spans)
after
10 -> acc
1 -> acc
end
end
end
43 changes: 43 additions & 0 deletions test/opencensus_test_support_span_capture_reporter_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Opencensus.TestSupport.SpanCaptureReporterTest do
use ExUnit.Case, async: false
import Opencensus.Trace

alias Opencensus.TestSupport.SpanCaptureReporter

describe "Opencensus.TestSupport.SpanCaptureReporter.collect/3" do
defp loop_count do
case System.get_env("CI") do
nil -> 10
_ -> 1000
end
end

test "before detach, gets the just-finished span" do
for _ <- 1..loop_count() do
SpanCaptureReporter.attach()

with_child_span "inner" do
[0, 1, 1, 2, 2, 2, 2, 3, 3, 4] |> Enum.random() |> :timer.sleep()
:...
end

assert SpanCaptureReporter.collect() |> length() == 1
SpanCaptureReporter.detach()
end
end

test "after detach, gets the just-finished span" do
for _ <- 1..loop_count() do
SpanCaptureReporter.attach()

with_child_span "inner" do
[0, 1, 1, 2, 2, 2, 2, 3, 3, 4] |> Enum.random() |> :timer.sleep()
:...
end

SpanCaptureReporter.detach()
assert SpanCaptureReporter.collect() |> length() == 1
end
end
end
end