glowworm 0.3.0
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.
- 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
|