blitz 0.1.1 → 0.1.2
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.
- 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
|
+
## 
|
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
|
-
## 
|
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.
|