stella 0.6.0 → 0.7.0.002

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 (55) hide show
  1. data/CHANGES.txt +7 -15
  2. data/LICENSE.txt +1 -1
  3. data/README.rdoc +93 -63
  4. data/Rakefile +32 -42
  5. data/bin/stella +138 -0
  6. data/examples/basic/listing_ids.csv +7 -0
  7. data/examples/basic/plan.rb +71 -0
  8. data/lib/stella/cli.rb +66 -0
  9. data/lib/stella/client.rb +199 -0
  10. data/lib/stella/config.rb +87 -0
  11. data/lib/stella/data/http/body.rb +15 -0
  12. data/lib/stella/data/http/request.rb +116 -0
  13. data/lib/stella/data/http/response.rb +92 -0
  14. data/lib/stella/data/http.rb +2 -257
  15. data/lib/stella/data.rb +85 -0
  16. data/lib/stella/dsl.rb +5 -0
  17. data/lib/stella/engine/functional.rb +39 -0
  18. data/lib/stella/engine/load.rb +106 -0
  19. data/lib/stella/engine.rb +55 -0
  20. data/lib/stella/exceptions.rb +15 -0
  21. data/lib/stella/guidelines.rb +18 -0
  22. data/lib/stella/mixins.rb +2 -0
  23. data/lib/stella/stats.rb +3 -7
  24. data/lib/stella/testplan/stats.rb +26 -0
  25. data/lib/stella/testplan/usecase.rb +67 -0
  26. data/lib/stella/testplan.rb +95 -220
  27. data/lib/{util → stella/utils}/httputil.rb +0 -0
  28. data/lib/stella/utils.rb +126 -0
  29. data/lib/stella/version.rb +15 -0
  30. data/lib/stella.rb +58 -104
  31. data/lib/threadify.rb +0 -6
  32. data/stella.gemspec +43 -49
  33. data/support/example_webapp.rb +246 -0
  34. data/support/useragents.txt +75 -0
  35. metadata +68 -32
  36. data/bin/example_test.rb +0 -82
  37. data/bin/example_webapp.rb +0 -63
  38. data/lib/logger.rb +0 -79
  39. data/lib/stella/clients.rb +0 -161
  40. data/lib/stella/command/base.rb +0 -20
  41. data/lib/stella/command/form.rb +0 -36
  42. data/lib/stella/command/get.rb +0 -44
  43. data/lib/stella/common.rb +0 -53
  44. data/lib/stella/crypto.rb +0 -88
  45. data/lib/stella/data/domain.rb +0 -82
  46. data/lib/stella/environment.rb +0 -66
  47. data/lib/stella/functest.rb +0 -105
  48. data/lib/stella/loadtest.rb +0 -186
  49. data/lib/stella/testrunner.rb +0 -64
  50. data/lib/storable.rb +0 -280
  51. data/lib/timeunits.rb +0 -65
  52. data/tryouts/drb/drb_test.rb +0 -65
  53. data/tryouts/drb/open4.rb +0 -19
  54. data/tryouts/drb/slave.rb +0 -27
  55. data/tryouts/oo_tryout.rb +0 -30
data/lib/stella.rb CHANGED
@@ -1,119 +1,73 @@
1
1
 
2
- require 'date'
3
- require 'time'
4
- require 'rubygems'
5
- require 'logger'
6
- require 'uri'
7
- require 'httpclient'
2
+ unless defined?(STELLA_LIB_HOME)
3
+ STELLA_LIB_HOME = File.expand_path File.dirname(__FILE__)
4
+ end
5
+
6
+ local_libs = %w{drydock storable sysinfo gibbler}
7
+ local_libs.each { |dir| $:.unshift File.join(STELLA_LIB_HOME, '..', '..', dir, 'lib') }
8
+ #require 'rubygems'
8
9
 
9
10
  require 'storable'
10
- require 'stella/stats'
11
+ require 'sysinfo'
12
+ require 'gibbler'
13
+ require 'gibbler/aliases'
14
+ require 'ostruct'
11
15
  require 'threadify'
12
- require 'timeunits'
13
-
14
- require 'stella/crypto'
15
-
16
- require 'stella/common'
17
-
18
- require 'stella/data/http'
19
- require 'stella/data/domain'
20
-
21
- require 'stella/environment'
22
- require 'stella/clients'
23
- require 'stella/testrunner'
24
- require 'stella/testplan'
25
- require 'stella/loadtest'
26
- require 'stella/functest'
27
-
28
- srand
29
-
30
- # Common dependencies
31
- STELLA_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
32
- $: << File.join(STELLA_HOME, 'vendor', 'useragent', 'lib')
16
+ require 'drydock/screen'
33
17
 
34
-
35
- # A friend in performance testing.
36
- module Stella
37
-
38
- LOGGER = Logger.new(:debug_level=>0) unless defined? LOGGER
39
-
40
- module VERSION #:nodoc:
41
- MAJOR = 0.freeze unless defined? MAJOR
42
- MINOR = 6.freeze unless defined? MINOR
43
- TINY = 0.freeze unless defined? TINY
44
- def self.to_s
45
- [MAJOR, MINOR, TINY].join('.')
46
- end
47
- def self.to_f
48
- self.to_s.to_f
49
- end
50
- end
51
-
52
-
53
- def self.debug_level
54
- Stella::LOGGER.debug_level
55
- end
18
+ module Stella
19
+ VERSION = "0.7.0.002"
20
+ extend self
21
+ require 'stella/version'
22
+ require 'stella/exceptions'
23
+ require 'stella/utils'
24
+ require 'stella/stats'
25
+ require 'stella/mixins'
26
+ require 'stella/dsl'
27
+ require 'stella/engine'
28
+ require 'stella/testplan'
29
+
30
+ autoload :Utils, STELLA_LIB_HOME + "/stella/utils"
31
+ autoload :Data, STELLA_LIB_HOME + "/stella/data"
32
+ autoload :Config, STELLA_LIB_HOME + "/stella/config"
33
+ autoload :Client, STELLA_LIB_HOME + "/stella/client"
56
34
 
57
- def self.debug_level=(level)
58
- Stella::LOGGER.debug_level = level
59
- end
35
+ @@sysinfo = SysInfo.new.freeze
36
+
37
+ @@logger = Drydock::Screen
38
+ @@loglev = 1
60
39
 
61
- def self.info(*args)
62
- LOGGER.info(*args)
63
- end
40
+ # Puts +msg+ to +@@logger+
41
+ def li(*msg); msg.each { |m| @@logger.puts m } if !quiet? end
42
+ def li1(*msg); li *msg if @@loglev >= 1 end
43
+ def li2(*msg); li *msg if @@loglev >= 2 end
44
+ def li3(*msg); li *msg if @@loglev >= 3 end
45
+ def li4(*msg); li *msg if @@loglev >= 4 end
64
46
 
65
- def self.error(*args)
66
- LOGGER.error(*args)
47
+ # Puts +msg+ to +@@logger+ with "ERROR: " prepended
48
+ def le(*msg); @@logger.puts " " << msg.join("#{$/} ").color(:red); end
49
+ # Puts +msg+ to +@@logger+ if +Rudy.debug?+ returns true
50
+ def ld(*msg)
51
+ @@logger.puts "D: " << msg.join("#{$/}D: ") if debug?
67
52
  end
68
53
 
69
- def self.fatal(*args)
70
- LOGGER.error(*args)
71
- exit 1
72
- end
54
+ def loglev; @@loglev; end
55
+ def loglev=(val); @@loglev = val; end
56
+ def sysinfo; @@sysinfo; end
73
57
 
74
- def self.debug(*args)
75
- LOGGER.debug(*args)
76
- end
77
- end
58
+ def quiet?; @@loglev == 0; end
59
+ def enable_quiet; @@loglev = 0; end
60
+ def disable_quiet; @@loglev = 1; end
78
61
 
79
- module Stella
80
- module DSL
81
- include Stella::DSL::TestPlan
82
- include Stella::DSL::FunctionalTest
83
- include Stella::DSL::LoadTest
84
- include Stella::DSL::Environment
85
- # For Modules
86
- #extend Stella::DSL::TestPlan
87
- #extend Stella::DSL::FunctionalTest
62
+ def debug?; @@loglev > 3; end
63
+ def enable_debug; @@loglev = 4; end
64
+ def disable_debug; @@loglev = 1; end
65
+
66
+ def rescue(&blk)
67
+ blk.call
68
+ rescue => ex
69
+ Stella.le "ERROR: #{ex.message}"
70
+ Stella.ld ex.backtrace
88
71
  end
89
72
  end
90
73
 
91
- class Object #:nodoc: all
92
- # The hidden singleton lurks behind everyone
93
- def metaclass; class << self; self; end; end
94
- def meta_eval &blk; metaclass.instance_eval &blk; end
95
-
96
- # Adds methods to a metaclass
97
- def meta_def name, &blk
98
- meta_eval { define_method name, &blk }
99
- end
100
-
101
- # Defines an instance method within a class
102
- def class_def name, &blk
103
- class_eval { define_method name, &blk }
104
- end
105
-
106
- end
107
-
108
- class Array
109
- # create a hash from an array of [key,value] tuples
110
- # you can set default or provide a block just as with Hash::new
111
- # Note: if you use [key, value1, value2, value#], hash[key] will
112
- # be [value1, value2, value#]
113
- # From: http://www.ruby-forum.com/topic/138218#615260
114
- def stella_to_hash(default=nil, &block)
115
- hash = block_given? ? Hash.new(&block) : Hash.new(default)
116
- each { |(key, *value)| hash[key]=*value }
117
- hash
118
- end
119
- end
data/lib/threadify.rb CHANGED
@@ -137,12 +137,6 @@ class Thread
137
137
  end
138
138
  end
139
139
 
140
- class Object
141
- def threadify! *values
142
- throw :threadify, *values
143
- end
144
- end
145
-
146
140
 
147
141
  if __FILE__ == $0
148
142
  require 'open-uri'
data/stella.gemspec CHANGED
@@ -1,69 +1,63 @@
1
1
  @spec = Gem::Specification.new do |s|
2
- s.name = "stella"
3
- s.rubyforge_project = "stella"
4
- s.version = "0.6.0"
5
- s.summary = "Your friend in performance testing"
6
- s.description = s.summary
7
- s.author = "Delano Mandelbaum"
8
- s.email = "delano@solutious.com"
9
- s.homepage = "http://github.com/solutious/stella"
2
+ s.name = "stella"
3
+ s.rubyforge_project = 'stella'
4
+ s.version = "0.7.0.002"
5
+ s.summary = "Stella: Your friend in performance testing."
6
+ s.description = s.summary
7
+ s.author = "Delano Mandelbaum"
8
+ s.email = "delano@solutious.com"
9
+ s.homepage = "http://solutious.com/projects/stella/"
10
10
 
11
- # = DEPENDENCIES =
12
- # Add all gem dependencies
13
- s.add_dependency 'httpclient'
11
+ s.extra_rdoc_files = %w[README.rdoc LICENSE.txt CHANGES.txt]
12
+ s.has_rdoc = true
13
+ s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
14
+ s.require_paths = %w[lib]
14
15
 
16
+ s.executables = %w[stella]
17
+
18
+ s.add_dependency 'drydock', '>= 0.6.7'
19
+ s.add_dependency 'gibbler', '>= 0.6.2'
20
+ s.add_dependency 'storable', '>= 0.5.7'
21
+ s.add_dependency 'httpclient', '>= 2.1.5'
15
22
 
16
23
  # = MANIFEST =
17
- # The complete list of files to be included in the release. When GitHub packages your gem,
18
- # it doesn't allow you to run any command that accesses the filesystem. You will get an
19
- # error. You can ask your VCS for the list of versioned files:
20
24
  # git ls-files
21
- # svn list -R
22
25
  s.files = %w(
23
26
  CHANGES.txt
24
27
  LICENSE.txt
25
28
  README.rdoc
26
29
  Rakefile
27
- bin/example_test.rb
28
- bin/example_webapp.rb
29
- lib/logger.rb
30
+ bin/stella
31
+ examples/basic/listing_ids.csv
32
+ examples/basic/plan.rb
30
33
  lib/stella.rb
31
- lib/stella/clients.rb
32
- lib/stella/command/base.rb
33
- lib/stella/command/form.rb
34
- lib/stella/command/get.rb
35
- lib/stella/common.rb
36
- lib/stella/crypto.rb
37
- lib/stella/data/domain.rb
34
+ lib/stella/cli.rb
35
+ lib/stella/client.rb
36
+ lib/stella/config.rb
37
+ lib/stella/data.rb
38
38
  lib/stella/data/http.rb
39
- lib/stella/environment.rb
40
- lib/stella/functest.rb
41
- lib/stella/loadtest.rb
39
+ lib/stella/data/http/body.rb
40
+ lib/stella/data/http/request.rb
41
+ lib/stella/data/http/response.rb
42
+ lib/stella/dsl.rb
43
+ lib/stella/engine.rb
44
+ lib/stella/engine/functional.rb
45
+ lib/stella/engine/load.rb
46
+ lib/stella/exceptions.rb
47
+ lib/stella/guidelines.rb
48
+ lib/stella/mixins.rb
42
49
  lib/stella/stats.rb
43
50
  lib/stella/testplan.rb
44
- lib/stella/testrunner.rb
45
- lib/storable.rb
51
+ lib/stella/testplan/stats.rb
52
+ lib/stella/testplan/usecase.rb
53
+ lib/stella/utils.rb
54
+ lib/stella/utils/httputil.rb
55
+ lib/stella/version.rb
46
56
  lib/threadify.rb
47
- lib/timeunits.rb
48
- lib/util/httputil.rb
49
57
  stella.gemspec
50
- tryouts/drb/drb_test.rb
51
- tryouts/drb/open4.rb
52
- tryouts/drb/slave.rb
53
- tryouts/oo_tryout.rb
58
+ support/example_webapp.rb
59
+ support/useragents.txt
54
60
  )
55
-
56
- # = EXECUTABLES =
57
- # The list of executables in your project (if any). Don't include the path,
58
- # just the base filename.
59
- s.executables = %w[]
60
-
61
- s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
62
- s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
63
-
64
- s.has_rdoc = true
65
- s.require_paths = %w[lib]
66
- s.rubygems_version = '1.1.1'
67
61
 
68
62
 
69
- end
63
+ end
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # Use Ruby 1.8
4
+
5
+ require "rubygems"
6
+ require "rack"
7
+ require "sinatra"
8
+
9
+ require 'yaml'
10
+
11
+ set :run => true
12
+ set :environment => :development
13
+ set :dump_errors => true
14
+ set :port => 3114
15
+ set :reload => true
16
+ set :max_listings => 1000
17
+
18
+ #log = File.new("/dev/null", "a")
19
+ #STDOUT.reopen(log)
20
+ #STDERR.reopen(log)
21
+
22
+ #use Rack::Auth::Basic do |username, password|
23
+ # username == 'stella' && password == 'stella'
24
+ #end
25
+
26
+ before do
27
+ @title = "Business Finder"
28
+ end
29
+
30
+ get '/' do
31
+ @title << " - Search"
32
+ erb :search_form
33
+ end
34
+
35
+
36
+ get '/search/?' do
37
+ redirect '/' if blank?(params[:what]) && blank?(params[:where])
38
+ params[:what] ||= ''
39
+ params[:where] ||= ''
40
+ @title << " - Search Results"
41
+ @listings = filter_name(params[:what], options.listings)
42
+ if !blank?(params[:where])
43
+ @listings = filter_city(params[:where], @listings)
44
+ end
45
+ if @listings.empty?
46
+ status 404
47
+ erb :search_error
48
+ else
49
+ erb :search_results
50
+ end
51
+ end
52
+
53
+ get '/listing/add' do
54
+ erb :add_form
55
+ end
56
+
57
+ post '/listing/add' do
58
+ @title = "Add a Business"
59
+ if blank?(params[:name]) || blank?(params[:city])
60
+ status 500
61
+ @msg = blank?(params[:city]) ? "Must specify city" : "Must specify name"
62
+ erb :add_form
63
+ else
64
+ @listings = options.listings
65
+ if find_name(params[:name], @listings).empty?
66
+ @listings.shift if @listings.size >= options.max_listings
67
+ @listings << { :name => params[:name], :id => rand(100000), :city => params[:city] }
68
+ redirect '/listings'
69
+ else
70
+ status 500
71
+ @msg = "That business exists (#{params[:name]})"
72
+ erb :add_form
73
+ end
74
+ end
75
+ end
76
+
77
+ get '/listing/:id.yaml' do
78
+ content_type "text/yaml"
79
+ listing = filter_id params[:id], options.listings
80
+ listing.to_yaml
81
+ end
82
+
83
+ get '/listing/:id' do
84
+ @listings = filter_id(params[:id], options.listings)
85
+ redirect '/' if @listings.empty?
86
+ @title = "Business Listing - #{@listings.first[:name]}"
87
+ erb :listings
88
+ end
89
+
90
+ get '/listings' do
91
+ @listings = options.listings
92
+ @title = "Business Listings"
93
+ erb :listings
94
+ end
95
+
96
+ get '/listings.yaml' do
97
+ content_type "text/yaml"
98
+ @listings = options.listings
99
+ @title = "Business Listings"
100
+ @listings.to_yaml
101
+ end
102
+
103
+ set :listings => [
104
+ { :id => 1000, :name => 'John West Smoked Oysters', :city => 'Toronto' },
105
+ { :id => 1001, :name => 'Fire Town Lightning Rods', :city => 'Toronto' },
106
+ { :id => 1002, :name => 'Oversized Pen and Ink Co', :city => 'Toronto' },
107
+ { :id => 1003, :name => 'The Rathzenburg Brothers', :city => 'Toronto' },
108
+ { :id => 1004, :name => 'Forever and Always Beads', :city => 'Montreal' },
109
+ { :id => 1005, :name => "Big Al's Flavour Country", :city => 'Montreal' },
110
+ { :id => 1006, :name => 'Big Time Furniture World', :city => 'Montreal' },
111
+ { :id => 1007, :name => 'High-End Keyboard Makers', :city => 'Montreal' }
112
+ ]
113
+
114
+ before do
115
+ @cookie = request.cookies["bff-history"]
116
+ @cookie = blank?(@cookie) ? {} : YAML.load(@cookie)
117
+ @cookie[:history] ||= []
118
+ if params[:clear] == 'true'
119
+ @cookie[:history] = []
120
+ @cookie[:location] = ''
121
+ end
122
+ @cookie[:history].delete params[:what]
123
+ @cookie[:history].unshift params[:what] unless blank?(params[:what])
124
+ @cookie[:history].pop if @cookie[:history].size > 5
125
+ @cookie[:location] = params[:where] unless blank?(params[:where])
126
+ response.set_cookie "bff-history", :path => '/', :value => @cookie.to_yaml
127
+ end
128
+
129
+ helpers do
130
+
131
+ def blank?(v)
132
+ v.nil? || v.empty?
133
+ end
134
+
135
+ def filter_id(id, listings)
136
+ listings.select { |l| l[:id] == id.to_i }
137
+ end
138
+
139
+ def filter_name(name, listings)
140
+ listings.select { |l| l[:name].match(/#{name}/i) }
141
+ end
142
+
143
+ def find_name(name, listings)
144
+ listings.select { |l| l[:name] == name }
145
+ end
146
+
147
+ def filter_city(city, listings)
148
+ listings.select { |l| l[:city].match(/#{city}/i) }
149
+ end
150
+
151
+ def format_listing(lid, name, city)
152
+ listing = %Q{<div class="listing" id="listing-#{lid}">}
153
+ listing << %Q{<a href="/listing/#{lid}.yaml">#{name}</a> }
154
+ listing << %Q{#{city}</div>}
155
+ end
156
+
157
+ # Generates a string of random alphanumeric characters
158
+ # These are used as IDs throughout the system
159
+ def strand( len )
160
+ chars = ("a".."z").to_a + ("0".."9").to_a
161
+ newpass = ""
162
+ 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
163
+ return newpass
164
+ end
165
+
166
+ end
167
+
168
+ __END__
169
+
170
+ @@layout
171
+ <html>
172
+ <head>
173
+ <title><%= @title %></title>
174
+ <style>
175
+ .hilite { background-color: #FEE00B; font-weight: bold; }
176
+ .footer { color: #ccc; font-weight: lighter; font-size: 80%; margin-top: 30px; }
177
+ .footer a { color: #69c;}
178
+ </style>
179
+ </head>
180
+ <body>
181
+ <h1>Business Finder</h1>
182
+ <p style="margin-left: 50px; margin-top: 20px;"><em>
183
+ <a href="/">New Search</a> -
184
+ <a href="/listing/add?name=<%= params[:what] %>&amp;city=<%= params[:where] %>">Add Listing</a> -
185
+ <a href="/?clear=true">!!</a> -
186
+ <a href="/listings">View All</a>
187
+ </em></p>
188
+ <%= yield %>
189
+ <div class="footer">
190
+ A <a href="http://solutious.com/projects/stella/">Stella</a> demo by <a href="http://solutious.com/">Solutious</a>.
191
+ </div>
192
+ </body>
193
+ </html>
194
+
195
+ @@add_form
196
+ <% city = blank?(params[:city]) ? 'Toronto' : params[:city] %>
197
+ <% if !blank?(@msg) %>
198
+ <p style="color: red"><em>Error: <%= @msg %></em></p>
199
+ <% end %>
200
+ <form method="post">
201
+ Name: <input name="name" value="<%= params[:name] %>"/><br/>
202
+ City: <input name="city" value="<%= city %>" /><br/>
203
+ <input type="submit" />
204
+ </form>
205
+
206
+ @@listings
207
+ <% for l in @listings %>
208
+ <%= format_listing(l[:id], l[:name], l[:city]) %>
209
+ <% end %>
210
+
211
+ @@search_form
212
+ <form action="/search">
213
+ What: <input name="what" value="" /><br/>
214
+ Where: <input name="where" value="<%= @cookie[:location] %>" /><br/>
215
+ <input type="submit" />
216
+ </form>
217
+ <ul id="history">
218
+ <% unless @cookie[:history].empty? %>
219
+ <h3>Previous Searches</h3>
220
+ <% end %>
221
+ <% for what in @cookie[:history] %>
222
+ <li><em><a href="/search/?what=<%= what %>&amp;where=<%= @cookie[:location] %>"><%= what %></a></em></li>
223
+ <% end %>
224
+ </ul>
225
+
226
+ @@search_results
227
+ Looking
228
+ <% if !blank?(params[:what]) %>
229
+ for "<b><%= params[:what] %></b>"
230
+ <% end %>
231
+ <% if !blank?(params[:where]) %>
232
+ in "<b><%= params[:where] %></b>"
233
+ <% end %>
234
+ <br/><br/>
235
+ <% for l in @listings %>
236
+ <% name = l[:name].gsub(/(#{params[:what]})/i, "<span class='hilite'>\\1</span>") %>
237
+ <% city = l[:city].gsub(/(#{params[:where]})/i, "<span class='hilite'>\\1</span>") %>
238
+ <%= format_listing(l[:id], name, city) %>
239
+ <% end %>
240
+
241
+ @@search_error
242
+ Looking for "<b><%= params[:what] %></b>"
243
+ <% if !blank?(params[:where]) %>
244
+ in "<b><%= params[:where] %></b>"
245
+ <% end %>
246
+ <p><i>Nothing found</i></p>
@@ -0,0 +1,75 @@
1
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
2
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
4
+ Opera/9.50 (X11; Linux i686; U; en)
5
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en; rv:1.8.1.16) Gecko/20080827 Epiphany/2.22 Firefox/2.0.0.16
6
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 Firefox/2.0.0.16
7
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.0.2) Gecko/2008100107 Firefox/3.0.2
8
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008111318 Ubuntu/8.10 (intrepid) Firefox/3.0.4
9
+ Opera/9.52 (X11; FreeBSD 7.0-RELEASE amd64; U; en)
10
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080311 (Debian-1.8.1.13+nobinonly-0ubuntu1) Galeon/2.0.4 (Ubuntu 2.0.4-1ubuntu1)
11
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 Galeon/2.0.6 Firefox/2.0.0.16
12
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3
13
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 SeaMonkey/1.1.11
14
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.18) Gecko/20081112 Fedora/1.1.13-1.fc10 SeaMonkey/1.1.13
15
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.4.154.29 Safari/525.19
16
+ Opera/9.51 (X11; Linux i686; U; en)
17
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de; rv:1.8) Gecko/20051111 Firefox/1.5
18
+ Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
19
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1a2) Gecko/20080829082037 Shiretoko/3.1a2
20
+ Dillo/0.8.6-i18n-misc
21
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061302 Firefox/3.0 Flock/2.0b1
22
+ Opera/9.27 (X11; Linux i686; U; en)
23
+ Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0
24
+ Opera/9.27 (Windows NT 5.0; U; de)
25
+ Opera/9.62 (X11; Linux i686; U; de) Presto/2.1.1
26
+ Opera/9.62 (Windows NT 5.1; U; en) Presto/2.1.1
27
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1pre) Gecko/20080911002759 SeaMonkey/2.0a1pre
28
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.17) Gecko/20080910 Firefox/2.0.0.17 Flock/1.2.6
29
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.8.1.12) Gecko/20080203 K-Meleon/1.1.4
30
+ Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
31
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.18) Gecko/20081031 SeaMonkey/1.1.13
32
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4
33
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
34
+ Opera/8.53 (Windows NT 5.1; U; en)
35
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.4) Gecko/2008112016 Firefox/3.0.4 Flock/2.0.2
36
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceape/1.1.13 (Debian-1.1.13-1)
37
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008112309 Iceweasel/3.0.4 (Debian-3.0.4-1)
38
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.17pre) Gecko/20080716 K-Meleon/1.5.0
39
+ Opera/9.26 (Windows NT 5.0; U; de)
40
+ Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.10 (like Gecko) (Debian)
41
+ Mozilla/5.0 (X11; U; Linux i686; en; rv:1.9.0.4) Gecko/20080528 Epiphany/2.22
42
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1
43
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.14eol) Gecko/20070505 (Debian-1.8.0.15~pre080614d-0etch1) Epiphany/2.14
44
+ Opera/9.52 (X11; Linux i686; U; en)
45
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8.1.11pre) Gecko/20071206 Firefox/2.0.0.11 Navigator/9.0.0.5
46
+ Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
47
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20081206 Minefield/3.2a1pre
48
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko Kazehakase/0.5.4 Debian/0.5.4-2.1ubuntu3
49
+ Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)
50
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.36 Safari/525.19
51
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.14eol) Gecko/20070505 Iceape/1.0.9 (Debian-1.0.13~pre080323b-0etch3)
52
+ Opera/9.25 (Windows NT 5.1; U; de)
53
+ Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.11 [en]
54
+ Mozilla/4.0 (compatible; MSIE 4.01; Windows NT 5.0; SV1)
55
+ Opera/9.51 (Windows NT 5.1; U; en)
56
+ Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
57
+ Opera/9.61 (Windows NT 5.1; U; en) Presto/2.1.1
58
+ Opera/9.50 (Windows NT 5.1; U; en)
59
+ Opera/9.52 (Windows NT 5.1; U; en)
60
+ Opera/9.24 (Windows NT 5.1; U; it)
61
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/523.12.9 (KHTML, like Gecko) Version/3.0 Safari/523.12.9
62
+ Opera/9.23 (Windows NT 5.1; U; it)
63
+ Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1)
64
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceweasel/2.0.0.18 (Debian-2.0.0.18-0etch1)
65
+ Mozilla/5.0 (X11; Linux i686; U;) Gecko/0 Kazehakase/0.4.2 Debian/0.4.2-1etch1
66
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008031501 SeaMonkey/2.0a1pre
67
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Flock/1.1d
68
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6
69
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1a1) Gecko/2008072306 Shiretoko/3.1a1
70
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080211 Firefox/2.0.0.12 Flock/1.0.9
71
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.30 Safari/525.13
72
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3pre) Gecko/20081201 Minefield/3.1b3pre
73
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceweasel/2.0.0.18 (Debian-2.0.0.18-0etch1)
74
+ Opera/10.00 (X11; Linux i686 ; U; en) Presto/2.2.0
75
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; nl-NL) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.1.2 Safari/525.21