V0.3.3 #4

Merged
irammini merged 24 commits from 0.3.3 into main 2026-01-30 18:23:13 +00:00
irammini commented 2026-01-25 14:02:55 +00:00 (Migrated from github.com)
No description provided.
irammini commented 2026-01-25 15:10:29 +00:00 (Migrated from github.com)

In this commit:

  • Added ReplicationTest covering command propagation and Partial Resync logic.
  • Added JsonCommandTest for JSON.SET and JSON.GET with nested paths.
  • Added TDigestCommandTest for TD.ADD, TD.QUANTILE, TD.CDF.
  • Added PersistenceCorruptionTest for truncated RDB/AOF.
  • Added ExpirationTest for passive and active expiration.
  • Added ClientBufferTest for client stability under load.
  • Added LuaConcurrencyTest for script atomicity and isolation.
  • Refactored tests to use a shared MockClientHandler for consistency.
In this commit: - Added `ReplicationTest` covering command propagation and Partial Resync logic. - Added `JsonCommandTest` for `JSON.SET` and `JSON.GET` with nested paths. - Added `TDigestCommandTest` for `TD.ADD`, `TD.QUANTILE`, `TD.CDF`. - Added `PersistenceCorruptionTest` for truncated RDB/AOF. - Added `ExpirationTest` for passive and active expiration. - Added `ClientBufferTest` for client stability under load. - Added `LuaConcurrencyTest` for script atomicity and isolation. - Refactored tests to use a shared `MockClientHandler` for consistency.
irammini commented 2026-01-25 16:50:18 +00:00 (Migrated from github.com)

In this commit:

Added the following benchmark scenarios:

  • Complex Data Structures (ZSET, LIST)
  • Payload Size Variation (10KB, 100KB)
  • Pipelining (Batch processing)
  • Connection Churn (Connect/Disconnect storm)
  • Pub/Sub Fan-out
  • Probabilistic Data Structures (Bloom Filter, T-Digest)

Updated main.rs to support --scenario argument.

In this commit: Added the following benchmark scenarios: - Complex Data Structures (ZSET, LIST) - Payload Size Variation (10KB, 100KB) - Pipelining (Batch processing) - Connection Churn (Connect/Disconnect storm) - Pub/Sub Fan-out - Probabilistic Data Structures (Bloom Filter, T-Digest) Updated `main.rs` to support `--scenario` argument.
irammini commented 2026-01-25 19:18:04 +00:00 (Migrated from github.com)

In this commit:

Introduced resetSingleton() methods in CaradeDatabase and WriteSequencer to allow tests to clear static state.
Updated AofPersistenceTest to properly reset these singletons in setup(), ensuring that CommandLogger updates are propagated correctly and CaradeDatabase state (like eviction counters) is fresh. This prevents test pollution and the reported NullPointerException.

And some other changes.

In this commit: Introduced `resetSingleton()` methods in `CaradeDatabase` and `WriteSequencer` to allow tests to clear static state. Updated `AofPersistenceTest` to properly reset these singletons in `setup()`, ensuring that `CommandLogger` updates are propagated correctly and `CaradeDatabase` state (like eviction counters) is fresh. This prevents test pollution and the reported NullPointerException. And some other changes.
irammini commented 2026-01-25 21:09:27 +00:00 (Migrated from github.com)

In this commit:

Validated the destination host in MigrateCommand to prevent connections to private/internal IP addresses.
Added a new test class MigrateCommandTest to verify the fix.

In this commit: Validated the destination host in MigrateCommand to prevent connections to private/internal IP addresses. Added a new test class MigrateCommandTest to verify the fix.
github-code-quality[bot] (Migrated from github.com) reviewed 2026-01-25 21:11:20 +00:00
@ -0,0 +51,4 @@
assertNotNull(client.lastResponse);
// lastResponse is "[500.5]" because sendArray was used
String valStr = client.lastResponse.replace("[", "").replace("]", "");
double median = Double.parseDouble(valStr);
github-code-quality[bot] (Migrated from github.com) commented 2026-01-25 21:11:20 +00:00

Missing catch of NumberFormatException

Potential uncaught 'java.lang.NumberFormatException'.


In general, to fix missing NumberFormatException handling, you wrap the numeric parsing operation in a try block and catch NumberFormatException, then handle it appropriately (e.g., log, convert to a test assertion failure, or propagate as a checked exception). For tests, the natural behavior is to fail the test with a clear message instead of letting an unchecked exception bubble up unannotated.

Here, the best minimal fix is to wrap each Double.parseDouble(valStr) in a try/catch (NumberFormatException e) and, in the catch block, call fail(...) from JUnit with a descriptive error message that includes the offending string and the exception. This preserves existing functionality when input is correct and provides clearer diagnostics when it is not, while satisfying the static analysis requirement that NumberFormatException be handled. We only need to edit src/test/java/core/commands/tdigest/TDigestCommandTest.java around lines 53–55 in testTDigestAccuracy and around lines 83–85 in testTDigestCDF. No extra imports are needed because fail is already available via import static org.junit.jupiter.api.Assertions.*;.

## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. --- In general, to fix missing <code>NumberFormatException</code> handling, you wrap the numeric parsing operation in a <code>try</code> block and catch <code>NumberFormatException</code>, then handle it appropriately (e.g., log, convert to a test assertion failure, or propagate as a checked exception). For tests, the natural behavior is to fail the test with a clear message instead of letting an unchecked exception bubble up unannotated.</p> <p>Here, the best minimal fix is to wrap each <code>Double.parseDouble(valStr)</code> in a <code>try/catch (NumberFormatException e)</code> and, in the catch block, call <code>fail(...)</code> from JUnit with a descriptive error message that includes the offending string and the exception. This preserves existing functionality when input is correct and provides clearer diagnostics when it is not, while satisfying the static analysis requirement that <code>NumberFormatException</code> be handled. We only need to edit <code>src/test/java/core/commands/tdigest/TDigestCommandTest.java</code> around lines 53–55 in <code>testTDigestAccuracy</code> and around lines 83–85 in <code>testTDigestCDF</code>. No extra imports are needed because <code>fail</code> is already available via <code>import static org.junit.jupiter.api.Assertions.*;</code>.
@ -0,0 +81,4 @@
cdfCmd.execute(client, argsC);
String valStr = client.lastResponse.replace("[", "").replace("]", "");
double cdf = Double.parseDouble(valStr);
github-code-quality[bot] (Migrated from github.com) commented 2026-01-25 21:11:20 +00:00

Missing catch of NumberFormatException

Potential uncaught 'java.lang.NumberFormatException'.


In general, to fix this kind of issue, you should either (a) validate the string before parsing and fail with a clear message if the format is invalid, or (b) wrap the parse call in a try/catch for NumberFormatException and handle the error appropriately (e.g., fail the test with an informative assertion message). The goal is to avoid an uncaught runtime exception and to make failures explicit and meaningful.

For this specific test file, the best targeted fix without changing intended functionality is to wrap Double.parseDouble(valStr) in a try/catch that catches NumberFormatException and calls fail(...) from JUnit with a descriptive message. That way, if valStr ever stops being a valid double, the test will fail with a clear cause instead of throwing an unhandled exception. The normal case (valid double) will behave exactly as before. This change is localized to testTDigestCDF in src/test/java/core/commands/tdigest/TDigestCommandTest.java. No new imports are needed because fail is already available via import static org.junit.jupiter.api.Assertions.*;.

## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. --- In general, to fix this kind of issue, you should either (a) validate the string before parsing and fail with a clear message if the format is invalid, or (b) wrap the parse call in a <code>try</code>/<code>catch</code> for <code>NumberFormatException</code> and handle the error appropriately (e.g., fail the test with an informative assertion message). The goal is to avoid an uncaught runtime exception and to make failures explicit and meaningful.</p> <p>For this specific test file, the best targeted fix without changing intended functionality is to wrap <code>Double.parseDouble(valStr)</code> in a <code>try</code>/<code>catch</code> that catches <code>NumberFormatException</code> and calls <code>fail(...)</code> from JUnit with a descriptive message. That way, if <code>valStr</code> ever stops being a valid double, the test will fail with a clear cause instead of throwing an unhandled exception. The normal case (valid double) will behave exactly as before. This change is localized to <code>testTDigestCDF</code> in <code>src/test/java/core/commands/tdigest/TDigestCommandTest.java</code>. No new imports are needed because <code>fail</code> is already available via <code>import static org.junit.jupiter.api.Assertions.*;</code>.
@ -0,0 +23,4 @@
int chunkSize = 1024 * 1024; // 1MB
byte[] chunk = new byte[chunkSize];
List<byte[]> largeData = new ArrayList<>();
github-code-quality[bot] (Migrated from github.com) commented 2026-01-25 21:11:19 +00:00

Container contents are never accessed

The contents of this container are never accessed.


To fix the problem, remove the unused container so that no list is created whose contents are never accessed. This keeps the test’s behavior identical while eliminating dead code.

Concretely, in src/test/java/core/network/ClientBufferTest.java, inside testSlowClientSimulation, remove the declaration and initialization of largeData and the line that adds chunk to it:

  • Delete line 26: List<byte[]> largeData = new ArrayList<>();
  • Delete line 27: largeData.add(chunk);

No additional imports, methods, or definitions are needed. The rest of the test continues to use chunk directly as before.

## Container contents are never accessed The contents of this container are never accessed. --- To fix the problem, remove the unused container so that no list is created whose contents are never accessed. This keeps the test’s behavior identical while eliminating dead code.</p> <p>Concretely, in <code>src/test/java/core/network/ClientBufferTest.java</code>, inside <code>testSlowClientSimulation</code>, remove the declaration and initialization of <code>largeData</code> and the line that adds <code>chunk</code> to it:</p> <ul> <li>Delete line 26: <code>List&lt;byte[]&gt; largeData = new ArrayList&lt;&gt;();</code></li> <li>Delete line 27: <code>largeData.add(chunk);</code></li> </ul> <p>No additional imports, methods, or definitions are needed. The rest of the test continues to use <code>chunk</code> directly as before.
@ -0,0 +26,4 @@
List<byte[]> largeData = new ArrayList<>();
largeData.add(chunk);
long start = System.currentTimeMillis();
github-code-quality[bot] (Migrated from github.com) commented 2026-01-25 21:11:20 +00:00

Unread local variable

Variable 'long start' is never read.


To fix the problem in general, remove local variables that are never read, or start using them meaningfully (e.g., for logging, assertions, or calculations). This keeps the code clean, reduces confusion, and avoids misleading indicators of functionality (such as performance measurement) that is not actually present.

In this specific case, the single best fix that does not change existing functionality is to delete the unused long start = System.currentTimeMillis(); line from testSlowClientSimulation in src/test/java/core/network/ClientBufferTest.java. The test currently does not assert on timing, and adding such behavior would alter its semantics. Removing the line keeps the test’s behavior exactly the same while eliminating the redundant variable. No new methods, imports, or definitions are required.

## Unread local variable Variable 'long start' is never read. --- To fix the problem in general, remove local variables that are never read, or start using them meaningfully (e.g., for logging, assertions, or calculations). This keeps the code clean, reduces confusion, and avoids misleading indicators of functionality (such as performance measurement) that is not actually present.</p> <p>In this specific case, the single best fix that does not change existing functionality is to delete the unused <code>long start = System.currentTimeMillis();</code> line from <code>testSlowClientSimulation</code> in <code>src/test/java/core/network/ClientBufferTest.java</code>. The test currently does not assert on timing, and adding such behavior would alter its semantics. Removing the line keeps the test’s behavior exactly the same while eliminating the redundant variable. No new methods, imports, or definitions are required.
github-advanced-security[bot] (Migrated from github.com) reviewed 2026-01-26 03:29:59 +00:00
@ -0,0 +30,4 @@
run: |
cd tools
ruff format . --check
github-advanced-security[bot] (Migrated from github.com) commented 2026-01-26 03:29:59 +00:00

Workflow does not contain permissions

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

Show more details

## Workflow does not contain permissions Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}} [Show more details](https://github.com/CodeTease/carade/security/code-scanning/11)
@ -0,0 +48,4 @@
- name: Run Benchmark (Test Only)
run: |
cd tools/rust-benchmarks
cargo run --release -- --clients 20 --requests 2000 || exit 0
github-advanced-security[bot] (Migrated from github.com) commented 2026-01-26 03:29:59 +00:00

Workflow does not contain permissions

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

Show more details

## Workflow does not contain permissions Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}} [Show more details](https://github.com/CodeTease/carade/security/code-scanning/10)
irammini commented 2026-01-26 04:17:28 +00:00 (Migrated from github.com)

In this commit:

Added detailed README.md files for:

  • src/main/java/core/structs/: Explaining algorithms (SkipList, HLL, BloomFilter).
  • src/main/java/core/replication/: Explaining Master/Slave flow, Backlog, and PSYNC.
  • src/main/java/core/server/: Explaining the Hybrid I/O + Single Writer threading model.
  • tools/rust-benchmarks/: Explaining Rust setup and usage for benchmarking.

These docs follow the standard "Carade Module Template".

In this commit: Added detailed README.md files for: - `src/main/java/core/structs/`: Explaining algorithms (SkipList, HLL, BloomFilter). - `src/main/java/core/replication/`: Explaining Master/Slave flow, Backlog, and PSYNC. - `src/main/java/core/server/`: Explaining the Hybrid I/O + Single Writer threading model. - `tools/rust-benchmarks/`: Explaining Rust setup and usage for benchmarking. These docs follow the standard "Carade Module Template".
irammini commented 2026-01-26 04:31:20 +00:00 (Migrated from github.com)

Fixed a concurrency bug in CaradeDatabase.get() where multiple threads accessing the same expired key could both trigger 'expired' notifications. The fix conditionalizes the notification on the successful removal of the key, ensuring the event is emitted exactly once per expiration.

Fixed a concurrency bug in `CaradeDatabase.get()` where multiple threads accessing the same expired key could both trigger 'expired' notifications. The fix conditionalizes the notification on the successful removal of the key, ensuring the event is emitted exactly once per expiration.
irammini commented 2026-01-26 15:01:03 +00:00 (Migrated from github.com)

Added a suite of Python scripts in tools/chaos to perform chaos engineering tests against the Carade server.
Includes:

  • Protocol Fuzzing (Length Dishonesty, Recursive Depth, Partial Frames)
  • Concurrency Stress (Thundering Herd, Eviction Race, Interleaved Transactions)
  • Storage Sabotage (AOF Truncation, RDB Bit-flipping)
  • Resource/Network Stress (Pub/Sub Backpressure, Lua Exhaustion, Zombie Connections)
  • utils.py for shared RESP handling.
  • README.md with usage instructions.
Added a suite of Python scripts in `tools/chaos` to perform chaos engineering tests against the Carade server. Includes: - Protocol Fuzzing (Length Dishonesty, Recursive Depth, Partial Frames) - Concurrency Stress (Thundering Herd, Eviction Race, Interleaved Transactions) - Storage Sabotage (AOF Truncation, RDB Bit-flipping) - Resource/Network Stress (Pub/Sub Backpressure, Lua Exhaustion, Zombie Connections) - `utils.py` for shared RESP handling. - `README.md` with usage instructions.
github-advanced-security[bot] (Migrated from github.com) reviewed 2026-01-26 15:52:24 +00:00
@ -0,0 +68,4 @@
run: |
if [ -f server.pid ]; then
kill $(cat server.pid) || true
fi
github-advanced-security[bot] (Migrated from github.com) commented 2026-01-26 15:52:24 +00:00

Workflow does not contain permissions

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

Show more details

## Workflow does not contain permissions Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}} [Show more details](https://github.com/CodeTease/carade/security/code-scanning/12)
irammini commented 2026-01-30 18:22:11 +00:00 (Migrated from github.com)

Seems fine

Seems fine
Sign in to join this conversation.
No description provided.