Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e6f9fde
Update documentation and code formatting for clarity and consistency
peter-lawrey Nov 19, 2025
cb9cdde
Add CLAUDE.md and GEMINI.md for project guidance and documentation
peter-lawrey Nov 19, 2025
8f445e4
Add CLAUDE.md and GEMINI.md for project guidance and documentation
peter-lawrey Nov 19, 2025
a8a992f
Handle error messages in ChronicleWriterMain by printing to stderr an…
peter-lawrey Nov 19, 2025
095c764
Remove timeout and expected exception from stateWindows test
peter-lawrey Nov 19, 2025
522d9ec
Improve documentation clarity by fixing formatting and enhancing read…
peter-lawrey Nov 19, 2025
058f7a4
Refactor test error handling to throw AssertionError instead of exiting
peter-lawrey Nov 20, 2025
2539604
Add method writer diagnostics and FAQ guidance
peter-lawrey Nov 20, 2025
1d3ad2e
Update docs for JDK builds and method-writer troubleshooting
peter-lawrey Nov 20, 2025
ef10b34
Revert behaviour for InternalDumpMain and InternalUnlockMain
peter-lawrey Nov 20, 2025
ef945b6
Refactor stateWindows test to assert file state and remove expected e…
peter-lawrey Nov 20, 2025
1e7d8fb
Refactor tests to improve code clarity and consistency
peter-lawrey Nov 20, 2025
0a32633
Refactor tests to improve code clarity and consistency
peter-lawrey Nov 21, 2025
e32fe94
Update tests to handle exceptions and improve stability
peter-lawrey Nov 21, 2025
6902956
Add throws declaration to testWithQueueHistory method for improved er…
peter-lawrey Nov 24, 2025
58522c8
Add throws declaration to testWithQueueHistory method for improved er…
peter-lawrey Nov 24, 2025
544891c
Remove redundant exception expectation in SingleChronicleQueueTest fo…
peter-lawrey Nov 24, 2025
9a17719
Revert dropping InvalidEventHandlerException
peter-lawrey Nov 24, 2025
5eebb56
Revert dropping Exception
peter-lawrey Nov 24, 2025
ce328dd
Code Analysis fixes
peter-lawrey Nov 21, 2025
3c4cb65
Code Analysis fixes
peter-lawrey Nov 21, 2025
d6051a9
Docs: Add COMPLETED.md for task archiving
peter-lawrey Nov 24, 2025
af5f160
Remove unnecessary blank lines in various classes for improved code r…
peter-lawrey Nov 24, 2025
745c315
Suppress warnings for unused finalizer fields in StoreAppender and St…
peter-lawrey Nov 26, 2025
696407b
Mark multiple methods and fields as deprecated, scheduled for removal…
peter-lawrey Nov 27, 2025
988ff8d
Add @SuppressWarnings for deprecation and removal in multiple classes
peter-lawrey Nov 28, 2025
009a672
Refactor TableStoreWriteLock to improve locking mechanism; streamline…
peter-lawrey Dec 1, 2025
e11fe1b
Merge remote-tracking branch 'origin/adv/javadoc' into adv/develop
peter-lawrey Dec 11, 2025
39bf090
revert change
peter-lawrey Dec 11, 2025
bfc4c7b
Refactor code for clarity and performance improvements in various cla…
peter-lawrey Dec 11, 2025
d22ad2e
Enhance test clarity and performance by refactoring various test clas…
peter-lawrey Dec 11, 2025
9a4dbef
Update Javadoc to remove misleading null return indication for store …
peter-lawrey Dec 11, 2025
4d6e0f6
Refactor close methods to remove IOException declaration and update b…
peter-lawrey Dec 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ image:https://img.shields.io/gitter/room/OpenHFT/Lobby.svg?style=popout[link="ht
image:https://img.shields.io/badge/release%20notes-subscribe-brightgreen[link="https://chronicle.software/release-notes/"]
image:https://sonarcloud.io/api/project_badges/measure?project=OpenHFT_Chronicle-Queue&metric=alert_status[link="https://sonarcloud.io/dashboard?id=OpenHFT_Chronicle-Queue"]

image::docs/images/Queue_line.png[width=20%]
image::src/main/docs/images/Queue_line.png[width=20%]

toc::[]

Expand Down Expand Up @@ -572,12 +572,12 @@ console output:
[main] WARN SingleChronicleQueueBuilder - Overriding roll cycle from HOURLY to MINUTELY.
----
The maximum number of messages that can be stored in a queue file depends on roll cycle.
See https://github.com/OpenHFT/Chronicle-Queue/tree/master/docs/FAQ.adoc[FAQ] for more information on this.
See https://github.com/OpenHFT/Chronicle-Queue/tree/master/src/main/docs/FAQ.adoc[FAQ] for more information on this.

In Chronicle Queue, the rollover time is based on UTC. The Timezone Rollover Enterprise feature extends Chronicle Queue's ability to specify the time and periodicity of queue rollovers, rather than UTC. For more information see link:https://portal.chronicle.software/docs/queue/chronicle-queue/configuration/timezone_rollover.html[Timezone Queue Rollover].

The Chronicle Queue `FileUtil` class provides useful methods for managing queue files.
See link:docs/managing_roll_files_directly.adoc[Managing Roll Files Directly].
See link:src/main/docs/managing_roll_files_directly.adoc[Managing Roll Files Directly].

* _wireType_

Expand Down Expand Up @@ -732,7 +732,7 @@ try (final DocumentContext dc = appender.writingDocument()) {
The high-level methods below such as `writeText()` are convenience methods on calling `appender.writingDocument()`, but both approaches essentially do the same thing.
The actual code of `writeText(CharSequence text)` looks like this:

[source,java]
[source,java,opts=novalidate]
----
/**
* @param text the message to write
Expand Down Expand Up @@ -1866,10 +1866,10 @@ For comparison see http://kafka.apache.org/documentation.html[Kafka Documentatio

=== Links

* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/docs/BigDataAndChronicleQueue.adoc[Big Data and Chronicle Queue] - a detailed description of some techniques utilised by Chronicle Queue
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/docs/FAQ.adoc[FAQ] - questions asked by customers
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/docs/How_it_works.adoc[How it works] - more depth on how Chronicle Queue is implemented
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/docs/utilities.adoc[Utilities] - lists some useful utilities for working with queue files
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/src/main/docs/BigDataAndChronicleQueue.adoc[Big Data and Chronicle Queue] - a detailed description of some techniques utilised by Chronicle Queue
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/src/main/docs/FAQ.adoc[FAQ] - questions asked by customers
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/src/main/docs/How_it_works.adoc[How it works] - more depth on how Chronicle Queue is implemented
* https://github.com/OpenHFT/Chronicle-Queue/tree/develop/src/main/docs/utilities.adoc[Utilities] - lists some useful utilities for working with queue files

==== Online support

Expand Down
3 changes: 2 additions & 1 deletion docs/antora/modules/configuration/pages/roll-cycle.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ SingleChronicleQueue queue = ChronicleQueue.singleBuilder("/timezone")
== Archiving Old Queue Files ★

Over time, it may become necessary to automatically delete or archive old queue files.
An automated process needs to ensure that there are no active file-handles open on a queue file before attempting to delete. facilitate housekeeping of older roll files, Chronicle Queue Enterprise provides the xref:command-line:command_line_tools.adoc#_archiverollfiles[ArchiveRollFiles utility].
An automated process needs to ensure that there are no active file-handles open on a queue file before attempting to delete.
facilitate housekeeping of older roll files, Chronicle Queue Enterprise provides the xref:command-line:command_line_tools.adoc#_archiverollfiles[ArchiveRollFiles utility].

== General Advice on Rolling

Expand Down
9 changes: 9 additions & 0 deletions docs/antora/modules/demos/pages/message-history.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.openhft.compiler.MyJavaFileManager (file:/C:/Users/peter/.m2/repository/net/openhft/compiler/2.3.4/compiler-2.3.4.jar) to method com.sun.tools.javac.file.JavacFileManager.listLocationsForModules(javax.tools.JavaFileManager$Location)
----

=== Debugging method-writer fallback warnings

If you see `Failed to compile generated method writer - falling back to proxy method writer` during tests:

* Chronicle Queue’s tests will log extra context (test name, `java.version`, `wire.generator.v2`, `disableProxyCodegen`) when this occurs.
* Reproduce on Java 8 with `mvn -Dtest=MessageHistoryTest test -DfailIfNoTests=false` and keep the log.
* You can force the newer code generator with `-Dwire.generator.v2=true`, and optionally disable proxy fallback with `-DdisableProxyCodegen=true` (may fail fast if codegen is still broken).
* See the FAQ entry “Debugging method writer codegen fallbacks” for more guidance.

== Expected Output

The microsecond timestamps are based on wall clock, however the nanosecond time stamps are based on the uptime of the machine.
Expand Down
2 changes: 1 addition & 1 deletion docs/antora/modules/getting-started/pages/glossary.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ author: Julia Gustafsson
[#d]
== D

* *Document:* Chronicle Queue reads and writes documents.Each document comprises a 4-byte header, followed by the data excerpt.
* *Document:* Chronicle Queue reads and writes documents. Each document comprises a 4-byte header, followed by the data excerpt.

[#e]
== E
Expand Down
2 changes: 1 addition & 1 deletion docs/antora/modules/getting-started/pages/quick-start.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Hence, most of the topics are explained in greater depth throughout the Chronicl
Before starting with the set up, make sure your development environment meets the following requirements:

* Maven 3.6.x or later
* Java 8 update 180+ or later
* Java 8 update 180+ or later (tests also run on Java 21)
* Access to the internet to allow Maven or Gradle to download the JARs needed

Use an explicit `JAVA_HOME` when building or running tools so the intended JDK is used, for example:
Expand Down
3 changes: 2 additions & 1 deletion docs/antora/modules/queue-operations/pages/tailing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ They can both be run from the command line in a number of ways described below.

== DumpMain

TIP: The canonical CLI reference for `DumpMain` lives at xref:command-line:command_line_tools.adoc#_dumpmain[]. Use it to double-check flags before scripting automation.
TIP: The canonical CLI reference for `DumpMain` lives at xref:command-line:command_line_tools.adoc#dumpmain[].
Use it to double-check flags before scripting automation.

If you have a project pom file that includes the Chronicle-Queue artifact, you can read a `cq4` file with the following command:

Expand Down
2 changes: 2 additions & 0 deletions docs/system-properties.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ https://github.com/OpenHFT/Chronicle-Core/blob/351e79ed593fa656c21b4e5a540a3a583
| queue.ignoreIndexingFailure | `false` | Setting this property to "yes", "true" or "", an exception is not thrown if the number of entries exceeds the max number for the current rollcycle | _IGNORE_INDEXING_FAILURE_ (boolean)
| queue.check.index | `false` | Setting this property to "yes", "true" or "" returns if Chronicle Queue shall assert certain index invariants on various occasions throughout the code. Setting this property to "", "yes" or "true" will enable this feature. Enabling the feature will slow down execution if assertions (-ea) are enabled. | _CHECK_INDEX_ (boolean)
| SingleChronicleQueueExcerpts.earlyAcquireNextCycle | `false` | Used by the pretoucher to acquire the next cycle file, but does NOT do the roll. Setting this property to "yes", "true" or "" results in acquiring the cycle file early | _EARLY_ACQUIRE_NEXT_CYCLE_ (boolean)
| wire.generator.v2 | `false` | Use the v2 method-writer code generator (helpful when diagnosing codegen failures). | -
| disableProxyCodegen | `false` | Prevent fallback to proxy method writer; may cause tests to fail if codegen still fails. | -
|===
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<dependency>
<groupId>net.openhft</groupId>
<artifactId>third-party-bom</artifactId>
<version>3.27ea5</version>
<version>3.27ea7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -229,7 +229,7 @@
<configuration>
<referenceVersion>5.27ea0</referenceVersion>
<artifactsURI>https://teamcity.chronicle.software/repository/download</artifactsURI>
<binaryCompatibilityPercentageRequired>99.8</binaryCompatibilityPercentageRequired>
<binaryCompatibilityPercentageRequired>98</binaryCompatibilityPercentageRequired>
<extraOptions>
<!--This skips "internal" but checks "impl"-->
<extraOption>
Expand Down
116 changes: 116 additions & 0 deletions src/main/docs/testing-strategy.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
= Chronicle Queue Testing Strategy
:toc:
:sectnums:
:lang: en-GB
:toclevels: 2
:doctype: book
:source-highlighter: rouge

This document describes the testing strategy for Chronicle Queue.
It explains how unit, integration and performance tests validate the requirements in `project-requirements.adoc` and the decisions in `decision-log.adoc`, and how new tests should be designed to maintain those guarantees.

== Objectives

Testing for Chronicle Queue aims to:

* verify the core functional requirements (`QUEUE-FN-*`) such as durable appends, ordered tailing, random access and builder configuration;
* exercise non-functional requirements (`QUEUE-NF-*`) around performance, durability, operability and security boundaries;
* detect regressions when internal structures (for example tiered indices or roll-cycle handling) evolve;
* ensure that off-heap resources and memory-mapped files are released deterministically.

Tests are organised by type, with increasing scope and cost.

== Unit Tests

Unit tests focus on individual classes and small collaborations within a single JVM.
Typical responsibilities include:

* basic append and tail behaviour for small queues;
* roll-cycle transitions at boundaries (for example end of hour or day);
* index creation, update and simple seeks within a roll file;
* builder validation for configuration options and preconditions;
* simple error cases such as invalid paths or unsupported combinations of settings.

Patterns:

* use temporary directories for queue data and ensure they are cleaned up after tests;
* use small roll cycles in tests (for example minute-based) to exercise multiple roll events quickly;
* check that exceptions are deterministic and messages are informative when configuration is invalid.

== Integration Tests

Integration tests validate behaviour across multiple classes and, where practical, across restarts and multiple threads.
Areas covered include:

* producer-consumer scenarios with one or more writer threads and multiple tailers;
* crash-recovery simulations where a queue is written, the process is terminated and a new process reopens the directory;
* concurrent access patterns that use separate appender and tailer instances in different threads;
* compatibility across roll boundaries and across minor version changes where file formats remain stable.

Recommended practices:

* use Chronicle-Test-Framework support classes (for example `assertReferencesReleased`) to ensure off-heap resources and file handles are released once queues are closed;
* structure tests so that they can be run repeatedly without manual clean-up;
* where tests depend on timing or delays, allow generous margins and avoid relying on wall-clock timing alone.

== Performance and Benchmark Tests

Performance tests validate `QUEUE-NF-P-*` requirements and provide early warning when changes impact latency or throughput.
These are typically implemented as:

* micro-benchmarks using JMH or JLBH harnesses for append-plus-tail microbenchmarks;
* macro-level tests that write and read larger volumes of data to evaluate sustained throughput and tail latency;
* experiments documented in `performance.adoc`.

Principles:

* keep performance tests separate from fast unit tests; they may require dedicated hardware and are often run manually or in specialised CI jobs;
* record benchmark configurations and results to allow comparison across versions;
* avoid embedding hard latency numbers in assertions; instead, compare against baselines and investigate significant deviations.

== Testing Specific Requirements

=== Functional Requirements (QUEUE-FN-*)

* `QUEUE-FN-001` (append-only durability):
** tests should append messages, close the queue, reopen it and verify that all acknowledged messages are present in order;
** crash-recovery tests may simulate abrupt termination between appends and reopen the queue to ensure no partial messages are exposed.
* `QUEUE-FN-002` (tailers with independent positions):
** tests should create multiple tailers over the same queue, advance them independently and confirm that each sees the expected sequence of messages.
* `QUEUE-FN-003` (random access by index):
** tests should store indices at which key messages were written, then seek back to them and verify that the right messages are returned.
* `QUEUE-FN-004` and `QUEUE-FN-005` (builder configuration and Wire integration):
** tests should exercise different builder configurations and use Chronicle-Wire marshalling over queues for end-to-end verification.

=== Non-Functional Requirements (QUEUE-NF-*)

* `QUEUE-NF-P-*` (performance):
** benchmark tests should report median and tail latencies and throughput, and compare them against documented targets;
** where possible, tests should be run under realistic load and hardware configurations.
* `QUEUE-NF-S-*` (security-related behaviour):
** tests should verify that corruption is not introduced by out-of-bounds writes and that queue structures can be opened and scanned safely, relying on Chronicle-Bytes safety guarantees;
** additional tests should validate the documented encryption boundary by ensuring that applying external or application-level encryption does not break queue semantics.
* `QUEUE-NF-O-*` (operability):
** tests should confirm that system properties in `system-properties.adoc` have the documented effects (for example enabling warnings or consistency checks).

== Resource Management and Leak Detection

Chronicle Queue uses off-heap memory and memory-mapped files via Chronicle-Bytes.
To avoid leaks:

* tests should close queues, appenders and tailers via try-with-resources where possible;
* Chronicle-Test-Framework utilities (for example `assertReferencesReleased`) should be used in modules that depend on it to confirm that all off-heap resources are released after tests;
* tests that intentionally leave queues open (for example crash-recovery simulations) should document this and clean up files afterwards.

== Adding New Tests

When implementing new features or changing existing behaviour:

* identify the affected requirements in `project-requirements.adoc` and, where appropriate, add or update requirement entries;
* design tests that:
** exercise normal behaviour and edge cases;
** cover interactions with roll cycles and indexing;
** validate behaviour across restart and under concurrent access where relevant;
* keep unit tests fast and deterministic; move long-running scenarios into dedicated integration or performance tests.

Tests should be kept as self-documenting as possible, with clear method names and minimal inline commentary that explains non-obvious invariants or requirements.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import org.apache.commons.cli.*;
import org.jetbrains.annotations.NotNull;

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -134,7 +136,7 @@ protected void printHelpAndExit(final Options options, int status) {
* @param message Optional message to print before help
*/
protected void printHelpAndExit(final Options options, int status, String message) {
final PrintWriter writer = new PrintWriter(System.out);
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
new HelpFormatter().printHelp(
writer,
180,
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/net/openhft/chronicle/queue/ChronicleQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ default LongValue indexForId(String id) {
/**
* Removes all the excerpts in the current ChronicleQueue.
*/
@Deprecated(/* to be removed in 2027, only used in tests */)
void clear();

/**
Expand Down Expand Up @@ -287,6 +288,7 @@ default String fileAbsolutePath() {
* @param toIndex last index (inclusive)
* @throws NullPointerException if the provided {@code writer} is {@code null}
*/
@Deprecated(/* to be removed in 2027, only used in tests */)
default void dump(@NotNull OutputStream stream, long fromIndex, long toIndex) {
dump(new OutputStreamWriter(stream, StandardCharsets.UTF_8), fromIndex, toIndex);
}
Expand Down Expand Up @@ -408,6 +410,7 @@ default long lastAcknowledgedIndexReplicated() {
*
* @return the last index that was msync-ed to disk
*/
@Deprecated(/* to be removed in 2027, only used in tests */)
default long lastIndexMSynced() {
return -1;
}
Expand All @@ -434,6 +437,7 @@ default long lastIndexMSynced() {
* @param lastIndexMSynced last msync-ed index
* @see #lastIndexMSynced()
*/
@Deprecated(/* to be removed in 2027, only used in tests */)
default void lastIndexMSynced(long lastIndexMSynced) {
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import org.jetbrains.annotations.NotNull;

import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.time.ZoneId;
import java.util.function.Consumer;
Expand Down Expand Up @@ -131,7 +133,8 @@ protected void printHelpAndExit(final Options options, int status) {
* @param message Optional message to display before help
*/
protected void printHelpAndExit(final Options options, int status, String message) {
final PrintWriter writer = new PrintWriter(System.out);
final PrintWriter writer = new PrintWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
new HelpFormatter().printHelp(
writer,
180,
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/openhft/chronicle/queue/ExcerptTailer.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ default void acknowledgedIndexReplicatedCheck(AcknowledgedIndexReplicatedCheck a
*
* @return the Read After Replica Acknowledged property of this Tailer
*/
@Deprecated(/* to be removed in 2027, only used in tests */)
default boolean readAfterReplicaAcknowledged() {
return false;
}
Expand All @@ -241,6 +242,7 @@ default boolean readAfterReplicaAcknowledged() {
* <p>
* Calling this method may move ExcerptTailer to the specified cycle and release its store.
*
* @param cycle cycle to inspect
* @return the exact number of excerpts in a cycle.
*/
default long excerptsInCycle(int cycle) {
Expand Down
Loading