zache 0.15.0 → 0.15.2

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.
data/test/test_zache.rb DELETED
@@ -1,311 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require 'concurrent'
7
- require 'minitest/autorun'
8
- require 'securerandom'
9
- require 'threads'
10
- require 'timeout'
11
- require_relative '../lib/zache'
12
- require_relative 'test__helper'
13
-
14
- Thread.report_on_exception = true
15
-
16
- # Cache test.
17
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
18
- # Copyright:: Copyright (c) 2018-2025 Yegor Bugayenko
19
- # License:: MIT
20
- class ZacheTest < Minitest::Test
21
- def test_caches
22
- z = Zache.new(sync: false)
23
- first = z.get(:hey, lifetime: 5) { rand }
24
- second = z.get(:hey) { rand }
25
- assert_equal(first, second)
26
- assert_equal(1, z.size)
27
- end
28
-
29
- def test_caches_and_expires
30
- z = Zache.new
31
- first = z.get(:hey, lifetime: 0.01) { rand }
32
- sleep 0.1
33
- second = z.get(:hey) { rand }
34
- refute_equal(first, second)
35
- end
36
-
37
- def test_calculates_age
38
- z = Zache.new
39
- z.get(:hey) { rand }
40
- sleep 0.1
41
- assert_operator(z.mtime(:hey), :<, Time.now - 0.05)
42
- end
43
-
44
- def test_caches_in_threads
45
- z = Zache.new
46
- Threads.new(10).assert(100) do
47
- z.get(:hey, lifetime: 0.0001) { rand }
48
- end
49
- end
50
-
51
- def test_key_exists
52
- z = Zache.new
53
- z.get(:hey) { rand }
54
- exists_result = z.exists?(:hey)
55
- not_exists_result = z.exists?(:bye)
56
- assert(exists_result)
57
- refute(not_exists_result)
58
- end
59
-
60
- def test_put_and_exists
61
- z = Zache.new
62
- z.put(:hey, 'hello', lifetime: 0.1)
63
- sleep 0.2
64
- refute(z.exists?(:hey))
65
- end
66
-
67
- def test_remove_key
68
- z = Zache.new
69
- z.get(:hey) { rand }
70
- z.get(:wey) { rand }
71
- assert(z.exists?(:hey))
72
- assert(z.exists?(:wey))
73
- z.remove(:hey)
74
- refute(z.exists?(:hey))
75
- assert(z.exists?(:wey))
76
- end
77
-
78
- def test_remove_by_block
79
- z = Zache.new
80
- z.get('first') { rand }
81
- z.get('second') { rand }
82
- z.remove_by { |k| k == 'first' }
83
- refute(z.exists?('first'))
84
- assert(z.exists?('second'))
85
- end
86
-
87
- def test_remove_key_with_sync_false
88
- z = Zache.new(sync: false)
89
- z.get(:hey) { rand }
90
- z.get(:wey) { rand }
91
- assert(z.exists?(:hey))
92
- assert(z.exists?(:wey))
93
- z.remove(:hey)
94
- refute(z.exists?(:hey))
95
- assert(z.exists?(:wey))
96
- end
97
-
98
- def test_clean_with_threads
99
- z = Zache.new
100
- Threads.new(300).assert(3000) do
101
- z.get(:hey) { rand }
102
- z.get(:bye, lifetime: 0.01) { rand }
103
- sleep 0.1
104
- z.clean
105
- end
106
- assert(z.exists?(:hey))
107
- refute(z.exists?(:bye))
108
- end
109
-
110
- def test_clean
111
- z = Zache.new
112
- z.get(:hey) { rand }
113
- z.get(:bye, lifetime: 0.01) { rand }
114
- sleep 0.1
115
- z.clean
116
- assert(z.exists?(:hey))
117
- refute(z.exists?(:bye))
118
- end
119
-
120
- def test_clean_size
121
- z = Zache.new
122
- z.get(:hey, lifetime: 0.01) { rand }
123
- sleep 0.1
124
- z.clean
125
- assert_empty(z)
126
- end
127
-
128
- def test_clean_with_sync_false
129
- z = Zache.new(sync: false)
130
- z.get(:hey) { rand }
131
- z.get(:bye, lifetime: 0.01) { rand }
132
- sleep 0.1
133
- z.clean
134
- assert(z.exists?(:hey))
135
- refute(z.exists?(:bye))
136
- end
137
-
138
- def test_remove_absent_key
139
- z = Zache.new
140
- z.remove(:hey)
141
- end
142
-
143
- def test_check_and_remove
144
- z = Zache.new
145
- z.get(:hey, lifetime: 0) { rand }
146
- refute(z.exists?(:hey))
147
- end
148
-
149
- def test_remove_all_with_threads
150
- z = Zache.new
151
- Threads.new(10).assert(100) do |i|
152
- z.get(:"hey#{i}") { rand }
153
- assert(z.exists?(:"hey#{i}"))
154
- z.remove_all
155
- end
156
- 10.times do |i|
157
- refute(z.exists?(:"hey#{i}"))
158
- end
159
- end
160
-
161
- def test_remove_all_with_sync
162
- z = Zache.new
163
- z.get(:hey) { rand }
164
- z.get(:bye) { rand }
165
- z.remove_all
166
- refute(z.exists?(:hey))
167
- refute(z.exists?(:bye))
168
- end
169
-
170
- def test_remove_all_without_sync
171
- z = Zache.new(sync: false)
172
- z.get(:hey) { rand }
173
- z.get(:bye) { rand }
174
- z.remove_all
175
- refute(z.exists?(:hey))
176
- refute(z.exists?(:bye))
177
- end
178
-
179
- def test_puts_something_in
180
- z = Zache.new(sync: false)
181
- z.get(:hey) { rand }
182
- z.put(:hey, 123)
183
- assert_equal(123, z.get(:hey))
184
- end
185
-
186
- def test_sync_zache_is_not_reentrant
187
- z = Zache.new
188
- assert_raises ThreadError do
189
- z.get(:first) { z.get(:first) { 1 } }
190
- end
191
- end
192
-
193
- def test_sync_zache_is_reentrant_for_different_keys
194
- z = Zache.new
195
- z.get(:first) { z.get(:second) { 1 } }
196
- end
197
-
198
- def test_calculates_only_once
199
- z = Zache.new
200
- long = Thread.start do
201
- z.get(:x) do
202
- sleep 0.5
203
- 'first'
204
- end
205
- end
206
- sleep 0.1
207
- assert(z.locked?(:x))
208
- z.get(:x) { 'second' }
209
- refute(z.locked?(:x))
210
- long.kill
211
- end
212
-
213
- def test_checks_locked_status_from_inside
214
- z = Zache.new
215
- z.get(:x) do
216
- assert(z.locked?(:x))
217
- 'done'
218
- end
219
- refute(z.locked?(:x))
220
- end
221
-
222
- def test_returns_dirty_result
223
- z = Zache.new(dirty: true)
224
- z.get(:x, lifetime: 0) { 1 }
225
- long = Thread.start do
226
- z.get(:x) do
227
- sleep 1000
228
- 2
229
- end
230
- end
231
- sleep 0.1
232
- Timeout.timeout(1) do
233
- assert(z.exists?(:x))
234
- assert(z.expired?(:x))
235
- assert_equal(1, z.get(:x))
236
- assert_equal(1, z.get(:x) { 2 })
237
- end
238
- long.kill
239
- end
240
-
241
- def test_returns_dirty_result_when_not_locked
242
- z = Zache.new(dirty: true)
243
- z.get(:x, lifetime: 0) { 1 }
244
- assert(z.exists?(:x))
245
- assert_equal(1, z.get(:x))
246
- assert_equal(2, z.get(:x) { 2 })
247
- end
248
-
249
- def test_fetches_multiple_keys_in_many_threads_in_dirty_mode
250
- z = Zache.new(dirty: true)
251
- set = Concurrent::Set.new
252
- threads = 50
253
- barrier = Concurrent::CyclicBarrier.new(threads)
254
- Threads.new(threads).assert(threads * 2) do |i|
255
- barrier.wait if i < threads
256
- set << z.get(i, lifetime: 0.001) { i }
257
- end
258
- assert_equal(threads, set.size)
259
- end
260
-
261
- def test_fetches_multiple_keys_in_many_threads
262
- z = Zache.new
263
- set = Concurrent::Set.new
264
- threads = 50
265
- barrier = Concurrent::CyclicBarrier.new(threads)
266
- Threads.new(threads).assert(threads * 2) do |i|
267
- barrier.wait if i < threads
268
- set << z.get(i) { i }
269
- end
270
- assert_equal(threads, set.size)
271
- end
272
-
273
- def test_fake_class_works
274
- z = Zache::Fake.new
275
- assert_equal(1, z.get(:x) { 1 })
276
- end
277
-
278
- def test_rethrows
279
- z = Zache.new
280
- assert_raises RuntimeError do
281
- z.get(:hey) { raise 'intentional' }
282
- end
283
- end
284
-
285
- def test_returns_placeholder_in_eager_mode
286
- z = Zache.new
287
- a = z.get(:me, placeholder: 42, eager: true) do
288
- sleep 0.1
289
- 43
290
- end
291
- assert_equal(42, a)
292
- sleep 0.2
293
- b = z.get(:me)
294
- assert_equal(43, b)
295
- end
296
-
297
- def test_returns_placeholder_and_releases_lock
298
- z = Zache.new
299
- z.get(:slow, placeholder: 42, eager: true) do
300
- sleep 9999
301
- end
302
- sleep 0.1
303
- assert_equal(555, z.get(:fast) { 555 })
304
- end
305
-
306
- private
307
-
308
- def rand
309
- SecureRandom.uuid
310
- end
311
- end