1Code.require_file("../../test_helper.exs", __DIR__) 2 3defmodule Mix.Tasks.Profile.EprofTest do 4 use MixTest.Case 5 6 import ExUnit.CaptureIO 7 alias Mix.Tasks.Profile.Eprof 8 9 @expr "Enum.each(1..5, &String.Chars.Integer.to_string/1)" 10 11 test "profiles evaluated expression", context do 12 in_tmp(context.test, fn -> 13 assert capture_io(fn -> 14 Eprof.run(["-e", @expr]) 15 end) =~ ~r/String\.Chars\.Integer\.to_string\/1\s+\d/ 16 end) 17 end 18 19 test "profiles evaluated expression in multiple processes", context do 20 in_tmp(context.test, fn -> 21 assert capture_io(fn -> 22 Eprof.run(["-e", "spawn(fn -> #{@expr} end)"]) 23 end) =~ ~r/String\.Chars\.Integer\.to_string\/1\s+\d/ 24 end) 25 end 26 27 test "profiles the script", context do 28 in_tmp(context.test, fn -> 29 profile_script_name = "profile_script.ex" 30 File.write!(profile_script_name, @expr) 31 32 assert capture_io(fn -> 33 Eprof.run([profile_script_name]) 34 end) =~ ~r/String\.Chars\.Integer\.to_string\/1\s+\d/ 35 end) 36 end 37 38 test "filters based on count", context do 39 in_tmp(context.test, fn -> 40 refute capture_io(fn -> 41 Eprof.run(["--calls", "5", "-e", @expr]) 42 end) =~ ":erlang.apply/2" 43 end) 44 end 45 46 test "sorts based on the calls count", context do 47 in_tmp(context.test, fn -> 48 assert capture_io(fn -> 49 Eprof.run(["--sort", "calls", "-e", @expr]) 50 end) =~ ~r/erlang\.apply\/2.*String\.Chars\.Integer\.to_string\/1/s 51 end) 52 end 53 54 test "Module matching", context do 55 in_tmp(context.test, fn -> 56 refute capture_io(fn -> 57 Eprof.run(["--matching", "Enum", "-e", @expr]) 58 end) =~ ~r/String\.Chars\.Integer\.to_string\/1/ 59 end) 60 end 61 62 test "Module.function matching", context do 63 in_tmp(context.test, fn -> 64 refute capture_io(fn -> 65 Eprof.run(["--matching", "Enum.each", "-e", @expr]) 66 end) =~ ~r/anonymous fn\/3 in Enum\.each\/2/ 67 end) 68 end 69 70 test "Module.function/arity matching", context do 71 in_tmp(context.test, fn -> 72 assert capture_io(fn -> 73 Eprof.run(["--matching", "Enum.each/8", "-e", @expr]) 74 end) =~ ~r/Profile done over 0 matching functions/ 75 end) 76 end 77 78 test "errors on missing files", context do 79 in_tmp(context.test, fn -> 80 message = "No files matched pattern \"non-existent\" given to --require" 81 82 assert_raise Mix.Error, message, fn -> 83 capture_io(fn -> Eprof.run(["-r", "non-existent"]) end) 84 end 85 86 message = "No files matched pattern \"non-existent\" given to --require" 87 88 assert_raise Mix.Error, message, fn -> 89 capture_io(fn -> Eprof.run(["-pr", "non-existent"]) end) 90 end 91 92 assert_raise Mix.Error, "No such file: non-existent", fn -> 93 capture_io(fn -> Eprof.run(["non-existent"]) end) 94 end 95 96 File.mkdir_p!("lib") 97 98 assert_raise Mix.Error, "No such file: lib", fn -> 99 capture_io(fn -> Eprof.run(["lib"]) end) 100 end 101 end) 102 end 103 104 test "warmup", context do 105 in_tmp(context.test, fn -> 106 assert capture_io(fn -> 107 Eprof.run(["-e", @expr]) 108 end) =~ "Warmup..." 109 110 refute capture_io(fn -> 111 Eprof.run(["-e", @expr, "--no-warmup"]) 112 end) =~ "Warmup..." 113 end) 114 end 115end 116