Skip to content

Instantly share code, notes, and snippets.

@shamshirz
Last active April 12, 2024 19:24
Show Gist options
  • Save shamshirz/9c715e5d474129312b30990b7187222b to your computer and use it in GitHub Desktop.
Save shamshirz/9c715e5d474129312b30990b7187222b to your computer and use it in GitHub Desktop.
Analyze the Elixir test time output by `MIX_DEBUG=1`
### CMD Example : Partition & Cover (73s)
# MIX_TEST_PARTITION=1 MIX_DEBUG=1 mix test test/crowbar/scan/vciso_card_test.exs --partitions 2 --cover > tmp.txt && elixir ./analyze.exs
#
# Total Running time: 73.277s
# Total Test time: 54.554s
# Partial test time: 5.2s
# Unaccounted for test time: 49.354s
# Note: The total time isn't right because some of the steps are nested, meaning duplicate counts of time
# eg. start deps.loadpaths, start archive.check, end archive.check Xms, end deps.loadpaths X+Yms
human_readable = fn result ->
IO.puts("Total Running time: #{result.total / 1000}s")
IO.puts("Total Test time: #{result.total_test_time / 1000}s")
IO.puts("Partial test time: #{result.partial_test_time / 1000}s")
IO.puts("Unaccounted for test time: #{result.unaccounted_for_test_time / 1000}s")
# IO.puts("Steps:")
# Enum.each(result.steps, &IO.puts("* " <> &1))
end
result =
"./tmp.txt"
|> File.stream!()
|> Stream.filter(fn line ->
String.match?(line, ~r/^<-.*(\d+)ms/) or String.match?(line, ~r/^Finished in (.*)\sseconds.*/)
end)
|> Stream.map(fn
"<-" <> line ->
millis = ~r/(\d+)ms/ |> Regex.run(line) |> List.last() |> String.to_integer()
{String.trim(line), millis}
"Finished in " <> line ->
millis = ~r/^(.*)\sseconds.*/ |> Regex.run(line) |> List.last() |> String.to_float() |> Kernel.*(1000) |> round()
{String.trim("Finished in " <> line), millis}
end)
|> Enum.reduce(%{steps: [], total_test_time: nil, partial_test_time: 0, total: 0, unaccounted_for_test_time: 0}, fn
{"Ran mix test" <> rest, millis}, acc ->
%{acc | steps: ["Ran mix test" <> rest | acc.steps], total: acc.total + millis, total_test_time: millis}
{"Finished in " <> line, millis}, acc ->
%{acc | steps: [line | acc.steps], total: acc.total + millis, partial_test_time: millis}
{line, millis}, acc ->
%{acc | steps: [line | acc.steps], total: acc.total + millis}
end)
|> then(fn result ->
%{result | unaccounted_for_test_time: result.total_test_time - result.partial_test_time}
end)
# IO.inspect(result)
human_readable.(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment