Skip to content

ci/test: add automated simulation testing to CI/CD and unit test suite - #127

Draft
arena-ai-coding-agent[bot] wants to merge 5 commits into
2026-offseason-botfrom
arena/019fbfe2-2026-spectrum
Draft

ci/test: add automated simulation testing to CI/CD and unit test suite#127
arena-ai-coding-agent[bot] wants to merge 5 commits into
2026-offseason-botfrom
arena/019fbfe2-2026-spectrum

Conversation

@arena-ai-coding-agent

@arena-ai-coding-agent arena-ai-coding-agent Bot commented Aug 2, 2026

Copy link
Copy Markdown

Summary

Adds automated simulation testing to the repository so that robot simulation, mechanism physics, subsystem state transitions, and autonomous routines are tested automatically in CI/CD without requiring GUI/X11 display servers.

Changes

1. Automated Simulation Integration Tests (src/test/java/frc/robot/sim/)

  • SimTestBase: Shared test fixture that initializes WPILib HAL in simulation mode (HAL.initialize(50, 0)), manages DriverStation simulation states (DriverStationSim), provides time-stepping helper stepSim(dt, duration), and cleans up CommandScheduler and simulation loops between tests.
  • MechanismSimTest: Tests initialization and simulation loop updates for individual subsystem mechanisms (Hood, Turret, IntakeExtension).
  • SuperStructureSimTest: Tests initialization and coordination of SuperStructure across all subsystems and verifies state transitions (e.g. INTAKE_FUEL).
  • AutonSimTest: Tests autonomous chooser registration and Auton.init() execution in simulated autonomous mode.
  • RobotSimTest: Tests RobotSim visualizer and fuel physics simulation updates in simulated teleop.

2. Headless Simulation Support (build.gradle)

  • Automatically disables wpi.sim.addGui().defaultEnabled and wpi.sim.addDriverstation().defaultEnabled when running in CI (CI=true) or when -Pheadless=true is passed.
  • Configures Gradle testLogging to report passed, skipped, and failed test events in CI logs.

3. Subsystem & Sim Lifecycle Hardening

  • SimLoop.reset(): Added static reset method so step callbacks and notifier threads are cleanly reset between test runs.
  • Swerve.close(): Implemented AutoCloseable on Swerve to stop the MapleSim simulation notifier thread when a test closes the subsystem.
  • Auton.pathChooser: Added getter annotation so tests can verify SendableChooser registration.

4. Local Verification Script & Docs

  • scripts/verify.sh: Single-command verification script to run Spotless, SpotBugs, and headless unit/simulation tests locally.
  • docs/tools/simulation.md: Documented the new automated simulation testing setup.

Summary by CodeRabbit

  • New Features

    • Added automated simulation coverage for autonomous, teleoperated, robot integration, mechanism, and superstructure behavior.
    • Added a verification script for formatting, static analysis, and headless test execution.
    • Added access to the autonomous path chooser.
  • Bug Fixes

    • Improved simulation cleanup and reset behavior between tests.
  • Documentation

    • Added guidance for running automated simulation tests in CI/CD and locally.
  • Chores

    • Expanded test logs with detailed results and exception information.
    • Disabled simulation interfaces by default in CI and headless runs.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@arena-ai-coding-agent
arena-ai-coding-agent Bot requested a review from a team as a code owner August 2, 2026 00:41
@Project516
Project516 changed the base branch from main to 2026-offseason-bot August 2, 2026 00:42
@Project516

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Project516 Project516 self-assigned this Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request adds headless simulation verification, reusable simulation test setup and cleanup, lifecycle controls for simulation notifiers, and tests for robot mechanisms, superstructure, autonomous routines, and full robot simulation.

Changes

Simulation testing

Layer / File(s) Summary
Headless verification entrypoints
build.gradle, scripts/verify.sh, docs/tools/simulation.md
Build settings add detailed test logging and disable simulation UI in CI or headless mode. The verification script runs formatting, SpotBugs, and headless tests. Documentation describes the simulation test workflow.
Simulation lifecycle and test fixture
src/main/java/frc/spectrumLib/sim/SimLoop.java, src/main/java/frc/robot/subsystems/swerve/Swerve.java, src/test/java/frc/robot/sim/SimTestBase.java
Simulation loops and swerve notifiers can be reset and closed. SimTestBase initializes and tears down simulation state, advances simulated time, and sets Driver Station modes.
Robot and autonomous simulation coverage
src/main/java/frc/robot/auton/Auton.java, src/test/java/frc/robot/sim/*
Auton exposes its path chooser. Tests cover mechanisms, robot integration, superstructure execution, and autonomous chooser and routine execution.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SimTestBase
  participant SimLoop
  participant DriverStation
  participant CommandScheduler
  participant RobotSimulation
  SimTestBase->>SimLoop: reset simulation state
  SimTestBase->>DriverStation: enable autonomous or teleoperated simulation
  SimTestBase->>CommandScheduler: run scheduled commands during stepSim
  SimTestBase->>RobotSimulation: advance simulation
  SimTestBase->>SimLoop: clear callbacks and notifier during teardown
Loading

Possibly related PRs

Suggested reviewers: project516

Poem

A rabbit tests the robot bright,
In headless halls without the light.
Loops reset and notifiers close,
Commands step where simulation goes.
Choosers hop through autonomous flight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding automated simulation testing to CI/CD and the unit test suite.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch arena/019fbfe2-2026-spectrum

Comment @coderabbitai help to get the list of available commands.

@coderabbitai
coderabbitai Bot requested a review from Project516 August 2, 2026 00:44
@Project516
Project516 marked this pull request as draft August 2, 2026 00:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/frc/robot/sim/AutonSimTest.java`:
- Around line 30-51: The full robot-stack construction is duplicated across four
test sites; centralize it in a shared SimTestBase factory. Add a helper that
wires the OM2026-configured Swerve, all listed subsystems, and SuperStructure
while preserving resource ownership, then replace the duplicate blocks in
src/test/java/frc/robot/sim/AutonSimTest.java lines 30-51 and 65-86,
src/test/java/frc/robot/sim/RobotSimTest.java lines 30-51, and
src/test/java/frc/robot/sim/SuperStructureSimTest.java lines 30-51 with the
shared helper call.

In `@src/test/java/frc/robot/sim/MechanismSimTest.java`:
- Around line 49-61: Update testIntakeExtensionSimPeriodic to construct
IntakeExtension with a valid populated IntakeExtensionConfig, following the
existing OM2026 configuration pattern used by the other simulation tests, or
provide valid LeftConfig and RightConfig arguments directly. Preserve the test’s
scheduler registration, simulation stepping, and getSim assertion.

In `@src/test/java/frc/robot/sim/SuperStructureSimTest.java`:
- Around line 57-59: Replace the deprecated schedule() call in
SuperStructureSimTest with CommandScheduler.getInstance().schedule(...), passing
the command returned by
setStateCommand(SuperStructure.WantedSuperState.INTAKE_FUEL). Preserve the
existing command behavior and add or use the appropriate scheduler import.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5e8a9213-977d-4f0c-b4cf-8f12f5dca334

📥 Commits

Reviewing files that changed from the base of the PR and between 8c80c3e and 78b50d4.

📒 Files selected for processing (11)
  • build.gradle
  • docs/tools/simulation.md
  • scripts/verify.sh
  • src/main/java/frc/robot/auton/Auton.java
  • src/main/java/frc/robot/subsystems/swerve/Swerve.java
  • src/main/java/frc/spectrumLib/sim/SimLoop.java
  • src/test/java/frc/robot/sim/AutonSimTest.java
  • src/test/java/frc/robot/sim/MechanismSimTest.java
  • src/test/java/frc/robot/sim/RobotSimTest.java
  • src/test/java/frc/robot/sim/SimTestBase.java
  • src/test/java/frc/robot/sim/SuperStructureSimTest.java

Comment thread src/test/java/frc/robot/sim/AutonSimTest.java Outdated
Comment thread src/test/java/frc/robot/sim/MechanismSimTest.java
Comment thread src/test/java/frc/robot/sim/SuperStructureSimTest.java Outdated
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 5 file(s) based on 3 unresolved review comments.

Files modified:

  • src/test/java/frc/robot/sim/AutonSimTest.java
  • src/test/java/frc/robot/sim/MechanismSimTest.java
  • src/test/java/frc/robot/sim/RobotSimTest.java
  • src/test/java/frc/robot/sim/SimTestBase.java
  • src/test/java/frc/robot/sim/SuperStructureSimTest.java

Commit: b69ea01a068893d98f08209d4dd3f71965383476

The changes have been pushed to the arena/019fbfe2-2026-spectrum branch.

Time taken: 3m 44s

Fixed 5 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Note

Docstrings generation - SUCCESS
Generated docstrings and committed to branch arena/019fbfe2-2026-spectrum (commit: 67a27776535f323e0ed272b4a829d810f4ce4720)

Docstrings generation was requested by @Project516.

The following files were modified:

* `src/main/java/frc/robot/subsystems/swerve/Swerve.java`
* `src/main/java/frc/spectrumLib/sim/SimLoop.java`
* `src/test/java/frc/robot/sim/SimTestBase.java`

These files were ignored:
* `src/test/java/frc/robot/sim/AutonSimTest.java`
* `src/test/java/frc/robot/sim/MechanismSimTest.java`
* `src/test/java/frc/robot/sim/RobotSimTest.java`
* `src/test/java/frc/robot/sim/SuperStructureSimTest.java`

These file types are not supported:
* `build.gradle`
* `docs/tools/simulation.md`
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Committed CI fixes to this branch (5bfe423). CI will re-run on the new commit.

Note: Fixing CI failures is a beta feature and may encounter errors. Expect some limitations and changes as we gather feedback and continue to improve it.

2 failing check(s)
  • GitHub Actions: CI / build
  • GitHub Actions: CI / 0_build.txt
2 file(s) modified
  • src/main/java/frc/robot/subsystems/swerve/Swerve.java
  • src/test/java/frc/robot/sim/SimTestBase.java
View agent analysis
Fixed the two Spotless formatting violations by rewrapping the Javadoc comments to match the expected line-wrap width, exactly as indicated in the CI diff:

1. `src/main/java/frc/robot/subsystems/swerve/Swerve.java:751-753` — rewrapped the `startSimThread()` Javadoc.
2. `src/test/java/frc/robot/sim/SimTestBase.java:26-29` and `:80-83` — rewrapped the `RobotStack` and `createRobotStack()` Javadocs.

No source logic was changed, only comment line-wrapping to satisfy `spotlessJavaCheck`.

…: CI / 0_build.txt

Co-Authored-By: CodeRabbit <noreply@coderabbit.ai>
@Project516

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/test/java/frc/robot/sim/SimTestBase.java (1)

158-164: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Advance the requested simulation duration exactly.

Math.round(durationSeconds / dtSeconds) can advance less or more time than durationSeconds. This changes test behavior for non-integral durations.

Execute full steps and one final remainder step.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/frc/robot/sim/SimTestBase.java` around lines 158 - 164, Update
stepSim to advance exactly durationSeconds by executing the full dtSeconds
steps, then one final step for any remaining fractional duration. Replace the
rounded step count logic while preserving the existing SimHooks.stepTiming and
CommandScheduler execution for every step.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/frc/spectrumLib/sim/SimLoop.java`:
- Around line 45-49: Update the Javadoc for the tick() method by removing the
invalid `@param` dt tag and keeping the description focused on notifying
registered callbacks with the computed elapsed time.

In `@src/test/java/frc/robot/sim/RobotSimTest.java`:
- Around line 20-21: At the four try-with-resources sites in
src/test/java/frc/robot/sim/RobotSimTest.java (20-21),
src/test/java/frc/robot/sim/SuperStructureSimTest.java (21-22), and
src/test/java/frc/robot/sim/AutonSimTest.java (20-21, 34-35), remove the local
Swerve resource variable and use stack.swerve directly; remove the now-unused
Swerve imports from all affected files.

In `@src/test/java/frc/robot/sim/SimTestBase.java`:
- Around line 89-119: Update createRobotStack around the Swerve and subsequent
subsystem construction so any constructor failure closes the already-created
swerve before rethrowing the original failure. Preserve normal RobotStack
creation and return behavior when construction succeeds.

---

Outside diff comments:
In `@src/test/java/frc/robot/sim/SimTestBase.java`:
- Around line 158-164: Update stepSim to advance exactly durationSeconds by
executing the full dtSeconds steps, then one final step for any remaining
fractional duration. Replace the rounded step count logic while preserving the
existing SimHooks.stepTiming and CommandScheduler execution for every step.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 36fd3f0d-cdad-424e-af1e-a6685d7025df

📥 Commits

Reviewing files that changed from the base of the PR and between 78b50d4 and 5bfe423.

📒 Files selected for processing (7)
  • src/main/java/frc/robot/subsystems/swerve/Swerve.java
  • src/main/java/frc/spectrumLib/sim/SimLoop.java
  • src/test/java/frc/robot/sim/AutonSimTest.java
  • src/test/java/frc/robot/sim/MechanismSimTest.java
  • src/test/java/frc/robot/sim/RobotSimTest.java
  • src/test/java/frc/robot/sim/SimTestBase.java
  • src/test/java/frc/robot/sim/SuperStructureSimTest.java

Comment on lines +45 to +49
/**
* Advances the simulation loop and notifies each registered callback of the elapsed time.
*
* @param dt the elapsed time in seconds since the previous update
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C3 'javadoc|doclint|Xdoclint' build.gradle build.gradle.kts 2>/dev/null || true
sed -n '45,56p' src/main/java/frc/spectrumLib/sim/SimLoop.java

Repository: Spectrum3847/2026-Spectrum

Length of output: 1453


Remove the invalid @param dt tag. tick() has no dt parameter. Keep the description focused on notifying callbacks with the computed elapsed time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/frc/spectrumLib/sim/SimLoop.java` around lines 45 - 49, Update
the Javadoc for the tick() method by removing the invalid `@param` dt tag and
keeping the description focused on notifying registered callbacks with the
computed elapsed time.

Comment on lines +20 to +21
RobotStack stack = createRobotStack();
try (Swerve swerve = stack.swerve) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C2 'sourceCompatibility|targetCompatibility|JavaLanguageVersion' build.gradle build.gradle.kts 2>/dev/null || true
rg -n -C2 'try \(Swerve swerve = stack\.swerve\)' src/test/java/frc/robot/sim

Repository: Spectrum3847/2026-Spectrum

Length of output: 2536


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- test files ---'
cat -n src/test/java/frc/robot/sim/RobotSimTest.java
cat -n src/test/java/frc/robot/sim/SuperStructureSimTest.java
cat -n src/test/java/frc/robot/sim/AutonSimTest.java

printf '%s\n' '--- RobotStack and Swerve declarations/usages ---'
rg -n -C3 'class RobotStack|record RobotStack|stack\.swerve|class Swerve|interface Swerve|implements .*AutoCloseable|close\(' src/main/java src/test/java build.gradle gradle.properties 2>/dev/null || true

printf '%s\n' '--- PMD configuration and Java toolchain ---'
rg -n -C3 'pmd|PMD|sourceCompatibility|targetCompatibility|toolchain|JavaLanguageVersion' . -g '!build' -g '!node_modules' -g '!vendor' 2>/dev/null || true

Repository: Spectrum3847/2026-Spectrum

Length of output: 13135


🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

cat >"$tmpdir/TryResourceField.java" <<'JAVA'
public class TryResourceField {
    static class Resource implements AutoCloseable {
        public void close() {}
    }

    static class Holder {
        Resource resource = new Resource();

        void method() {
            try (resource) {
                System.out.println("body");
            }
        }
    }

    public static void main(String[] args) {
        new Holder().method();
    }
}
JAVA

if command -v javac >/dev/null 2>&1; then
    javac --release 17 "$tmpdir/TryResourceField.java"
    echo 'Java 17 accepts an instance-field try-with-resources reference.'
else
    echo 'javac is unavailable; source-level behavior requires manual verification.'
fi

Repository: Spectrum3847/2026-Spectrum

Length of output: 238


🌐 Web query:

Java 17 JLS try-with-resources VariableAccess field access effectively final resource

💡 Result:

As of Java 17 and later, the Java Language Specification (JLS) allows a try-with-resources statement to use an existing variable as a resource, provided that the variable is final or effectively final [1][2]. This capability was introduced in Java 9 to simplify resource management [1][2]. Under the JLS, the resource specification in a try-with-resources statement can consist of: 1. A formal local variable declaration (the original Java 7 approach) [2][3]. 2. A reference to an existing final or effectively final local variable [1][2]. It is important to note that field access or other arbitrary expressions (such as array access or method calls) are not permitted directly within the resource specification [4]. The resource must be a simple variable name that refers to an object implementing AutoCloseable [4]. If you need to manage a resource accessed via a field, you must first assign that field to a local variable and ensure that the local variable remains effectively final before using it in the try-with-resources statement [4]. A variable is considered effectively final if its value is not changed after it is initialized [2]. If you attempt to use a non-final or non-effectively final variable (e.g., a variable reassigned later in the scope) as a resource, the compiler will issue an error [2]. The requirement for a final or effectively final variable ensures that the resource being closed is the same one intended throughout the block's lifecycle, avoiding ambiguity [5].

Citations:


🌐 Web query:

site:docs.oracle.com/javase/specs/jls/se17/html/jls-14.html try-with-resources VariableAccess FieldAccess

💡 Result:

In a try-with-resources statement in Java, the resources declared within the resource specification act as local variables [1]. These variables are scoped strictly to the try-with-resources statement itself, meaning they are accessible within the associated try block and any corresponding catch or finally blocks [1]. Regarding VariableAccess and FieldAccess, there are no special restrictions imposed by the try-with-resources construct that prevent you from accessing class fields or other variables that are in scope [1]. You can access instance or static fields of an object, or any other accessible variables, from within the body of the try-with-resources statement just as you would in any other block of code [1]. The resource variables declared in the header are simply treated as local variable declarations, adhering to standard Java scoping and access rules [1].

Citations:


🌐 Web query:

Java 17 javac try (object.field) field access try-with-resources

💡 Result:

In Java 17, the try-with-resources statement does not support arbitrary field access expressions (such as object.field) directly within the resource specification [1][2]. Starting with Java 9, the try-with-resources statement was enhanced to allow the use of existing variables, provided they are declared as final or effectively final [2][3][4][5]. However, this support is strictly limited to variable identifiers; it does not extend to general expressions like field access expressions (object.field) or array access expressions [2][6][5]. If you attempt to use a field expression like try (this.field) { ... } or try (obj.field) { ... }, the compiler will generate an error because the syntax requires a simple variable identifier [4][5]. To use an instance field in a try-with-resources statement, you must first assign the field's value to a local final or effectively final variable [2][3]: final var myResource = this.field; try (myResource) { // Use myResource here } This design restriction exists for several reasons: 1. Stability: Fields can be modified by other threads or parts of the program during the execution of the try block, which could lead to unpredictable behavior regarding resource cleanup [2][3][4]. 2. Complexity: Allowing general expressions introduces significant specification and implementation complexities, particularly concerning how to evaluate the expression, when to capture its value, and how to handle potential side effects [6][5]. 3. Semantics: Requiring a simple variable identifier ensures clarity regarding the lifecycle and closing of the resource [6][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from urllib.request import urlopen
from re import search

urls = [
    "https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html",
    "https://docs.oracle.com/javase/specs/jls/se17/jls17.pdf",
]
for url in urls:
    try:
        data = urlopen(url, timeout=15).read()
        print(f"URL: {url}")
        print(f"HTTP bytes: {len(data)}")
        if url.endswith(".html"):
            text = data.decode("utf-8", "replace")
            for needle in ("Resource:", "VariableAccess:", "FieldAccess:"):
                pos = text.find(needle)
                print(f"--- {needle} ---")
                print(text[pos:pos + 1800] if pos >= 0 else "not found")
    except Exception as exc:
        print(f"URL: {url}\nERROR: {exc}")
PY

printf '%s\n' '--- available Java tools ---'
for tool in javac java ecj kotlinc groovy; do
    if command -v "$tool" >/dev/null 2>&1; then
        printf '%s: %s\n' "$tool" "$(command -v "$tool")"
    fi
done

Repository: Spectrum3847/2026-Spectrum

Length of output: 626


🏁 Script executed:

#!/bin/bash
set -euo pipefail

if command -v curl >/dev/null 2>&1; then
    curl --silent --show-error --fail --insecure \
        https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html |
        sed -n '/id="jls-14.20.3"/,/id="jls-14.20.4"/p' |
        grep -E -A8 -B3 'Resource:|VariableAccess:|FieldAccess:' || true
fi

printf '%s\n' '--- Java compiler module availability ---'
java --list-modules 2>/dev/null | grep -E '^(jdk.compiler|java.compiler)@' || true

printf '%s\n' '--- Java runtime version ---'
java -version 2>&1

Repository: Spectrum3847/2026-Spectrum

Length of output: 483


🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

cat >"$tmpdir/TryResourceField.java" <<'JAVA'
public class TryResourceField {
    static final class Resource implements AutoCloseable {
        `@Override`
        public void close() {}
    }

    static final class RobotStack {
        public final Resource swerve = new Resource();
    }

    static void useStack() {
        RobotStack stack = new RobotStack();
        try (stack.swerve) {
            System.out.println("body");
        }
    }
}
JAVA

java --add-modules jdk.compiler com.sun.tools.javac.Main \
    --release 17 -d "$tmpdir/out" "$tmpdir/TryResourceField.java"

echo 'Java 17 accepted try (stack.swerve).'

Repository: Spectrum3847/2026-Spectrum

Length of output: 201


Remove the unused resource locals and imports.

At all four sites, use try (stack.swerve) and remove the now-unused Swerve imports.

🧰 Tools
🪛 PMD (7.26.0)

[Medium] 21-21: UnusedLocalVariable (Best Practices): Avoid unused local variables such as 'swerve'.

(UnusedLocalVariable (Best Practices))

📍 Affects 3 files
  • src/test/java/frc/robot/sim/RobotSimTest.java#L20-L21 (this comment)
  • src/test/java/frc/robot/sim/SuperStructureSimTest.java#L21-L22
  • src/test/java/frc/robot/sim/AutonSimTest.java#L20-L21
  • src/test/java/frc/robot/sim/AutonSimTest.java#L34-L35
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/frc/robot/sim/RobotSimTest.java` around lines 20 - 21, At the
four try-with-resources sites in src/test/java/frc/robot/sim/RobotSimTest.java
(20-21), src/test/java/frc/robot/sim/SuperStructureSimTest.java (21-22), and
src/test/java/frc/robot/sim/AutonSimTest.java (20-21, 34-35), remove the local
Swerve resource variable and use stack.swerve directly; remove the now-unused
Swerve imports from all affected files.

Source: Linters/SAST tools

Comment on lines +89 to +119
Swerve swerve = new Swerve(config.swerve);
FuelIntake fuelIntake = new FuelIntake(config.fuelIntake);
IntakeExtension intakeExtension = new IntakeExtension(config.intakeExtension);
DyeRotor dyeRotor = new DyeRotor(config.dyeRotor);
Launcher launcher = new Launcher(config.launcher);
LauncherTower launcherTower = new LauncherTower(config.launcherTower);
Turret turret = new Turret(config.turret);
Hood hood = new Hood(config.hood);

SuperStructure superStructure =
new SuperStructure(
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood);

return new RobotStack(
config,
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood,
superStructure);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Close Swerve when stack construction fails.

If a constructor after Line 89 throws, createRobotStack() does not return. The caller never enters its try-with-resources block. The Swerve notifier then remains active for later tests.

Close swerve in a catch block before rethrowing the failure.

Proposed fix
         Swerve swerve = new Swerve(config.swerve);
-        FuelIntake fuelIntake = new FuelIntake(config.fuelIntake);
-        IntakeExtension intakeExtension = new IntakeExtension(config.intakeExtension);
-        DyeRotor dyeRotor = new DyeRotor(config.dyeRotor);
-        Launcher launcher = new Launcher(config.launcher);
-        LauncherTower launcherTower = new LauncherTower(config.launcherTower);
-        Turret turret = new Turret(config.turret);
-        Hood hood = new Hood(config.hood);
+        try {
+            FuelIntake fuelIntake = new FuelIntake(config.fuelIntake);
+            IntakeExtension intakeExtension = new IntakeExtension(config.intakeExtension);
+            DyeRotor dyeRotor = new DyeRotor(config.dyeRotor);
+            Launcher launcher = new Launcher(config.launcher);
+            LauncherTower launcherTower = new LauncherTower(config.launcherTower);
+            Turret turret = new Turret(config.turret);
+            Hood hood = new Hood(config.hood);
 
-        SuperStructure superStructure =
-                new SuperStructure(
-                        swerve,
-                        fuelIntake,
-                        intakeExtension,
-                        dyeRotor,
-                        launcher,
-                        launcherTower,
-                        turret,
-                        hood);
+            SuperStructure superStructure =
+                    new SuperStructure(
+                            swerve,
+                            fuelIntake,
+                            intakeExtension,
+                            dyeRotor,
+                            launcher,
+                            launcherTower,
+                            turret,
+                            hood);
 
-        return new RobotStack(
-                config,
-                swerve,
-                fuelIntake,
-                intakeExtension,
-                dyeRotor,
-                launcher,
-                launcherTower,
-                turret,
-                hood,
-                superStructure);
+            return new RobotStack(
+                    config,
+                    swerve,
+                    fuelIntake,
+                    intakeExtension,
+                    dyeRotor,
+                    launcher,
+                    launcherTower,
+                    turret,
+                    hood,
+                    superStructure);
+        } catch (RuntimeException | Error exception) {
+            swerve.close();
+            throw exception;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Swerve swerve = new Swerve(config.swerve);
FuelIntake fuelIntake = new FuelIntake(config.fuelIntake);
IntakeExtension intakeExtension = new IntakeExtension(config.intakeExtension);
DyeRotor dyeRotor = new DyeRotor(config.dyeRotor);
Launcher launcher = new Launcher(config.launcher);
LauncherTower launcherTower = new LauncherTower(config.launcherTower);
Turret turret = new Turret(config.turret);
Hood hood = new Hood(config.hood);
SuperStructure superStructure =
new SuperStructure(
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood);
return new RobotStack(
config,
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood,
superStructure);
Swerve swerve = new Swerve(config.swerve);
try {
FuelIntake fuelIntake = new FuelIntake(config.fuelIntake);
IntakeExtension intakeExtension = new IntakeExtension(config.intakeExtension);
DyeRotor dyeRotor = new DyeRotor(config.dyeRotor);
Launcher launcher = new Launcher(config.launcher);
LauncherTower launcherTower = new LauncherTower(config.launcherTower);
Turret turret = new Turret(config.turret);
Hood hood = new Hood(config.hood);
SuperStructure superStructure =
new SuperStructure(
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood);
return new RobotStack(
config,
swerve,
fuelIntake,
intakeExtension,
dyeRotor,
launcher,
launcherTower,
turret,
hood,
superStructure);
} catch (RuntimeException | Error exception) {
swerve.close();
throw exception;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/frc/robot/sim/SimTestBase.java` around lines 89 - 119, Update
createRobotStack around the Swerve and subsequent subsystem construction so any
constructor failure closes the already-created swerve before rethrowing the
original failure. Preserve normal RobotStack creation and return behavior when
construction succeeds.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 5 file(s) based on 3 unresolved review comments.

Files modified:

  • src/main/java/frc/spectrumLib/sim/SimLoop.java
  • src/test/java/frc/robot/sim/AutonSimTest.java
  • src/test/java/frc/robot/sim/RobotSimTest.java
  • src/test/java/frc/robot/sim/SimTestBase.java
  • src/test/java/frc/robot/sim/SuperStructureSimTest.java

Commit: bec6b0a407132ab1c3ac2ec31c98b44d6956489f

The changes have been pushed to the arena/019fbfe2-2026-spectrum branch.

Time taken: 3m 1s

Fixed 5 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@Project516

Copy link
Copy Markdown
Contributor

last ci ran for an hour i canceled it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants