Skip to content

Commit e2edf2b

Browse files
committed
recently learned updates...
1 parent d72d492 commit e2edf2b

1 file changed

Lines changed: 39 additions & 4 deletions

File tree

CLAUDE.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,39 @@ The build is Gradle multi-module. JDK 21+ is required to drive Gradle. Optional
1717

1818
### Running an individual test fast
1919

20-
Most BC tests extend `org.bouncycastle.util.test.SimpleTest` and have a `main()` that registers `BouncyCastleProvider` and runs `performTest()`. Gradle's `:test` only matches `AllTest*` JUnit wrappers (which iterate over `RegressionTest.tests` arrays and run each `SimpleTest`). To iterate quickly on one test, run its `main()` directly — much faster than spinning up Gradle:
20+
Two conventions coexist:
21+
22+
- `org.bouncycastle.util.test.SimpleTest` subclasses (~half of the suite) override `performTest()` and call `fail(msg)` / `isTrue(msg, cond)` / `areEqual(a, b)`. They have a `main()` that registers `BouncyCastleProvider` and prints `<TestName>: Okay` on success or `<TestName>: <message>` on failure.
23+
- `junit.framework.TestCase` subclasses (the other half, especially in `pkix/.../pkcs/test`, `pkix/.../cms/test`, etc.) use plain JUnit assertions and are aggregated by an `AllTests` suite class. Run one via `junit.textui.TestRunner`:
24+
```
25+
java -cp ... junit.textui.TestRunner org.bouncycastle.pkcs.test.PKCS12UtilTest
26+
```
27+
28+
To iterate quickly on either flavour, run directly without Gradle. The full classpath you need:
2129

2230
```
2331
java -cp pkix/build/classes/java/main:pkix/build/classes/java/test:pkix/src/test/resources:\
24-
prov/build/classes/java/main:core/build/classes/java/main:core/build/classes/java/test:\
25-
util/build/classes/java/main:$(find ~/.gradle -name 'junit-*.jar' | head -1) \
32+
prov/build/classes/java/main:prov/build/classes/java/test:prov/build/resources/main:\
33+
prov/src/test/resources:\
34+
core/build/classes/java/main:core/build/classes/java/test:core/build/resources/main:\
35+
core/src/test/resources:\
36+
util/build/classes/java/main:\
37+
$(find ~/.gradle -name 'junit-*.jar' | head -1):\
38+
$(find ~/.gradle -name 'hamcrest-core-1*.jar' | head -1) \
39+
-Dbc.test.data.home=core/src/test/data \
2640
org.bouncycastle.openssl.test.ParserTest
2741
```
2842

29-
Test resources live under `*/src/test/resources` and must be on the classpath. Failures inside `performTest()` print `<TestName>: <message>`; success prints `<TestName>: Okay`.
43+
Common gotchas:
44+
- `*/build/resources/main` directories are required — some tests pull resource files (e.g. `lowmcL1.bin.properties` for Picnic, GOST tables) that fail with cryptic `NullPointerException` if missing.
45+
- `prov/src/test/resources` and `core/src/test/resources` carry test fixtures referenced by `TestResourceFinder` and direct classpath lookups.
46+
- IDE-built classes under `out/production/...` (IntelliJ) are NOT on the Gradle classpath — don't reference them, and beware that they can drift from Gradle's outputs.
47+
48+
### Verifying a fix actually catches the bug
49+
50+
The repo's working norm for any defect-fix patch is: write the test that reproduces the bug, then **stash the fix** (`git stash push <fix-files>`), recompile (`./gradlew :<module>:compileJava`), rerun the test to confirm it now fails on the original symptom, then `git stash pop` and rerun to confirm it now passes. This catches tests that pass for the wrong reason. Use it whenever you add a regression test alongside a fix.
51+
52+
When the fix is in `core/`, remember to recompile `prov` too (the `core`-into-`prov` trap below) so the test JVM picks up the updated bytecode rather than a stale `prov/build/classes` shadow.
3053

3154
## Architecture
3255

@@ -73,6 +96,18 @@ The same applies to tests: `src/test/java` is the Gradle-driven tree; `src/test/
7396

7497
Many tests assert on exact exception message text (e.g. `isTrue(e.getMessage().equals("..."))` or `getCause().getMessage()` checks). Changing the wording of a thrown exception — even something as small as adding a colon, rewording for clarity, or wrapping with `Exceptions.illegalArgumentException(...)` — will silently break tests in another module. Before modifying any exception message, grep the whole tree for the existing string and update every matching assertion in lockstep.
7598

99+
### System / security property constants
100+
101+
Any system or security property that controls BC behaviour belongs in `core/src/main/java/org/bouncycastle/util/Properties.java` as a `public static final String`, e.g. `Properties.PKCS12_MAX_IT_COUNT`, `Properties.PKCS12_IGNORE_USELESS_PASSWD`, `Properties.EMULATE_ORACLE`. Callers should reference the constant rather than inlining the literal `"org.bouncycastle.…"` name — both in production code and in tests that flip the property via `System.setProperty`. New properties should be added to `Properties` with the same naming pattern (`org.bouncycastle.<area>.<flag>`).
102+
76103
### Release notes
77104

78105
Defects fixed and additional features go into `docs/releasenotes.html` under the **current** unreleased version block (e.g. section 2.1 with header "Release: 1.85"). Each entry is a single `<li>...</li>` referencing the GitHub issue number where applicable. The file is hand-edited HTML; preserve the existing prose style and `<ul>` structure.
106+
107+
### Commit messages
108+
109+
Existing convention: a short imperative sentence ending with `relates to github #NNNN.` for issue-driven work (e.g. `Corrected casing of Falcon naming when used with NamedParameterSpec, relates to github #2194`). Multi-line bodies are unusual — keep the headline self-contained.
110+
111+
### Code style
112+
113+
Match the surrounding file: Allman braces (open brace on its own line for class / method / control structures), 4-space indentation, no tabs. Don't reformat untouched code while editing — diffs that include unrelated whitespace changes are noisy and slow review.

0 commit comments

Comments
 (0)