perfmonger 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +6 -0
  3. data/.tachikoma.yml +1 -0
  4. data/.travis.yml +18 -6
  5. data/Gemfile +1 -3
  6. data/Guardfile +26 -0
  7. data/NEWS +21 -0
  8. data/README.md +8 -9
  9. data/Rakefile +33 -1
  10. data/core/Makefile +23 -0
  11. data/core/build.sh +48 -0
  12. data/core/perfmonger-player.go +165 -0
  13. data/core/perfmonger-recorder.go +296 -0
  14. data/core/perfmonger-summarizer.go +207 -0
  15. data/core/subsystem/Makefile +3 -0
  16. data/core/subsystem/perfmonger.go +60 -0
  17. data/core/subsystem/perfmonger_darwin.go +22 -0
  18. data/core/subsystem/perfmonger_linux.go +292 -0
  19. data/core/subsystem/perfmonger_linux_test.go +73 -0
  20. data/core/subsystem/stat.go +214 -0
  21. data/core/subsystem/stat_test.go +281 -0
  22. data/core/subsystem/usage.go +410 -0
  23. data/core/subsystem/usage_test.go +496 -0
  24. data/lib/exec/operationBinding.rb.svn-base +59 -0
  25. data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
  26. data/lib/exec/perfmonger-player_linux_386 +0 -0
  27. data/lib/exec/perfmonger-player_linux_amd64 +0 -0
  28. data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
  29. data/lib/exec/perfmonger-recorder_linux_386 +0 -0
  30. data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
  31. data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
  32. data/lib/exec/perfmonger-summarizer_linux_386 +0 -0
  33. data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
  34. data/lib/exec/perfmonger-summary_linux_386 +0 -0
  35. data/lib/exec/perfmonger-summary_linux_amd64 +0 -0
  36. data/lib/perfmonger/cli.rb +8 -3
  37. data/lib/perfmonger/command/core.rb +62 -0
  38. data/lib/perfmonger/command/live.rb +39 -0
  39. data/lib/perfmonger/command/play.rb +56 -0
  40. data/lib/perfmonger/command/plot.rb +30 -22
  41. data/lib/perfmonger/command/record.rb +3 -2
  42. data/lib/perfmonger/command/record_option.rb +40 -59
  43. data/lib/perfmonger/command/server.rb +7 -2
  44. data/lib/perfmonger/command/stat.rb +2 -2
  45. data/lib/perfmonger/command/stat_option.rb +1 -1
  46. data/lib/perfmonger/command/summary.rb +11 -326
  47. data/lib/perfmonger/version.rb +1 -3
  48. data/lib/perfmonger.rb +3 -0
  49. data/misc/_perfmonger +128 -0
  50. data/misc/perfmonger-completion.bash +49 -0
  51. data/perfmonger.gemspec +6 -5
  52. data/spec/data/busy100.pgr +0 -0
  53. data/spec/fingerprint_spec.rb +35 -0
  54. data/spec/live_spec.rb +25 -0
  55. data/spec/perfmonger_spec.rb +37 -0
  56. data/spec/play_spec.rb +21 -0
  57. data/spec/plot_spec.rb +42 -0
  58. data/spec/record_spec.rb +15 -0
  59. data/spec/spec_helper.rb +33 -0
  60. data/spec/stat_spec.rb +15 -0
  61. data/spec/summary_spec.rb +51 -0
  62. data/spec/support/aruba.rb +11 -0
  63. data/wercker.yml +59 -0
  64. metadata +117 -45
  65. data/ext/perfmonger/extconf.rb +0 -19
  66. data/ext/perfmonger/perfmonger.h +0 -58
  67. data/ext/perfmonger/perfmonger_record.c +0 -754
  68. data/ext/perfmonger/sysstat/common.c +0 -627
  69. data/ext/perfmonger/sysstat/common.h +0 -207
  70. data/ext/perfmonger/sysstat/ioconf.c +0 -515
  71. data/ext/perfmonger/sysstat/ioconf.h +0 -84
  72. data/ext/perfmonger/sysstat/iostat.c +0 -1100
  73. data/ext/perfmonger/sysstat/iostat.h +0 -121
  74. data/ext/perfmonger/sysstat/libsysstat.h +0 -19
  75. data/ext/perfmonger/sysstat/mpstat.c +0 -953
  76. data/ext/perfmonger/sysstat/mpstat.h +0 -79
  77. data/ext/perfmonger/sysstat/rd_stats.c +0 -2388
  78. data/ext/perfmonger/sysstat/rd_stats.h +0 -651
  79. data/ext/perfmonger/sysstat/sysconfig.h +0 -13
  80. data/test/run-test.sh +0 -39
  81. data/test/spec/bin_spec.rb +0 -37
  82. data/test/spec/data/2devices.expected +0 -42
  83. data/test/spec/data/2devices.output +0 -42
  84. data/test/spec/spec_helper.rb +0 -20
  85. data/test/spec/summary_spec.rb +0 -193
  86. data/test/test-perfmonger.c +0 -145
  87. data/test/test.h +0 -9
@@ -61,340 +61,25 @@ EOS
61
61
 
62
62
  summary_title ||= @logfile
63
63
 
64
- show_summary(@logfile, summary_title)
65
- end
66
-
67
-
68
- def read_logfile(logfile)
69
- File.read(logfile).lines.map do |line|
70
- begin
71
- JSON.parse(line)
72
- rescue JSON::ParserError => err
73
- nil
74
- end
75
- end.compact
76
- end
77
-
78
- def make_accumulation(records)
79
- unless records.all?{|record| record.has_key?("ioinfo")}
80
- return nil
81
- end
82
- unless records.size > 1
83
- return nil
84
- end
85
-
86
- accum = Hash.new
87
-
88
- devices = records.first["ioinfo"]["devices"]
89
- accum["ioinfo"] = Hash.new
90
-
91
- devices.each do |device|
92
- read_requests = 0
93
- read_bytes = 0
94
- write_requests = 0
95
- write_bytes = 0
96
-
97
- (1..(records.size - 1)).each do |idx|
98
- last_record = records[idx - 1]
99
- record = records[idx]
100
- dt = record["time"] - last_record["time"]
101
-
102
- read_requests += record["ioinfo"][device]["riops"] * dt
103
- write_requests += record["ioinfo"][device]["wiops"] * dt
104
- read_bytes += record["ioinfo"][device]["rsecps"] * 512 * dt
105
- write_bytes += record["ioinfo"][device]["wsecps"] * 512 * dt
106
- end
107
-
108
- accum["ioinfo"][device] = Hash.new
109
- accum["ioinfo"][device]["read_requests"] = read_requests
110
- accum["ioinfo"][device]["read_bytes"] = read_bytes
111
- accum["ioinfo"][device]["write_requests"] = write_requests
112
- accum["ioinfo"][device]["write_bytes"] = write_bytes
113
- end
114
-
115
- accum
116
- end
117
-
118
- def make_summary(records)
119
- if records.empty?
120
- return nil
121
- elsif records.size == 1
122
- return records.first
123
- end
124
-
125
- # setup getters and setters all attributes for avg. calculation
126
- # getter.call(record) returns value
127
- # setter.call(record, value) set value
128
- # getters and setters include attribute info as a closure
129
- getters = []
130
- setters = []
131
-
132
- if records.first.include?("ioinfo")
133
- records.first["ioinfo"]["devices"].each do |device|
134
- records.first["ioinfo"][device].keys.each do |attr|
135
- getters << lambda do |record|
136
- record["ioinfo"][device][attr]
137
- end
138
- setters << lambda do |record, value|
139
- record["ioinfo"][device][attr] = value
140
- end
141
- end
142
- end
143
-
144
- records.first["ioinfo"]["total"].keys.each do |attr|
145
- getters << lambda do |record|
146
- record["ioinfo"]["total"][attr]
147
- end
148
- setters << lambda do |record, value|
149
- record["ioinfo"]["total"][attr] = value
150
- end
151
- end
152
- end
153
-
154
- if records.first.include?("cpuinfo")
155
- records.first["cpuinfo"]["all"].keys.each do |attr|
156
- getters << lambda do |record|
157
- record["cpuinfo"]["all"][attr]
158
- end
159
- setters << lambda do |record, value|
160
- record["cpuinfo"]["all"][attr] = value
161
- end
162
- end
163
-
164
- records.first["cpuinfo"]["nr_cpu"].times do |cpu_idx|
165
- records.first["cpuinfo"]["cpus"][cpu_idx].keys.each do |attr|
166
- getters << lambda do |record|
167
- record["cpuinfo"]["cpus"][cpu_idx][attr]
168
- end
169
- setters << lambda do |record, value|
170
- record["cpuinfo"]["cpus"][cpu_idx][attr] = value
171
- end
172
- end
173
- end
174
- end
175
-
176
- avg_record = Marshal.load(Marshal.dump(records.first)); # deep copy
177
-
178
- setters.each do |setter|
179
- setter.call(avg_record, 0.0)
180
- end
181
-
182
- (1..(records.size - 1)).each do |idx|
183
- record = records[idx]
184
-
185
- last_t = records[idx - 1]["time"]
186
- t = record["time"]
187
-
188
- getters.size.times do |_etters_idx|
189
- getter = getters[_etters_idx]
190
- setter = setters[_etters_idx]
191
-
192
- setter.call(avg_record,
193
- getter.call(avg_record) + getter.call(record) * (t - last_t))
194
- end
195
- end
196
-
197
- getters.size.times do |_etters_idx|
198
- getter = getters[_etters_idx]
199
- setter = setters[_etters_idx]
200
-
201
- setter.call(avg_record,
202
- getter.call(avg_record) / (records[-1]["time"] - records[0]["time"]))
203
- end
204
-
64
+ @summarizer_bin = ::PerfMonger::Command::CoreFinder.summarizer()
205
65
 
206
- # r_await/w_await need special handling
207
- if records.first.include?("ioinfo")
208
- records.first["ioinfo"]["devices"].each do |device|
209
- accum_r_io_time = 0.0
210
- accum_w_io_time = 0.0
211
- r_io_count = 0
212
- w_io_count = 0
213
-
214
- (records.size - 1).times do |idx|
215
- rec0 = records[idx]
216
- rec1 = records[idx + 1]
217
- dev_ioinfo = rec1["ioinfo"][device]
218
- dt = rec1["time"] - rec0["time"]
219
-
220
- accum_r_io_time += dev_ioinfo["r_await"] * dev_ioinfo["riops"] * dt
221
- accum_w_io_time += dev_ioinfo["w_await"] * dev_ioinfo["wiops"] * dt
222
- r_io_count += dev_ioinfo["riops"] * dt
223
- w_io_count += dev_ioinfo["wiops"] * dt
224
- end
225
-
226
- if r_io_count > 0
227
- avg_record["ioinfo"][device]["r_await"] = accum_r_io_time / r_io_count
228
- else
229
- avg_record["ioinfo"][device]["r_await"] = 0.0
230
- end
231
-
232
- if w_io_count > 0
233
- avg_record["ioinfo"][device]["w_await"] = accum_w_io_time / w_io_count
234
- else
235
- avg_record["ioinfo"][device]["w_await"] = 0.0
236
- end
237
- end
66
+ if ! @summarizer_bin
67
+ puts("[ERROR] no executable binary found.")
68
+ exit(false)
238
69
  end
239
70
 
240
- avg_record
241
- end
242
-
243
- def show_summary(logfile, summary_title)
244
- records = read_logfile(logfile)
245
- summary = make_summary(records)
246
- accum = make_accumulation(records)
247
-
248
- duration = records.last["time"] - records.first["time"]
71
+ cmd = [@summarizer_bin]
249
72
 
250
73
  if @json
251
- output = Hash.new
252
-
253
- output["duration"] = duration
254
- if summary
255
- if summary["cpuinfo"]
256
- output["cpuinfo"] = summary["cpuinfo"]
257
- end
258
-
259
- if summary['ioinfo']
260
- output["ioinfo"] = summary["ioinfo"]
261
- end
262
- end
263
-
264
- puts output.to_json
265
- else
266
- if $stdout.tty? && @pager
267
- output_file = IO.popen(@pager, "w")
268
- else
269
- output_file = $stdout
270
- end
271
-
272
- output_file.puts("")
273
- output_file.puts("== Performance summary of '#{summary_title}' ==")
274
- output_file.puts("")
275
- duration_str = sprintf("%.2f", duration)
276
- output_file.puts("record duration: #{duration_str} sec")
277
-
278
- if summary.nil?
279
- output_file.puts("")
280
- output_file.puts("No performance info was collected.")
281
- output_file.puts("This is because command execution time was too short, or something went wrong.")
282
- end
283
-
284
- if summary && summary["cpuinfo"]
285
- nr_cpu = records.first["cpuinfo"]["nr_cpu"]
286
-
287
- usr, sys, iowait, irq, soft, idle =
288
- [summary['cpuinfo']['all']['usr'] + summary['cpuinfo']['all']['nice'],
289
- summary['cpuinfo']['all']['sys'],
290
- summary['cpuinfo']['all']['iowait'],
291
- summary['cpuinfo']['all']['irq'],
292
- summary['cpuinfo']['all']['soft'],
293
- summary['cpuinfo']['all']['idle']].map do |val|
294
- val * nr_cpu
295
- end
296
-
297
- other = [100.0 - (usr + sys + iowait + irq + soft + idle), 0.0].max * nr_cpu
298
-
299
- usr_str, sys_str, iowait_str, irq_str, soft_str, other_str, idle_str =
300
- [usr, sys, iowait, irq, soft, other, idle].map do |value|
301
- sprintf("%.2f", value)
302
- end
303
-
304
- total_non_idle_str = sprintf("%.2f", usr + sys + irq + soft + other)
305
- total_idle_str = sprintf("%.2f", iowait + idle)
306
-
307
- output_file.puts("")
308
- output_file.puts <<EOS
309
- * Average CPU usage (MAX: #{100 * nr_cpu} %)
310
- * Non idle portion: #{total_non_idle_str}
311
- %usr: #{usr_str}
312
- %sys: #{sys_str}
313
- %irq: #{irq_str}
314
- %soft: #{soft_str}
315
- %other: #{other_str}
316
- * Idle portion: #{total_idle_str}
317
- %iowait: #{iowait_str}
318
- %idle: #{idle_str}
319
- EOS
320
- end
321
-
322
- if summary && summary['ioinfo']
323
- total_r_iops, total_w_iops, total_r_sec, total_w_sec = [0.0] * 4
324
-
325
- summary['ioinfo']['devices'].each do |device|
326
- r_iops, w_iops, r_sec, w_sec, r_await, w_await =
327
- [summary['ioinfo'][device]['riops'],
328
- summary['ioinfo'][device]['wiops'],
329
- summary['ioinfo'][device]['rsecps'] * 512 / 1024.0 / 1024.0,
330
- summary['ioinfo'][device]['wsecps'] * 512 / 1024.0 / 1024.0,
331
- summary['ioinfo'][device]['r_await'],
332
- summary['ioinfo'][device]['w_await']]
333
-
334
- total_r_iops += r_iops
335
- total_w_iops += w_iops
336
- total_r_sec += r_sec
337
- total_w_sec += w_sec
338
-
339
- r_iops_str, w_iops_str, r_sec_str, w_sec_str = [r_iops, w_iops, r_sec, w_sec].map do |value|
340
- sprintf("%.2f", value)
341
- end
342
-
343
- r_await_str, w_await_str = [r_await, w_await].map do |await|
344
- if await < 1.0
345
- sprintf("%.1f usec", await * 1000)
346
- else
347
- sprintf("%.2f msec", await)
348
- end
349
- end
350
-
351
- total_r_bytes_str, total_w_bytes_str = ["read_bytes", "write_bytes"].map do |key|
352
- bytes = accum["ioinfo"][device][key]
353
- if bytes > 2**30
354
- sprintf("%.2f GB", bytes / 2**30)
355
- elsif bytes > 2**20
356
- sprintf("%.2f MB", bytes / 2**20)
357
- elsif bytes > 2**10
358
- sprintf("%.2f KB", bytes / 2**10)
359
- else
360
- sprintf("%.2f bytes", bytes)
361
- end
362
- end
363
-
364
-
365
- output_file.puts("")
366
- output_file.puts("* Average DEVICE usage: #{device}")
367
- output_file.puts(" read IOPS: #{r_iops_str}")
368
- output_file.puts(" write IOPS: #{w_iops_str}")
369
- output_file.puts(" read throughput: #{r_sec_str} MB/s")
370
- output_file.puts(" write throughput: #{w_sec_str} MB/s")
371
- output_file.puts(" read latency: #{r_await_str}")
372
- output_file.puts(" write latency: #{w_await_str}")
373
- output_file.puts(" read amount: #{total_r_bytes_str}")
374
- output_file.puts(" write amount: #{total_w_bytes_str}")
375
- end
376
-
377
- if summary['ioinfo']['devices'].size > 1
378
- total_r_iops_str, total_w_iops_str, total_r_sec_str, total_w_sec_str =
379
- [total_r_iops, total_w_iops, total_r_sec, total_w_sec].map do |value|
380
- sprintf("%.2f", value)
381
- end
74
+ cmd << "-json"
75
+ end
382
76
 
383
- output_file.puts("")
384
- output_file.puts("* TOTAL DEVICE usage: #{summary['ioinfo']['devices'].join(', ')}")
385
- output_file.puts(" read IOPS: #{total_r_iops_str}")
386
- output_file.puts(" write IOPS: #{total_w_iops_str}")
387
- output_file.puts(" read throughput: #{total_r_sec_str} MB/s")
388
- output_file.puts(" write throughput: #{total_w_sec_str} MB/s")
389
- end
77
+ cmd << "-title"
78
+ cmd << summary_title
390
79
 
391
- output_file.puts("")
392
- end
80
+ cmd << @logfile
393
81
 
394
- if output_file != $stdout
395
- output_file.close
396
- end
397
- end
82
+ Process.exec(*cmd)
398
83
  end
399
84
  end
400
85
 
@@ -1,5 +1,3 @@
1
- # This file is automatically generated by Autoconf: 2014-06-23 19:42:25
2
-
3
1
  module PerfMonger
4
- VERSION = "0.6.1"
2
+ VERSION = "0.7.0"
5
3
  end
data/lib/perfmonger.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  require 'perfmonger/version.rb'
2
2
  require 'perfmonger/config.rb'
3
3
  require 'perfmonger/cli.rb'
4
+ require 'perfmonger/command/core.rb'
4
5
  require 'perfmonger/command/base_command.rb'
5
6
  require 'perfmonger/command/record.rb'
6
7
  require 'perfmonger/command/record_option.rb'
8
+ require 'perfmonger/command/live.rb'
7
9
  require 'perfmonger/command/stat.rb'
8
10
  require 'perfmonger/command/stat_option.rb'
9
11
  require 'perfmonger/command/summary.rb'
12
+ require 'perfmonger/command/play.rb'
10
13
  require 'perfmonger/command/plot.rb'
11
14
  require 'perfmonger/command/server.rb'
12
15
  require 'perfmonger/command/fingerprint.rb'
data/misc/_perfmonger ADDED
@@ -0,0 +1,128 @@
1
+ #compdef perfmonger
2
+
3
+ _perfmonger-record() {
4
+ local curcontext=$curcontext state line ret=1
5
+ declare -A opt_args
6
+
7
+ # TODO: match -d,--device multiple times
8
+ _arguments -w -C -S \
9
+ '(-D --all-devices)'{-d,--device}'[device name to be monitored]: :__perfmonger_devices' \
10
+ '(-d --device)'{-D,--all-devices}'[monitor all devices]' \
11
+ '(-i --interval)'{-i,--interval}'[measurement interval]: interval in sec' \
12
+ {-l,--logfile}'[log file name]:_files' \
13
+ {-B,--no-interval-backoff}'[prevent interval backoff]' \
14
+ {-s,--start-delay}'[wait specified time before starting measurement]: wait time in sec' \
15
+ {-t,--timeout}'[length of measurement time]: timeout in sec' \
16
+ {-C,--cpu}'[report CPU usage]' \
17
+ {-S,--context-switch}'[report context switches per sec]' \
18
+ {-v,--verbose}'[verbose]' \
19
+ {-h,--help}'[show help]' \
20
+ && return
21
+ }
22
+
23
+ _perfmonger-stat() {
24
+ local ret
25
+ _call_function ret _perfmonger-record
26
+ return ret
27
+ }
28
+
29
+ _perfmonger-summary() {
30
+ local curcontext=$curcontext state line ret=1
31
+ declare -A opt_args
32
+
33
+ # TODO: accept only 1 file
34
+ _arguments -w -C -S \
35
+ '--json[output summary in JSON format]' \
36
+ {-p,--pager}'[use pager to see summary output]: pager program' \
37
+ {-h,--help}'[show help]' \
38
+ {-h,--help}'[show help]' \
39
+ '*:: :_files' \
40
+ && return
41
+ }
42
+
43
+ _perfmonger-plot() {
44
+ local curcontext=$curcontext state line ret=1
45
+ declare -A opt_args
46
+
47
+ # TODO: accept only 1 file
48
+ _arguments -w -C -S \
49
+ '--offset-time: offset time in sec' \
50
+ {-o,--output-dir}'[output directory]:_directories' \
51
+ {-T,--output-type}'[output image type]:output type:(pdf png)' \
52
+ {-p,--prefix}'[output file name prefix]:prefix' \
53
+ {-s,--save}'[save gnuplot script and data files]' \
54
+ {-h,--help}'[show help]' \
55
+ '*:: :_files' \
56
+ && return
57
+ }
58
+
59
+ _perfmonger-fingerprint() {
60
+ local curcontext=$curcontext state line ret=1
61
+ declare -A opt_args
62
+
63
+ _arguments -w -C -S \
64
+ '*::output tarball:_files -g "*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|)|(tbz|tgz|txz))(-.)"' \
65
+ {-h,--help}'[show help]' \
66
+ && return
67
+ }
68
+
69
+ _perfmonger-server() {
70
+ local curcontext=$curcontext state line ret=1
71
+ declare -A opt_args
72
+
73
+ # TODO: complete record options after '--'
74
+ _arguments -w -C \
75
+ {-H,--hostname}'[host name to display]:host name' \
76
+ '--http-host[host name for HTTP URL]:host name' \
77
+ '--port[port number]:port number' \
78
+ {-h,--help}'[show help]' \
79
+ && return
80
+
81
+ return $ret
82
+ }
83
+
84
+ __perfmonger_devices() {
85
+ _values 'device' $(tail -n +3 /proc/partitions | awk '{print $4}')
86
+ }
87
+
88
+ # main completion function
89
+ # (( $+functions[_perfmonger] )) ||
90
+ _perfmonger() {
91
+ local curcontext context state line
92
+ declare -A opt_args
93
+
94
+ integer ret=1
95
+
96
+ _arguments -C -S \
97
+ '(- :)'{-h,--help}'[show help]' \
98
+ '(- :)'{-v,--version}'[show version]' \
99
+ '(-): :->commands' \
100
+ '(-)*:: :->option-or-argument' && return
101
+
102
+ case $state in
103
+ (commands)
104
+ _perfmonger_commands && ret=0
105
+ ;;
106
+ (option-or-argument)
107
+ if (( $+functions[_perfmonger-$words[1]] )); then
108
+ _call_function ret _perfmonger-$words[1]
109
+ else
110
+ _message 'unknown sub-command'
111
+ fi
112
+ ;;
113
+ esac
114
+
115
+ return $ret
116
+ }
117
+
118
+ _perfmonger_commands() {
119
+ _values 'command' \
120
+ 'record[record system performance]' \
121
+ 'stat[run a command and record system performance during execution]' \
122
+ 'plot[plot system performance graphs from a perfmonger log file]' \
123
+ 'fingerprint[gather all possible system config information]' \
124
+ 'server[launch self-contained HTML5 realtime graph server]' \
125
+ 'summary[show summary of a perfmonger log file]'
126
+ }
127
+
128
+ compdef _perfmonger perfmonger
@@ -0,0 +1,49 @@
1
+ # bash completion support for PerfMonger
2
+
3
+ _perfmonger() {
4
+ local cmd cur prev subcmd
5
+ cmd=$1
6
+ cur=$2
7
+ prev=$3
8
+
9
+ subcmds="record stat plot fingerprint server summary"
10
+
11
+ # contextual completion
12
+ case $prev in
13
+ perfmonger)
14
+ COMPREPLY=( $(compgen -W "$subcmds" $cur) )
15
+ return 0
16
+ ;;
17
+ -d|--device)
18
+ COMPREPLY=( $(tail -n +3 /proc/partitions | awk '{print $4}') )
19
+ return 0
20
+ ;;
21
+ -l|--logfile)
22
+ COMPREPLY=( $(compgen -o default) )
23
+ return 0
24
+ ;;
25
+ -i|--interval|-s|--start-delay|-t|--timeout)
26
+ COMPREPLY=()
27
+ return 0
28
+ ;;
29
+ esac
30
+
31
+ # complete options
32
+ subcmd=${COMP_WORDS[1]}
33
+
34
+ case "$cur" in
35
+ # complete options
36
+ -*)
37
+ COMPREPLY=( $(compgen -W "$(perfmonger $subcmd -h | egrep -o ' ([-][[:alnum:]]|-{2}[[:alnum:]-]+)\b')" -- "$cur") )
38
+ return 0
39
+ ;;
40
+ *)
41
+ COMPREPLY=( $(compgen -o default "$cur") )
42
+ return 0
43
+ ;;
44
+ esac
45
+
46
+ return 0
47
+ }
48
+
49
+ complete -F _perfmonger perfmonger
data/perfmonger.gemspec CHANGED
@@ -1,12 +1,11 @@
1
1
  # -*- mode: ruby -*-
2
2
 
3
3
  $:.push File.expand_path("../lib", __FILE__)
4
- require 'perfmonger'
4
+ require 'perfmonger/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'perfmonger'
8
8
  s.version = PerfMonger::VERSION
9
- s.date = '2015-01-19'
10
9
  s.summary = "yet anothor performance measurement/monitoring tool"
11
10
  s.description = "yet anothor performance measurement/monitoring tool"
12
11
  s.authors = ["Yuto HAYAMIZU"]
@@ -14,18 +13,20 @@ Gem::Specification.new do |s|
14
13
  s.homepage = 'http://github.com/hayamiz/perfmonger/'
15
14
  s.license = 'GPL-2'
16
15
 
17
- s.required_ruby_version = '>= 1.9.0'
16
+ s.required_ruby_version = '>= 1.9.3'
18
17
 
18
+ s.add_development_dependency "bundler"
19
19
  s.add_development_dependency "rake"
20
20
  s.add_development_dependency "rspec"
21
21
  s.add_development_dependency "rake-compiler"
22
+ s.add_development_dependency "guard-rspec"
23
+ s.add_development_dependency "aruba"
22
24
 
23
25
  s.files = `git ls-files`.split("\n")
26
+ s.files += Dir.glob("lib/exec/*")
24
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
28
  s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
26
29
 
27
- s.extensions << 'ext/perfmonger/extconf.rb'
28
-
29
30
  s.post_install_message = <<EOS
30
31
 
31
32
  ============================================================
Binary file
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ describe '[fingerprint] subcommand' do
5
+ before(:each) do
6
+ @old_pwd = Dir.pwd
7
+ @tmpdir = Dir.mktmpdir
8
+ Dir.chdir(@tmpdir)
9
+ end
10
+
11
+ after(:each) do
12
+ Dir.chdir(@old_pwd)
13
+ FileUtils.rm_rf(@tmpdir)
14
+ end
15
+
16
+ it 'should create output tgz successfully' do
17
+ run("#{perfmonger_bin} fingerprint output.tgz", 20)
18
+ assert_success(true)
19
+ check_file_presence("output.tgz")
20
+ end
21
+
22
+ it 'should create output tgz successfully with alias invocation' do
23
+ run("#{perfmonger_bin} fp output.tgz", 20)
24
+ assert_success(true)
25
+ check_file_presence("output.tgz")
26
+ end
27
+
28
+ it "should create output tgz successfully with content" do
29
+ run("#{perfmonger_bin} fingerprint output.tgz", 20)
30
+ assert_success(true)
31
+ run("tar xf output.tgz")
32
+ assert_success(true)
33
+ check_directory_presence(["output"], true)
34
+ end
35
+ end
data/spec/live_spec.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe '[live] subcommand' do
4
+ before(:each) do
5
+ skip_if_proc_is_not_available
6
+ end
7
+
8
+ it 'should print JSON records for 3 seconds and exit successfully.' do
9
+ cmd = "#{perfmonger_bin} live --timeout 3"
10
+ run(cmd, 5)
11
+ assert_success(true)
12
+ expect(stdout_from(cmd).lines.to_a.size).to eq 3
13
+
14
+ stdout_from(cmd).each_line do |line|
15
+ expect do
16
+ JSON.parse(line)
17
+ end.not_to raise_error
18
+
19
+ json = JSON.parse(line)
20
+ expect(json.keys.sort).to eq %w{time cpu disk net}.sort
21
+ end
22
+
23
+ check_file_presence("perfmonger.pgr")
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe "perfmonger command" do
5
+ it "should be an executable" do
6
+ expect(File.executable?(perfmonger_bin)).to be true
7
+ end
8
+
9
+ it 'should print help and exit with failure when no arguments given' do
10
+ cmd = "#{perfmonger_bin}"
11
+ run(cmd)
12
+ assert_success(false)
13
+ expect(stdout_from(cmd)).to match(/^Usage: perfmonger/)
14
+ end
15
+
16
+ it 'should print help and exit with success when --help is given' do
17
+ ["-h", "--help"].each do |arg|
18
+ cmd = "#{perfmonger_bin} #{arg}"
19
+ run(cmd)
20
+ assert_success(true)
21
+ expect(stdout_from(cmd)).to match(/^Usage: perfmonger/)
22
+ end
23
+ end
24
+
25
+ it 'should print version number if --version given' do
26
+ cmd = "#{perfmonger_bin} --version"
27
+ run(cmd)
28
+ assert_success(true)
29
+ expect(stdout_from(cmd)).to include(PerfMonger::VERSION)
30
+ end
31
+
32
+ it 'fails if unknown subcommand given' do
33
+ cmd = "#{perfmonger_bin} piyo"
34
+ run(cmd)
35
+ assert_success(false)
36
+ end
37
+ end