diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c87572cf..af7b66e0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -260,6 +260,83 @@ jobs: with: name: jar-${{ matrix.artifact-name }} path: photon-server/build/libs + + run-smoketest-native: + needs: [build-package] + + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + artifact-name: jar-Linux + extraOpts: -Djdk.lang.Process.launchMechanism=vfork + - os: windows-latest + artifact-name: jar-Win64 + extraOpts: "" + - os: macos-latest + artifact-name: jar-macOS + architecture: x64 + + runs-on: ${{ matrix.os }} + + steps: + - name: Install Java 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + - uses: actions/download-artifact@v4 + with: + name: ${{ matrix.artifact-name }} + # On linux, install mrcal packages + - run: | + sudo apt-get update + sudo apt-get install --yes libcholmod3 liblapack3 libsuitesparseconfig5 + if: ${{ (matrix.os) == 'ubuntu-latest' }} + # and actually run the jar + - run: java -jar ${{ matrix.extraOpts }} *.jar --smoketest + if: ${{ (matrix.os) != 'windows-latest' }} + - run: ls *.jar | %{ Write-Host "Running $($_.Name)"; Start-Process "java" -ArgumentList "-jar `"$($_.FullName)`" --smoketest" -NoNewWindow -Wait; break } + if: ${{ (matrix.os) == 'windows-latest' }} + + run-smoketest-chroot: + needs: [build-package] + + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + artifact-name: LinuxArm64 + image_suffix: RaspberryPi + image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.4/photonvision_raspi.img.xz + cpu: cortex-a7 + image_additional_mb: 0 + extraOpts: -Djdk.lang.Process.launchMechanism=vfork + + runs-on: ${{ matrix.os }} + name: smoketest-${{ matrix.image_suffix }} + + steps: + - uses: actions/download-artifact@v4 + with: + name: jar-${{ matrix.artifact-name }} + + - uses: pguyot/arm-runner-action@v2 + name: Run photon smoketest + id: generate_image + with: + base_image: ${{ matrix.image_url }} + image_additional_mb: ${{ matrix.image_additional_mb }} + optimize_image: yes + cpu: ${{ matrix.cpu }} + # We do _not_ wanna copy photon into the image. Bind mount instead + bind_mount_repository: true + # our image better have java installed already + commands: | + java -jar ${{ matrix.extraOpts }} *.jar --smoketest + build-image: needs: [build-package] diff --git a/photon-server/src/main/java/org/photonvision/Main.java b/photon-server/src/main/java/org/photonvision/Main.java index 8ae7c8fd9..a78c0a79f 100644 --- a/photon-server/src/main/java/org/photonvision/Main.java +++ b/photon-server/src/main/java/org/photonvision/Main.java @@ -65,6 +65,7 @@ public class Main { private static final boolean isRelease = PhotonVersion.isRelease; private static boolean isTestMode = false; + private static boolean isSmoketest = false; private static Path testModeFolder = null; private static boolean printDebugLogs; @@ -90,6 +91,11 @@ public class Main { "clear-config", false, "Clears PhotonVision pipeline and networking settings. Preserves log files"); + options.addOption( + "s", + "smoketest", + false, + "Exit Photon after loading native libraries and camera configs, but before starting up camera runners"); CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse(options, args); @@ -127,6 +133,10 @@ public class Main { if (cmd.hasOption("clear-config")) { ConfigManager.getInstance().clearConfig(); } + + if (cmd.hasOption("smoketest")) { + isSmoketest = true; + } } return true; } @@ -337,11 +347,17 @@ public class Main { public static void main(String[] args) { try { - TestUtils.loadLibraries(); - logger.info("Native libraries loaded."); + boolean success = TestUtils.loadLibraries(); + + if (!success) { + logger.error("Failed to load native libraries! Giving up :("); + System.exit(1); + } } catch (Exception e) { logger.error("Failed to load native libraries!", e); + System.exit(1); } + logger.info("Native libraries loaded."); try { if (Platform.isRaspberryPi()) { @@ -412,6 +428,11 @@ public class Main { NeuralNetworkModelManager.getInstance() .initialize(ConfigManager.getInstance().getModelsDirectory()); + if (isSmoketest) { + logger.info("PhotonVision base functionality loaded -- smoketest complete"); + System.exit(0); + } + if (!isTestMode) { logger.debug("Loading VisionSourceManager..."); VisionSourceManager.getInstance()