From 9cf5c77d69fb53ec2895ddfe4b81d861f03ad184 Mon Sep 17 00:00:00 2001 From: Banks T Date: Tue, 31 Aug 2021 23:27:51 -0400 Subject: [PATCH] CI test fix (#280) Addresses OOM in CI --- .github/workflows/main.yml | 20 +++-- .../photonvision/common/util/TestUtils.java | 3 +- .../vision/pipeline/Calibrate3dPipeTest.java | 45 ++++++----- .../vision/pipeline/CirclePNPTest.java | 80 +++++++++---------- .../pipeline/ColoredShapePipelineTest.java | 62 +++++++------- .../org/photonvision/SimVisionSystem.java | 1 - .../java/org/photonvision/PhotonUtilTest.java | 1 - .../org/photonvision/SimVisionSystemTest.java | 1 - shared/common.gradle | 4 +- 9 files changed, 115 insertions(+), 102 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0d9045ab3..9feee3ea1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,8 +74,12 @@ jobs: chmod +x gradlew ./gradlew build -x check - # Run Tests Generate Coverage Report. - - name: Gradle Test and Coverage + # Run Gradle Tests. + - name: Gradle Tests + run: ./gradlew testHeadless -i + + # Generate Coverage Report. + - name: Gradle Coverage run: ./gradlew jacocoTestReport # Publish Coverage Report. @@ -242,11 +246,17 @@ jobs: - name: Install wpiformat run: pip3 install wpiformat - name: Run - run: | - ls -la - wpiformat -clang 10 -f photon-lib + run: wpiformat -clang 10 -f photon-lib - name: Check Output run: git --no-pager diff --exit-code HEAD + - name: Generate diff + run: git diff HEAD > wpiformat-fixes.patch + if: ${{ failure() }} + - uses: actions/upload-artifact@v2 + with: + name: wpiformat fixes + path: wpiformat-fixes.patch + if: ${{ failure() }} photon-build-package: needs: [photonclient-build, photon-build-all, photonserver-build-offline-docs, photonlib-build-host, photonlib-build-docker] diff --git a/photon-core/src/main/java/org/photonvision/common/util/TestUtils.java b/photon-core/src/main/java/org/photonvision/common/util/TestUtils.java index b752f5067..fa3e021a1 100644 --- a/photon-core/src/main/java/org/photonvision/common/util/TestUtils.java +++ b/photon-core/src/main/java/org/photonvision/common/util/TestUtils.java @@ -135,8 +135,7 @@ public class TestUtils { } private static Path getResourcesFolderPath(boolean testMode) { - return Path.of((testMode ? "photon-server/src/main" : "src/test"), "resources") - .toAbsolutePath(); + return Path.of((testMode ? "src/main" : "src/test"), "resources").toAbsolutePath(); } public static Path getTestMode2019ImagePath() { diff --git a/photon-core/src/test/java/org/photonvision/vision/pipeline/Calibrate3dPipeTest.java b/photon-core/src/test/java/org/photonvision/vision/pipeline/Calibrate3dPipeTest.java index e4cdb13a6..2beadbb7e 100644 --- a/photon-core/src/test/java/org/photonvision/vision/pipeline/Calibrate3dPipeTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/pipeline/Calibrate3dPipeTest.java @@ -79,6 +79,10 @@ public class Calibrate3dPipeTest { assertTrue(calibrate3dPipeOutput.output.perViewErrors.length > 0); System.out.println( "Per View Errors: " + Arrays.toString(calibrate3dPipeOutput.output.perViewErrors)); + + for (var f : frames) { + f.release(); + } } @Test @@ -98,14 +102,14 @@ public class Calibrate3dPipeTest { for (var file : directoryListing) { calibration3dPipeline.takeSnapshot(); - var output = - calibration3dPipeline.run( - new Frame( - new CVMat(Imgcodecs.imread(file.getAbsolutePath())), - new FrameStaticProperties(640, 480, 60, new Rotation2d(), null)), - QuirkyCamera.DefaultCamera); + var frame = + new Frame( + new CVMat(Imgcodecs.imread(file.getAbsolutePath())), + new FrameStaticProperties(640, 480, 60, new Rotation2d(), null)); + var output = calibration3dPipeline.run(frame, QuirkyCamera.DefaultCamera); // TestUtils.showImage(output.outputFrame.image.getMat()); output.release(); + frame.release(); } assertTrue( @@ -114,13 +118,12 @@ public class Calibrate3dPipeTest { .allMatch(it -> it.width() > 0 && it.height() > 0)); calibration3dPipeline.removeSnapshot(0); - calibration3dPipeline - .run( - new Frame( - new CVMat(Imgcodecs.imread(directoryListing[0].getAbsolutePath())), - new FrameStaticProperties(640, 480, 60, new Rotation2d(), null)), - QuirkyCamera.DefaultCamera) - .release(); + var frame = + new Frame( + new CVMat(Imgcodecs.imread(directoryListing[0].getAbsolutePath())), + new FrameStaticProperties(640, 480, 60, new Rotation2d(), null)); + calibration3dPipeline.run(frame, QuirkyCamera.DefaultCamera).release(); + frame.release(); assertTrue( calibration3dPipeline.foundCornersList.stream() @@ -263,16 +266,16 @@ public class Calibrate3dPipeTest { for (var file : directoryListing) { if (file.isFile()) { calibration3dPipeline.takeSnapshot(); - var output = - calibration3dPipeline.run( - new Frame( - new CVMat(Imgcodecs.imread(file.getAbsolutePath())), - new FrameStaticProperties( - (int) imgRes.width, (int) imgRes.height, 67, new Rotation2d(), null)), - QuirkyCamera.DefaultCamera); + var frame = + new Frame( + new CVMat(Imgcodecs.imread(file.getAbsolutePath())), + new FrameStaticProperties( + (int) imgRes.width, (int) imgRes.height, 67, new Rotation2d(), null)); + var output = calibration3dPipeline.run(frame, QuirkyCamera.DefaultCamera); // TestUtils.showImage(output.outputFrame.image.getMat(), file.getName(), 1); - output.outputFrame.release(); + output.release(); + frame.release(); } } diff --git a/photon-core/src/test/java/org/photonvision/vision/pipeline/CirclePNPTest.java b/photon-core/src/test/java/org/photonvision/vision/pipeline/CirclePNPTest.java index d982ce508..528b13535 100644 --- a/photon-core/src/test/java/org/photonvision/vision/pipeline/CirclePNPTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/pipeline/CirclePNPTest.java @@ -19,7 +19,6 @@ package org.photonvision.vision.pipeline; import static org.junit.jupiter.api.Assertions.*; -import edu.wpi.first.wpilibj.geometry.Rotation2d; import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,9 +30,7 @@ import org.photonvision.vision.frame.provider.FileFrameProvider; import org.photonvision.vision.opencv.CVMat; import org.photonvision.vision.opencv.ContourGroupingMode; import org.photonvision.vision.opencv.ContourIntersectionDirection; -import org.photonvision.vision.opencv.ContourShape; import org.photonvision.vision.pipeline.result.CVPipelineResult; -import org.photonvision.vision.target.TargetModel; import org.photonvision.vision.target.TrackedTarget; public class CirclePNPTest { @@ -83,43 +80,46 @@ public class CirclePNPTest { assertEquals(5, cameraCalibration.getCameraExtrinsicsMat().cols()); } - @Test - public void testCircle() { - var pipeline = new ColoredShapePipeline(); - - pipeline.getSettings().hsvHue.set(0, 100); - pipeline.getSettings().hsvSaturation.set(100, 255); - pipeline.getSettings().hsvValue.set(100, 255); - pipeline.getSettings().outputShouldDraw = true; - pipeline.getSettings().maxCannyThresh = 50; - pipeline.getSettings().accuracy = 15; - pipeline.getSettings().allowableThreshold = 5; - pipeline.getSettings().solvePNPEnabled = true; - pipeline.getSettings().cornerDetectionAccuracyPercentage = 4; - pipeline.getSettings().cornerDetectionUseConvexHulls = true; - pipeline.getSettings().cameraCalibration = getCoeffs(LIFECAM_480P_CAL_FILE); - pipeline.getSettings().targetModel = TargetModel.kCircularPowerCell7in; - pipeline.getSettings().outputShouldDraw = true; - pipeline.getSettings().outputShowMultipleTargets = false; - pipeline.getSettings().contourGroupingMode = ContourGroupingMode.Single; - pipeline.getSettings().contourIntersection = ContourIntersectionDirection.Up; - pipeline.getSettings().desiredShape = ContourShape.Circle; - pipeline.getSettings().allowableThreshold = 10; - pipeline.getSettings().minRadius = 30; - pipeline.getSettings().accuracyPercentage = 30.0; - - var frameProvider = - new FileFrameProvider( - TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_6, false), - TestUtils.WPI2020Image.FOV, - new Rotation2d(), - TestUtils.get2020LifeCamCoeffs(true)); - - CVPipelineResult pipelineResult = pipeline.run(frameProvider.get(), QuirkyCamera.DefaultCamera); - printTestResults(pipelineResult); - - TestUtils.showImage(pipelineResult.outputFrame.image.getMat(), "Pipeline output", 999999); - } + // @Test + // public void testCircle() { + // var pipeline = new ColoredShapePipeline(); + // + // pipeline.getSettings().hsvHue.set(0, 100); + // pipeline.getSettings().hsvSaturation.set(100, 255); + // pipeline.getSettings().hsvValue.set(100, 255); + // pipeline.getSettings().outputShouldDraw = true; + // pipeline.getSettings().maxCannyThresh = 50; + // pipeline.getSettings().accuracy = 15; + // pipeline.getSettings().allowableThreshold = 5; + // pipeline.getSettings().solvePNPEnabled = true; + // pipeline.getSettings().cornerDetectionAccuracyPercentage = 4; + // pipeline.getSettings().cornerDetectionUseConvexHulls = true; + // pipeline.getSettings().cameraCalibration = getCoeffs(LIFECAM_480P_CAL_FILE); + // pipeline.getSettings().targetModel = TargetModel.kCircularPowerCell7in; + // pipeline.getSettings().outputShouldDraw = true; + // pipeline.getSettings().outputShowMultipleTargets = false; + // pipeline.getSettings().contourGroupingMode = ContourGroupingMode.Single; + // pipeline.getSettings().contourIntersection = ContourIntersectionDirection.Up; + // pipeline.getSettings().desiredShape = ContourShape.Circle; + // pipeline.getSettings().allowableThreshold = 10; + // pipeline.getSettings().minRadius = 30; + // pipeline.getSettings().accuracyPercentage = 30.0; + // + // var frameProvider = + // new FileFrameProvider( + // + // TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_6, false), + // TestUtils.WPI2020Image.FOV, + // new Rotation2d(), + // TestUtils.get2020LifeCamCoeffs(false)); + // + // CVPipelineResult pipelineResult = pipeline.run(frameProvider.get(), + // QuirkyCamera.DefaultCamera); + // printTestResults(pipelineResult); + // + // TestUtils.showImage(pipelineResult.outputFrame.image.getMat(), "Pipeline output", + // 999999); + // } private static void continuouslyRunPipeline(Frame frame, ReflectivePipelineSettings settings) { var pipeline = new ReflectivePipeline(); diff --git a/photon-core/src/test/java/org/photonvision/vision/pipeline/ColoredShapePipelineTest.java b/photon-core/src/test/java/org/photonvision/vision/pipeline/ColoredShapePipelineTest.java index 5576b4fed..c7a8ba2e6 100644 --- a/photon-core/src/test/java/org/photonvision/vision/pipeline/ColoredShapePipelineTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/pipeline/ColoredShapePipelineTest.java @@ -17,7 +17,6 @@ package org.photonvision.vision.pipeline; -import org.junit.jupiter.api.Test; import org.photonvision.common.util.TestUtils; import org.photonvision.vision.camera.QuirkyCamera; import org.photonvision.vision.frame.Frame; @@ -58,33 +57,36 @@ public class ColoredShapePipelineTest { printTestResults(colouredShapePipelineResult); } - @Test - public static void testCircleShapeDetection( - ColoredShapePipeline pipeline, ColoredShapePipelineSettings settings, Frame frame) { - settings.desiredShape = ContourShape.Circle; - pipeline.settings = settings; - CVPipelineResult colouredShapePipelineResult = pipeline.run(frame, QuirkyCamera.DefaultCamera); - TestUtils.showImage( - colouredShapePipelineResult.outputFrame.image.getMat(), "Pipeline output: Circle."); - printTestResults(colouredShapePipelineResult); - } - - @Test - public static void testPowercellDetection( - ColoredShapePipelineSettings settings, ColoredShapePipeline pipeline) { - - settings.hsvHue.set(10, 40); - settings.hsvSaturation.set(100, 255); - settings.hsvValue.set(100, 255); - settings.maxCannyThresh = 50; - settings.accuracy = 15; - settings.allowableThreshold = 5; - var frameProvider = - new FileFrameProvider( - TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_6, false), - TestUtils.WPI2019Image.FOV); - testCircleShapeDetection(pipeline, settings, frameProvider.get()); - } + // @Test + // public static void testCircleShapeDetection( + // ColoredShapePipeline pipeline, ColoredShapePipelineSettings settings, Frame frame) { + // settings.desiredShape = ContourShape.Circle; + // pipeline.settings = settings; + // CVPipelineResult colouredShapePipelineResult = pipeline.run(frame, + // QuirkyCamera.DefaultCamera); + // TestUtils.showImage( + // colouredShapePipelineResult.outputFrame.image.getMat(), "Pipeline output: + // Circle."); + // printTestResults(colouredShapePipelineResult); + // } + // + // @Test + // public static void testPowercellDetection( + // ColoredShapePipelineSettings settings, ColoredShapePipeline pipeline) { + // + // settings.hsvHue.set(10, 40); + // settings.hsvSaturation.set(100, 255); + // settings.hsvValue.set(100, 255); + // settings.maxCannyThresh = 50; + // settings.accuracy = 15; + // settings.allowableThreshold = 5; + // var frameProvider = + // new FileFrameProvider( + // + // TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_6, false), + // TestUtils.WPI2019Image.FOV); + // testCircleShapeDetection(pipeline, settings, frameProvider.get()); + // } public static void main(String[] args) { TestUtils.loadLibraries(); @@ -110,8 +112,8 @@ public class ColoredShapePipelineTest { testTriangleDetection(pipeline, settings, frameProvider.get()); testQuadrilateralDetection(pipeline, settings, frameProvider.get()); testCustomShapeDetection(pipeline, settings, frameProvider.get()); - testCircleShapeDetection(pipeline, settings, frameProvider.get()); - testPowercellDetection(settings, pipeline); + // testCircleShapeDetection(pipeline, settings, frameProvider.get()); + // testPowercellDetection(settings, pipeline); } private static void printTestResults(CVPipelineResult pipelineResult) { diff --git a/photon-lib/src/main/java/org/photonvision/SimVisionSystem.java b/photon-lib/src/main/java/org/photonvision/SimVisionSystem.java index 0eec84729..a8ff9c265 100644 --- a/photon-lib/src/main/java/org/photonvision/SimVisionSystem.java +++ b/photon-lib/src/main/java/org/photonvision/SimVisionSystem.java @@ -125,7 +125,6 @@ public class SimVisionSystem { * PhotonVision parameters. */ public void processFrame(Pose2d robotPoseMeters) { - Pose2d cameraPos = robotPoseMeters.transformBy(cameraToRobot.inverse()); ArrayList visibleTgtList = new ArrayList<>(tgtList.size()); diff --git a/photon-lib/src/test/java/org/photonvision/PhotonUtilTest.java b/photon-lib/src/test/java/org/photonvision/PhotonUtilTest.java index ebcc8626d..85e652c3a 100644 --- a/photon-lib/src/test/java/org/photonvision/PhotonUtilTest.java +++ b/photon-lib/src/test/java/org/photonvision/PhotonUtilTest.java @@ -49,7 +49,6 @@ class PhotonUtilTest { @Test public void testTransform() { - var camHeight = 1; var tgtHeight = 3; var camPitch = 0; diff --git a/photon-lib/src/test/java/org/photonvision/SimVisionSystemTest.java b/photon-lib/src/test/java/org/photonvision/SimVisionSystemTest.java index 600a2e7e4..520ebe731 100644 --- a/photon-lib/src/test/java/org/photonvision/SimVisionSystemTest.java +++ b/photon-lib/src/test/java/org/photonvision/SimVisionSystemTest.java @@ -53,7 +53,6 @@ class SimVisionSystemTest { @ParameterizedTest @ValueSource(doubles = {5, 10, 15, 20, 25, 30}) public void testDistanceAligned(double dist) { - final var targetPose = new Pose2d(new Translation2d(35, 0), new Rotation2d()); var sysUnderTest = new SimVisionSystem("Test", 80.0, 0.0, new Transform2d(), 1, 99999, 320, 240, 0); diff --git a/shared/common.gradle b/shared/common.gradle index f7047a7d2..3b06902bf 100644 --- a/shared/common.gradle +++ b/shared/common.gradle @@ -53,12 +53,14 @@ test { testLogging { events "passed", "skipped", "failed", "standardOut", "standardError" } + workingDir = new File("${rootDir}") } task testHeadless(type: Test) { group = "verification" systemProperty("java.awt.headless", "true") useJUnitPlatform() + exclude '**/*BenchmarkTest*' } task generateJavaDocs(type: Javadoc) { @@ -68,7 +70,7 @@ task generateJavaDocs(type: Javadoc) { } jacocoTestReport { - dependsOn test // Tests are required to run before generating the report +// dependsOn testHeadless // Tests are required to run before generating the report reports { xml.enabled true