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.
Files changed (55) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +6 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +129 -0
  6. data/LICENSE +19 -0
  7. data/README.md +326 -0
  8. data/Rakefile +29 -0
  9. data/bin/basic_server_tester +311 -0
  10. data/bin/em_server/config.ru +2 -0
  11. data/bin/em_server/em_server.rb +19 -0
  12. data/bin/em_server_tester +68 -0
  13. data/bin/glowworm +90 -0
  14. data/bin/load_tester +84 -0
  15. data/ci_jobs/glowworm-continuous-deploy-next-staging/run.sh +10 -0
  16. data/ci_jobs/glowworm-integrations/run.sh +15 -0
  17. data/ci_jobs/glowworm-performance/run.sh +2 -0
  18. data/ci_jobs/glowworm-robustness/run.sh +2 -0
  19. data/ci_jobs/glowworm-units/run.sh +13 -0
  20. data/ci_jobs/setup.sh +119 -0
  21. data/example/example_server.ecology +6 -0
  22. data/example/example_server.rb +32 -0
  23. data/glowworm.gemspec +54 -0
  24. data/lib/glowworm.rb +501 -0
  25. data/lib/glowworm/em.rb +8 -0
  26. data/lib/glowworm/no_bg.rb +2 -0
  27. data/lib/glowworm/version.rb +3 -0
  28. data/server/Gemfile +27 -0
  29. data/server/Gemfile.lock +87 -0
  30. data/server/PROTOCOL +39 -0
  31. data/server/check_mk_checks/check_glowworm_server +43 -0
  32. data/server/db_migrations/20111004214649_change_feature_accounts_to_string.rb +60 -0
  33. data/server/db_migrations/20111028104546_add_value_to_account_set_features.rb +12 -0
  34. data/server/db_migrations/20120217090636_add_fully_active_flag_to_features.rb +15 -0
  35. data/server/example_test_data.rb +66 -0
  36. data/server/glowworm_server.ecology.erb +16 -0
  37. data/server/glowworm_server.rb +226 -0
  38. data/server/run/server.sh +7 -0
  39. data/server/server_test.rb +72 -0
  40. data/server/version.rb +3 -0
  41. data/test/integration/basic_server_test.rb +90 -0
  42. data/test/integration/create_sqlite_data.rb +196 -0
  43. data/test/integration/em_server_test.rb +68 -0
  44. data/test/integration/gemfile_for_specific_glowworm_version +17 -0
  45. data/test/integration/gemfile_for_specific_glowworm_version.lock +55 -0
  46. data/test/integration/integration_test_helper.rb +153 -0
  47. data/test/integration/load_test.rb +59 -0
  48. data/test/integration/nginx.conf +23 -0
  49. data/test/integration/server_test.ecology.erb +6 -0
  50. data/test/test_helper.rb +47 -0
  51. data/test/units/em_test.rb +41 -0
  52. data/test/units/feature_flag_test.rb +297 -0
  53. data/test/units/no_bg_test.rb +40 -0
  54. data/test/units/request_test.rb +51 -0
  55. 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,2 @@
1
+ require "./bin/em_server/em_server"
2
+ run EMServer
@@ -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