glowworm 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +6 -0
- data/.yardopts +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +129 -0
- data/LICENSE +19 -0
- data/README.md +326 -0
- data/Rakefile +29 -0
- data/bin/basic_server_tester +311 -0
- data/bin/em_server/config.ru +2 -0
- data/bin/em_server/em_server.rb +19 -0
- data/bin/em_server_tester +68 -0
- data/bin/glowworm +90 -0
- data/bin/load_tester +84 -0
- data/ci_jobs/glowworm-continuous-deploy-next-staging/run.sh +10 -0
- data/ci_jobs/glowworm-integrations/run.sh +15 -0
- data/ci_jobs/glowworm-performance/run.sh +2 -0
- data/ci_jobs/glowworm-robustness/run.sh +2 -0
- data/ci_jobs/glowworm-units/run.sh +13 -0
- data/ci_jobs/setup.sh +119 -0
- data/example/example_server.ecology +6 -0
- data/example/example_server.rb +32 -0
- data/glowworm.gemspec +54 -0
- data/lib/glowworm.rb +501 -0
- data/lib/glowworm/em.rb +8 -0
- data/lib/glowworm/no_bg.rb +2 -0
- data/lib/glowworm/version.rb +3 -0
- data/server/Gemfile +27 -0
- data/server/Gemfile.lock +87 -0
- data/server/PROTOCOL +39 -0
- data/server/check_mk_checks/check_glowworm_server +43 -0
- data/server/db_migrations/20111004214649_change_feature_accounts_to_string.rb +60 -0
- data/server/db_migrations/20111028104546_add_value_to_account_set_features.rb +12 -0
- data/server/db_migrations/20120217090636_add_fully_active_flag_to_features.rb +15 -0
- data/server/example_test_data.rb +66 -0
- data/server/glowworm_server.ecology.erb +16 -0
- data/server/glowworm_server.rb +226 -0
- data/server/run/server.sh +7 -0
- data/server/server_test.rb +72 -0
- data/server/version.rb +3 -0
- data/test/integration/basic_server_test.rb +90 -0
- data/test/integration/create_sqlite_data.rb +196 -0
- data/test/integration/em_server_test.rb +68 -0
- data/test/integration/gemfile_for_specific_glowworm_version +17 -0
- data/test/integration/gemfile_for_specific_glowworm_version.lock +55 -0
- data/test/integration/integration_test_helper.rb +153 -0
- data/test/integration/load_test.rb +59 -0
- data/test/integration/nginx.conf +23 -0
- data/test/integration/server_test.ecology.erb +6 -0
- data/test/test_helper.rb +47 -0
- data/test/units/em_test.rb +41 -0
- data/test/units/feature_flag_test.rb +297 -0
- data/test/units/no_bg_test.rb +40 -0
- data/test/units/request_test.rb +51 -0
- metadata +410 -0
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "bundler"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), "lib", "glowworm", "version")
|
5
|
+
|
6
|
+
desc "Run all tests"
|
7
|
+
task "test" => [ "test:units", "test:integration" ]
|
8
|
+
|
9
|
+
Rake::TestTask.new("test:units") do |t|
|
10
|
+
t.libs << "test"
|
11
|
+
t.test_files = Dir.glob("test/units/*test.rb")
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
Rake::TestTask.new("test:integration") do |t|
|
16
|
+
t.libs << "test"
|
17
|
+
t.test_files = Dir.glob("test/integration/*test.rb")
|
18
|
+
t.verbose = true
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Builds the gem'
|
22
|
+
task :build do
|
23
|
+
sh "gem build glowworm.gemspec"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Builds and installs the gem'
|
27
|
+
task :install => :build do
|
28
|
+
sh "gem install glowworm-#{Glowworm::VERSION}"
|
29
|
+
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "trollop"
|
4
|
+
OPTS = Trollop.options do
|
5
|
+
opt :server, "Glowworm server URL", :default => "localhost:4999"
|
6
|
+
opt :raise_on_assert, "Raise exception on failure", :default => false
|
7
|
+
opt :nbg, "Run Glowworm in no_bg mode", :default => false
|
8
|
+
end
|
9
|
+
|
10
|
+
require "glowworm"
|
11
|
+
Glowworm.server = OPTS[:server]
|
12
|
+
STATS = Hash.new(0)
|
13
|
+
FAKE_LOGGER = Object.new
|
14
|
+
STATS[:logger_error] = 0
|
15
|
+
STATS[:logger_warning] = 0
|
16
|
+
STATS[:logger_critical] = 0
|
17
|
+
STATS[:logger_fatal] = 0
|
18
|
+
STATS[:assert_count] = 0
|
19
|
+
STATS[:success] = 0
|
20
|
+
STATS[:failure] = 0
|
21
|
+
|
22
|
+
def FAKE_LOGGER.error(*args)
|
23
|
+
STDERR.puts("ERROR ", *args)
|
24
|
+
STATS[:logger_error] += 1
|
25
|
+
end
|
26
|
+
def FAKE_LOGGER.warn(*args)
|
27
|
+
STDERR.puts("WARN ", *args)
|
28
|
+
STATS[:logger_warning] += 1
|
29
|
+
end
|
30
|
+
def FAKE_LOGGER.critical(*args)
|
31
|
+
STDERR.puts("CRITICAL ", *args)
|
32
|
+
STATS[:logger_critical] += 1
|
33
|
+
end
|
34
|
+
def FAKE_LOGGER.fatal(*args)
|
35
|
+
STDERR.puts("FATAL ", *args)
|
36
|
+
STATS[:logger_fatal] += 1
|
37
|
+
end
|
38
|
+
def FAKE_LOGGER.debug(*args);
|
39
|
+
STDERR.puts("DEBUG ", *args)
|
40
|
+
end
|
41
|
+
def FAKE_LOGGER.info(*args);
|
42
|
+
STDERR.puts("INFO ", *args)
|
43
|
+
end
|
44
|
+
|
45
|
+
Glowworm.termite_logger = FAKE_LOGGER
|
46
|
+
Glowworm.termite_logger.debug("using ecology data: ", Ecology.data.to_s)
|
47
|
+
|
48
|
+
if OPTS[:nbg]
|
49
|
+
if Glowworm::VERSION < "0.1.6"
|
50
|
+
exit 0
|
51
|
+
end
|
52
|
+
Glowworm.no_bg
|
53
|
+
else
|
54
|
+
# Get things started
|
55
|
+
Glowworm.prefetch(:all, :all)
|
56
|
+
end
|
57
|
+
|
58
|
+
require "minitest/autorun"
|
59
|
+
require "minitest/unit"
|
60
|
+
require "minitap"
|
61
|
+
|
62
|
+
if ENV["TEST_GLOWWORM_VERSION"] && ENV["TEST_GLOWWORM_VERSION"] != "latest" && Glowworm::VERSION != ENV["TEST_GLOWWORM_VERSION"]
|
63
|
+
fail "Should be testing under #{ENV["TEST_GLOWWORM_VERSION"]}"
|
64
|
+
end
|
65
|
+
|
66
|
+
$stderr.puts "Glowworm version: #{Glowworm::VERSION}"
|
67
|
+
|
68
|
+
class Tester < MiniTest::Unit::TestCase
|
69
|
+
def test_large_timeout
|
70
|
+
if Glowworm::VERSION < "0.1.6"
|
71
|
+
assert_equal(10.0, Glowworm.timeout, "timeout must be 10.0")
|
72
|
+
elsif Glowworm.threadless
|
73
|
+
assert_equal(0.0, Glowworm.timeout, "timeout must be 0 with no bg")
|
74
|
+
else
|
75
|
+
assert_equal(10.0, Glowworm.timeout, "timeout must be 10.0")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_123_foo
|
80
|
+
assert Glowworm.feature_flag(123, 'foo'),
|
81
|
+
"Feature_flag(123, 'foo') should always return true on a test dataset."
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_low_ttl_timeout
|
85
|
+
(1..100).each do
|
86
|
+
assert Glowworm.feature_flag(123, 'foo', :ttl => 0, :timeout => 1),
|
87
|
+
"Feature_flag(123, 'foo') should always return true on a test dataset."
|
88
|
+
sleep 0.1
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
ONE_HORSE_TOWN = 1
|
93
|
+
TWO_HORSE_TOWN = 2
|
94
|
+
NO_HORSE_TOWN = 3
|
95
|
+
|
96
|
+
def feature_flag_test_with_override(override, fully_active)
|
97
|
+
if Glowworm::VERSION <= "0.0.15" && nil != override
|
98
|
+
skip "glowworm 0.0.15 and less are known not to behave as expected with a override"
|
99
|
+
end
|
100
|
+
|
101
|
+
if Glowworm::VERSION <= "0.0.22" && fully_active
|
102
|
+
skip "glowworm 0.0.22 and less do not implement fully_active"
|
103
|
+
end
|
104
|
+
|
105
|
+
[[], [ONE_HORSE_TOWN], [ONE_HORSE_TOWN, TWO_HORSE_TOWN]].each do |acct_sets|
|
106
|
+
num_accts = acct_sets.size
|
107
|
+
offset = override.nil? ? 0 : (override == true ? 1 : 2)
|
108
|
+
offset += 3 if fully_active
|
109
|
+
id = 1000 + offset * 100 + num_accts
|
110
|
+
account = "account_for_acct_sets_#{num_accts}_#{override.inspect}"
|
111
|
+
feature = "#{fully_active ? "fully_active_" : ""}feature_for_acct_sets_#{num_accts}_#{override.inspect}"
|
112
|
+
|
113
|
+
actual_values = {}
|
114
|
+
actual_values[:no_default] = Glowworm.feature_flag(account, feature)
|
115
|
+
[ true, false, 5, 0, nil, :default ].each do |default_value|
|
116
|
+
actual_values[default_value] = Glowworm.feature_flag(account, feature, :default => default_value)
|
117
|
+
end
|
118
|
+
|
119
|
+
if override != nil
|
120
|
+
# If there is an override, it should always be returned
|
121
|
+
actual_values.keys.each do |value|
|
122
|
+
assert_equal override, actual_values[value],
|
123
|
+
"With override of #{override.inspect}, feature_flag(#{account.inspect}, #{feature.inspect}) " +
|
124
|
+
"default #{value.inspect} must return #{override.inspect} not #{actual_values[value].inspect}"
|
125
|
+
end
|
126
|
+
else
|
127
|
+
if num_accts == 0
|
128
|
+
# If feature isn't active for any account_sets and there's no override,
|
129
|
+
# the default should be returned.
|
130
|
+
(actual_values.keys - [:no_default]).each do |value|
|
131
|
+
assert_equal value, actual_values[value],
|
132
|
+
"With no override and no account_sets active, feature_flag must " +
|
133
|
+
"return the default value of #{value.inspect}!"
|
134
|
+
end
|
135
|
+
|
136
|
+
assert_equal fully_active, actual_values[:no_default],
|
137
|
+
"With no override, no account_sets active #{fully_active ? "a fully active feature " : ""}and no default, " +
|
138
|
+
"feature_flag must return the (default) default value of #{fully_active}!"
|
139
|
+
elsif num_accts == 1
|
140
|
+
# If feature is switched for an account_set and there's no override,
|
141
|
+
# we should return the switched value.
|
142
|
+
actual_values.keys.each do |value|
|
143
|
+
assert_equal true, actual_values[value],
|
144
|
+
"With no override and one acct set active, feature_flag must " +
|
145
|
+
"return true!"
|
146
|
+
end
|
147
|
+
elsif num_accts == 2
|
148
|
+
# If feature is switched for two account_sets and there's no override,
|
149
|
+
# we should return the switched value.
|
150
|
+
actual_values.keys.each do |value|
|
151
|
+
assert_equal true, actual_values[value],
|
152
|
+
"With no override and two acct sets active, feature_flag must " +
|
153
|
+
"return true!"
|
154
|
+
end
|
155
|
+
else
|
156
|
+
raise "How many account sets are you testing, anyway?"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.add_feature_flag_test_with_override(override, fully_active)
|
163
|
+
instance_eval do
|
164
|
+
define_method "test_#{fully_active ? "fully_active_" : ""}feature_flag_with_override_#{override.inspect}" do
|
165
|
+
feature_flag_test_with_override(override, fully_active)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# test feature flags with various override settings
|
171
|
+
[nil, true, false].product([false, true]).each do |override, fully_active|
|
172
|
+
add_feature_flag_test_with_override(override, fully_active)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Get_value testing loop
|
176
|
+
|
177
|
+
LOW_ID_SET = 4
|
178
|
+
BIG_VALUE_SET = 5
|
179
|
+
LITTLE_VALUE_SET = 6
|
180
|
+
|
181
|
+
VALUE_FOR_ACCT_SET = {
|
182
|
+
ONE_HORSE_TOWN => 1,
|
183
|
+
TWO_HORSE_TOWN => 2,
|
184
|
+
BIG_VALUE_SET => 100,
|
185
|
+
LITTLE_VALUE_SET => 7,
|
186
|
+
LOW_ID_SET => 21,
|
187
|
+
}
|
188
|
+
|
189
|
+
def feature_value_test_with_override(override)
|
190
|
+
if Glowworm::VERSION <= "0.0.15" && nil != override
|
191
|
+
skip "glowworm 0.0.15 and less are known not to behave as expected with a override"
|
192
|
+
elsif Glowworm::VERSION < "0.1.4" && nil == override
|
193
|
+
skip "glowworm 0.1.2 and less are known not to behave as expected for a feature value in multiple sets"
|
194
|
+
end
|
195
|
+
|
196
|
+
counter = 0
|
197
|
+
[[],
|
198
|
+
[LITTLE_VALUE_SET],
|
199
|
+
[BIG_VALUE_SET, LITTLE_VALUE_SET],
|
200
|
+
[BIG_VALUE_SET, LITTLE_VALUE_SET, LOW_ID_SET]].each do |acct_sets|
|
201
|
+
acct_key = acct_sets.map(&:to_s).join("/")
|
202
|
+
id = 2000 + (override.nil? ? 0 : override + 1) * 100 + counter
|
203
|
+
counter += 1
|
204
|
+
account = "account_for_value_acct_sets_#{acct_key}_#{override.inspect}"
|
205
|
+
feature = "feature_for_value_acct_sets_#{acct_key}_#{override.inspect}"
|
206
|
+
|
207
|
+
actual_values = {}
|
208
|
+
actual_values[:no_default] = Glowworm.feature_flag(account, feature, :get_value => true)
|
209
|
+
assert_equal actual_values[:no_default], Glowworm.feature_value(account, feature),
|
210
|
+
"Glowworm must return the same value for .feature_value and .feature_flag(:get_value => true)!"
|
211
|
+
[ true, false, 5, 0, :default ].each do |default_value|
|
212
|
+
actual_values[default_value] = Glowworm.feature_flag(account, feature,
|
213
|
+
:default => default_value, :get_value => true)
|
214
|
+
assert_equal actual_values[default_value], Glowworm.feature_value(account, feature,
|
215
|
+
:default => default_value),
|
216
|
+
"Glowworm must return the same value for .feature_value and .feature_flag(:get_value => true)!"
|
217
|
+
end
|
218
|
+
|
219
|
+
if override != nil
|
220
|
+
# If there is an override, it should always be returned
|
221
|
+
actual_values.keys.each do |value|
|
222
|
+
assert_equal override, actual_values[value],
|
223
|
+
"With override of #{override.inspect}, feature_value(#{account.inspect}, #{feature.inspect}) " +
|
224
|
+
"default #{value.inspect} must return #{override.inspect} not #{actual_values[value].inspect}"
|
225
|
+
end
|
226
|
+
elsif acct_sets == []
|
227
|
+
# If feature isn't active for any account_sets and there's no override,
|
228
|
+
# the default should be returned.
|
229
|
+
(actual_values.keys - [:no_default]).each do |value|
|
230
|
+
assert_equal value, actual_values[value],
|
231
|
+
"With no override and no account_sets active, feature_value must " +
|
232
|
+
"return the default value of #{value.inspect}!"
|
233
|
+
end
|
234
|
+
|
235
|
+
assert_equal false, actual_values[:no_default],
|
236
|
+
"With no override, no account_sets active and no default, feature_value must " +
|
237
|
+
"return the (default) default value of false!"
|
238
|
+
elsif acct_sets.include?(LOW_ID_SET)
|
239
|
+
# If the feature is active for the set with the lowest
|
240
|
+
# account_set id and there's no override, it must return the
|
241
|
+
# value for that account_set id.
|
242
|
+
actual_values.keys.each do |value|
|
243
|
+
assert_equal VALUE_FOR_ACCT_SET[LOW_ID_SET], actual_values[value],
|
244
|
+
"With no override and the lowest-id account_set active, feature_value must " +
|
245
|
+
"return that account_set's value of #{VALUE_FOR_ACCT_SET[LOW_ID_SET]}!"
|
246
|
+
end
|
247
|
+
elsif acct_sets.include?(BIG_VALUE_SET)
|
248
|
+
# If the feature is active for the set with a lower account_set
|
249
|
+
# id and there's no override, it must return the value for that
|
250
|
+
# account_set id.
|
251
|
+
actual_values.keys.each do |value|
|
252
|
+
assert_equal VALUE_FOR_ACCT_SET[BIG_VALUE_SET], actual_values[value],
|
253
|
+
"With no override and the lowest-id account_set active, feature_value must " +
|
254
|
+
"return that account_set's value of #{VALUE_FOR_ACCT_SET[BIG_VALUE_SET]}!"
|
255
|
+
end
|
256
|
+
elsif acct_sets.include?(LITTLE_VALUE_SET)
|
257
|
+
# If the feature is active for the set with a lower account_set
|
258
|
+
# id and there's no override, it must return the value for that
|
259
|
+
# account_set id.
|
260
|
+
actual_values.keys.each do |value|
|
261
|
+
STDERR.puts "With no override and the lowest-id account_set active, feature_value must " +
|
262
|
+
"return that account_set's value of #{VALUE_FOR_ACCT_SET[LITTLE_VALUE_SET]}. " +
|
263
|
+
"Actual value returned is #{actual_values[value]}"
|
264
|
+
end
|
265
|
+
else
|
266
|
+
raise "You're testing some set of accounts I don't recognize!"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.add_feature_value_test_with_override(override)
|
272
|
+
instance_eval do
|
273
|
+
define_method "test_feature_value_with_override_#{override.inspect}" do
|
274
|
+
feature_value_test_with_override(override)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Basic testing loop...
|
280
|
+
[nil, 0, 1, 2, 5].each do |override|
|
281
|
+
add_feature_value_test_with_override(override)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
module MiniTest::Assertions
|
286
|
+
alias :old_assert :assert
|
287
|
+
def assert(test, msg = nil)
|
288
|
+
STATS[:assert_count] += 1
|
289
|
+
begin
|
290
|
+
old_assert(test, msg)
|
291
|
+
STATS[:success] += 1
|
292
|
+
rescue MiniTest::Assertion
|
293
|
+
STATS[:failure] += 1
|
294
|
+
raise
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
MiniTest::Unit.runner = MiniTest::TapY.new
|
300
|
+
|
301
|
+
# Output STATS to STDERR for easy debugging
|
302
|
+
MiniTest::Unit.after_tests do
|
303
|
+
STDERR.puts "Success: #{STATS[:success]}"
|
304
|
+
STDERR.puts "Failure: #{STATS[:failure]}"
|
305
|
+
STDERR.puts "Assert Count: #{STATS[:assert_count]}"
|
306
|
+
STDERR.puts "Logger warning: #{STATS[:logger_warning]}"
|
307
|
+
STDERR.puts "Logger error: #{STATS[:logger_error]}"
|
308
|
+
STDERR.puts "Logger critical: #{STATS[:logger_critical]}"
|
309
|
+
STDERR.puts "Logger fatal: #{STATS[:logger_fatal]}"
|
310
|
+
end
|
311
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "thin"
|
3
|
+
require "sinatra/base"
|
4
|
+
require "glowworm/em"
|
5
|
+
require "sinatra/synchrony"
|
6
|
+
|
7
|
+
class EMServer < Sinatra::Base
|
8
|
+
register Sinatra::Synchrony
|
9
|
+
|
10
|
+
get "/update" do
|
11
|
+
Glowworm.update_cache_in_foreground
|
12
|
+
"updated!"
|
13
|
+
end
|
14
|
+
|
15
|
+
get "/" do
|
16
|
+
val = Glowworm.feature_value(123, "foo")
|
17
|
+
val.to_s
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "minitest/unit"
|
6
|
+
require "minitap"
|
7
|
+
require "trollop"
|
8
|
+
require "httparty"
|
9
|
+
|
10
|
+
OPTS = Trollop.options do
|
11
|
+
opt :server, "EM server URL", :type => String
|
12
|
+
end
|
13
|
+
|
14
|
+
STATS = Hash.new(0)
|
15
|
+
STATS[:logger_error] = 0
|
16
|
+
STATS[:logger_warning] = 0
|
17
|
+
STATS[:logger_critical] = 0
|
18
|
+
STATS[:logger_fatal] = 0
|
19
|
+
STATS[:assert_count] = 0
|
20
|
+
STATS[:success] = 0
|
21
|
+
STATS[:failure] = 0
|
22
|
+
|
23
|
+
class Tester < MiniTest::Unit::TestCase
|
24
|
+
def test_em_get
|
25
|
+
begin
|
26
|
+
url = OPTS[:server]
|
27
|
+
assert_equal "1", HTTParty.get(url).to_s, "Request should return 1"
|
28
|
+
rescue
|
29
|
+
assert false, "request to #{url} failed"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_em_update
|
34
|
+
begin
|
35
|
+
url = OPTS[:server] + "/update"
|
36
|
+
assert_equal "updated!", HTTParty.get(url).to_s, "Update should succeed"
|
37
|
+
rescue
|
38
|
+
assert false, "request to #{url} failed"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module MiniTest::Assertions
|
44
|
+
alias :old_assert :assert
|
45
|
+
def assert(test, msg = nil)
|
46
|
+
STATS[:assert_count] += 1
|
47
|
+
begin
|
48
|
+
old_assert(test, msg)
|
49
|
+
STATS[:success] += 1
|
50
|
+
rescue MiniTest::Assertion
|
51
|
+
STATS[:failure] += 1
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
MiniTest::Unit.runner = MiniTest::TapY.new
|
58
|
+
|
59
|
+
# Output STATS to STDERR for easy debugging
|
60
|
+
MiniTest::Unit.after_tests do
|
61
|
+
STDERR.puts "Success: #{STATS[:success]}"
|
62
|
+
STDERR.puts "Failure: #{STATS[:failure]}"
|
63
|
+
STDERR.puts "Assert Count: #{STATS[:assert_count]}"
|
64
|
+
STDERR.puts "Logger warning: #{STATS[:logger_warning]}"
|
65
|
+
STDERR.puts "Logger error: #{STATS[:logger_error]}"
|
66
|
+
STDERR.puts "Logger critical: #{STATS[:logger_critical]}"
|
67
|
+
STDERR.puts "Logger fatal: #{STATS[:logger_fatal]}"
|
68
|
+
end
|
data/bin/glowworm
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "trollop"
|
4
|
+
require "pp"
|
5
|
+
require "glowworm"
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
opt :feature, "What feature name to query", :type => String, :default => "video_rec"
|
9
|
+
opt :account, "What account to query", :type => String, :default => "35"
|
10
|
+
opt :debug, "Whether to debug", :type => :boolean, :default => false
|
11
|
+
opt :dump_cache, "Whether to dump the Glowworm cache", :type => :boolean, :default => false
|
12
|
+
opt :load_test, "How many times to repeat the query", :type => :int, :default => 1
|
13
|
+
banner <<BANNER
|
14
|
+
Glowworm is a program to query the feature flags of accounts and providers.
|
15
|
+
|
16
|
+
Usage: #{$0} [options] [server name]
|
17
|
+
|
18
|
+
With a specific feature and account, Glowworm will print true or false, or
|
19
|
+
raise an exception if data can't be gotten.
|
20
|
+
|
21
|
+
You can specify "all" for the --feature or --account parameters to query all.
|
22
|
+
Doing both will dump a *lot* of data, so redirect to a file.
|
23
|
+
|
24
|
+
Options:
|
25
|
+
BANNER
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fake logger that ignores all calls
|
29
|
+
fake_logger = Object.new
|
30
|
+
def fake_logger.method_missing(*args); end
|
31
|
+
sensitive_logger = ::Termite::Logger.new(STDOUT)
|
32
|
+
sensitive_logger.level = ::Logger::INFO
|
33
|
+
|
34
|
+
Glowworm.server = ARGV.pop || "localhost:4999"
|
35
|
+
Glowworm.timeout = 5.0 # 5-second timeout by default
|
36
|
+
Glowworm.termite_logger = opts[:debug] ? sensitive_logger : fake_logger
|
37
|
+
Ecology.read # No ecology, must set options manually.
|
38
|
+
|
39
|
+
if opts[:debug]
|
40
|
+
puts <<END
|
41
|
+
Glowworm v#{Glowworm::VERSION}
|
42
|
+
Querying server #{Glowworm.server}
|
43
|
+
Feature #{opts[:feature]}, account #{opts[:account]}
|
44
|
+
END
|
45
|
+
end
|
46
|
+
|
47
|
+
opts[:account] = :all if opts[:account] == "all"
|
48
|
+
opts[:feature] = :all if opts[:feature] == "all"
|
49
|
+
|
50
|
+
if opts[:account] == :all || opts[:feature] == :all
|
51
|
+
puts "Prefetching: #{opts[:account]}, #{opts[:feature]}" if opts[:debug]
|
52
|
+
Glowworm.prefetch opts[:account], opts[:feature]
|
53
|
+
|
54
|
+
# Prefetch is instant, so we need to wait until the prefetch returns
|
55
|
+
Glowworm.feature_flag("fake_acct", "fake_flag")
|
56
|
+
|
57
|
+
accounts = opts[:account] == :all ? Glowworm.all_cached_accounts : [ opts[:account] ]
|
58
|
+
features = opts[:feature] == :all ? Glowworm.all_cached_features : [ opts[:feature] ]
|
59
|
+
|
60
|
+
STDERR.puts "Accounts: #{accounts.inspect}" if opts[:debug]
|
61
|
+
STDERR.puts "Features: #{features.inspect}" if opts[:debug]
|
62
|
+
|
63
|
+
cached_features = {}
|
64
|
+
accounts.each do |account|
|
65
|
+
cached_features[account] = {}
|
66
|
+
features.each do |feature|
|
67
|
+
flag = Glowworm.feature_flag(account, feature, :ttl => 1_000_000, :timeout => 0.0)
|
68
|
+
cached_features[account][feature] = flag
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
pp cached_features
|
73
|
+
else
|
74
|
+
opts[:load_test].times do
|
75
|
+
# 0 TTL means "always actually fetch, never treat as fresh"
|
76
|
+
puts "Querying #{Glowworm.server}, feature #{opts[:feature]}, account #{opts[:account]}:"
|
77
|
+
puts Glowworm.feature_flag(opts[:account], opts[:feature], :ttl => 0.0).inspect
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if opts[:dump_cache]
|
82
|
+
puts "*************** Dumping Glowworm Cache: ****************"
|
83
|
+
puts "\nGlowworm feature cache:"
|
84
|
+
pp Glowworm.feature_cache
|
85
|
+
puts "\nGlowworm account_set cache:"
|
86
|
+
pp Glowworm.account_set_cache
|
87
|
+
puts "\nGlowworm override cache:"
|
88
|
+
pp Glowworm.override_cache
|
89
|
+
puts "********************************************************"
|
90
|
+
end
|