Skip to content

Commit

Permalink
Merge pull request #174 from gmcgibbon/support_json_profiles
Browse files Browse the repository at this point in the history
Add json file support to profile reading
  • Loading branch information
tenderlove committed Mar 23, 2022
2 parents a08162e + 5a1f33a commit df24b85
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion bin/stackprof
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ reports = []
while ARGV.size > 0
begin
file = ARGV.pop
reports << StackProf::Report.new(Marshal.load(IO.binread(file)))
reports << StackProf::Report.from_file(file)
rescue TypeError => e
STDERR.puts "** error parsing #{file}: #{e.inspect}"
end
Expand Down
34 changes: 34 additions & 0 deletions lib/stackprof/report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,43 @@

require 'pp'
require 'digest/md5'
require 'json'

module StackProf
class Report
MARSHAL_SIGNATURE = "\x04\x08"

class << self
def from_file(file)
if (content = IO.binread(file)).start_with?(MARSHAL_SIGNATURE)
new(Marshal.load(content))
else
from_json(JSON.parse(content))
end
end

def from_json(json)
new(parse_json(json))
end

def parse_json(json)
json.keys.each do |key|
value = json.delete(key)
from_json(value) if value.is_a?(Hash)

new_key = case key
when /\A[0-9]*\z/
key.to_i
else
key.to_sym
end

json[new_key] = value
end
json
end
end

def initialize(data)
@data = data
end
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/profile.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{: modeI"cpu:ET
1 change: 1 addition & 0 deletions test/fixtures/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "mode": "cpu" }
24 changes: 24 additions & 0 deletions test/test_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,27 @@ def assert_dump(expected, marshal_data)
assert_equal expected, Marshal.load(marshal_data)
end
end

class ReportReadTest < MiniTest::Test
require 'pathname'

def test_from_file_read_json
file = fixture("profile.json")
report = StackProf::Report.from_file(file)

assert_equal({ mode: "cpu" }, report.data)
end

def test_from_file_read_marshal
file = fixture("profile.dump")
report = StackProf::Report.from_file(file)

assert_equal({ mode: "cpu" }, report.data)
end

private

def fixture(name)
Pathname.new(__dir__).join("fixtures", name)
end
end

0 comments on commit df24b85

Please sign in to comment.