bigbench 0.0.1

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 (92) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/README.textile +81 -0
  4. data/Rakefile +10 -0
  5. data/bigbench.gemspec +29 -0
  6. data/bin/bigbench +6 -0
  7. data/doc/BigBench.html +631 -0
  8. data/doc/BigBench/Benchmark.html +328 -0
  9. data/doc/BigBench/Benchmark/Benchmark.html +431 -0
  10. data/doc/BigBench/Bot.html +233 -0
  11. data/doc/BigBench/Configuration.html +312 -0
  12. data/doc/BigBench/Configuration/Config.html +375 -0
  13. data/doc/BigBench/Configuration/InvalidOptions.html +217 -0
  14. data/doc/BigBench/Executor.html +252 -0
  15. data/doc/BigBench/Executor/InvalidCommand.html +222 -0
  16. data/doc/BigBench/Fragment.html +404 -0
  17. data/doc/BigBench/Fragment/Fragment.html +384 -0
  18. data/doc/BigBench/Output.html +703 -0
  19. data/doc/BigBench/Runner.html +222 -0
  20. data/doc/BigBench/Runner/NoBenchmarksDefined.html +217 -0
  21. data/doc/BigBench/Store.html +639 -0
  22. data/doc/BigBench/Tracker.html +179 -0
  23. data/doc/BigBench/Tracker/Tracker.html +273 -0
  24. data/doc/Float.html +217 -0
  25. data/doc/Gemfile.html +129 -0
  26. data/doc/Helpers.html +163 -0
  27. data/doc/Object.html +181 -0
  28. data/doc/Rakefile.html +136 -0
  29. data/doc/TestWebServer.html +247 -0
  30. data/doc/created.rid +31 -0
  31. data/doc/images/add.png +0 -0
  32. data/doc/images/brick.png +0 -0
  33. data/doc/images/brick_link.png +0 -0
  34. data/doc/images/bug.png +0 -0
  35. data/doc/images/bullet_black.png +0 -0
  36. data/doc/images/bullet_toggle_minus.png +0 -0
  37. data/doc/images/bullet_toggle_plus.png +0 -0
  38. data/doc/images/date.png +0 -0
  39. data/doc/images/delete.png +0 -0
  40. data/doc/images/find.png +0 -0
  41. data/doc/images/loadingAnimation.gif +0 -0
  42. data/doc/images/macFFBgHack.png +0 -0
  43. data/doc/images/package.png +0 -0
  44. data/doc/images/page_green.png +0 -0
  45. data/doc/images/page_white_text.png +0 -0
  46. data/doc/images/page_white_width.png +0 -0
  47. data/doc/images/plugin.png +0 -0
  48. data/doc/images/ruby.png +0 -0
  49. data/doc/images/tag_blue.png +0 -0
  50. data/doc/images/tag_green.png +0 -0
  51. data/doc/images/transparent.png +0 -0
  52. data/doc/images/wrench.png +0 -0
  53. data/doc/images/wrench_orange.png +0 -0
  54. data/doc/images/zoom.png +0 -0
  55. data/doc/index.html +122 -0
  56. data/doc/js/darkfish.js +153 -0
  57. data/doc/js/jquery.js +18 -0
  58. data/doc/js/navigation.js +142 -0
  59. data/doc/js/search.js +94 -0
  60. data/doc/js/search_index.js +1 -0
  61. data/doc/js/searcher.js +228 -0
  62. data/doc/lib/bigbench/help/executor_txt.html +145 -0
  63. data/doc/rdoc.css +543 -0
  64. data/doc/table_of_contents.html +263 -0
  65. data/lib/bigbench.rb +18 -0
  66. data/lib/bigbench/benchmark.rb +126 -0
  67. data/lib/bigbench/bot.rb +34 -0
  68. data/lib/bigbench/configuration.rb +109 -0
  69. data/lib/bigbench/executor.rb +131 -0
  70. data/lib/bigbench/float_extensions.rb +6 -0
  71. data/lib/bigbench/fragment.rb +119 -0
  72. data/lib/bigbench/help/executor.txt +17 -0
  73. data/lib/bigbench/initializers.rb +2 -0
  74. data/lib/bigbench/output.rb +116 -0
  75. data/lib/bigbench/runner.rb +52 -0
  76. data/lib/bigbench/store.rb +92 -0
  77. data/lib/bigbench/tracker.rb +79 -0
  78. data/lib/bigbench/version.rb +3 -0
  79. data/spec/benchmark_spec.rb +69 -0
  80. data/spec/bot_spec.rb +31 -0
  81. data/spec/configure_spec.rb +39 -0
  82. data/spec/executor_spec.rb +80 -0
  83. data/spec/fragment_spec.rb +110 -0
  84. data/spec/helpers.rb +19 -0
  85. data/spec/lib/test_web_server.rb +18 -0
  86. data/spec/runner_spec.rb +40 -0
  87. data/spec/store_spec.rb +72 -0
  88. data/spec/tests/local.rb +15 -0
  89. data/spec/tests/local_invalid.rb +9 -0
  90. data/spec/tracker_spec.rb +50 -0
  91. data/spec/webserver_spec.rb +35 -0
  92. metadata +220 -0
@@ -0,0 +1,92 @@
1
+ module BigBench
2
+
3
+ # The store encapsulates the communication with the redis key-value store. To the outside it looks like normal module methods would be
4
+ # called. It allows the simple starting of a test on multiple bots with the latest test reciept.
5
+ module Store
6
+
7
+ TEST_RECEIPT_KEY = "bigbench_test_receipt"
8
+ RUNNING_KEY = "bigbench_running"
9
+ BOTS_KEY = "bigbench_bots"
10
+ TRACKINGS_KEY = "bigbench_trackings"
11
+
12
+ @redis = nil
13
+
14
+ # Setup the redis storage. Default values are <tt>localhost:6379</tt> and no password.
15
+ # This needs to be called for any bot test
16
+ def self.setup!(url = "localhost:6379", password = nil)
17
+ uri = URI(url)
18
+ @redis = ::Redis.new :host => uri.host, :port => uri.port, :password => password
19
+ true
20
+ end
21
+
22
+ # Deletes all BigBench related keys on the redis store
23
+ def self.reset!
24
+ return if @redis.nil?
25
+
26
+ @redis.del(TEST_RECEIPT_KEY)
27
+ @redis.del(RUNNING_KEY)
28
+ @redis.del(BOTS_KEY)
29
+ @redis.del(TRACKINGS_KEY)
30
+ end
31
+
32
+ # Stores the current test receipt for all bots on the redis instance
33
+ def self.test=(test)
34
+ if test
35
+ @redis.set(TEST_RECEIPT_KEY, test)
36
+ else
37
+ @redis.del(TEST_RECEIPT_KEY)
38
+ end
39
+ end
40
+
41
+ # Gets the current test from the redis
42
+ def self.test
43
+ @redis.get(TEST_RECEIPT_KEY)
44
+ end
45
+
46
+ # Start the tests for all bots by setting the running key
47
+ def self.start
48
+ @redis.set(RUNNING_KEY, "1")
49
+ end
50
+
51
+ # Stops the test for all bots by unsetting the running key
52
+ def self.stop
53
+ @redis.set(RUNNING_KEY, "0")
54
+ end
55
+
56
+ # Returns true if a bot test has been started
57
+ def self.running?
58
+ @redis.get(RUNNING_KEY) == "1"
59
+ end
60
+
61
+ # Adds a bot to the currently working bots list
62
+ def self.bot_is_working(id)
63
+ @redis.sadd(BOTS_KEY, id)
64
+ end
65
+
66
+ # Removes a bot to the currently working bots list
67
+ def self.bot_stopped_working(id)
68
+ @redis.srem(BOTS_KEY, id)
69
+ end
70
+
71
+ # Shows all currently working bots
72
+ def self.bots
73
+ @redis.smembers(BOTS_KEY)
74
+ end
75
+
76
+ # Add a tracking to the trackings
77
+ def self.add_tracking(tracking)
78
+ @redis.rpush(TRACKINGS_KEY, tracking)
79
+ end
80
+
81
+ # Pop a tracking from the beginning of the list
82
+ def self.pop_tracking
83
+ @redis.lpop(TRACKINGS_KEY)
84
+ end
85
+
86
+ # How many trackings are in the list
87
+ def self.count_trackings
88
+ @redis.llen(TRACKINGS_KEY)
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,79 @@
1
+ module BigBench
2
+
3
+ # The tracker records all request results a benchmark makes. When the benchmark is finished, the trackings are written depending on the mode
4
+ # of BigBench:
5
+ #
6
+ # [config.mode == :bot] All trackings are appended to the redis store's tracking key
7
+ # [config.mode == :local] All trackings are written straight to the file defined by <tt>config.output</tt>
8
+ # [config.mode == :bots] All trackings are imported from the redis store's tracking key and written to the file defined by <tt>config.output</tt>
9
+ #
10
+ module Tracker
11
+
12
+ class Tracker
13
+
14
+ attr_accessor :trackings
15
+
16
+ def initialize
17
+ @trackings = []
18
+ end
19
+
20
+ def track object
21
+ @trackings << object.to_json
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ # Writes the trackings of a bot to the redis after he finishes the run
28
+ def self.write_trackings_to_store!
29
+ trackings, counter = 0, 0
30
+ BigBench.benchmarks.each{ |benchmark| trackings += benchmark.tracker.trackings.size }
31
+ BigBench::Output.writing_trackings(trackings)
32
+
33
+ BigBench.benchmarks.each do |benchmark|
34
+ benchmark.tracker.trackings.each do |tracking|
35
+ BigBench::Output.wrote_trackings(counter) if counter % 100 == 0
36
+ BigBench::Store.add_tracking(tracking)
37
+ counter += 1
38
+ end
39
+ end
40
+
41
+ BigBench::Output.finished_writing_trackings(counter)
42
+ end
43
+
44
+ # Writes the locals trackings from the benchmark to a file
45
+ def self.write_local_trackings_to_file!
46
+ trackings, counter = 0, 0
47
+ BigBench.benchmarks.each{ |benchmark| trackings += benchmark.tracker.trackings.size }
48
+ BigBench::Output.writing_trackings(trackings)
49
+
50
+ File.open(BigBench.config.output, "w+") do |file|
51
+ BigBench.benchmarks.each do |benchmark|
52
+ benchmark.tracker.trackings.each do |tracking|
53
+ BigBench::Output.wrote_trackings(counter) if counter % 100 == 0
54
+ file.write tracking + "\n"
55
+ counter += 1
56
+ end
57
+ end
58
+ end
59
+
60
+ BigBench::Output.finished_writing_trackings(counter)
61
+ end
62
+
63
+ # Gathers the trackings from the redis and writes them to a local file
64
+ def self.write_store_trackings_to_file!
65
+ trackings, counter = BigBench::Store.count_trackings, 0
66
+ BigBench::Output.writing_trackings(trackings)
67
+
68
+ File.open(BigBench.config.output, "w+") do |file|
69
+ while tracking = BigBench::Store.pop_tracking do
70
+ BigBench::Output.wrote_trackings(counter) if counter % 100 == 0
71
+ file.write tracking + "\n"
72
+ counter += 1
73
+ end
74
+ end
75
+
76
+ BigBench::Output.finished_writing_trackings(counter)
77
+ end
78
+
79
+ end
@@ -0,0 +1,3 @@
1
+ module BigBench
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,69 @@
1
+ require_relative "./helpers"
2
+
3
+ describe BigBench::Benchmark do
4
+
5
+ it "should add an empty benchmark with a name" do
6
+ BigBench.benchmark "a test page" => "http://localhost:3001"
7
+ BigBench.benchmark "a second test page" => "http://localhost:3001"
8
+ BigBench.benchmarks.size.should == 0
9
+ end
10
+
11
+ it "should add a benchmark block with a get fragment" do
12
+ BigBench.benchmark "a test page" => "http://localhost:3001" do
13
+ get "/"
14
+ end
15
+
16
+ BigBench.benchmarks.size.should == 1
17
+ BigBench.benchmarks.first.fragments.size.should == 1
18
+ BigBench.benchmarks.first.threads.should == 1
19
+ BigBench.benchmarks.first.fragments.first.uri.to_s.should == "http://localhost:3001/"
20
+ end
21
+
22
+ it "should add a benchmark with custom threads" do
23
+ BigBench.benchmark "a test page" => "http://localhost:3001", :threads => 20 do
24
+ get "/"
25
+ end
26
+
27
+ BigBench.benchmarks.size.should == 1
28
+ BigBench.benchmarks.first.fragments.size.should == 1
29
+ BigBench.benchmarks.first.threads.should == 20
30
+ end
31
+
32
+ it "should return the longest duration of all benchmarks" do
33
+ BigBench.benchmark "a test page" => "http://localhost:3001", :duration => 1.second do
34
+ get "/"
35
+ end
36
+
37
+ BigBench.benchmark "a test page" => "http://localhost:3001", :duration => 3.minutes do
38
+ get "/"
39
+ end
40
+
41
+ BigBench.benchmark "a test page" => "http://localhost:3001", :duration => 20.seconds do
42
+ get "/"
43
+ end
44
+
45
+ BigBench.duration.should == 3.minutes
46
+ end
47
+
48
+ context "should run an entire benchmark" do
49
+
50
+ it "make 3 GETs" do
51
+
52
+ benchmark = BigBench.benchmark "a test page" => "http://localhost:3001" do
53
+ get "/"
54
+ get "/index"
55
+ get "/blog"
56
+ end
57
+
58
+ benchmark.run!
59
+ benchmark.tracker.trackings.size.should > 100
60
+ benchmark.runs.should == 1
61
+
62
+ benchmark.run!
63
+ benchmark.tracker.trackings.size.should > 100
64
+ benchmark.runs.should == 2
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "./helpers"
2
+
3
+ describe BigBench::Bot do
4
+
5
+ before(:each) do
6
+ BigBench::Store.reset!
7
+ end
8
+
9
+ it "should check for an empty receipt" do
10
+ BigBench::Store.setup!("http://localhost:6379").should be_true
11
+
12
+ BigBench::Bot.check_test!
13
+ BigBench.benchmarks.size.should == 0
14
+ end
15
+
16
+ it "should load and run a test from the redis store" do
17
+ BigBench::Store.setup!("http://localhost:6379").should be_true
18
+
19
+ test = File.open("spec/tests/local.rb", "rb"){ |file| file.read }
20
+ BigBench::Store.test = test
21
+ BigBench::Store.start
22
+
23
+ BigBench::Bot.check_test!
24
+
25
+ BigBench.config.mode.should == :bot
26
+ BigBench.benchmarks.size.should == 2
27
+ BigBench.benchmarks.each{ |benchmark| benchmark.runs.should == 1 }
28
+ BigBench::Store.count_trackings.should > 100
29
+ end
30
+
31
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "./helpers"
2
+
3
+ describe BigBench::Configuration do
4
+
5
+ it "should store the config values" do
6
+
7
+ BigBench.configure = {
8
+ :duration => 10.seconds,
9
+ :output => "test.ljson",
10
+ :threads => 20
11
+ }
12
+
13
+ BigBench.config.duration.should == 10.seconds
14
+ BigBench.config.output.should == "test.ljson"
15
+ BigBench.config.threads.should == 20
16
+
17
+ end
18
+
19
+ it "should allow to set options seperately" do
20
+ BigBench.config.duration = 5.seconds
21
+ BigBench.config.duration.should == 5.seconds
22
+ end
23
+
24
+ it "should check the minimal options" do
25
+ BigBench.config.should_not be_valid
26
+
27
+ BigBench.configure = {
28
+ :duration => 10.seconds,
29
+ :output => "test.ljson",
30
+ :threads => 20
31
+ }
32
+ BigBench.config.should be_valid
33
+ end
34
+
35
+ it "should allow to check the validity of the config" do
36
+ lambda {BigBench.check_config!}.should raise_error(BigBench::Configuration::InvalidOptions, "At least: #{BigBench::Configuration::Config::VALIDATE_OPTIONS.join(', ')} are required")
37
+ end
38
+
39
+ end
@@ -0,0 +1,80 @@
1
+ require_relative "./helpers"
2
+
3
+ describe BigBench::Executor do
4
+
5
+ context "should raise an argument error for" do
6
+
7
+ it "nil arguments" do
8
+ argv = nil
9
+ lambda{ BigBench::Executor.run!(argv) }.should raise_exception(BigBench::Executor::InvalidCommand)
10
+ end
11
+
12
+ it "empty arguments" do
13
+ argv = []
14
+ lambda{ BigBench::Executor.run!(argv) }.should raise_exception(BigBench::Executor::InvalidCommand)
15
+ end
16
+
17
+ it "weird arguments" do
18
+ argv = ["something"]
19
+ lambda{ BigBench::Executor.run!(argv) }.should raise_exception(BigBench::Executor::InvalidCommand)
20
+ end
21
+
22
+ it "longer weird arguments" do
23
+ argv = ["something", "really", "strange"]
24
+ lambda{ BigBench::Executor.run!(argv) }.should raise_exception(BigBench::Executor::InvalidCommand)
25
+ end
26
+
27
+ end
28
+
29
+ it "should run a local test with trackings" do
30
+
31
+ argv = ["run", "local", "spec/tests/local.rb"]
32
+ BigBench::Executor.run!(argv)
33
+
34
+ BigBench.benchmarks.size.should == 2
35
+ BigBench.benchmarks.each{ |benchmark| benchmark.runs.should == 1 }
36
+
37
+ File.exist?(BigBench.config.output).should be_true
38
+ File.open(BigBench.config.output) do |file|
39
+ file.each_line{ |json| JSON.parse(json).is_a?(Hash).should be_true }
40
+ end
41
+
42
+ File.delete BigBench.config.output
43
+
44
+ end
45
+
46
+ it "should run a bot test" do
47
+
48
+ argv = ["run", "bots", "spec/tests/local.rb"]
49
+ BigBench::Executor.run!(argv)
50
+
51
+ BigBench.benchmarks.size.should == 2
52
+ BigBench.benchmarks.each{ |benchmark| benchmark.runs.should == 0 }
53
+
54
+ File.exist?(BigBench.config.output).should be_true
55
+ File.open(BigBench.config.output) do |file|
56
+ file.each_line{ |json| JSON.parse(json).is_a?(Hash).should be_true }
57
+ end
58
+
59
+ File.delete BigBench.config.output
60
+
61
+ end
62
+
63
+ it "should show the help file" do
64
+ argv = ["--help"]
65
+ lambda{ BigBench::Executor.run!(argv) }.should_not raise_exception
66
+ File.exists?("lib/bigbench/help/executor.txt").should be_true
67
+ end
68
+
69
+ it "should reset everything" do
70
+ BigBench::Store.setup!("http://localhost:6379").should be_true
71
+ BigBench::Store.test = "something"
72
+
73
+ argv = ["reset", "all"]
74
+ BigBench::Executor.run!(argv)
75
+
76
+ BigBench.benchmarks.size.should == 0
77
+ BigBench::Store.test.should be_nil
78
+ end
79
+
80
+ end
@@ -0,0 +1,110 @@
1
+ require_relative "./helpers"
2
+
3
+ describe BigBench::Fragment do
4
+
5
+ before(:each) do
6
+ @benchmark = BigBench::Benchmark::Benchmark.new("a test benchmark", "http://localhost:3001", {}){}
7
+ @benchmark.start = Time.now
8
+ end
9
+
10
+ it "should parse a single fragment" do
11
+ fragments = BigBench::Fragment.parse(@benchmark){ get "/" }
12
+ fragments.size.should == 1
13
+ fragments.first.uri.to_s.should == "http://localhost:3001/"
14
+ end
15
+
16
+ it "should parse multiple fragments" do
17
+ fragments = BigBench::Fragment.parse(@benchmark) do
18
+ get "/index"
19
+ get "/page"
20
+ end
21
+ fragments.size.should == 2
22
+ fragments.first.uri.to_s.should == "http://localhost:3001/index"
23
+ fragments.last.uri.to_s.should == "http://localhost:3001/page"
24
+ end
25
+
26
+ context "should support following fragment methods" do
27
+
28
+ it "GET" do
29
+ fragments = BigBench::Fragment.parse(@benchmark){ get "/" }
30
+ fragments.size.should == 1
31
+ fragments.first.uri.to_s.should == "http://localhost:3001/"
32
+ fragments.first.method.should == :get
33
+ fragments.first.params.should == {}
34
+ end
35
+
36
+ it "POST" do
37
+ fragments = BigBench::Fragment.parse(@benchmark){ post "/login", { :user => "tommy@test.com", :password => "secret" } }
38
+ fragments.size.should == 1
39
+ fragments.first.uri.to_s.should == "http://localhost:3001/login"
40
+ fragments.first.method.should == :post
41
+ fragments.first.params.should == { :user => "tommy@test.com", :password => "secret" }
42
+ end
43
+
44
+ it "PUT" do
45
+ fragments = BigBench::Fragment.parse(@benchmark){ put "/books", { :book => "A Book" } }
46
+ fragments.size.should == 1
47
+ fragments.first.uri.to_s.should == "http://localhost:3001/books"
48
+ fragments.first.method.should == :put
49
+ fragments.first.params.should == { :book => "A Book" }
50
+ end
51
+
52
+ it "DELETE" do
53
+ fragments = BigBench::Fragment.parse(@benchmark){ delete "/books/5", { :user => "tommy@test.com", :password => "secret" } }
54
+ fragments.size.should == 1
55
+ fragments.first.uri.to_s.should == "http://localhost:3001/books/5"
56
+ fragments.first.method.should == :delete
57
+ fragments.first.params.should == { :user => "tommy@test.com", :password => "secret" }
58
+ end
59
+
60
+ end
61
+
62
+ context "should run following fragment methods" do
63
+
64
+ it "GET" do
65
+ fragment = BigBench::Fragment.parse(@benchmark){ get "/" }.first
66
+ result = nil
67
+ Net::HTTP.start(fragment.uri.host, fragment.uri.port) do |http|
68
+ result = fragment.run!(http)
69
+ end
70
+ result.code.to_i.should == 200
71
+ result.body.should == "Test"
72
+ @benchmark.tracker.trackings.size.should == 1
73
+ end
74
+
75
+ it "POST" do
76
+ fragment = BigBench::Fragment.parse(@benchmark){ post "/" }.first
77
+ result = nil
78
+ Net::HTTP.start(fragment.uri.host, fragment.uri.port) do |http|
79
+ result = fragment.run!(http)
80
+ end
81
+ result.code.to_i.should == 200
82
+ result.body.should == "Test"
83
+ @benchmark.tracker.trackings.size.should == 1
84
+ end
85
+
86
+ it "PUT" do
87
+ fragment = BigBench::Fragment.parse(@benchmark){ put "/" }.first
88
+ result = nil
89
+ Net::HTTP.start(fragment.uri.host, fragment.uri.port) do |http|
90
+ result = fragment.run!(http)
91
+ end
92
+ result.code.to_i.should == 200
93
+ result.body.should == "Test"
94
+ @benchmark.tracker.trackings.size.should == 1
95
+ end
96
+
97
+ it "DELETE" do
98
+ fragment = BigBench::Fragment.parse(@benchmark){ delete "/" }.first
99
+ result = nil
100
+ Net::HTTP.start(fragment.uri.host, fragment.uri.port) do |http|
101
+ result = fragment.run!(http)
102
+ end
103
+ result.code.to_i.should == 200
104
+ result.body.should == "Test"
105
+ @benchmark.tracker.trackings.size.should == 1
106
+ end
107
+
108
+ end
109
+
110
+ end