valkey-glide-rb 0.9.0 → 0.9.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8484606712ab999a0bf01200af02c0165c1ee0815925fa44aa4da1b5fd22f3f5
4
- data.tar.gz: 6d1df7c477683b58040f5847be09574de0ac51ec5c193c58d39652b7d268341f
3
+ metadata.gz: a8824baa9eb08b0496a2428dd1a0c4997d9716810ba75d607bbadd0c40a99dde
4
+ data.tar.gz: 23704fe50125575ad927860cabf0cae7f7ed9d915f651d049b608ca809fda2e9
5
5
  SHA512:
6
- metadata.gz: 8c59dd26f5e47dfa9b095a73ff0b307d095dc58e6f874b7be9eb3341a1db108fc26d53cb0f62c7fe439d73fc8c1e8fd24e460b0de1d4a43a0610348ae6087d5f
7
- data.tar.gz: f1c321849dbd57c34d04bbd3c5ad313b14d2139961db138e996b2eeaa56bd218d6c9946aabe396f94dfb61177e9205c988dc34f822b4b1e41acb69468f44017a
6
+ metadata.gz: 62a9bd00a4bc4f1cde9da036e86703a504f7a7ef355ffce8f254c5cf46ebb103c88242e20255a14d7adee3fbf3089db584c8703c5a5f89f9a7c0e04863254abb
7
+ data.tar.gz: 7a7b9672f5cd499878aef940198b3f48e58fff82d9a8468eb12ab3abc57446dd905326c44aa33145926fd1c28af226817937ac9cb3b69717b7f1d07b08e3fc0f
data/.rubocop.yml CHANGED
@@ -66,4 +66,5 @@ Metrics/ModuleLength:
66
66
  - 'lib/valkey/utils.rb'
67
67
  - 'lib/valkey/commands/*.rb'
68
68
  - 'lib/valkey/bindings.rb'
69
+ - 'lib/valkey/opentelemetry.rb'
69
70
  - 'test/**/*.rb'
data/AGENTS.md CHANGED
@@ -35,8 +35,8 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-rb` gem.
35
35
  **Supported Platforms:**
36
36
 
37
37
  - Linux: Ubuntu 20+, Amazon Linux 2/2023 (x86_64, aarch64)
38
+ - Alpine Linux 3.18+ (x86_64, aarch64) — musl libc
38
39
  - macOS: 13.7+ (x86_64), 14.7+ (aarch64)
39
- - **Note:** Alpine Linux / MUSL is **not** supported
40
40
 
41
41
  **Ruby Versions:** 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, JRuby (CI matrix)
42
42
 
@@ -54,12 +54,12 @@ bin/setup # bundle install
54
54
  bundle exec rubocop
55
55
 
56
56
  # Testing
57
- bundle exec rake test # standalone (default)
58
- bundle exec rake test:valkey # standalone explicitly
59
- bundle exec rake test:cluster # cluster (needs nodes 7000-7005)
57
+ bundle exec rake test # standalone + cluster
58
+ bundle exec rake test:standalone # standalone only
59
+ bundle exec rake test:cluster # cluster only (needs nodes 7000-7005)
60
60
 
61
61
  # Verbose / CI mode
62
- CI=1 bundle exec rake test:valkey
62
+ CI=1 bundle exec rake test:standalone
63
63
 
64
64
  # Console
65
65
  bundle exec bin/console
@@ -72,7 +72,7 @@ bundle exec bin/console
72
72
  bundle exec ruby test/valkey/string_commands_test.rb
73
73
 
74
74
  # Run with custom port
75
- VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:valkey
75
+ VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:standalone
76
76
 
77
77
  # Load gem from lib/ without install
78
78
  RUBYOPT="-I$(pwd)/lib" ruby -r valkey -e 'p Valkey.new.ping'
@@ -82,7 +82,7 @@ RUBYOPT="-I$(pwd)/lib" ruby -r valkey -e 'p Valkey.new.ping'
82
82
 
83
83
  | Suite | Server requirement |
84
84
  |-------|-------------------|
85
- | `test:valkey` | Standalone Valkey/Redis on `localhost:6379` (DB 15) |
85
+ | `test:standalone` | Standalone Valkey/Redis on `localhost:6379` (DB 15) |
86
86
  | `test:cluster` | 6-node cluster on `127.0.0.1:7000`–`7005` |
87
87
  | SSL tests | TLS Valkey on port `6380` + certs in `test/fixtures/ssl/` |
88
88
  | Module tests | JSON, Bloom, Search modules loaded (see CI workflow) |
@@ -191,7 +191,7 @@ valkey-glide-ruby/
191
191
  ## Quality Gates (Agent Checklist)
192
192
 
193
193
  - [ ] `bundle exec rubocop` passes
194
- - [ ] `bundle exec rake test:valkey` passes (with Valkey running)
194
+ - [ ] `bundle exec rake test:standalone` passes (with Valkey running)
195
195
  - [ ] `bundle exec rake test:cluster` passes (if cluster commands touched)
196
196
  - [ ] New commands have tests in `test/valkey/` and lint coverage where applicable
197
197
  - [ ] `RequestType` matches glide-core enum
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## Pending
4
+
5
+ ### Changes
6
+
7
+ * Ruby: Add Alpine Linux (musl libc) support for x86_64 and aarch64 — runtime detection of musl libc, CI/CD pipeline for native builds, and prebuilt `libglide_ffi.so` for musl targets ([#143](https://github.com/valkey-io/valkey-glide-ruby/pull/143))
8
+ * Ruby: Add distributed tracing support — `Valkey::OpenTelemetry.set_parent_span_context_provider` (and `init(parent_span_context_provider:)`) let an app propagate its current W3C trace context into command/pipeline spans, so they become children of the app's trace instead of independent root spans, matching the Node.js client's `parentSpanContextProvider` behavior.
data/CLAUDE.md CHANGED
@@ -27,14 +27,14 @@ Valkey GLIDE Ruby (`valkey-rb`) is the official Ruby binding for Valkey and Redi
27
27
 
28
28
  ### Before Task Completion
29
29
 
30
- - Tests cover the change and pass (`bundle exec rake test:valkey` at minimum)
30
+ - Tests cover the change and pass (`bundle exec rake test:standalone` at minimum)
31
31
  - `bundle exec rubocop` passes for changed Ruby files
32
32
  - If FFI binary updated, smoke-test: `Valkey.new.ping` on target OS
33
33
 
34
34
  ### Before Push
35
35
 
36
36
  - `git pull --rebase` on your base branch; resolve conflicts
37
- - Run tests for relevant scope (`test:valkey` and/or `test:cluster`)
37
+ - Run tests for relevant scope (`test:standalone` and/or `test:cluster`)
38
38
 
39
39
  ### Before PR Creation/Update
40
40
 
@@ -108,7 +108,7 @@ When working on a feature, read these paths first:
108
108
  ```bash
109
109
  bin/setup
110
110
  bundle exec rubocop
111
- bundle exec rake test:valkey # needs localhost:6379
111
+ bundle exec rake test:standalone # needs localhost:6379
112
112
  bundle exec rake test:cluster # needs cluster 7000-7005
113
113
  ```
114
114
 
data/CONTRIBUTING.md CHANGED
@@ -30,7 +30,7 @@ For issues that affect the shared Rust core or other language clients, consider
30
30
  3. Run local checks (see [DEVELOPER.md](./DEVELOPER.md)):
31
31
  ```bash
32
32
  bundle exec rubocop
33
- bundle exec rake test:valkey # standalone — requires Valkey on :6379
33
+ bundle exec rake test:standalone # standalone — requires Valkey on :6379
34
34
  bundle exec rake test:cluster # if cluster-related — requires nodes :7000–:7005
35
35
  ```
36
36
  4. Commit with **DCO sign-off** and **conventional commits**:
@@ -102,7 +102,7 @@ This project follows the [Amazon Open Source Code of Conduct](https://aws.github
102
102
 
103
103
  ## Security
104
104
 
105
- Report security vulnerabilities via [valkey-glide SECURITY.md](https://github.com/valkey-io/valkey-glide/blob/main/SECURITY.md).
105
+ See [SECURITY.md](https://github.com/valkey-io/.github/blob/main/SECURITY.md).
106
106
 
107
107
  ## Licensing
108
108
 
data/DEVELOPER.md CHANGED
@@ -47,7 +47,7 @@ valkey-glide-ruby/
47
47
  │ └── cd.yml # Build and publish gem
48
48
  ├── valkey.gemspec
49
49
  ├── Gemfile
50
- └── Rakefile # test:valkey, test:cluster, native:build
50
+ └── Rakefile # test:standalone, test:cluster, native:build
51
51
  ```
52
52
 
53
53
  ## Prerequisites
@@ -58,7 +58,7 @@ valkey-glide-ruby/
58
58
  - **Bundler**
59
59
  - **git**
60
60
  - **Valkey** or Redis OSS (for integration tests)
61
- - **Docker** (optional; matches CI setup)
61
+ - **Docker** (optional; only needed for module tests with `valkey-bundle` image)
62
62
 
63
63
  To **build** the native FFI library from source:
64
64
 
@@ -188,21 +188,25 @@ Default test configuration (see `test/test_helper.rb`):
188
188
  |----------|---------|---------|
189
189
  | `VALKEY_PORT` | `6379` | Plain TCP |
190
190
  | `VALKEY_SSL_PORT` | `6380` | TLS (optional) |
191
+ | `TLS_CERT_DIR` | `valkey-glide/utils/tls_crts` | Path to TLS certs (set by CI) |
191
192
  | `TIMEOUT` | `5.0` | Client timeout |
192
193
  | DB | `15` | Test database |
193
194
 
194
195
  ```bash
195
- # Example: Docker standalone (matches CI)
196
- docker run -d --name valkey-test -p 6379:6379 valkey/valkey:8 \
197
- valkey-server --enable-module-command yes
196
+ # Preferred: use cluster_manager.py (same as CI and all other GLIDE clients)
197
+ python3 valkey-glide/utils/cluster_manager.py start -r 0 -p 6379 --prefix standalone
198
+
199
+ # Alternative: Docker standalone
200
+ docker run -d --name valkey-test -p 6379:6379 valkey/valkey:8 valkey-server
198
201
  ```
199
202
 
200
203
  ### Start Valkey Cluster
201
204
 
202
- Cluster tests expect six nodes on `127.0.0.1:7000`–`7005`. CI uses `grokzen/redis-cluster:7.0.15`.
205
+ Cluster tests auto-start via `cluster_manager.py` (the `TestCluster` class handles lifecycle).
206
+ You can also start manually:
203
207
 
204
208
  ```bash
205
- docker run -d --name redis-cluster -p 7000-7005:7000-7005 grokzen/redis-cluster:7.0.15
209
+ python3 valkey-glide/utils/cluster_manager.py start --cluster-mode --prefix cluster
206
210
  ```
207
211
 
208
212
  ### Run Tests
@@ -211,39 +215,51 @@ docker run -d --name redis-cluster -p 7000-7005:7000-7005 grokzen/redis-cluster:
211
215
  # All default (standalone) tests
212
216
  bundle exec rake test
213
217
  # or
214
- bundle exec rake test:valkey
218
+ bundle exec rake test:standalone
215
219
 
216
220
  # Cluster tests only
217
221
  bundle exec rake test:cluster
218
222
 
219
223
  # Verbose output (also enabled when CI=1)
220
- CI=1 bundle exec rake test:valkey
224
+ CI=1 bundle exec rake test:standalone
221
225
  ```
222
226
 
223
227
  ### SSL Tests
224
228
 
225
- Generate test certificates:
229
+ The preferred approach (matching CI and all other GLIDE clients) uses `cluster_manager.py`:
226
230
 
227
231
  ```bash
228
- ruby test/fixtures/ssl/generate_certs.rb
232
+ # Start a TLS-only server on port 6380 (generates certs in valkey-glide/utils/tls_crts/)
233
+ python3 valkey-glide/utils/cluster_manager.py --tls start -r 0 -p 6380 --prefix tls-standalone
234
+
235
+ # Point tests at the generated certs
236
+ export TLS_CERT_DIR=$(pwd)/valkey-glide/utils/tls_crts
237
+
238
+ # Run tests
239
+ bundle exec rake test:standalone
240
+
241
+ # Stop the TLS server
242
+ python3 valkey-glide/utils/cluster_manager.py --tls stop --prefix tls-standalone
229
243
  ```
230
244
 
231
- Start TLS Valkey on port 6380 (see `.github/workflows/CI.yml` for a full Docker example).
245
+ Alternatively, for local development without Python, generate certs and start manually:
232
246
 
233
- ### Module Tests (JSON, Bloom, Search)
247
+ ```bash
248
+ ruby test/fixtures/ssl/generate_certs.rb
249
+ # Then start a TLS Valkey server on port 6380 using those certs
250
+ ```
234
251
 
235
- CI copies prebuilt modules into `test/fixtures/`:
252
+ ### Module Tests (JSON, Bloom, Search)
236
253
 
237
- - `redisjson.so` JSON commands
238
- - `redisbloom.so` Bloom filters
239
- - `redisearch.so` — Vector / FT commands
254
+ CI uses the shared `start-valkey-docker` action with `valkey/valkey-bundle:9.1` (modules pre-loaded).
255
+ Tests connect via `STANDALONE_ENDPOINTS` env var.
240
256
 
241
257
  Load modules when starting Valkey if you run module-specific tests locally.
242
258
 
243
259
  ### Environment Overrides
244
260
 
245
261
  ```bash
246
- VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:valkey
262
+ VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:standalone
247
263
  ```
248
264
 
249
265
  ## Linters
@@ -427,7 +443,7 @@ ruby -e "require 'valkey'; c = Valkey.new; puts c.ping; c.close"
427
443
  | `LoadError` / FFI library not found | Confirm `lib/valkey/libglide_ffi.{so,dylib}` exists and matches your OS/arch. |
428
444
  | Wrong architecture after FFI rebuild | Rebuild `glide-ffi` on the target platform; do not copy Linux `.so` to macOS. |
429
445
  | Cluster tests flaky | Wait for `cluster_state:ok`; increase `TIMEOUT` env var. |
430
- | SSL test failures | Regenerate certs: `ruby test/fixtures/ssl/generate_certs.rb`. |
446
+ | SSL test failures | Use `cluster_manager.py --tls` (see SSL Tests above), or regenerate local certs: `ruby test/fixtures/ssl/generate_certs.rb`. |
431
447
  | Pipeline / MULTI crashes | Transaction commands in `pipelined` use sequential fallback by design. |
432
448
 
433
449
  ## Recommended Editor Extensions
data/README.md CHANGED
@@ -36,8 +36,7 @@ The release of Valkey GLIDE Ruby was tested on the following platforms:
36
36
 
37
37
  - Ubuntu 20+ (x86_64/amd64 and arm64/aarch64)
38
38
  - Amazon Linux 2 (AL2) and 2023 (AL2023) (x86_64)
39
-
40
- **Note:** Alpine Linux / MUSL is **not** currently supported.
39
+ - Alpine Linux 3.18+ (x86_64 and arm64/aarch64) — musl libc
41
40
 
42
41
  **macOS:**
43
42
 
@@ -137,6 +136,45 @@ end
137
136
 
138
137
  > **Note:** Transactional commands (`MULTI` / `EXEC` / `DISCARD`) in a pipeline are executed sequentially as a workaround for FFI batch stability. Prefer `multi` / `exec` on the main client for transactions.
139
138
 
139
+ ### Generic Command Dispatch (`call` / `call_v`)
140
+
141
+ Not every command has a dedicated method yet. `call`/`call_v` are the escape hatch — send any
142
+ command as plain arguments and get the raw reply back, matching `redis-client`'s `#call`/`#call_v`:
143
+
144
+ ```ruby
145
+ client.call("SET", "mykey", "value")
146
+ # => "OK"
147
+
148
+ client.call_v(["MGET"] + keys)
149
+ ```
150
+
151
+ `call`/`call_v` apply the same argument coercion as `redis-client`:
152
+
153
+ ```ruby
154
+ # Integers/Floats auto-stringify
155
+ client.call("SET", "mykey", 42)
156
+ # equivalent to call("SET", "mykey", "42")
157
+
158
+ # Arrays flatten (including nested arrays)
159
+ client.call("LPUSH", "list", [1, 2, 3])
160
+ # equivalent to call("LPUSH", "list", "1", "2", "3")
161
+
162
+ # Hashes flatten to alternating key/value
163
+ client.call("HMSET", "hash", { "foo" => "1" })
164
+ # equivalent to call("HMSET", "hash", "foo", "1")
165
+
166
+ # Keyword args become trailing command flags (call only, not call_v):
167
+ # a truthy value emits the upcased flag name; a non-boolean value also emits
168
+ # the stringified value. Falsy/nil values are dropped entirely, not stringified.
169
+ client.call("SET", "k", "v", nx: true, ex: 60)
170
+ # equivalent to call("SET", "k", "v", "NX", "EX", "60")
171
+ client.call("SET", "k", "v", nx: false, ex: nil)
172
+ # equivalent to call("SET", "k", "v")
173
+ ```
174
+
175
+ `call_v` takes the whole command as a single Array (no keyword flags) — useful when the command is
176
+ built dynamically. Both return the raw reply with no type-casting based on the command name.
177
+
140
178
  ### Connection Options (redis-rb compatible)
141
179
 
142
180
  | Option | Description |
@@ -153,6 +191,11 @@ end
153
191
  | `protocol` | `:resp2` (default) or `:resp3` |
154
192
  | `client_name` | `CLIENT SETNAME` value |
155
193
  | `reconnect_attempts`, `reconnect_delay`, `reconnect_delay_max` | Connection retry strategy |
194
+ | `read_from` *(GLIDE-native)* | Read routing: `:primary`, `:prefer_replica`, `:az_affinity`, `:az_affinity_replicas_and_primary` symbols, the exact-match GLIDE strings (e.g. `"PreferReplica"`), or the `Valkey::ReadFrom::*` constants (e.g. `Valkey::ReadFrom::PREFER_REPLICA`). `:az_affinity`/`:az_affinity_replicas_and_primary` require `client_az` to also be set. `LowestLatency` is a valid GLIDE value but not yet usable via the vendored native library. |
195
+ | `client_az` *(GLIDE-native)* | Availability-zone identifier for `:az_affinity` / `:az_affinity_replicas_and_primary` routing (e.g. `"us-west-2a"`) |
196
+ | `inflight_requests_limit` *(GLIDE-native)* | Maximum concurrent in-flight requests (non-negative integer) |
197
+ | `lazy_connect` *(GLIDE-native)* | Delay the actual connection until the first command is sent |
198
+ | `periodic_checks` *(GLIDE-native)* | Cluster topology health checks: `{ manual_interval: { duration_in_sec: N } }` or `{ disabled: true }`. Accepted (as a no-op) on standalone connections. |
156
199
 
157
200
  ```ruby
158
201
  client = Valkey.new(
@@ -195,6 +238,50 @@ client.set("key", "value") # traced when sampling applies
195
238
 
196
239
  OpenTelemetry can only be initialized **once per process**. Spans are created in the FFI layer when sampling is enabled.
197
240
 
241
+ ### Distributed tracing (parent context propagation)
242
+
243
+ By default, every command span is an independent root span — it doesn't nest under your
244
+ application's request trace. To fix that, register a `parent_span_context_provider`: a
245
+ callable invoked before every command that returns the current W3C trace context (or `nil`
246
+ when there isn't one). When it returns a valid context, the command/pipeline span is created
247
+ as a **child** of it instead of an independent span.
248
+
249
+ ```ruby
250
+ require "valkey"
251
+ require "opentelemetry/sdk" # if your app uses the real opentelemetry-ruby gem
252
+
253
+ Valkey::OpenTelemetry.init(
254
+ traces: { endpoint: "http://localhost:4318/v1/traces", sample_percentage: 10 }
255
+ )
256
+
257
+ Valkey::OpenTelemetry.set_parent_span_context_provider do
258
+ span = ::OpenTelemetry::Trace.current_span
259
+ next nil unless span.context.valid?
260
+
261
+ {
262
+ trace_id: span.context.hex_trace_id,
263
+ span_id: span.context.hex_span_id,
264
+ trace_flags: span.context.trace_flags.sampled? ? 1 : 0,
265
+ tracestate: span.context.tracestate.to_s
266
+ }
267
+ end
268
+ ```
269
+
270
+ The provider must return either `nil` or a Hash with `:trace_id` (32-char lowercase hex),
271
+ `:span_id` (16-char lowercase hex), `:trace_flags` (Integer 0-255), and `:tracestate`
272
+ (String or `nil`). Anything else is rejected with a warning and treated as `nil` — a broken
273
+ provider degrades to independent root spans, it never raises into your command path.
274
+
275
+ You can also pass `parent_span_context_provider:` directly to `init(...)` instead of calling
276
+ `set_parent_span_context_provider` separately.
277
+
278
+ **Note on the `OpenTelemetry` constant name:** `Valkey::OpenTelemetry` (this gem's module) and
279
+ the real `opentelemetry-ruby` gem's top-level `::OpenTelemetry` module are unrelated constants
280
+ and don't collide. But if you write a provider block from code that's lexically nested inside
281
+ `Valkey` (uncommon for typical app-level code), a bare `OpenTelemetry::Trace` reference would
282
+ resolve to `Valkey::OpenTelemetry::Trace` (undefined) instead of the real gem — always use the
283
+ leading-`::` form, `::OpenTelemetry::Trace`, as in the example above.
284
+
198
285
  ## Examples
199
286
 
200
287
  Runnable examples are in [examples/](./examples/):
data/Rakefile CHANGED
@@ -29,7 +29,10 @@ namespace :native do
29
29
  task build: :submodule do
30
30
  puts "Building native FFI library..."
31
31
  Dir.chdir("valkey-glide/ffi") do
32
- sh "cargo build --release"
32
+ # Set GLIDE_NAME to identify this as the Ruby client in CLIENT SETINFO
33
+ # GLIDE_VERSION is set from lib/valkey/version.rb
34
+ version = File.read("../../lib/valkey/version.rb")[/VERSION = "([^"]+)"/, 1] || "unknown"
35
+ sh({ "GLIDE_NAME" => "GlideRuby", "GLIDE_VERSION" => version }, "cargo build --release")
33
36
  end
34
37
  puts "Native library built successfully!"
35
38
  puts "Location: valkey-glide/ffi/target/release/libglide_ffi.#{native_lib_ext}"
@@ -39,7 +42,9 @@ namespace :native do
39
42
  task build_debug: :submodule do
40
43
  puts "Building native FFI library (debug)..."
41
44
  Dir.chdir("valkey-glide/ffi") do
42
- sh "cargo build"
45
+ # Set GLIDE_NAME to identify this as the Ruby client in CLIENT SETINFO
46
+ version = File.read("../../lib/valkey/version.rb")[/VERSION = "([^"]+)"/, 1] || "unknown"
47
+ sh({ "GLIDE_NAME" => "GlideRuby", "GLIDE_VERSION" => version }, "cargo build")
43
48
  end
44
49
  puts "Native library built successfully!"
45
50
  puts "Location: valkey-glide/ffi/target/debug/libglide_ffi.#{native_lib_ext}"
@@ -106,7 +111,7 @@ task native: "native:build"
106
111
  # =============================================================================
107
112
 
108
113
  namespace :test do
109
- groups = %i[valkey cluster]
114
+ groups = %i[standalone cluster]
110
115
  groups.each do |group|
111
116
  Rake::TestTask.new(group) do |t|
112
117
  t.libs << "test"
@@ -117,10 +122,15 @@ namespace :test do
117
122
  end
118
123
  end
119
124
 
120
- lost_tests = Dir["test/**/*_test.rb"] - groups.map { |g| Dir["test/#{g}/**/*_test.rb"] }.flatten
125
+ # Exclude module directories (valkey/, lint/) from lost_tests check
126
+ # These contain reusable test modules, not standalone test files
127
+ module_dirs = %w[valkey lint]
128
+ lost_tests = Dir["test/**/*_test.rb"] -
129
+ groups.map { |g| Dir["test/#{g}/**/*_test.rb"] }.flatten -
130
+ module_dirs.map { |d| Dir["test/#{d}/**/*_test.rb"] }.flatten
121
131
  abort "The following test files are in no group:\n#{lost_tests.join("\n")}" unless lost_tests.empty?
122
132
  end
123
133
 
124
- task test: ["test:valkey"]
134
+ task test: ["test:standalone", "test:cluster"]
125
135
 
126
136
  task default: :test