blitz 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -0
- data/README.md +36 -0
- data/blitz.gemspec +8 -4
- data/lib/blitz.rb +2 -1
- data/lib/blitz/client.rb +0 -4
- data/lib/blitz/command/couch.rb +136 -0
- data/lib/blitz/command/help.rb +2 -1
- metadata +35 -18
- data/README.rdoc +0 -22
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
couchrest (1.0.1)
|
5
|
+
json (>= 1.4.6)
|
6
|
+
mime-types (>= 1.15)
|
7
|
+
rest-client (>= 1.5.1)
|
4
8
|
git (1.2.5)
|
5
9
|
hexy (0.1.1)
|
6
10
|
jeweler (1.5.1)
|
@@ -19,6 +23,7 @@ PLATFORMS
|
|
19
23
|
|
20
24
|
DEPENDENCIES
|
21
25
|
bundler (~> 1.0.0)
|
26
|
+
couchrest (~> 1.0.1)
|
22
27
|
hexy (~> 0.1.1)
|
23
28
|
jeweler (~> 1.5.1)
|
24
29
|
json (~> 1.4.6)
|
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## ![blitz.io](http://blitz.io/images/logo2.png)
|
2
|
+
|
3
|
+
Make load and performance a fun sport.
|
4
|
+
|
5
|
+
* Run a sprint from around the world
|
6
|
+
* Rush your API and website to scale it out
|
7
|
+
* Condition your site around the clock
|
8
|
+
|
9
|
+
## Getting started
|
10
|
+
Login to [blitz.io](http://blitz.io) and in the blitz bar type:
|
11
|
+
--api-key
|
12
|
+
|
13
|
+
Now
|
14
|
+
gem install blitz
|
15
|
+
|
16
|
+
and run a sprint like this:
|
17
|
+
blitz curl --region california http://blitz.io
|
18
|
+
|
19
|
+
and you can rush like this:
|
20
|
+
blitz curl --region california --pattern 1-100:60 http://blitz.io
|
21
|
+
|
22
|
+
## Using the couch:fuzz command
|
23
|
+
Simply point this blitz gem to your CouchDB URL and we'll auto generate
|
24
|
+
full parameterized tests that you can use to measure view performance.
|
25
|
+
|
26
|
+
blitz http://localhost:5984 my_database
|
27
|
+
|
28
|
+
will generate tests like this:
|
29
|
+
|
30
|
+
-v:l number[1,10] -v:gl number[1,5] http://dell-5:5984/pcapr_local_root/_design/pcaps/_view/by_service?group=true&limit=#{l}&group_level=#{gl}
|
31
|
+
-v:sk alpha[4,12] -v:ek alpha[4,12] -v:l number[1,10] -v:id [true,false] http://dell-5:5984/pcapr_local_root/_design/pcaps/_view/indexed?startkey=%22am#{sk}%22&endkey=%22ykz#{ek}%22&include_docs=#{id}&limit=#{l}
|
32
|
+
|
33
|
+
which you can simply copy/paste to the [blitz.io](http://blitz.io). Your
|
34
|
+
CouchDB must be on the public cloud though.
|
35
|
+
|
36
|
+
Copyright (c) 2011 Mu Dynamics. See LICENSE.txt for further details.
|
data/blitz.gemspec
CHANGED
@@ -5,25 +5,25 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{blitz}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["pcapr"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-15}
|
13
13
|
s.default_executable = %q{blitz}
|
14
14
|
s.description = %q{Make load and performance testing a fun sport}
|
15
15
|
s.email = %q{kowsik@gmail.com}
|
16
16
|
s.executables = ["blitz"]
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE.txt",
|
19
|
-
"README.
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
"Gemfile",
|
24
24
|
"Gemfile.lock",
|
25
25
|
"LICENSE.txt",
|
26
|
-
"README.
|
26
|
+
"README.md",
|
27
27
|
"Rakefile",
|
28
28
|
"bin/blitz",
|
29
29
|
"blitz.gemspec",
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/blitz/client.rb",
|
32
32
|
"lib/blitz/command.rb",
|
33
33
|
"lib/blitz/command/api.rb",
|
34
|
+
"lib/blitz/command/couch.rb",
|
34
35
|
"lib/blitz/command/curl.rb",
|
35
36
|
"lib/blitz/command/help.rb",
|
36
37
|
"lib/blitz/curl/error.rb",
|
@@ -55,6 +56,7 @@ Gem::Specification.new do |s|
|
|
55
56
|
s.specification_version = 3
|
56
57
|
|
57
58
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
+
s.add_runtime_dependency(%q<couchrest>, ["~> 1.0.1"])
|
58
60
|
s.add_runtime_dependency(%q<rest-client>, ["~> 1.6.1"])
|
59
61
|
s.add_runtime_dependency(%q<json>, ["~> 1.4.6"])
|
60
62
|
s.add_runtime_dependency(%q<json_pure>, ["~> 1.4.6"])
|
@@ -62,6 +64,7 @@ Gem::Specification.new do |s|
|
|
62
64
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
63
65
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
64
66
|
else
|
67
|
+
s.add_dependency(%q<couchrest>, ["~> 1.0.1"])
|
65
68
|
s.add_dependency(%q<rest-client>, ["~> 1.6.1"])
|
66
69
|
s.add_dependency(%q<json>, ["~> 1.4.6"])
|
67
70
|
s.add_dependency(%q<json_pure>, ["~> 1.4.6"])
|
@@ -70,6 +73,7 @@ Gem::Specification.new do |s|
|
|
70
73
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
71
74
|
end
|
72
75
|
else
|
76
|
+
s.add_dependency(%q<couchrest>, ["~> 1.0.1"])
|
73
77
|
s.add_dependency(%q<rest-client>, ["~> 1.6.1"])
|
74
78
|
s.add_dependency(%q<json>, ["~> 1.4.6"])
|
75
79
|
s.add_dependency(%q<json_pure>, ["~> 1.4.6"])
|
data/lib/blitz.rb
CHANGED
data/lib/blitz/client.rb
CHANGED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'couchrest'
|
2
|
+
|
3
|
+
class Blitz
|
4
|
+
class Command
|
5
|
+
class Couch < Command
|
6
|
+
attr_reader :urls
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@urls = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def cmd_fuzz argv
|
13
|
+
assert argv.size != 0, "need a CouchDB URL (like http://localhost:5984)"
|
14
|
+
|
15
|
+
url = argv.shift
|
16
|
+
database = argv.shift
|
17
|
+
|
18
|
+
uri = URI.parse url rescue nil
|
19
|
+
assert_not_nil uri, "Can't parse #{url} - Is it valid?"
|
20
|
+
|
21
|
+
couch = CouchRest.new(uri)
|
22
|
+
couch.databases.reject { |n| n[0,1] == '_' }.each do |name|
|
23
|
+
next if database and database != name
|
24
|
+
msg "-------------- processing #{name}... ----------------------"
|
25
|
+
db = couch.database(name)
|
26
|
+
designs = db.documents :startkey => "_design", :endkey => "_design0", :include_docs => true
|
27
|
+
designs['rows'].each do |row|
|
28
|
+
design = row['doc']
|
29
|
+
|
30
|
+
# Ignore design documents that don't have views
|
31
|
+
next unless design['views']
|
32
|
+
analyze_design db, design
|
33
|
+
end
|
34
|
+
|
35
|
+
if urls.empty?
|
36
|
+
error "Nothing interesting found. Sorry."
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
output_urls db
|
41
|
+
urls.clear
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def analyze_design db, design
|
46
|
+
_, dname = design['_id'].split('/', 2)
|
47
|
+
views = design['views']
|
48
|
+
views.each_pair do |vname, view|
|
49
|
+
analyze_view db, dname, vname, view['reduce']
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def analyze_view db, design, view, reduce
|
54
|
+
msg " analyzing #{design}/#{view}..."
|
55
|
+
|
56
|
+
opts = {}
|
57
|
+
opts[:group] = true if reduce
|
58
|
+
first = db.view "#{design}/#{view}", opts.merge(:limit => 1)
|
59
|
+
last = db.view "#{design}/#{view}", opts.merge(:limit => 1, :descending => true)
|
60
|
+
|
61
|
+
return if first['rows'].empty?
|
62
|
+
|
63
|
+
first_row = first['rows'][0]
|
64
|
+
first_key = first_row['key']
|
65
|
+
last_row = last['rows'][0]
|
66
|
+
last_key = last_row['key']
|
67
|
+
|
68
|
+
# Randomize the limit so it's anywhere from 1 to 10 docs maximum
|
69
|
+
variables = { :l => 'number[1,10]' }
|
70
|
+
query = { :limit => '#{l}' }
|
71
|
+
if reduce
|
72
|
+
query.merge! :group => true
|
73
|
+
else
|
74
|
+
variables.merge! :id => '[true,false]'
|
75
|
+
query.merge! :include_docs => '#{id}'
|
76
|
+
end
|
77
|
+
|
78
|
+
case first_key
|
79
|
+
when Array
|
80
|
+
# If the key is an array and this view is reducing, randomize the
|
81
|
+
# group level to have the query server work harder
|
82
|
+
if reduce
|
83
|
+
variables[:gl] = 'number[1,5]'
|
84
|
+
query[:group_level] = '#{gl}'
|
85
|
+
end
|
86
|
+
when Integer
|
87
|
+
# Randomize start/end keys, but within the valid range
|
88
|
+
variables[:sk] = "number[#{first_key},#{last_key}]"
|
89
|
+
variables[:ek] = "number[#{first_key},#{last_key}]"
|
90
|
+
query[:startkey] = '#{sk}'
|
91
|
+
query[:endkey] = '#{ek}'
|
92
|
+
when String
|
93
|
+
# Randomize start/end keys, but within the valid range
|
94
|
+
variables[:sk] = "alpha[4,12]"
|
95
|
+
variables[:ek] = "alpha[4,12]"
|
96
|
+
query[:startkey] = "%22#{first_key[0,2]}\#{sk}%22"
|
97
|
+
query[:endkey] = "%22#{last_key[0,2]}z\#{ek}%22"
|
98
|
+
when TrueClass, FalseClass
|
99
|
+
variables[:sk] = "[true,false]"
|
100
|
+
variables[:ek] = "[true,false,false,true]"
|
101
|
+
query[:startkey] = '#{sk}'
|
102
|
+
query[:endkey] = '#{ek}'
|
103
|
+
# TODO: Handle the case when the key is a Hash
|
104
|
+
end
|
105
|
+
|
106
|
+
vs = variables.to_a.map do |k, v|
|
107
|
+
if v =~ /\s/
|
108
|
+
"-v:#{k} '#{v}'"
|
109
|
+
else
|
110
|
+
"-v:#{k} #{v}"
|
111
|
+
end
|
112
|
+
end.join(' ')
|
113
|
+
qs = query.to_a.map { |k, v| "#{k}=#{v}" }.join('&')
|
114
|
+
|
115
|
+
# Generate blitz query URL's with all sorts of randomization
|
116
|
+
@urls << {
|
117
|
+
:reduce => reduce ? true : false,
|
118
|
+
:design => design,
|
119
|
+
:view => view,
|
120
|
+
:url => "#{vs} #{db.to_s}/_design/#{design}/_view/#{view}?#{qs}"
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def output_urls db
|
125
|
+
puts
|
126
|
+
msg "Here are full parameterized blitz URL's for each view. Simply copy "
|
127
|
+
msg "paste these into the blitz bar @ http://blitz.io to generate load "
|
128
|
+
msg "on your couch."
|
129
|
+
puts
|
130
|
+
puts urls.map { |u| u[:url] }.join("\n\n")
|
131
|
+
puts
|
132
|
+
puts
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end # Command
|
136
|
+
end # Blitz
|
data/lib/blitz/command/help.rb
CHANGED
@@ -8,7 +8,8 @@ class Help < Command
|
|
8
8
|
{ :cmd => 'help', :help => "Display this help" },
|
9
9
|
{ :cmd => 'api:init', :help => 'Validate your API key' },
|
10
10
|
{ :cmd => 'curl', :help => 'Run a sprint or a rush' },
|
11
|
-
{ :cmd => 'curl:help', :help => 'Show help on sprint and rushing' }
|
11
|
+
{ :cmd => 'curl:help', :help => 'Show help on sprint and rushing' },
|
12
|
+
{ :cmd => 'couch:fuzz', :help => 'Auto generate blitz tests from CouchDB' }
|
12
13
|
]
|
13
14
|
|
14
15
|
max_cmd_size = helps.inject(0) { |memo, obj| [ obj[:cmd].size, memo ].max } + 4
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blitz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- pcapr
|
@@ -15,14 +15,30 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-15 00:00:00 -07:00
|
19
19
|
default_executable: blitz
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
name:
|
24
|
+
name: couchrest
|
25
25
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 21
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 0
|
34
|
+
- 1
|
35
|
+
version: 1.0.1
|
36
|
+
requirement: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
name: rest-client
|
41
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
26
42
|
none: false
|
27
43
|
requirements:
|
28
44
|
- - ~>
|
@@ -33,12 +49,12 @@ dependencies:
|
|
33
49
|
- 6
|
34
50
|
- 1
|
35
51
|
version: 1.6.1
|
36
|
-
requirement: *
|
52
|
+
requirement: *id002
|
37
53
|
- !ruby/object:Gem::Dependency
|
38
54
|
type: :runtime
|
39
55
|
prerelease: false
|
40
56
|
name: json
|
41
|
-
version_requirements: &
|
57
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
42
58
|
none: false
|
43
59
|
requirements:
|
44
60
|
- - ~>
|
@@ -49,12 +65,12 @@ dependencies:
|
|
49
65
|
- 4
|
50
66
|
- 6
|
51
67
|
version: 1.4.6
|
52
|
-
requirement: *
|
68
|
+
requirement: *id003
|
53
69
|
- !ruby/object:Gem::Dependency
|
54
70
|
type: :runtime
|
55
71
|
prerelease: false
|
56
72
|
name: json_pure
|
57
|
-
version_requirements: &
|
73
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
58
74
|
none: false
|
59
75
|
requirements:
|
60
76
|
- - ~>
|
@@ -65,12 +81,12 @@ dependencies:
|
|
65
81
|
- 4
|
66
82
|
- 6
|
67
83
|
version: 1.4.6
|
68
|
-
requirement: *
|
84
|
+
requirement: *id004
|
69
85
|
- !ruby/object:Gem::Dependency
|
70
86
|
type: :runtime
|
71
87
|
prerelease: false
|
72
88
|
name: hexy
|
73
|
-
version_requirements: &
|
89
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
74
90
|
none: false
|
75
91
|
requirements:
|
76
92
|
- - ~>
|
@@ -81,12 +97,12 @@ dependencies:
|
|
81
97
|
- 1
|
82
98
|
- 1
|
83
99
|
version: 0.1.1
|
84
|
-
requirement: *
|
100
|
+
requirement: *id005
|
85
101
|
- !ruby/object:Gem::Dependency
|
86
102
|
type: :development
|
87
103
|
prerelease: false
|
88
104
|
name: bundler
|
89
|
-
version_requirements: &
|
105
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
90
106
|
none: false
|
91
107
|
requirements:
|
92
108
|
- - ~>
|
@@ -97,12 +113,12 @@ dependencies:
|
|
97
113
|
- 0
|
98
114
|
- 0
|
99
115
|
version: 1.0.0
|
100
|
-
requirement: *
|
116
|
+
requirement: *id006
|
101
117
|
- !ruby/object:Gem::Dependency
|
102
118
|
type: :development
|
103
119
|
prerelease: false
|
104
120
|
name: jeweler
|
105
|
-
version_requirements: &
|
121
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
106
122
|
none: false
|
107
123
|
requirements:
|
108
124
|
- - ~>
|
@@ -113,7 +129,7 @@ dependencies:
|
|
113
129
|
- 5
|
114
130
|
- 1
|
115
131
|
version: 1.5.1
|
116
|
-
requirement: *
|
132
|
+
requirement: *id007
|
117
133
|
description: Make load and performance testing a fun sport
|
118
134
|
email: kowsik@gmail.com
|
119
135
|
executables:
|
@@ -122,13 +138,13 @@ extensions: []
|
|
122
138
|
|
123
139
|
extra_rdoc_files:
|
124
140
|
- LICENSE.txt
|
125
|
-
- README.
|
141
|
+
- README.md
|
126
142
|
files:
|
127
143
|
- .document
|
128
144
|
- Gemfile
|
129
145
|
- Gemfile.lock
|
130
146
|
- LICENSE.txt
|
131
|
-
- README.
|
147
|
+
- README.md
|
132
148
|
- Rakefile
|
133
149
|
- bin/blitz
|
134
150
|
- blitz.gemspec
|
@@ -136,6 +152,7 @@ files:
|
|
136
152
|
- lib/blitz/client.rb
|
137
153
|
- lib/blitz/command.rb
|
138
154
|
- lib/blitz/command/api.rb
|
155
|
+
- lib/blitz/command/couch.rb
|
139
156
|
- lib/blitz/command/curl.rb
|
140
157
|
- lib/blitz/command/help.rb
|
141
158
|
- lib/blitz/curl/error.rb
|
data/README.rdoc
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
## ![blitz.io](http://blitz.io/images/logo2.png)
|
2
|
-
|
3
|
-
Make load and performance a fun sport.
|
4
|
-
|
5
|
-
* Run a sprint from around the world
|
6
|
-
* Rush your API and website to scale it out
|
7
|
-
* Condition your site around the clock
|
8
|
-
|
9
|
-
## Getting started
|
10
|
-
Login to [blitz.io](http://blitz.io) and in the blitz bar type:
|
11
|
-
--api-key
|
12
|
-
|
13
|
-
Now
|
14
|
-
gem install blitz
|
15
|
-
|
16
|
-
and run a sprint like this:
|
17
|
-
blitz curl --region california http://blitz.io
|
18
|
-
|
19
|
-
and you can rush like this:
|
20
|
-
blitz curl --region california --pattern 1-100:60 http://blitz.io
|
21
|
-
|
22
|
-
Copyright (c) 2011 Mu Dynamics. See LICENSE.txt for further details.
|