beaker-benchmark 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 922c931b423b9789170751154af7dc4a6a6329ec
4
- data.tar.gz: 2acd0c5534b6c7a435b8680f502b768cd8ff3e94
3
+ metadata.gz: d3d7e588bdbad5a3f018e49fa02f007aa9a6b80c
4
+ data.tar.gz: b2f79746d5e092f9e4fbdca47fe02010167a7e17
5
5
  SHA512:
6
- metadata.gz: 887223881be37ff961623e150fbf954232d3229a5d73dab2f9aefefc93467418c8e014408e068774dbadd8958515f23d54a144e5d53727bd8b8c929be2e06105
7
- data.tar.gz: 253c9dbb32aa9425cca0be231e4fcb40539a11b020ac43064e971b85e9eca8de3282f8f7f7d7136f09d2163722665dec4a370d071ca0dbe7a38dc06b038e77b6
6
+ metadata.gz: ad55ce1d5233f656f454b359491a12a21c04ece6dff547d6b0e687eb04fbdba234a29ee72038d0da1ac8f09eda556bee80840c38729475c3f1ac8b00e08426e1
7
+ data.tar.gz: ec1b08f2300581e6e8f20692b5f85084991561b6c9d611512cc9adc8143d6b41f32b28ae65a89e3e57941b28dd0f1062eaffc4c37a4f689eab1c2e70d34ccf24
@@ -0,0 +1,17 @@
1
+ require 'beaker-benchmark'
2
+ require 'fileutils'
3
+
4
+ # Acceptance level testing goes into files in the tests directory like this one,
5
+ # Each file corresponding to a new test made up of individual testing steps
6
+ test_name "measure_perf_on test" do
7
+ if Dir.exist?('tmp/atop')
8
+ FileUtils.rm_r('tmp/atop')
9
+ end
10
+ result = measure_perf_on master, 'sleep test' do
11
+ on master, 'sleep 10'
12
+ end
13
+
14
+ assert(File.exist?('tmp/atop/ubuntu-server-1404-x64/atop_log_measure_perf_on_test_sleep_test.log'))
15
+ result.log_csv
16
+ assert(File.exist?('tmp/atop/ubuntu-server-1404-x64/atop_log_measure_perf_on_test_sleep_test.csv'))
17
+ end
@@ -1,11 +1,36 @@
1
1
  require 'csv'
2
+ require 'fileutils'
2
3
 
3
4
  module Beaker
4
5
  module DSL
5
6
  module BeakerBenchmark
6
7
  module Helpers
8
+ include Beaker::HostPrebuiltSteps
9
+ # Column indexes for atop CSV style output
10
+ MEASURE_TYPE_INDEX = 0
7
11
 
8
- # Example usage:
12
+ SYSTEM_CPU_INDEX = 8
13
+ USR_CPU_INDEX = 9
14
+ IOWAIT_CPU_INDEX = 12
15
+ IDLE_CPU_INDEX = 11
16
+
17
+ MEM_INDEX = 10
18
+
19
+ DISK_READ_INDEX = 9
20
+ DISK_WRITE_INDEX = 11
21
+
22
+ PROC_PID_INDEX = 6
23
+
24
+ PROC_CPU_INDEX = 16
25
+
26
+ PROC_MEM_INDEX = 11
27
+
28
+ PROC_DISK_READ_INDEX = 11
29
+ PROC_DISK_WRITE_INDEX = 13
30
+
31
+ TMP_DIR = 'tmp/atop'
32
+
33
+ # Example usage:
9
34
  # test_name('measure_perf_on_puppetserver_start') {
10
35
  # on(master, 'puppet resource service pe-puppetserver ensure=stopped')
11
36
  # result = measure_perf_on(master, 'start_pe-puppetserver', true) {
@@ -21,63 +46,69 @@ module Beaker
21
46
  # Append action name to test case name if test name is available
22
47
  action_name = metadata[:case][:name] + "_#{action_name}" if defined? metadata && metadata[:case] && metadata[:case][:name]
23
48
 
24
- atop_log = 'atop_log.log'
25
-
26
- start_monitoring(infrastructure_host, atop_log, include_processes)
49
+ start_monitoring(infrastructure_host, action_name, include_processes)
27
50
 
28
51
  yield
29
52
 
30
- stop_monitoring(infrastructure_host, action_name, atop_log, include_processes.nil? ? nil : process_regex)
53
+ stop_monitoring(infrastructure_host, include_processes.nil? ? nil : process_regex)
31
54
  end
32
55
 
33
56
  def setup_atop(infrastructure_host)
34
- @benchmark_tmpdir = Dir.mktmpdir
35
57
  # Only install atop once per host
36
58
  unless infrastructure_host.check_for_package('atop')
37
- add_el_extras(infrastructure_host)
59
+ add_el_extras(infrastructure_host, @options)
38
60
  infrastructure_host.install_package('atop')
39
61
  end
40
62
  end
41
63
 
42
- def start_monitoring(infrastructure_host, atop_log, include_processes=false, sample_interval=1)
64
+ def start_monitoring(infrastructure_host, action_name, include_processes=false, sample_interval=1)
65
+ raise('Monitoring already in progress, call stop_monitoring before calling start_monitoring a second time') unless @beaker_benchmark_start.nil?
66
+ @atop_log = "atop_log_#{action_name.downcase.gsub(/[^a-z0-9]/i, '_')}.log"
67
+ @action_name = action_name
43
68
  setup_atop(infrastructure_host)
44
69
  additional_args = ''
45
70
  additional_args = ',PRC,PRM,PRD' if include_processes
46
- atop_cmd = "sh -c 'nohup atop -P CPU,SWP,DSK#{additional_args} -i #{sample_interval} > #{atop_log} 2>&1 &'"
71
+ atop_cmd = "sh -c 'nohup atop -P CPU,SWP,DSK#{additional_args} -i #{sample_interval} > #{@atop_log} 2>&1 &'"
47
72
 
48
73
  on(infrastructure_host, atop_cmd)
49
74
  @beaker_benchmark_start = Time.now
50
75
  end
51
76
 
52
- def stop_monitoring(infrastructure_host, action_name, atop_log_name, process_regex='.*')
53
- if defined?@beaker_benchmark_start && !@beaker_benchmark_start.nil?
54
- duration = Time.now - @beaker_benchmark_start
55
- else
56
- duration = nil
57
- end
77
+ def stop_monitoring(infrastructure_host, process_regex='.*')
78
+ begin
79
+ if defined?@beaker_benchmark_start && !@beaker_benchmark_start.nil?
80
+ duration = Time.now - @beaker_benchmark_start
81
+ else
82
+ raise('No monitoring in progress, call start_monitoring before calling stop_monitoring')
83
+ end
58
84
 
59
- # The atop process sticks around unless killed
60
- on infrastructure_host, 'pkill -15 -f atop'
61
- set_processes_to_monitor(infrastructure_host, process_regex)
62
- parse_atop_log(infrastructure_host, action_name, duration, atop_log_name)
85
+ # The atop process sticks around unless killed
86
+ # It can also take some time to kill depending on how long it has been running and sampling rate.
87
+ retry_on infrastructure_host, 'pkill -15 -f atop', {:max_retries => 3, :retry_interval => 5}
88
+ set_processes_to_monitor(infrastructure_host, process_regex)
89
+ parse_atop_log(infrastructure_host, duration)
90
+ ensure
91
+ @beaker_benchmark_start = nil
92
+ end
63
93
  end
64
94
 
65
- def parse_atop_log(infrastructure_host, action_name, duration, atop_log_name)
66
- unless infrastructure_host.file_exist?(atop_log_name)
67
- raise("atop log does not exist at #{atop_log_name}")
95
+ def parse_atop_log(infrastructure_host, duration)
96
+ unless infrastructure_host.file_exist?(@atop_log)
97
+ raise("atop log does not exist at #{@atop_log}")
68
98
  end
69
99
 
70
- scp_from(infrastructure_host, atop_log_name, '/tmp')
100
+ log_dir = "#{TMP_DIR}/#{infrastructure_host.hostname}"
101
+ FileUtils::mkdir_p log_dir unless Dir.exist? log_dir
102
+ scp_from(infrastructure_host, @atop_log, log_dir)
71
103
  cpu_usage = []
72
104
  mem_usage = []
73
105
  disk_read = []
74
106
  disk_write = []
75
107
 
76
- process_cpu = []
77
108
  skip = true
78
- CSV.parse(File.read("/tmp/#{File.basename(atop_log_name)}"), { :col_sep => ' ' }) do |row|
109
+ CSV.parse(File.read(File.expand_path(File.basename(@atop_log), log_dir)), { :col_sep => ' ' }) do |row|
79
110
  #skip the first entry, until the first separator 'SEP'.
80
- measure_type = row[0]
111
+ measure_type = row[MEASURE_TYPE_INDEX]
81
112
  if skip
82
113
  skip = (measure_type != 'SEP')
83
114
  next
@@ -85,28 +116,28 @@ module Beaker
85
116
  case measure_type
86
117
  when 'CPU'
87
118
  # system + usr + iowait
88
- cpu_active = row[8].to_i + row[9].to_i + row[12].to_i
119
+ cpu_active = row[SYSTEM_CPU_INDEX].to_i + row[USR_CPU_INDEX].to_i + row[IOWAIT_CPU_INDEX].to_i
89
120
  # active + idle
90
- cpu_total = cpu_active + row[11].to_i
121
+ cpu_total = cpu_active + row[IDLE_CPU_INDEX].to_i
91
122
  cpu_percent = cpu_active * 100 / cpu_total
92
123
  cpu_usage.push(cpu_percent)
93
124
  when 'SWP'
94
- mem_usage.push(row[10].to_i)
125
+ mem_usage.push(row[MEM_INDEX].to_i)
95
126
  when 'DSK'
96
- disk_read.push(row[9].to_i)
97
- disk_write.push(row[11].to_i)
127
+ disk_read.push(row[DISK_READ_INDEX].to_i)
128
+ disk_write.push(row[DISK_WRITE_INDEX].to_i)
98
129
  when 'PRC'
99
- add_process_measure(:cpu_usage, row[6], row[16].to_i)
130
+ add_process_measure(:cpu_usage, row[PROC_PID_INDEX], row[PROC_CPU_INDEX].to_i)
100
131
  when 'PRM'
101
- add_process_measure(:mem_usage, row[6], row[11].to_i)
132
+ add_process_measure(:mem_usage, row[PROC_PID_INDEX], row[PROC_MEM_INDEX].to_i)
102
133
  when 'PRD'
103
134
  # TODO: investigate why atop always shows disk_read as 0
104
- # add_process_measure(:disk_read, row[6], row[11].to_i)
105
- add_process_measure(:disk_write, row[6], row[13].to_i)
135
+ # add_process_measure(:disk_read, row[PROC_PID_INDEX], row[PROC_DISK_READ_INDEX].to_i)
136
+ add_process_measure(:disk_write, row[PROC_PID_INDEX], row[PROC_DISK_WRITE_INDEX].to_i)
106
137
  end
107
138
  end
108
139
 
109
- PerformanceResult.new({ :cpu => cpu_usage, :mem => mem_usage, :disk_read => disk_read, :disk_write => disk_write, :action => action_name, :duration => duration, :processes => @processes_to_monitor, :logger => @logger})
140
+ PerformanceResult.new({ :cpu => cpu_usage, :mem => mem_usage, :disk_read => disk_read, :disk_write => disk_write, :action => @action_name, :duration => duration, :processes => @processes_to_monitor, :logger => @logger, :hostname => infrastructure_host})
110
141
  end
111
142
 
112
143
  def set_processes_to_monitor(infrastructure_host, process_regex)
@@ -120,7 +151,6 @@ module Beaker
120
151
  @processes_to_monitor[line.split(' ').first] = { :cmd => line.split(' ')[1..-1].join(' '), :cpu_usage => [], :mem_usage => [], :disk_read => [], :disk_write => [] }
121
152
  end
122
153
  end
123
- @logger.info result.stdout
124
154
  end
125
155
 
126
156
  def add_process_measure measure_type, pid, value
@@ -136,7 +166,7 @@ module Beaker
136
166
  # Process pid: 14067, command: '/opt/puppetlabs/server/apps/postgresql/bin/postgres -D /opt/puppetlabs/server/data/postgresql/9.6/data -c log_directory=/var/log/puppetlabs/postgresql'
137
167
  # Avg CPU: '1', Avg MEM: 48888, Avg DSK Write: 20
138
168
  class PerformanceResult
139
- attr_accessor :avg_cpu, :avg_mem, :avg_disk_read, :avg_disk_write, :action_name, :duration, :processes
169
+ attr_accessor :avg_cpu, :avg_mem, :avg_disk_read, :avg_disk_write, :action_name, :duration, :processes, :hostname
140
170
  def initialize(args)
141
171
  @avg_cpu = args[:cpu].empty? ? 0 : args[:cpu].inject{ |sum, el| sum + el } / args[:cpu].size
142
172
  @avg_mem = args[:mem].empty? ? 0 : args[:mem].inject{ |sum, el| sum + el } / args[:mem].size
@@ -146,6 +176,8 @@ module Beaker
146
176
  @duration = args[:duration]
147
177
  @processes = args[:processes]
148
178
  @logger = args[:logger]
179
+ @hostname = args[:hostname] || ''
180
+
149
181
 
150
182
  @processes.keys.each do |key|
151
183
  @processes[key][:avg_cpu] = @processes[key][:cpu_usage].inject{ |sum, el| sum + el } / @processes[key][:cpu_usage].size unless @processes[key][:cpu_usage].empty?
@@ -165,6 +197,20 @@ module Beaker
165
197
  @logger.info " Avg CPU: '#{@processes[key][:avg_cpu]}%', Avg MEM: #{@processes[key][:avg_mem]}, Avg DSK read: #{@processes[key][:avg_disk_read]}, Avg DSK Write: #{@processes[key][:avg_disk_write]}"
166
198
  end
167
199
  end
200
+
201
+ def log_csv file_path=nil
202
+ file_path = file_path || "#{TMP_DIR}/#{@hostname}/atop_log_#{action_name.downcase.gsub(/[^a-z0-9]/i, '_')}.csv"
203
+ FileUtils.mkdir_p "#{TMP_DIR}/#{@hostname}/" unless Dir.exist?("#{TMP_DIR}/#{@hostname}/")
204
+ file = File.open file_path, 'w'
205
+ file.write "Action,Duration,Avg CPU,Avg MEM,Avg DSK read,Avg DSK Write\n"
206
+ file.write "#{@action_name},#{@duration},#{@avg_cpu},#{@avg_mem},#{@avg_disk_read},#{@avg_disk_write}\n\n"
207
+ file.write "Process pid,command,Avg CPU,Avg MEM,Avg DSK read,Avg DSK Write\n"
208
+ @processes.keys.each do |key|
209
+ file.write "#{key},'#{@processes[key][:cmd]}','#{@processes[key][:avg_cpu]},#{@processes[key][:avg_mem]},#{@processes[key][:avg_disk_read]},#{@processes[key][:avg_disk_write]}\n"
210
+ end
211
+ file.close
212
+ file.path
213
+ end
168
214
  end
169
215
 
170
216
  end
@@ -3,7 +3,7 @@ module Beaker
3
3
  module BeakerBenchmark
4
4
 
5
5
  module Version
6
- STRING = '0.0.1'
6
+ STRING = '0.0.2'
7
7
  end
8
8
 
9
9
  end
@@ -117,37 +117,6 @@ describe ClassMixedWithDSLHelpers do
117
117
 
118
118
  end
119
119
 
120
- describe 'PerformanceResult::initialize' do
121
-
122
- it 'properly averages arrays of values' do
123
-
124
- end
125
-
126
- it 'sets overall averages to 0 if no values are set' do
127
-
128
- end
129
-
130
- it 'raises an exception if :mem, :cpu, :disk_read or :disk_write args do not exist' do
131
-
132
- end
133
-
134
- it 'creates a result without no process data if @processes_to_monitor is empty or nil' do
135
-
136
- end
137
-
138
- it 'raises an exception if :mem, :cpu, :disk_read or :disk_write args do not exist' do
139
-
140
- end
141
-
142
- end
143
-
144
- describe 'PerformanceResult::log' do
145
-
146
- it 'prints out the results' do
147
-
148
- end
149
-
150
- end
151
120
  end
152
121
 
153
122
 
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ class ClassMixedWithDSLHelpers
4
+ include BeakerTestHelpers
5
+ include Beaker::DSL::BeakerBenchmark::Helpers
6
+
7
+ def logger
8
+ RSpec::Mocks::Double.new('logger').as_null_object
9
+ end
10
+
11
+ end
12
+
13
+ describe ClassMixedWithDSLHelpers do
14
+ subject { Beaker::DSL::BeakerBenchmark::Helpers::PerformanceResult.new (
15
+ {:cpu => [60, 40], :mem => [6000, 4000], :disk_write => [600, 400], :action => 'test_action', :duration => 10,
16
+ :processes => {1000 => {:cmd => 'proc1', :cpu_usage => [10, 20], :mem_usage => [1000, 2000], :disk_write => [100, 200]},
17
+ 2000 => {:cmd => 'proc2', :cpu_usage => [20, 40], :mem_usage => [2000, 4000], :disk_write => [200, 400]}},
18
+ :logger => logger, :hostname => 'my_host'}) }
19
+
20
+ describe 'initialize' do
21
+
22
+ it 'properly averages arrays of values' do
23
+
24
+ end
25
+
26
+ it 'sets overall averages to 0 if no values are set' do
27
+
28
+ end
29
+
30
+ it 'raises an exception if :mem, :cpu, :disk_read or :disk_write args do not exist' do
31
+
32
+ end
33
+
34
+ it 'creates a result without no process data if @processes_to_monitor is empty or nil' do
35
+
36
+ end
37
+
38
+ it 'raises an exception if :mem, :cpu, :disk_read or :disk_write args do not exist' do
39
+
40
+ end
41
+
42
+ end
43
+
44
+ describe 'log_summary' do
45
+
46
+ it 'prints out the results' do
47
+
48
+ end
49
+
50
+ end
51
+
52
+ describe 'log_csv' do
53
+
54
+ it 'prints out the results in CSV format' do
55
+ file_path = subject.log_csv
56
+ file = File.open file_path
57
+ csv_file_content = file.readlines
58
+ expected_content = <<-EOS
59
+ Process pid,command,Avg CPU,Avg MEM,Avg DSK read,Avg DSK Write
60
+ 1000,'proc1','15,1500,,150
61
+ 2000,'proc2','30,3000,,300
62
+ EOS
63
+ expect(csv_file_content == expected_content)
64
+ end
65
+
66
+ end
67
+
68
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker-benchmark
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppetlabs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-06 00:00:00.000000000 Z
11
+ date: 2018-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -167,13 +167,14 @@ files:
167
167
  - README.md
168
168
  - Rakefile
169
169
  - acceptance/config/nodes/vagrant-ubuntu-1404.yml
170
- - acceptance/tests/first.rb
170
+ - acceptance/tests/measure_perf_on.rb
171
171
  - beaker-benchmark.gemspec
172
172
  - bin/beaker-benchmark
173
173
  - lib/beaker-benchmark.rb
174
174
  - lib/beaker-benchmark/helpers.rb
175
175
  - lib/beaker-benchmark/version.rb
176
176
  - spec/beaker-benchmark/helpers_spec.rb
177
+ - spec/beaker-benchmark/performance_result_spec.rb
177
178
  - spec/beaker_test_helpers.rb
178
179
  - spec/helpers.rb
179
180
  - spec/spec_helper.rb
@@ -203,6 +204,7 @@ specification_version: 4
203
204
  summary: Beaker benchmark Helpers!
204
205
  test_files:
205
206
  - spec/beaker-benchmark/helpers_spec.rb
207
+ - spec/beaker-benchmark/performance_result_spec.rb
206
208
  - spec/beaker_test_helpers.rb
207
209
  - spec/helpers.rb
208
210
  - spec/spec_helper.rb
@@ -1,8 +0,0 @@
1
-
2
- # Acceptance level testing goes into files in the tests directory like this one,
3
- # Each file corresponding to a new test made up of individual testing steps
4
- test_name "Template Acceptance Test Example"
5
-
6
- step "Fail fast!"
7
-
8
- fail_test("There are no acceptance tests yet!")