capistrano-measure 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eadd92174e96e597201141c0a2f294990ec9d07c
4
+ data.tar.gz: 27ce160e16255e34390600ee63da024ca96419fd
5
+ SHA512:
6
+ metadata.gz: 62bc32ba3dc76fe31d7ddf03f028d940c0ce3efaf746cda5b572d0ab7082d04c677faa6936a4c666a65686af1462731d2ca063f9832849d4c8f0320140fe685d
7
+ data.tar.gz: 7c6c040eb11a1ad307593e384c347c10c264da91b3e7ff00e7cfc9b00beee376763173ce7899237ce3da8dbcedf8e141e102fd513632de144dd34c83a7d44ab7
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-measure.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Artūrs Mekšs
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Capistrano::Measure - deployment speed measure tool
2
+
3
+ In order to improve something you have to measure it! This helps you measure performance of your Capistrano deployments by appending performance reports after each Capistrano execution
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'capistrano-measure'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install capistrano-measure
20
+
21
+ Enable it in `Capfile`
22
+
23
+ require 'capistrano/measure'
24
+
25
+ ## Usage
26
+ It will append every capistrano execution with similar report
27
+
28
+ ...
29
+ INFO[adb409a1] Finished in 0.050 seconds with exit status 0 (successful).
30
+ I, [2014-10-23T18:10:31.384161 #14352] INFO -- : ==========================================================
31
+ I, [2014-10-23T18:10:31.384214 #14352] INFO -- : Performance Report
32
+ I, [2014-10-23T18:10:31.384234 #14352] INFO -- : ==========================================================
33
+ I, [2014-10-23T18:10:31.384289 #14352] INFO -- : upgrade
34
+ I, [2014-10-23T18:10:31.384391 #14352] INFO -- : ..load:defaults 0s
35
+ I, [2014-10-23T18:10:31.384437 #14352] INFO -- : ..rbenv:validate 0s
36
+ I, [2014-10-23T18:10:31.384474 #14352] INFO -- : ..rbenv:map_bins 0s
37
+ I, [2014-10-23T18:10:31.384510 #14352] INFO -- : ..bundler:map_bins 0s
38
+ I, [2014-10-23T18:10:31.384576 #14352] INFO -- : ..deploy:set_rails_env 0s
39
+ I, [2014-10-23T18:10:31.384611 #14352] INFO -- : upgrade 0s
40
+ I, [2014-10-23T18:10:31.384636 #14352] INFO -- : deploy
41
+ I, [2014-10-23T18:10:31.384658 #14352] INFO -- : ..deploy:starting
42
+ I, [2014-10-23T18:10:31.384681 #14352] INFO -- : ....deploy:check
43
+ I, [2014-10-23T18:10:31.384715 #14352] INFO -- : ......deploy:check:directories 0s
44
+ I, [2014-10-23T18:10:31.384780 #14352] INFO -- : ......deploy:check:linked_dirs 0s
45
+ I, [2014-10-23T18:10:31.384819 #14352] INFO -- : ......deploy:check:make_linked_dirs 0s
46
+ I, [2014-10-23T18:10:31.384856 #14352] INFO -- : ......deploy:check:linked_files 0s
47
+ I, [2014-10-23T18:10:31.384888 #14352] INFO -- : ....deploy:check 1s
48
+ I, [2014-10-23T18:10:31.384924 #14352] INFO -- : ....deploy:set_previous_revision 0s
49
+ I, [2014-10-23T18:10:31.384957 #14352] INFO -- : ..deploy:starting 1s
50
+ I, [2014-10-23T18:10:31.385020 #14352] INFO -- : ..deploy:started 0s
51
+ I, [2014-10-23T18:10:31.385058 #14352] INFO -- : ..deploy:new_release_path 0s
52
+ I, [2014-10-23T18:10:31.385084 #14352] INFO -- : ..deploy:updating
53
+ I, [2014-10-23T18:10:31.385148 #14352] INFO -- : ....deploy:set_current_revision 0s
54
+ I, [2014-10-23T18:10:31.385176 #14352] INFO -- : ....deploy:symlink:shared
55
+ I, [2014-10-23T18:10:31.385210 #14352] INFO -- : ......deploy:symlink:linked_files 0s
56
+ I, [2014-10-23T18:10:31.385247 #14352] INFO -- : ......deploy:symlink:linked_dirs 1s
57
+ I, [2014-10-23T18:10:31.385283 #14352] INFO -- : ....deploy:symlink:shared 1s
58
+ I, [2014-10-23T18:10:31.385315 #14352] INFO -- : ..deploy:updating 3s
59
+ I, [2014-10-23T18:10:31.385378 #14352] INFO -- : ..bundler:install 0s
60
+ I, [2014-10-23T18:10:31.385403 #14352] INFO -- : ..deploy:updated
61
+ I, [2014-10-23T18:10:31.385426 #14352] INFO -- : ....deploy:compile_assets
62
+ I, [2014-10-23T18:10:31.385467 #14352] INFO -- : ......deploy:assets:precompile 48s
63
+ I, [2014-10-23T18:10:31.385504 #14352] INFO -- : ......deploy:assets:backup_manifest 0s
64
+ I, [2014-10-23T18:10:31.385536 #14352] INFO -- : ....deploy:compile_assets 48s
65
+ I, [2014-10-23T18:10:31.385587 #14352] INFO -- : ....deploy:normalize_assets 0s
66
+ I, [2014-10-23T18:10:31.385623 #14352] INFO -- : ....deploy:migrate 23s
67
+ I, [2014-10-23T18:10:31.385657 #14352] INFO -- : ....whenever:update_crontab 1s
68
+ I, [2014-10-23T18:10:31.385690 #14352] INFO -- : ..deploy:updated 73s
69
+ I, [2014-10-23T18:10:31.385728 #14352] INFO -- : ..deploy:copy_config 0s
70
+ I, [2014-10-23T18:10:31.385753 #14352] INFO -- : ..deploy:publishing
71
+ I, [2014-10-23T18:10:31.385796 #14352] INFO -- : ....deploy:symlink:release 0s
72
+ I, [2014-10-23T18:10:31.385829 #14352] INFO -- : ..deploy:publishing 0s
73
+ I, [2014-10-23T18:10:31.385867 #14352] INFO -- : ..deploy:restart 10s
74
+ I, [2014-10-23T18:10:31.385911 #14352] INFO -- : ..deploy:generate_error_pages 5s
75
+ I, [2014-10-23T18:10:31.385945 #14352] INFO -- : ..delayed_job:restart 8s
76
+ I, [2014-10-23T18:10:31.385994 #14352] INFO -- : ..deploy:published 0s
77
+ I, [2014-10-23T18:10:31.386019 #14352] INFO -- : ..deploy:finishing
78
+ I, [2014-10-23T18:10:31.386052 #14352] INFO -- : ....deploy:cleanup 0s
79
+ I, [2014-10-23T18:10:31.386083 #14352] INFO -- : ..deploy:finishing 0s
80
+ I, [2014-10-23T18:10:31.386107 #14352] INFO -- : ..deploy:finished
81
+ I, [2014-10-23T18:10:31.386142 #14352] INFO -- : ....deploy:log_revision 0s
82
+ I, [2014-10-23T18:10:31.386192 #14352] INFO -- : ..deploy:finished 0s
83
+ I, [2014-10-23T18:10:31.386225 #14352] INFO -- : deploy 104s
84
+ I, [2014-10-23T18:10:31.386246 #14352] INFO -- : ==========================================================
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it ( https://github.com/[my-github-username]/capistrano-measure/fork )
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/measure/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capistrano-measure"
8
+ spec.version = Capistrano::Measure::VERSION
9
+ spec.authors = ["Artūrs Mekšs"]
10
+ spec.email = ["arturs.mekss@tieto.com"]
11
+ spec.summary = "Capistrano deployment speed measure tool"
12
+ spec.description = "In order to improve something you have to measure it! This helps you measure performance of your Capistrano deployments by appending performance reports after each Capistrano execution"
13
+ spec.homepage = "https://github.com/AMekss/capistrano-measure.git"
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "capistrano", ">= 2", "< 4"
21
+ spec.add_dependency "colored", "~> 1.2"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency 'timecop', '~> 0.7'
27
+
28
+ end
@@ -0,0 +1,30 @@
1
+ module Capistrano
2
+ module Measure
3
+ class Adapter
4
+
5
+ def self.capistrano_version
6
+ return ::Capistrano::Version::MAJOR.to_i if defined?(::Capistrano::Version::MAJOR)
7
+ return ::Capistrano::VERSION[0].to_i if defined?(::Capistrano::VERSION)
8
+ nil
9
+ end
10
+
11
+ def initialize(logger=nil)
12
+ @timer = Capistrano::Measure::Timer.new
13
+ @log_reporter = Capistrano::Measure::LogReporter.new(logger)
14
+ end
15
+
16
+ def before_task(task_name)
17
+ @timer.start(task_name)
18
+ end
19
+
20
+ def after_task(task_name)
21
+ @timer.stop(task_name)
22
+ end
23
+
24
+ def print_report
25
+ @log_reporter.render(@timer.report_events)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do |config|
2
+ adapter = Capistrano::Measure::Adapter.new(logger)
3
+
4
+ on :before do
5
+ adapter.before_task(current_task.fully_qualified_name)
6
+ end
7
+
8
+ on :after do
9
+ adapter.after_task(current_task.fully_qualified_name)
10
+ end
11
+
12
+ config.on :exit do
13
+ adapter.print_report
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ module Capistrano
2
+ module Measure
3
+ module Integration
4
+ module Capistrano3
5
+ def measure_adapter
6
+ @measure_adapter ||= Capistrano::Measure::Adapter.new
7
+ end
8
+
9
+ def insert_measuer_tasks
10
+ Rake.application.tasks.each do |current_task|
11
+ before(current_task, :"bm_#{current_task}_before_hook") do
12
+ measure_adapter.before_task(current_task)
13
+ end
14
+
15
+ after(current_task, :"bm_#{current_task}_after_hook") do
16
+ measure_adapter.after_task(current_task)
17
+ end
18
+ end
19
+ end
20
+
21
+ def invoke_task(task_string)
22
+ name, _ = parse_task_string(task_string)
23
+
24
+ insert_measuer_tasks if top_level_tasks.first == name
25
+ super(task_string)
26
+ measure_adapter.print_report if top_level_tasks.last == name
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module Capistrano
34
+ class Application
35
+ include Capistrano::Measure::Integration::Capistrano3
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'colored'
2
+ require 'logger'
3
+
4
+ module Capistrano
5
+ module Measure
6
+ class LogReporter
7
+ ALERT_TRASHOLD = 60
8
+ WARNING_TRASHOLD = 30
9
+
10
+ def initialize(logger=nil)
11
+ @logger = logger || ::Logger.new(STDOUT)
12
+ end
13
+
14
+ def render(events)
15
+ return if events.to_a.empty?
16
+
17
+ log_sepertor
18
+ log " Performance Report".green
19
+ log_sepertor
20
+
21
+ events.each do |event|
22
+ log "#{'..' * event.indent}#{event.name} #{colorize_time(event.elapsed_time)}"
23
+ end
24
+ log_sepertor
25
+ end
26
+
27
+ private
28
+
29
+ def log_sepertor
30
+ log "=========================================================="
31
+ end
32
+
33
+ def log(text)
34
+ @logger.info text
35
+ end
36
+
37
+ def colorize_time(time_spent)
38
+ return if time_spent.nil?
39
+ color = (time_spent > ALERT_TRASHOLD ? :red : (time_spent > WARNING_TRASHOLD ? :yellow : :green))
40
+ "#{time_spent}s".send(color)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,66 @@
1
+ module Capistrano
2
+ module Measure
3
+ class Timer
4
+ attr_reader :events
5
+
6
+ Event = Struct.new(:name, :action, :time, :indent, :elapsed_time) do
7
+ def id
8
+ "#{name}_#{indent}".freeze
9
+ end
10
+
11
+ def eq?(event)
12
+ id == event.id
13
+ end
14
+
15
+ def start?
16
+ action == :start
17
+ end
18
+ end
19
+
20
+ def initialize
21
+ @indent = 0
22
+ @open_events = []
23
+ @events = []
24
+ end
25
+
26
+ def start(event_name)
27
+ event = Event.new(event_name, :start, Time.now, @indent)
28
+ @open_events << event
29
+ @events << event
30
+ @indent += 1
31
+
32
+ event
33
+ end
34
+
35
+ def stop(event_name)
36
+ event = close_event(event_name)
37
+ @open_events.pop
38
+ @events << event
39
+ @indent = event.indent
40
+
41
+ event
42
+ end
43
+
44
+ def report_events
45
+ raise 'Performance measure is not completed' unless @open_events.empty?
46
+ return to_enum(__callee__) unless block_given?
47
+
48
+ (events + [Event.new]).each_cons(2) do |event, next_event|
49
+ yield event unless event.start? && event.eq?(next_event)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def close_event(event_name)
56
+ event = Event.new(event_name, :stop, Time.now, @indent-1)
57
+ open_event = @open_events.last
58
+ raise "You're trying to stop unstarted event" unless event.eq?(open_event)
59
+
60
+ event.elapsed_time = (event.time - open_event.time).to_i
61
+ event
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module Measure
3
+ VERSION = "0.8.0"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'capistrano'
2
+ require 'capistrano/measure/version'
3
+ require 'capistrano/measure/timer'
4
+ require 'capistrano/measure/log_reporter'
5
+ require 'capistrano/measure/adapter'
6
+
7
+ case ::Capistrano::Measure::Adapter::capistrano_version
8
+ when 2
9
+ require 'capistrano/measure/integration/capistrano_2'
10
+ when 3
11
+ require 'capistrano/measure/integration/capistrano_3'
12
+ else
13
+ raise 'This version of Capistrano is not supported.'
14
+ end
15
+
16
+ module Capistrano
17
+ module Measure
18
+
19
+ end
20
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'capistrano/measure/timer'
3
+ require 'capistrano/measure/log_reporter'
4
+ require 'capistrano/measure/adapter'
5
+
6
+ describe Capistrano::Measure::Adapter do
7
+ let(:logger) { ::StringLogger.new }
8
+ subject { Capistrano::Measure::Adapter.new(logger) }
9
+
10
+ it "end-to-end test" do
11
+ subject.before_task('root_task')
12
+ subject.before_task('sub_task')
13
+ subject.before_task('sub_task1')
14
+ subject.after_task('sub_task1')
15
+ subject.after_task('sub_task')
16
+ subject.before_task('sub_task')
17
+ subject.after_task('sub_task')
18
+ subject.after_task('root_task')
19
+
20
+ subject.print_report
21
+
22
+ expect(logger.to_s).not_to be_empty
23
+ end
24
+
25
+ describe "::capistrano_version" do
26
+ subject { Capistrano::Measure::Adapter }
27
+
28
+ it "should return nil if Capistrano version isn't recognizable" do
29
+ expect(subject.capistrano_version).to be_nil
30
+ end
31
+
32
+ it "should detect Capistrano 2 version" do
33
+ stub_const('Capistrano::Version::MAJOR', 2)
34
+ expect(subject.capistrano_version).to eq 2
35
+ end
36
+
37
+ it "should detect Capistrano 3 version" do
38
+ stub_const('Capistrano::VERSION', '3.0.1')
39
+ expect(subject.capistrano_version).to eq 3
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'capistrano/measure/log_reporter'
3
+
4
+ LogItem = Struct.new(:indent, :name, :elapsed_time)
5
+
6
+ describe Capistrano::Measure::LogReporter do
7
+ let(:logger) { ::StringLogger.new }
8
+ subject { Capistrano::Measure::LogReporter.new(logger) }
9
+
10
+ it "should be able to create with default logger" do
11
+ expect(::Logger).to receive(:new).with(STDOUT)
12
+ Capistrano::Measure::LogReporter.new
13
+ end
14
+
15
+ describe "#render" do
16
+ {green: [0, 30], yellow: [31, 60], red: [61, 100]}.each do |color, times|
17
+ times.each do |elapsed_time|
18
+ it "should render line with time in #{color} when elapsed time eq #{elapsed_time}" do
19
+ subject.render([LogItem.new(0, 'test', elapsed_time)])
20
+ colorized_time = "#{elapsed_time}s".send(color)
21
+
22
+ expect(logger.to_s).to include("test #{colorized_time}\n")
23
+ end
24
+ end
25
+ end
26
+
27
+ it "should not render empty report" do
28
+ subject.render([])
29
+ expect(logger.to_s).to eq ""
30
+ end
31
+
32
+ it "should include title" do
33
+ subject.render([LogItem.new(0, 'test')])
34
+ expect(logger.to_s).to include("Performance Report")
35
+ end
36
+
37
+ it "should render line without time if it missing" do
38
+ subject.render([LogItem.new(0, 'test')])
39
+ expect(logger.to_s).to include("test \n")
40
+ end
41
+
42
+ it "should render items with indention" do
43
+ subject.render([LogItem.new(1, 'test1'), LogItem.new(2, 'test2')])
44
+ expect(logger.to_s).to include("..test1 \n")
45
+ expect(logger.to_s).to include("....test2 \n")
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+ require 'capistrano/measure/timer'
3
+
4
+ describe Capistrano::Measure::Timer do
5
+ describe "#start" do
6
+ it "should increase events array" do
7
+ expect(subject.events.size).to eq 0
8
+ event = subject.start('test')
9
+ expect(subject.events.size).to eq 1
10
+ expect(subject.events.last).to eq event
11
+ end
12
+
13
+ it "should produce start event" do
14
+ Timecop.freeze do
15
+ event = subject.start('test')
16
+
17
+ expect(event.name).to eq 'test'
18
+ expect(event.action).to eq :start
19
+ expect(event.time).to eq Time.now
20
+ expect(event.elapsed_time).to be_nil
21
+ end
22
+ end
23
+
24
+ it "should increase event's indent on every subsequent method call" do
25
+ event = subject.start('test')
26
+ expect(event.indent).to eq 0
27
+
28
+ event = subject.start('test1')
29
+ expect(event.indent).to eq 1
30
+ end
31
+ end
32
+
33
+ describe "#stop" do
34
+ before(:each) do
35
+ subject.start('test')
36
+ subject.start('test1')
37
+ end
38
+
39
+ it "should increase events array" do
40
+ expect(subject.events.size).to eq 2
41
+ event = subject.stop('test1')
42
+ expect(subject.events.size).to eq 3
43
+ expect(subject.events.last).to eq event
44
+ end
45
+
46
+ it "should produce stop event" do
47
+ Timecop.freeze do
48
+ event = subject.stop('test1')
49
+
50
+ expect(event.name).to eq 'test1'
51
+ expect(event.action).to eq :stop
52
+ expect(event.time).to eq Time.now
53
+ end
54
+ end
55
+
56
+ it "should calculate elapsed time for closed events" do
57
+ Timecop.freeze do
58
+ subject.start('test1')
59
+
60
+ Timecop.travel(Time.now + 200) do
61
+ event = subject.stop('test1')
62
+ expect(event.elapsed_time).to eq 200
63
+ end
64
+ end
65
+ end
66
+
67
+ it "should decrease event's indent on every subsequent method call" do
68
+ subject.stop('test1')
69
+ event = subject.events.last
70
+ expect(event.indent).to eq 1
71
+
72
+ subject.stop('test')
73
+ event = subject.events.last
74
+ expect(event.indent).to eq 0
75
+ end
76
+
77
+ it "should raise exception with unstarted event" do
78
+ expect{ subject.stop('test123') }.to raise_exception
79
+ end
80
+ end
81
+
82
+ describe "#report_events" do
83
+ it "should raise exception if called in the middle of process" do
84
+ subject.start('test')
85
+ expect{ subject.report_events }.to raise_exception
86
+ end
87
+
88
+ context "in completed state" do
89
+ before(:each) do
90
+ subject.start('test')
91
+ subject.start('test1')
92
+ subject.stop('test1')
93
+ subject.stop('test')
94
+
95
+ subject.start('test')
96
+ subject.stop('test')
97
+ end
98
+
99
+ it { expect(subject.report_events).to be_a ::Enumerator }
100
+ it { expect(subject.report_events.to_a.size).to eq 4 }
101
+ end
102
+ end
103
+
104
+ end
@@ -0,0 +1,92 @@
1
+ require 'timecop'
2
+ require 'support/string_logger'
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
7
+ # file to always be loaded, without a need to explicitly require it in any files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need it.
15
+ #
16
+ # The `.rspec` file also contains a few flags that are not defaults but that
17
+ # users commonly want.
18
+ #
19
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
+ RSpec.configure do |config|
21
+ # rspec-expectations config goes here. You can use an alternate
22
+ # assertion/expectation library such as wrong or the stdlib/minitest
23
+ # assertions if you prefer.
24
+ config.expect_with :rspec do |expectations|
25
+ # This option will default to `true` in RSpec 4. It makes the `description`
26
+ # and `failure_message` of custom matchers include text for helper methods
27
+ # defined using `chain`, e.g.:
28
+ # be_bigger_than(2).and_smaller_than(4).description
29
+ # # => "be bigger than 2 and smaller than 4"
30
+ # ...rather than:
31
+ # # => "be bigger than 2"
32
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+
44
+ # The settings below are suggested to provide a good initial experience
45
+ # with RSpec, but feel free to customize to your heart's content.
46
+ =begin
47
+ # These two settings work together to allow you to limit a spec run
48
+ # to individual examples or groups you care about by tagging them with
49
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
50
+ # get run.
51
+ config.filter_run :focus
52
+ config.run_all_when_everything_filtered = true
53
+
54
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
55
+ # For more details, see:
56
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
57
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
58
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
59
+ config.disable_monkey_patching!
60
+
61
+ # This setting enables warnings. It's recommended, but in some cases may
62
+ # be too noisy due to issues in dependencies.
63
+ config.warnings = true
64
+
65
+ # Many RSpec users commonly either run the entire suite or an individual
66
+ # file, and it's useful to allow more verbose output when running an
67
+ # individual spec file.
68
+ if config.files_to_run.one?
69
+ # Use the documentation formatter for detailed output,
70
+ # unless a formatter has already been configured
71
+ # (e.g. via a command-line flag).
72
+ config.default_formatter = 'doc'
73
+ end
74
+
75
+ # Print the 10 slowest examples and example groups at the
76
+ # end of the spec run, to help surface which specs are running
77
+ # particularly slow.
78
+ config.profile_examples = 10
79
+
80
+ # Run specs in random order to surface order dependencies. If you find an
81
+ # order dependency and want to debug it, you can fix the order by providing
82
+ # the seed, which is printed after each run.
83
+ # --seed 1234
84
+ config.order = :random
85
+
86
+ # Seed global randomization in this process using the `--seed` CLI option.
87
+ # Setting this allows you to use `--seed` to deterministically reproduce
88
+ # test failures related to randomization by passing the same `--seed` value
89
+ # as the one that triggered the failure.
90
+ Kernel.srand config.seed
91
+ =end
92
+ end
@@ -0,0 +1,13 @@
1
+ require 'stringio'
2
+ require 'logger'
3
+
4
+ class StringLogger < Logger
5
+ def initialize
6
+ @strio = StringIO.new
7
+ super @strio
8
+ end
9
+
10
+ def to_s
11
+ @strio.string
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-measure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Artūrs Mekšs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '4'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '4'
33
+ - !ruby/object:Gem::Dependency
34
+ name: colored
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.2'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.7'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.7'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: timecop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.7'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.7'
103
+ description: In order to improve something you have to measure it! This helps you
104
+ measure performance of your Capistrano deployments by appending performance reports
105
+ after each Capistrano execution
106
+ email:
107
+ - arturs.mekss@tieto.com
108
+ executables: []
109
+ extensions: []
110
+ extra_rdoc_files: []
111
+ files:
112
+ - ".gitignore"
113
+ - ".rspec"
114
+ - Gemfile
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - capistrano-measure.gemspec
119
+ - lib/capistrano/measure.rb
120
+ - lib/capistrano/measure/adapter.rb
121
+ - lib/capistrano/measure/integration/capistrano_2.rb
122
+ - lib/capistrano/measure/integration/capistrano_3.rb
123
+ - lib/capistrano/measure/log_reporter.rb
124
+ - lib/capistrano/measure/timer.rb
125
+ - lib/capistrano/measure/version.rb
126
+ - spec/capistrano/measure/adapter_spec.rb
127
+ - spec/capistrano/measure/lib_reporter_spec.rb
128
+ - spec/capistrano/measure/timer_spec.rb
129
+ - spec/spec_helper.rb
130
+ - spec/support/string_logger.rb
131
+ homepage: https://github.com/AMekss/capistrano-measure.git
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.2.2
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Capistrano deployment speed measure tool
155
+ test_files:
156
+ - spec/capistrano/measure/adapter_spec.rb
157
+ - spec/capistrano/measure/lib_reporter_spec.rb
158
+ - spec/capistrano/measure/timer_spec.rb
159
+ - spec/spec_helper.rb
160
+ - spec/support/string_logger.rb