logster 2.20.1 → 3.0.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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -92
  3. data/README.md +29 -14
  4. data/assets/javascript/main-B82IoCiW.js +1 -0
  5. data/assets/javascript/modules-4-12-BHA4lR2U.js +1 -0
  6. data/assets/javascript/vendor.js +11 -5260
  7. data/assets/logster-config.json +18 -0
  8. data/assets/manifest.json +23 -0
  9. data/assets/stylesheets/main-CgAFFyi8.css +1 -0
  10. data/lib/logster/configuration.rb +1 -0
  11. data/lib/logster/group.rb +2 -2
  12. data/lib/logster/message.rb +4 -4
  13. data/lib/logster/middleware/reporter.rb +34 -3
  14. data/lib/logster/middleware/viewer.rb +205 -33
  15. data/lib/logster/rails/railtie.rb +4 -20
  16. data/lib/logster/redis_store.rb +0 -2
  17. data/lib/logster/version.rb +1 -1
  18. data/lib/logster.rb +1 -1
  19. metadata +17 -186
  20. data/.github/workflows/ci.yml +0 -140
  21. data/.gitignore +0 -3
  22. data/.rubocop.yml +0 -8
  23. data/.streerc +0 -2
  24. data/Gemfile +0 -10
  25. data/Guardfile +0 -10
  26. data/Rakefile +0 -27
  27. data/assets/javascript/.gitkeep +0 -0
  28. data/assets/javascript/chunk.524.c3042190e39d148beaf9.js +0 -22
  29. data/assets/javascript/chunk.582.695dcbfb11a784b110cd.js +0 -22
  30. data/assets/javascript/chunk.747.a730c497582bb6742a6e.js +0 -579
  31. data/assets/javascript/chunk.761.64949d89942c829e5c1b.js +0 -1213
  32. data/assets/javascript/client-app.js +0 -1390
  33. data/assets/stylesheets/.gitkeep +0 -0
  34. data/assets/stylesheets/client-app.css +0 -1
  35. data/assets/stylesheets/vendor.css +0 -1
  36. data/build_client_app.sh +0 -10
  37. data/client-app/.editorconfig +0 -19
  38. data/client-app/.ember-cli +0 -9
  39. data/client-app/.eslintignore +0 -20
  40. data/client-app/.eslintrc +0 -10
  41. data/client-app/.gitignore +0 -23
  42. data/client-app/.prettierignore +0 -21
  43. data/client-app/.prettierrc +0 -1
  44. data/client-app/.template-lintrc.js +0 -10
  45. data/client-app/.watchmanconfig +0 -3
  46. data/client-app/README.md +0 -56
  47. data/client-app/app/app.js +0 -12
  48. data/client-app/app/components/actions-menu.js +0 -50
  49. data/client-app/app/components/back-to-site-link.js +0 -9
  50. data/client-app/app/components/back-trace.js +0 -153
  51. data/client-app/app/components/env-tab.js +0 -68
  52. data/client-app/app/components/message-info.js +0 -151
  53. data/client-app/app/components/message-row.js +0 -46
  54. data/client-app/app/components/page-nav.js +0 -42
  55. data/client-app/app/components/panel-resizer.js +0 -108
  56. data/client-app/app/components/patterns-list.js +0 -142
  57. data/client-app/app/components/tab-contents.js +0 -23
  58. data/client-app/app/components/tabbed-section.js +0 -45
  59. data/client-app/app/components/time-formatter.js +0 -36
  60. data/client-app/app/controllers/index.js +0 -269
  61. data/client-app/app/controllers/show.js +0 -39
  62. data/client-app/app/helpers/logster-url.js +0 -12
  63. data/client-app/app/helpers/or.js +0 -7
  64. data/client-app/app/index.html +0 -31
  65. data/client-app/app/initializers/app-init.js +0 -71
  66. data/client-app/app/lib/decorators.js +0 -13
  67. data/client-app/app/lib/preload.js +0 -43
  68. data/client-app/app/lib/utilities.js +0 -230
  69. data/client-app/app/models/group.js +0 -34
  70. data/client-app/app/models/message-collection.js +0 -303
  71. data/client-app/app/models/message.js +0 -128
  72. data/client-app/app/models/pattern-item.js +0 -32
  73. data/client-app/app/resolver.js +0 -3
  74. data/client-app/app/router.js +0 -13
  75. data/client-app/app/routes/index.js +0 -64
  76. data/client-app/app/routes/settings.js +0 -32
  77. data/client-app/app/routes/show.js +0 -16
  78. data/client-app/app/services/events.js +0 -4
  79. data/client-app/app/styles/app.css +0 -829
  80. data/client-app/app/templates/application.hbs +0 -1
  81. data/client-app/app/templates/components/actions-menu.hbs +0 -31
  82. data/client-app/app/templates/components/back-to-site-link.hbs +0 -8
  83. data/client-app/app/templates/components/back-trace.hbs +0 -15
  84. data/client-app/app/templates/components/env-tab.hbs +0 -10
  85. data/client-app/app/templates/components/message-info.hbs +0 -86
  86. data/client-app/app/templates/components/message-row.hbs +0 -32
  87. data/client-app/app/templates/components/page-nav.hbs +0 -37
  88. data/client-app/app/templates/components/panel-resizer.hbs +0 -3
  89. data/client-app/app/templates/components/patterns-list.hbs +0 -78
  90. data/client-app/app/templates/components/tabbed-section.hbs +0 -18
  91. data/client-app/app/templates/components/time-formatter.hbs +0 -1
  92. data/client-app/app/templates/index.hbs +0 -165
  93. data/client-app/app/templates/settings.hbs +0 -47
  94. data/client-app/app/templates/show.hbs +0 -13
  95. data/client-app/config/ember-cli-update.json +0 -18
  96. data/client-app/config/environment.js +0 -51
  97. data/client-app/config/icons.js +0 -28
  98. data/client-app/config/optional-features.json +0 -6
  99. data/client-app/config/targets.js +0 -26
  100. data/client-app/ember-cli-build.js +0 -28
  101. data/client-app/package.json +0 -76
  102. data/client-app/preload-json-manager.rb +0 -35
  103. data/client-app/public/assets/images/icon_144x144.png +0 -0
  104. data/client-app/public/assets/images/icon_64x64.png +0 -0
  105. data/client-app/testem.js +0 -23
  106. data/client-app/tests/index.html +0 -41
  107. data/client-app/tests/integration/components/back-to-site-link-test.js +0 -20
  108. data/client-app/tests/integration/components/back-trace-test.js +0 -138
  109. data/client-app/tests/integration/components/env-tab-test.js +0 -220
  110. data/client-app/tests/integration/components/message-info-test.js +0 -122
  111. data/client-app/tests/integration/components/patterns-list-test.js +0 -76
  112. data/client-app/tests/test-helper.js +0 -12
  113. data/client-app/tests/unit/controllers/index-test.js +0 -77
  114. data/client-app/tests/unit/controllers/show-test.js +0 -12
  115. data/client-app/tests/unit/routes/index-test.js +0 -11
  116. data/client-app/tests/unit/routes/show-test.js +0 -11
  117. data/client-app/yarn.lock +0 -9905
  118. data/gemfiles/rails_6.1.gemfile +0 -12
  119. data/gemfiles/rails_7.0.gemfile +0 -12
  120. data/gemfiles/rails_7.1.gemfile +0 -9
  121. data/gemfiles/rails_7.2.gemfile +0 -9
  122. data/logster.gemspec +0 -43
  123. data/test/dummy/config/application.rb +0 -31
  124. data/test/dummy/config/boot.rb +0 -6
  125. data/test/dummy/config/environment.rb +0 -6
  126. data/test/examples/test_sidekiq_reporter_example.rb +0 -47
  127. data/test/fake_data/Gemfile +0 -6
  128. data/test/fake_data/generate.rb +0 -23
  129. data/test/logster/middleware/test_reporter.rb +0 -84
  130. data/test/logster/middleware/test_viewer.rb +0 -495
  131. data/test/logster/test_base_store.rb +0 -224
  132. data/test/logster/test_cache.rb +0 -39
  133. data/test/logster/test_defer_logger.rb +0 -36
  134. data/test/logster/test_group.rb +0 -92
  135. data/test/logster/test_ignore_pattern.rb +0 -42
  136. data/test/logster/test_logger.rb +0 -177
  137. data/test/logster/test_message.rb +0 -269
  138. data/test/logster/test_pattern.rb +0 -144
  139. data/test/logster/test_railtie.rb +0 -21
  140. data/test/logster/test_redis_rate_limiter.rb +0 -246
  141. data/test/logster/test_redis_store.rb +0 -1165
  142. data/test/test_helper.rb +0 -44
@@ -1,269 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../test_helper"
4
- require "logster/message"
5
-
6
- class TestMessage < MiniTest::Test
7
- def test_merge_similar
8
- msg1 = Logster::Message.new(0, "", "test", 10)
9
- msg1.populate_from_env(a: "1", b: "2")
10
-
11
- msg2 = Logster::Message.new(0, "", "test", 20)
12
- msg2.populate_from_env(a: "2", c: "3")
13
- assert_equal(msg2.grouping_key, msg1.grouping_key)
14
- msg1.merge_similar_message(msg2)
15
-
16
- assert_equal(20, msg1.timestamp)
17
- assert_equal(10, msg1.first_timestamp)
18
- assert_equal(msg1.env_buffer, [msg2.env])
19
- end
20
-
21
- def test_populate_from_env_will_add_time_to_env_unless_it_already_exists
22
- t = (Time.now.to_f * 1000).to_i
23
- msg = Logster::Message.new(0, "", "test", t)
24
- msg.populate_from_env({})
25
- assert_equal(t, msg.env["time"])
26
-
27
- msg = Logster::Message.new(0, "", "test", t)
28
- msg.populate_from_env(time: 5)
29
- assert_nil(msg.env["time"])
30
- assert_equal(5, msg.env[:time])
31
-
32
- msg = Logster::Message.new(0, "", "test", t)
33
- msg.populate_from_env("time" => 6)
34
- assert_equal(6, msg.env["time"])
35
- assert_nil(msg.env[:time])
36
-
37
- msg = Logster::Message.new(0, "", "test", t)
38
- msg.populate_from_env([{ "time" => 6 }, { "time" => 8 }])
39
- assert_equal([6, 8], msg.env.map { |e| e["time"] })
40
- assert_equal([nil, nil], msg.env.map { |e| e[:time] })
41
-
42
- msg = Logster::Message.new(0, "", "test", t)
43
- msg.populate_from_env([{ dsd: 6 }, { dsd: 8 }])
44
- assert_equal([t, t], msg.env.map { |e| e["time"] })
45
- end
46
-
47
- def test_merge_messages_both_with_array_envs
48
- msg1 = Logster::Message.new(0, "", "test", 10)
49
- msg1.env = [{ a: "aa", b: "bb" }, { c: "cc", d: "dd" }]
50
-
51
- msg2 = Logster::Message.new(0, "", "test", 20)
52
- msg2.env = [{ e: "ee", f: "ff" }, { g: "gg", h: "hh" }]
53
-
54
- msg1.merge_similar_message(msg2)
55
- assert_equal(msg2.env, msg1.env_buffer)
56
- end
57
-
58
- def test_merge_messages_one_with_array_envs
59
- msg1 = Logster::Message.new(0, "", "test", 10)
60
- msg1.env = { e: "ee", f: "ff" }
61
-
62
- msg2 = Logster::Message.new(0, "", "test", 20)
63
- msg2.env = [{ a: "aa", b: "bb" }, { c: "cc", d: "dd" }]
64
-
65
- msg1.merge_similar_message(msg2)
66
- assert_equal(msg2.env, msg1.env_buffer)
67
- end
68
-
69
- def test_adds_application_version
70
- Logster.config.application_version = "abc"
71
- msg = Logster::Message.new(0, "", "test", 10)
72
- msg.populate_from_env({})
73
-
74
- assert_equal("abc", msg.env["application_version"])
75
- ensure
76
- Logster.config.application_version = nil
77
- end
78
-
79
- def test_use_full_hostname
80
- Logster::Message.instance_variable_set(:@hostname, nil)
81
- Logster.config.use_full_hostname = true
82
- msg = Logster::Message.new(0, "", "test", 10)
83
- msg.populate_from_env({})
84
-
85
- assert_equal(`hostname -f`.strip!, msg.env["hostname"])
86
- ensure
87
- Logster.config.use_full_hostname = nil
88
- Logster::Message.instance_variable_set(:@hostname, nil)
89
- end
90
-
91
- def test_merging_sums_count_for_both_messages
92
- msg1 = Logster::Message.new(0, "", "test", 10, count: 15)
93
- msg2 = Logster::Message.new(0, "", "test", 20, count: 13)
94
- msg2.env = {}
95
-
96
- assert_equal(msg1.grouping_key, msg2.grouping_key)
97
-
98
- msg1.merge_similar_message(msg2)
99
- assert_equal(msg1.count, 15 + 13)
100
- end
101
-
102
- def test_messages_with_bad_encoding_dont_break_logster
103
- hash = {
104
- severity: 0,
105
- progname: "test",
106
- message: "invalid encoding",
107
- env: {
108
- a: "bad_value",
109
- b: ["bad_value"],
110
- },
111
- }
112
- json = hash.to_json.gsub("bad_value", "45\xC0\xBE")
113
- message = Logster::Message.from_json(json)
114
- message.to_json # test failure would be this raising exception
115
-
116
- message.env = JSON.parse(json)["env"]
117
- message.to_json
118
- end
119
-
120
- def test_populate_from_env_works_on_array
121
- msg = Logster::Message.new(0, "", "test", 10)
122
- hash = { "custom_key" => "key" }
123
- msg.populate_from_env([hash])
124
-
125
- assert Array === msg.env
126
- assert_equal(msg.env.size, 1)
127
- assert hash <= msg.env[0]
128
- end
129
-
130
- def test_merging_envs_add_new_envs_to_buffer
131
- msg1 = Logster::Message.new(0, "", "test", 10, count: 50)
132
- msg1.env = 50.times.map { |n| { a: n } }
133
- msg2 = Logster::Message.new(0, "", "test", 20, count: 13)
134
- msg2.env = 13.times.map { |n| { b: n } }
135
-
136
- assert_equal(msg1.grouping_key, msg2.grouping_key)
137
-
138
- msg1.merge_similar_message(msg2)
139
- assert_equal(63, msg1.count) # update count
140
- assert_equal(msg2.env, msg1.env_buffer)
141
- end
142
-
143
- def test_message_to_h_respects_params
144
- msg = Logster::Message.new(0, "", "test")
145
- test_hash = { test_key: "this is a test" }
146
- msg.env = test_hash
147
- assert_equal(test_hash, msg.to_h[:env])
148
- assert_nil(msg.to_h(exclude_env: true)[:env])
149
- end
150
-
151
- def test_message_to_json_respects_params
152
- msg = Logster::Message.new(0, "", "test")
153
- test_hash = { test_key: "this is a test" }
154
- msg.env = test_hash
155
- assert_includes(msg.to_json, test_hash.to_json)
156
- refute_includes(msg.to_json(exclude_env: true), test_hash.to_json)
157
- end
158
-
159
- def test_drop_redundant_envs
160
- message = Logster::Message.new(Logger::WARN, "", "message")
161
- message.env = [{ a: 4 }] * 10
162
- assert_equal(10, message.env.size)
163
- message.drop_redundant_envs(5)
164
- assert_equal(5, message.env.size)
165
-
166
- env = { f: 5, g: 4 }
167
- message.env = env.dup
168
- message.drop_redundant_envs(1)
169
- assert_equal(env, message.env)
170
- end
171
-
172
- def test_apply_env_size_limit_keeps_as_many_keys_as_possible
173
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
174
- env = { a: 1, bb: 22, ccc: 333 }
175
- message.env = env.dup
176
- message.apply_env_size_limit(24)
177
- assert_operator(message.env.to_json.bytesize, :<=, 24)
178
- assert_equal({ a: 1, bb: 22 }.to_json.bytesize, message.env.to_json.bytesize)
179
-
180
- message.env = [env.dup] * 5
181
- message.apply_env_size_limit(24)
182
- assert_equal(5, message.env.size)
183
- message.env.each do |e|
184
- assert_operator(e.to_json.bytesize, :<=, 24)
185
- assert_equal({ a: 1, bb: 22 }.to_json.bytesize, e.to_json.bytesize)
186
- end
187
-
188
- message.env = env.dup
189
- message.apply_env_size_limit(25)
190
- assert_operator(message.env.to_json.bytesize, :<=, 25)
191
- assert_equal({ a: 1, bb: 22, ccc: 333 }.to_json.bytesize, message.env.to_json.bytesize)
192
- end
193
-
194
- def test_apply_message_size_limit_removes_gems_dir_from_backtrace_to_keep_total_message_size_below_limit
195
- backtrace = <<~TEXT
196
- /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:220:in `with_connection'
197
- /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:60:in `with_connection'
198
- /var/www/discourse/lib/scheduler/defer.rb:89:in `do_work'
199
- /var/www/discourse/lib/scheduler/defer.rb:79:in `block (2 levels) in start_thread'
200
- TEXT
201
- without_gems_dir = <<~TEXT
202
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:220:in `with_connection'
203
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:60:in `with_connection'
204
- /var/www/discourse/lib/scheduler/defer.rb:89:in `do_work'
205
- /var/www/discourse/lib/scheduler/defer.rb:79:in `block (2 levels) in start_thread'
206
- TEXT
207
- gems_dir = "/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/"
208
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
209
-
210
- message.backtrace = backtrace.dup
211
- assert_operator(message.to_json(exclude_env: true).bytesize, :>=, 500)
212
- message.apply_message_size_limit(500, gems_dir: gems_dir)
213
- assert_operator(message.to_json(exclude_env: true).bytesize, :<=, 500)
214
- assert_equal(without_gems_dir.strip, message.backtrace.strip)
215
- end
216
-
217
- def test_apply_message_size_limit_removes_lines_from_backtrace_to_keep_total_size_below_limit
218
- backtrace = <<~TEXT
219
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:220:in `with_connection'
220
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:60:in `with_connection'
221
- /var/www/discourse/lib/scheduler/defer.rb:89:in `do_work'
222
- /var/www/discourse/lib/scheduler/defer.rb:79:in `block (2 levels) in start_thread'
223
- TEXT
224
-
225
- expected = <<~TEXT
226
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:220:in `with_connection'
227
- rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:60:in `with_connection'
228
- /var/www/discourse
229
- TEXT
230
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
231
- message.backtrace = backtrace.dup
232
- assert_operator(message.to_json(exclude_env: true).bytesize, :>=, 350)
233
- message.apply_message_size_limit(350)
234
- assert_operator(message.to_json(exclude_env: true).bytesize, :<=, 350)
235
- assert_equal(expected.strip, message.backtrace.strip)
236
- end
237
-
238
- def test_truncate_backtrace_shouldnt_corrupt_backtrace_when_it_contains_multibytes_characters
239
- backtrace = "aहa"
240
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
241
- message.backtrace = backtrace.dup
242
- message.truncate_backtrace(3)
243
- assert_equal("a", message.backtrace)
244
-
245
- message.backtrace = backtrace.dup
246
- message.truncate_backtrace(4)
247
- assert_equal("aह", message.backtrace)
248
-
249
- message.backtrace = backtrace.dup
250
- message.truncate_backtrace(5)
251
- assert_equal(backtrace, message.backtrace)
252
- end
253
-
254
- def test_apply_message_size_limit_doesnt_remove_backtrace_entirely
255
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
256
- message.backtrace = "a" * 1000
257
- assert_operator(message.to_json(exclude_env: true).bytesize, :>=, 500)
258
- message.apply_message_size_limit(500)
259
- assert_operator(message.to_json(exclude_env: true).bytesize, :<=, 500)
260
- assert_equal(("a" * 354).size, message.backtrace.size)
261
- end
262
-
263
- def test_apply_message_size_limit_doesnt_hang_forever_and_doesnt_remove_backtrace_entirely
264
- message = Logster::Message.new(Logger::WARN, "", "message", 1)
265
- message.backtrace = "aa" * 100
266
- message.apply_message_size_limit(10)
267
- assert_equal(("aa" * 100).size, message.backtrace.size)
268
- end
269
- end
@@ -1,144 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../test_helper"
4
- require "logster/redis_store"
5
- require "logster/pattern"
6
-
7
- class TestPattern < Minitest::Test
8
- class FakePattern < Logster::Pattern
9
- def self.set_name
10
- "__LOGSTER__fake_patterns_set".freeze
11
- end
12
- end
13
-
14
- class TestRedisStore < Logster::BaseStore
15
- def get_patterns(set_name)
16
- ["/differentstore/"]
17
- end
18
- end
19
-
20
- def setup
21
- Logster.store = Logster::RedisStore.new
22
- Logster.store.clear_all
23
- end
24
-
25
- def teardown
26
- Logster.store.clear_all
27
- Logster.store = nil
28
- end
29
-
30
- def test_parse_pattern_works_correctly
31
- assert_equal(/osama/i, klass.parse_pattern(/osama/i))
32
- assert_equal(/osama/i, klass.parse_pattern("/osama/i"))
33
- assert_equal(/osama/, klass.parse_pattern("/osama/"))
34
- assert_equal(/osama/, klass.parse_pattern("osama"))
35
- assert_equal(/[a-zA-Z]/, klass.parse_pattern("[a-zA-Z]"))
36
- assert_equal(/[a-zA-Z]/, klass.parse_pattern("/[a-zA-Z]/"))
37
-
38
- assert_nil(klass.parse_pattern("/osama"))
39
- assert_nil(klass.parse_pattern("["))
40
- assert_nil(klass.parse_pattern("/[/"))
41
- end
42
-
43
- def test_validity_checks_are_correct
44
- assert(klass.valid?(/osama/))
45
- refute(klass.valid?(//))
46
- refute(klass.valid?(//i))
47
- refute(klass.valid?(/ /))
48
- end
49
-
50
- def test_find_all_works_correctly
51
- patterns = ["/test/i", "tttt", "[d-y].*"]
52
- patterns.each { |p| FakePattern.new(p).save }
53
-
54
- results = FakePattern.find_all
55
- assert_equal(3, results.size)
56
- assert_includes(results, /test/i)
57
- assert_includes(results, /tttt/)
58
- assert_includes(results, /[d-y].*/)
59
-
60
- results = FakePattern.find_all(raw: true)
61
- assert_equal(3, results.size)
62
- assert_includes(results, "/test/i")
63
- assert_includes(results, "/tttt/")
64
- assert_includes(results, "/[d-y].*/")
65
- end
66
-
67
- def test_find_all_can_take_an_instance_of_store
68
- results = FakePattern.find_all(store: TestRedisStore.new)
69
- assert_equal(1, results.size)
70
- assert_equal(/differentstore/, results.first)
71
- end
72
-
73
- def test_find_works_correctly
74
- FakePattern.new("/wwwlll/").save
75
-
76
- record = FakePattern.find("wwwlll")
77
- assert_equal(/wwwlll/, record.pattern)
78
- record = FakePattern.find(/wwwlll/)
79
- assert_equal(/wwwlll/, record.pattern)
80
-
81
- assert_nil(FakePattern.find("dfsdfsdf"))
82
- assert_nil(FakePattern.find(nil))
83
- end
84
-
85
- def test_patterns_get_parsed_on_initialize
86
- assert_equal(/mypattern/, FakePattern.new("mypattern").pattern)
87
- assert_equal(/111333/, FakePattern.new(/111333/).pattern)
88
- end
89
-
90
- def test_save_works_correctly
91
- bad_patterns = ["/bruken", nil, "[a-z", "/(osa|sss{1/"]
92
- bad_patterns.each do |p|
93
- assert_raises(Logster::Pattern::PatternError) { FakePattern.new(p).save }
94
- end
95
- assert_equal(0, FakePattern.find_all.size)
96
-
97
- good_patterns = ["/logster/i", /logster/, "sssd", "(ccx|tqe){1,5}", "logster"]
98
- good_patterns.each { |p| FakePattern.new(p).save }
99
- results = FakePattern.find_all
100
- assert_equal(4, results.size) # 4 because /logster/ and logster are the same
101
- good_patterns_regex = [/logster/i, /logster/, /sssd/, /(ccx|tqe){1,5}/]
102
- results.each { |p| assert_includes(good_patterns_regex, p) }
103
- end
104
-
105
- def test_modify_works_correctly
106
- record = FakePattern.new(/logster/)
107
- record.save
108
-
109
- record.modify("/LoGsTEr/")
110
- all_patterns = FakePattern.find_all
111
- assert_equal(1, all_patterns.size)
112
- assert_equal(/LoGsTEr/, all_patterns.first)
113
- assert_equal(/LoGsTEr/, record.pattern)
114
- end
115
-
116
- def test_modify_doesnt_remove_old_pattern_when_new_is_bad
117
- record = FakePattern.new(/LoGsTEr/)
118
- record.save
119
-
120
- assert_raises(Logster::Pattern::PatternError) { record.modify("/badReg") }
121
- all_patterns = FakePattern.find_all
122
- assert_equal(1, all_patterns.size)
123
- assert_equal(/LoGsTEr/, all_patterns.first)
124
- assert_equal(/LoGsTEr/, record.pattern)
125
- end
126
-
127
- def test_destroy_works_correctly
128
- record = FakePattern.new(/somepattern/)
129
- record.save
130
-
131
- patterns = FakePattern.find_all
132
- assert_equal(1, patterns.size)
133
- assert_equal(/somepattern/, patterns.first)
134
-
135
- record.destroy
136
- assert_equal(0, FakePattern.find_all.size)
137
- end
138
-
139
- private
140
-
141
- def klass
142
- Logster::Pattern
143
- end
144
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ENV["RAILS_ENV"] = "test"
4
-
5
- require "redis"
6
- require_relative "../dummy/config/environment"
7
- ActiveRecord::Migrator.migrations_paths = [File.expand_path("dummy/db/migrate", __dir__)]
8
-
9
- require_relative "../test_helper"
10
-
11
- class TestRailtie < Minitest::Test
12
- def test_sets_logger
13
- refute_nil Logster.logger
14
-
15
- if Rails.version >= "7.1"
16
- assert_includes Rails.logger.broadcasts, Logster.logger
17
- else
18
- assert_equal Rails.logger, Logster.logger
19
- end
20
- end
21
- end
@@ -1,246 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../test_helper"
4
- require "logster/redis_store"
5
- require "rack"
6
-
7
- class TestRedisRateLimiter < Minitest::Test
8
- def setup
9
- @redis = Redis.new
10
- end
11
-
12
- def teardown
13
- @redis.flushall
14
- Timecop.return
15
- end
16
-
17
- def test_clear_all
18
- called = 0
19
-
20
- @redis.set("dont_nuke", "1")
21
-
22
- @rate_limiter =
23
- Logster::RedisRateLimiter.new(
24
- @redis,
25
- [Logger::WARN],
26
- 8,
27
- 60,
28
- Proc.new { "prefix" },
29
- Proc.new { called += 1 },
30
- )
31
-
32
- 9.times { @rate_limiter.check(Logger::WARN) }
33
-
34
- assert_equal 10, @rate_limiter.check(Logger::WARN)
35
-
36
- Logster::RedisRateLimiter.clear_all(@redis, Proc.new { "prefix" })
37
-
38
- assert_equal 1, @rate_limiter.check(Logger::WARN)
39
-
40
- # also clears when prefix missing
41
- Logster::RedisRateLimiter.clear_all(@redis)
42
-
43
- assert_equal 1, @rate_limiter.check(Logger::WARN)
44
-
45
- assert_equal "1", @redis.get("dont_nuke")
46
- @redis.del("dont_nuke")
47
- end
48
-
49
- def test_check
50
- time = Time.new(2015, 1, 1, 1, 1)
51
- Timecop.freeze(time)
52
- called = 0
53
-
54
- @rate_limiter =
55
- Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 8, 60, nil, Proc.new { called += 1 })
56
-
57
- assert_equal(1, @rate_limiter.check(Logger::WARN))
58
- assert_redis_key(60, 0)
59
- assert_equal(1, number_of_buckets)
60
-
61
- Timecop.freeze(time + 10) do
62
- assert_equal(2, @rate_limiter.check(Logger::WARN))
63
- assert_redis_key(60, 1)
64
- assert_equal(3, @rate_limiter.check(Logger::WARN))
65
- assert_equal(2, number_of_buckets)
66
- end
67
-
68
- Timecop.freeze(time + 20) do
69
- assert_equal(4, @rate_limiter.check(Logger::WARN))
70
- assert_redis_key(60, 2)
71
- assert_equal(3, number_of_buckets)
72
- end
73
-
74
- Timecop.freeze(time + 30) do
75
- assert_equal(5, @rate_limiter.check(Logger::WARN))
76
- assert_redis_key(60, 3)
77
- assert_equal(4, number_of_buckets)
78
- end
79
-
80
- Timecop.freeze(time + 40) do
81
- assert_equal(6, @rate_limiter.check(Logger::WARN))
82
- assert_redis_key(60, 4)
83
- assert_equal(5, number_of_buckets)
84
- end
85
-
86
- Timecop.freeze(time + 50) do
87
- assert_equal(7, @rate_limiter.check(Logger::WARN))
88
- assert_redis_key(60, 5)
89
- assert_equal(6, number_of_buckets)
90
- end
91
-
92
- Timecop.freeze(time + 60) do
93
- @redis.del("#{key}:0")
94
- assert_equal(5, number_of_buckets)
95
-
96
- assert_equal(7, @rate_limiter.check(Logger::WARN))
97
- assert_redis_key(60, 0)
98
- assert_equal(6, number_of_buckets)
99
-
100
- assert_equal(8, @rate_limiter.check(Logger::WARN))
101
- assert_equal(1, called)
102
- assert_equal(6, number_of_buckets)
103
- assert_equal("1", @redis.get(@rate_limiter.callback_key))
104
- end
105
-
106
- Timecop.freeze(time + 70) do
107
- @redis.del("#{key}:1")
108
- assert_equal(7, @rate_limiter.check(Logger::WARN))
109
- assert_nil(@redis.get(@rate_limiter.callback_key))
110
- end
111
- end
112
-
113
- def test_check_with_multiple_severities
114
- time = Time.new(2015, 1, 1, 1, 1)
115
- Timecop.freeze(time)
116
- called = 0
117
-
118
- @rate_limiter =
119
- Logster::RedisRateLimiter.new(
120
- @redis,
121
- [Logger::WARN, Logger::ERROR],
122
- 4,
123
- 60,
124
- nil,
125
- Proc.new { called += 1 },
126
- )
127
-
128
- assert_equal(1, @rate_limiter.check(Logger::WARN))
129
- assert_equal(2, @rate_limiter.check(Logger::ERROR))
130
-
131
- Timecop.freeze(time + 50) do
132
- assert_equal(3, @rate_limiter.check(Logger::WARN))
133
- assert_equal(4, @rate_limiter.check(Logger::ERROR))
134
- assert_equal(2, number_of_buckets)
135
- end
136
-
137
- assert_equal(5, @rate_limiter.check(Logger::ERROR))
138
- assert_equal(1, called)
139
- end
140
-
141
- def test_bucket_number_per_minute
142
- time = Time.new(2015, 1, 1, 1, 1)
143
- Timecop.freeze(time)
144
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
145
-
146
- assert_bucket_number(0, time)
147
- assert_bucket_number(0, time + 9)
148
- assert_bucket_number(1, time + 11)
149
- assert_bucket_number(5, time + 59)
150
- end
151
-
152
- def test_bucket_number_per_hour
153
- time = Time.new(2015, 1, 1, 1, 0)
154
- Timecop.freeze(time)
155
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 3600)
156
-
157
- assert_bucket_number(0, time)
158
- assert_bucket_number(1, time + 1199)
159
- assert_bucket_number(2, time + 1200)
160
- assert_bucket_number(5, time + 3599)
161
- end
162
-
163
- def test_bucket_expiry
164
- time = Time.new(2015, 1, 1, 1, 1)
165
- Timecop.freeze(time)
166
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
167
-
168
- assert_bucket_expiry(60, time)
169
- assert_bucket_expiry(55, time + 5)
170
- assert_bucket_expiry(60, time + 10)
171
- assert_bucket_expiry(58, time + 12)
172
- assert_bucket_expiry(55, time + 15)
173
- assert_bucket_expiry(51, time + 19)
174
- assert_bucket_expiry(60, time + 20)
175
- assert_bucket_expiry(55, time + 35)
176
- end
177
-
178
- def test_raw_connection
179
- time = Time.new(2015, 1, 1, 1, 1)
180
- Timecop.freeze(time)
181
- @rate_limiter =
182
- Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60, Proc.new { "lobster" })
183
-
184
- assert_equal(1, @rate_limiter.check(Logger::WARN))
185
- assert_redis_key(60, 0)
186
-
187
- toggle = true
188
-
189
- @rate_limiter =
190
- Logster::RedisRateLimiter.new(
191
- @redis,
192
- [Logger::WARN],
193
- 1,
194
- 60,
195
- Proc.new { toggle ? "lobster1" : "lobster2" },
196
- )
197
-
198
- assert_includes(key, "lobster1")
199
-
200
- toggle = false
201
- assert_includes(key, "lobster2")
202
- end
203
-
204
- def test_retrieve_rate
205
- time = Time.new(2015, 1, 1, 1, 1)
206
- Timecop.freeze(time)
207
-
208
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
209
-
210
- @rate_limiter.check(Logger::WARN)
211
- assert_equal(@rate_limiter.retrieve_rate, 1)
212
-
213
- Timecop.freeze(time + 50) do
214
- @rate_limiter.check(Logger::WARN)
215
- assert_equal(@rate_limiter.retrieve_rate, 2)
216
- end
217
- end
218
-
219
- private
220
-
221
- def key
222
- @rate_limiter.key
223
- end
224
-
225
- def number_of_buckets
226
- @redis.keys("#{key}:[0-#{Logster::RedisRateLimiter::BUCKETS}]").size
227
- end
228
-
229
- def assert_bucket_number(expected, time)
230
- Timecop.freeze(time) do
231
- assert_equal(expected, @rate_limiter.send(:bucket_number, Time.now.to_i))
232
- end
233
- end
234
-
235
- def assert_bucket_expiry(expected, time)
236
- Timecop.freeze(time) do
237
- assert_equal(expected, @rate_limiter.send(:bucket_expiry, Time.now.to_i))
238
- end
239
- end
240
-
241
- def assert_redis_key(expected_ttl, expected_bucket_number)
242
- redis_key = "#{key}:#{expected_bucket_number}"
243
- assert(@redis.get(redis_key), "the right bucket should be created")
244
- assert_equal(expected_ttl, @redis.ttl(redis_key))
245
- end
246
- end