perfmonger 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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