stackprof-webnav 0.1.0 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +39 -0
  3. data/.gitignore +2 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +57 -16
  6. data/README.md +27 -18
  7. data/Rakefile +24 -0
  8. data/bin/stackprof-webnav +7 -6
  9. data/lib/stackprof-webnav.rb +1 -1
  10. data/lib/stackprof-webnav/dump.rb +41 -0
  11. data/lib/stackprof-webnav/presenter.rb +0 -19
  12. data/lib/stackprof-webnav/public/css/application.css +17 -0
  13. data/lib/stackprof-webnav/public/flamegraph.js +983 -0
  14. data/lib/stackprof-webnav/public/lib/string_score.js +78 -0
  15. data/lib/stackprof-webnav/public/overview.js +29 -0
  16. data/lib/stackprof-webnav/server.rb +101 -53
  17. data/lib/stackprof-webnav/version.rb +1 -1
  18. data/lib/stackprof-webnav/views/error.haml +8 -0
  19. data/lib/stackprof-webnav/views/file.haml +7 -4
  20. data/lib/stackprof-webnav/views/flamegraph.haml +77 -0
  21. data/lib/stackprof-webnav/views/graph.haml +5 -0
  22. data/lib/stackprof-webnav/views/index.haml +18 -0
  23. data/lib/stackprof-webnav/views/invalid_dump.haml +4 -0
  24. data/lib/stackprof-webnav/views/layout.haml +1 -3
  25. data/lib/stackprof-webnav/views/method.haml +11 -8
  26. data/lib/stackprof-webnav/views/overview.haml +25 -5
  27. data/screenshots/callgraph.png +0 -0
  28. data/screenshots/directory.png +0 -0
  29. data/screenshots/file.png +0 -0
  30. data/screenshots/flamegraph.png +0 -0
  31. data/screenshots/method.png +0 -0
  32. data/screenshots/overview.png +0 -0
  33. data/spec/fixtures/test-raw.dump +0 -0
  34. data/spec/fixtures/test.dump +0 -0
  35. data/spec/helpers.rb +17 -0
  36. data/spec/integration_spec.rb +79 -0
  37. data/spec/spec_helper.rb +15 -0
  38. data/stackprof-webnav.gemspec +9 -4
  39. metadata +111 -20
  40. data/lib/stackprof-webnav/views/listing.haml +0 -23
  41. data/screenshots/main.png +0 -0
@@ -7,6 +7,4 @@
7
7
  %link(rel="stylesheet" href="/css/application.css")
8
8
 
9
9
  %body
10
- .row
11
- .large-12.columns
12
- = yield
10
+ = yield
@@ -1,12 +1,15 @@
1
1
  %h3 StackProf Navigator - #{@action} (#{@frames.count} frames)
2
2
  %hr
3
3
 
4
- %a{:href => '/'} ← Back to overview
5
- %br
4
+ %p
5
+ %a{:href => url_for("/overview")} ← Back to overview
6
6
 
7
7
  - @frames.each do |frame|
8
- %h4
9
- %a{:href => file_url(frame[:location])}= frame[:location]
8
+ %a{:href => url_for("/file", path: frame[:location])}
9
+ %button.btn
10
+ Browse
11
+ = frame[:location]
12
+
10
13
  - if frame[:callers].any?
11
14
  %table
12
15
  %thead
@@ -21,8 +24,8 @@
21
24
  %td= caller[:weight]
22
25
  %td= caller[:pct]
23
26
  %td
24
- %a{:href => method_url(caller[:method])}
25
- = caller[:method]
27
+ %a{:href => url_for("/method", name: caller[:method])}
28
+ &= caller[:method]
26
29
 
27
30
  - if frame[:callees].any?
28
31
  %table
@@ -38,8 +41,8 @@
38
41
  %td= caller[:weight]
39
42
  %td= caller[:pct]
40
43
  %td
41
- %a{:href => method_url(caller[:method])}
42
- = caller[:method]
44
+ %a{:href => url_for("/method", name: caller[:method])}
45
+ &= caller[:method]
43
46
 
44
47
  %h4 Code
45
48
  != frame[:source]
@@ -3,7 +3,21 @@
3
3
 
4
4
  %p
5
5
  Viewing dump
6
- %b= @file
6
+ %b= current_dump.path
7
+
8
+ %a{href: "/"}
9
+ %button.btn Browse directory
10
+
11
+
12
+ %a{href: url_for("/graph")}
13
+ %button.btn View call graph
14
+
15
+ - if current_report.data[:raw]
16
+ %a{href: url_for("/flamegraph")}
17
+ %button View flamegraph
18
+ - else
19
+ %a{href: "https://github.com/tmm1/stackprof#all-options"}
20
+ %button.secondary Flamegraph is not available
7
21
 
8
22
  %table.centered
9
23
  %thead
@@ -11,15 +25,21 @@
11
25
  %th %
12
26
  %th Samples
13
27
  %th %
14
- %th Method
28
+ %th
29
+ Method
30
+ %input.filter{:placeholder => "filter methods", :type => "text"}/
15
31
 
16
32
  %tbody
17
33
  - @frames.each do |frame|
18
- %tr
34
+ - # Filter keys are preprocessed to better match acronyms.
35
+ %tr{"data-filter-key" => frame[:method].gsub(/[A-Z]/, " \\0").gsub(/[\W_]+/, " ").strip}
19
36
  %td= frame[:total]
20
37
  %td= frame[:total_pct]
21
38
  %td= frame[:samples]
22
39
  %td= frame[:samples_pct]
23
40
  %td
24
- %a{:href => method_url(frame[:method])}
25
- = frame[:method]
41
+ %a{:href => url_for("/method", name: frame[:method])}
42
+ &= frame[:method]
43
+
44
+ %script{src: "lib/string_score.js"}
45
+ %script{src: "overview.js"}
Binary file
Binary file
data/screenshots/file.png CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/spec/helpers.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'rack/test'
2
+
3
+ module Helpers
4
+ def build_app(options={})
5
+ StackProf::Webnav::Server.cmd_options = options
6
+ Rack::Test::Session.new(Rack::MockSession.new(StackProf::Webnav::Server))
7
+ end
8
+
9
+ def fixture_path(name)
10
+ File.join(File.dirname(__FILE__), "fixtures", name)
11
+ end
12
+
13
+ def build_presenter(path)
14
+ report = StackProf::Report.new(Marshal.load(File.read(path)))
15
+ StackProf::Webnav::Presenter.new(report)
16
+ end
17
+ end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "integration tests" do
4
+ let(:app) { build_app }
5
+ let(:presenter) { build_presenter(fixture_path("test.dump")) }
6
+ let(:response) { app.last_response }
7
+
8
+ after(:each) do
9
+ Dir.glob("spec/fixtures/*.flames.json").each {|file| File.delete(file) }
10
+ Dir.glob("spec/fixtures/*.digraph.dot").each {|file| File.delete(file) }
11
+ Dir.glob("spec/fixtures/*.graph.svg").each {|file| File.delete(file) }
12
+ end
13
+
14
+ describe "index" do
15
+ it "lists the files in a folder" do
16
+ app = build_app(directory: "spec/fixtures")
17
+ app.get "/"
18
+ expect(app.last_response.body).to include("test.dump")
19
+ end
20
+
21
+ it "redirects to overview if path is specified" do
22
+ app = build_app(filepath: fixture_path("test.dump"))
23
+ app.get "/"
24
+ app.follow_redirect!
25
+ expect(app.last_response.body).to include("Dummy")
26
+ end
27
+ end
28
+
29
+ it "does not crash on unknown requests" do
30
+ app.get "/favicon.ico"
31
+ expect(response.status).to eq(404)
32
+ end
33
+
34
+ describe "overview" do
35
+ it "works with a valid dump" do
36
+ app.get "/overview", dump: fixture_path("test.dump")
37
+
38
+ frame = presenter.overview_frames.first
39
+ expect(response.body).to include(frame[:method])
40
+ end
41
+
42
+ it "communicates that flamegraph is not available for dump" do
43
+ app.get "/overview", dump: fixture_path("test.dump")
44
+ end
45
+
46
+ it "does not crash if selected file is not a dump" do
47
+ app.get "/overview", dump: "Rakefile"
48
+ expect(response.body).to include("Unable to open")
49
+ end
50
+ end
51
+
52
+ it "is able to generate flames.json file" do
53
+ app.get "/flames.json", dump: fixture_path("test-raw.dump")
54
+ expect(response.body).to include("flamegraph")
55
+ end
56
+
57
+ it "is able to render graph" do
58
+ app.get "/graph.svg", dump: fixture_path("test.dump")
59
+ expect(response.get_header("Content-Type")).to eq("image/svg+xml")
60
+ expect(response.body.size).to_not eq(0)
61
+ end
62
+
63
+ it "method page renders information about a method" do
64
+ frame = presenter.overview_frames.first
65
+ app.get "/method", dump: fixture_path("test.dump"), name: frame[:method]
66
+ expect(response.body).to include("Callers")
67
+ end
68
+
69
+ it "does not crash on a file page" do
70
+ frame = presenter.overview_frames.first
71
+ method_info = presenter.method_info frame[:method]
72
+
73
+ expect {
74
+ app.get "/file",
75
+ dump: fixture_path("test.dump"),
76
+ path: method_info.first[:location]
77
+ }.to_not raise_error
78
+ end
79
+ end
@@ -0,0 +1,15 @@
1
+ ENV['APP_ENV'] = 'test'
2
+ $LOAD_PATH.unshift File.join(Dir.pwd, "lib")
3
+
4
+ require "stackprof-webnav"
5
+ require "rspec"
6
+ require_relative 'helpers'
7
+
8
+ RSpec.configure do |config|
9
+ config.include Helpers
10
+ config.backtrace_exclusion_patterns << /.gem/
11
+
12
+ config.after(:each) do
13
+ StackProf::Webnav::Server.cmd_options = {}
14
+ end
15
+ end
@@ -21,10 +21,15 @@ Gem::Specification.new do |spec|
21
21
  spec.bindir = 'bin'
22
22
  spec.executables << 'stackprof-webnav'
23
23
 
24
- spec.add_dependency "sinatra", "~> 2.0.1"
25
- spec.add_dependency "haml", "~> 4.0"
26
- spec.add_dependency "stackprof", "~> 0.2"
24
+ spec.add_dependency "sinatra", "~> 2.1.0"
25
+ spec.add_dependency "haml", "~> 5.1.2"
26
+ spec.add_dependency "stackprof", ">= 0.2.13"
27
27
  spec.add_dependency "better_errors", "~> 1.1.0"
28
- spec.add_development_dependency "bundler", "~> 1.5"
28
+ spec.add_dependency "ruby-graphviz", "~> 1.2.4"
29
+ spec.add_dependency "sinatra-contrib", "~> 2.1.0"
30
+ spec.add_dependency "webrick", "~> 1.7.0"
31
+ spec.add_development_dependency "bundler", "~> 2.2"
29
32
  spec.add_development_dependency "rake", "~> 10.1"
33
+ spec.add_development_dependency "rspec", "~> 3.9.0"
34
+ spec.add_development_dependency "rack-test", "~> 1.1.0"
30
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackprof-webnav
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Lisnic
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-01 00:00:00.000000000 Z
11
+ date: 2021-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.1
19
+ version: 2.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.1
26
+ version: 2.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: haml
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: 5.1.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: 5.1.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: stackprof
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0.2'
47
+ version: 0.2.13
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0.2'
54
+ version: 0.2.13
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: better_errors
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,20 +66,62 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby-graphviz
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.4
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.4
83
+ - !ruby/object:Gem::Dependency
84
+ name: sinatra-contrib
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.1.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.1.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: webrick
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.7.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.7.0
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: bundler
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - "~>"
74
116
  - !ruby/object:Gem::Version
75
- version: '1.5'
117
+ version: '2.2'
76
118
  type: :development
77
119
  prerelease: false
78
120
  version_requirements: !ruby/object:Gem::Requirement
79
121
  requirements:
80
122
  - - "~>"
81
123
  - !ruby/object:Gem::Version
82
- version: '1.5'
124
+ version: '2.2'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: rake
85
127
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +136,34 @@ dependencies:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
138
  version: '10.1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 3.9.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 3.9.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: rack-test
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.1.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.1.0
97
167
  description: Provides the ability to analyze StackProf dumps
98
168
  email:
99
169
  - andrei.lisnic@gmail.com
@@ -102,6 +172,7 @@ executables:
102
172
  extensions: []
103
173
  extra_rdoc_files: []
104
174
  files:
175
+ - ".github/workflows/ruby.yml"
105
176
  - ".gitignore"
106
177
  - Gemfile
107
178
  - Gemfile.lock
@@ -111,27 +182,43 @@ files:
111
182
  - Rakefile
112
183
  - bin/stackprof-webnav
113
184
  - lib/stackprof-webnav.rb
185
+ - lib/stackprof-webnav/dump.rb
114
186
  - lib/stackprof-webnav/presenter.rb
115
187
  - lib/stackprof-webnav/public/css/application.css
116
188
  - lib/stackprof-webnav/public/css/code.css
117
189
  - lib/stackprof-webnav/public/css/foundation.min.css
118
190
  - lib/stackprof-webnav/public/css/normalize.css
191
+ - lib/stackprof-webnav/public/flamegraph.js
192
+ - lib/stackprof-webnav/public/lib/string_score.js
193
+ - lib/stackprof-webnav/public/overview.js
119
194
  - lib/stackprof-webnav/server.rb
120
195
  - lib/stackprof-webnav/version.rb
196
+ - lib/stackprof-webnav/views/error.haml
121
197
  - lib/stackprof-webnav/views/file.haml
198
+ - lib/stackprof-webnav/views/flamegraph.haml
199
+ - lib/stackprof-webnav/views/graph.haml
200
+ - lib/stackprof-webnav/views/index.haml
201
+ - lib/stackprof-webnav/views/invalid_dump.haml
122
202
  - lib/stackprof-webnav/views/layout.haml
123
- - lib/stackprof-webnav/views/listing.haml
124
203
  - lib/stackprof-webnav/views/method.haml
125
204
  - lib/stackprof-webnav/views/overview.haml
205
+ - screenshots/callgraph.png
206
+ - screenshots/directory.png
126
207
  - screenshots/file.png
127
- - screenshots/main.png
208
+ - screenshots/flamegraph.png
128
209
  - screenshots/method.png
210
+ - screenshots/overview.png
211
+ - spec/fixtures/test-raw.dump
212
+ - spec/fixtures/test.dump
213
+ - spec/helpers.rb
214
+ - spec/integration_spec.rb
215
+ - spec/spec_helper.rb
129
216
  - stackprof-webnav.gemspec
130
217
  homepage: https://github.com/alisnic/stackprof-webnav
131
218
  licenses:
132
219
  - MIT
133
220
  metadata: {}
134
- post_install_message:
221
+ post_install_message:
135
222
  rdoc_options: []
136
223
  require_paths:
137
224
  - lib
@@ -146,9 +233,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
233
  - !ruby/object:Gem::Version
147
234
  version: '0'
148
235
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.7.5
151
- signing_key:
236
+ rubygems_version: 3.1.4
237
+ signing_key:
152
238
  specification_version: 4
153
239
  summary: View stackprof dumps in a web UI
154
- test_files: []
240
+ test_files:
241
+ - spec/fixtures/test-raw.dump
242
+ - spec/fixtures/test.dump
243
+ - spec/helpers.rb
244
+ - spec/integration_spec.rb
245
+ - spec/spec_helper.rb