CI: run fprime-examples integration tests in the examples workflow#197
CI: run fprime-examples integration tests in the examples workflow#197devin-ai-integration[bot] wants to merge 3 commits into
Conversation
Original prompt from thomas.boyer.chammard
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
75b9fe2 to
86208dc
Compare
| - name: "Install requirements.txt" | ||
| run: | | ||
| if [ -f "${{ inputs.build_location }}/requirements.txt" ]; then | ||
| (cd "${{ inputs.build_location }}" && pip3 install -r requirements.txt) | ||
| else | ||
| pip3 install -r ${FPRIME_LOCATION}/requirements.txt | ||
| fi | ||
| shell: bash |
There was a problem hiding this comment.
🔍 Integration job uses different requirements.txt installation logic than build and UT jobs
The integration job (reusable-project-builder.yml:199-204) has a unique requirements installation strategy: it first checks for ${{ inputs.build_location }}/requirements.txt and only falls back to the F´ submodule requirements if that file doesn't exist. The comment at line 196-197 explains this is to pick up GDS plugins (e.g. custom framing). The build job (line 99-100) and runUT job (line 143-144) always install from ${FPRIME_LOCATION}/requirements.txt. This behavioral difference is intentional but means the integration job could have a different Python environment than the build job — if the project-level requirements.txt doesn't include everything from the F´ requirements.txt, the integration build step could behave differently.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Intentional. The integration job needs the target project's GDS-side dependencies — specifically its custom fprime-gds plugins (e.g. the ExamplesDeployment decaf framing plugin in GdsExamples/gds-plugins) — which are only declared in the project's own requirements.txt, not in F´'s. The build/UT jobs only need FSW build deps, so they install F´'s requirements. When the project has no requirements.txt we fall back to F´'s requirements, preserving prior behavior for callers that don't need GDS plugins.
| integration_binary: ../build-artifacts/*/ExamplesDeployment/bin/ExamplesDeployment | ||
| integration_gds_args: "--dictionary ../build-artifacts/*/ExamplesDeployment/dict/ExamplesDeploymentTopologyDictionary.json" | ||
| integration_pytest_args: "DataProduct/test/int ManagerWorker/Subtopology/test/int --dictionary build-artifacts/*/ExamplesDeployment/dict/ExamplesDeploymentTopologyDictionary.json --no-zmq" |
There was a problem hiding this comment.
🔍 Shell glob patterns in binary and dictionary paths could match multiple entries
The integration_binary path (ext-build-examples-repo.yml:44) uses ../build-artifacts/*/ExamplesDeployment/bin/ExamplesDeployment with a shell glob *. The chmod +x step at reusable-project-builder.yml:228 runs this unquoted in bash, so the glob will expand. If build-artifacts/ contains exactly one platform directory (e.g. Linux), this works correctly. If multiple platform directories exist (unlikely in CI with a single target_platform), the chmod would apply to all matches (harmless), but the binary input passed to the run-integration-tests action would be a literal unexpanded string since GitHub Actions inputs are strings, not shell-expanded. The action would need to handle glob expansion internally for this to work.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
The globs are expanded by the shell inside nasa/fprime-actions/run-integration-tests, which uses $BINARY_PATH/$GDS_ARGS unquoted when launching the FSW binary and fprime-gds. In CI there's exactly one platform directory under build-artifacts/ (the single target_platform), so each glob resolves to a single path. Confirmed against the live run: the chmod +x step and the FSW launch both resolved the binary correctly. The * is used deliberately so the workflow is platform-agnostic (e.g. Linux vs Darwin) rather than hard-coding the artifact directory name.
Coverage report — base
|
| Module | Line | Function | Branch |
|---|---|---|---|
CFDP/Checksum |
71.15 | 57.14 | 53.85 |
Drv/AsyncByteStreamBufferAdapter |
100.00 | 100.00 | 100.00 |
Drv/ByteStreamBufferAdapter |
100.00 | 100.00 | 100.00 |
Drv/Ip |
45.12 | 57.38 | 27.17 |
Drv/TcpClient |
75.00 | 100.00 | 47.37 |
Drv/TcpServer |
84.72 | 100.00 | 60.00 |
Drv/Udp |
68.09 | 90.91 | 42.86 |
Fw/Buffer |
81.25 | 89.47 | 58.62 |
Fw/DataStructures |
98.48 | 97.14 | 83.21 |
Fw/Dp |
94.83 | 96.67 | 95.95 |
Fw/FilePacket |
75.24 | 89.06 | 54.30 |
Fw/Log |
86.96 | 100.00 | 68.18 |
Fw/Logger |
100.00 | 100.00 | 100.00 |
Fw/SerializableFile |
90.00 | 100.00 | 79.41 |
Fw/Time |
88.62 | 85.48 | 86.84 |
Fw/Tlm |
63.77 | 72.73 | 44.12 |
Fw/Types |
55.04 | 58.63 | 35.70 |
Os |
17.98 | 19.40 | 14.47 |
Os/Generic |
89.10 | 96.30 | 67.18 |
Os/Generic/Types |
92.45 | 91.67 | 82.14 |
Os/Posix |
62.40 | 84.21 | 44.10 |
Svc/ActiveRateGroup |
100.00 | 100.00 | 92.31 |
Svc/ActiveTextLogger |
79.05 | 90.00 | 71.23 |
Svc/AssertFatalAdapter |
94.74 | 100.00 | 86.67 |
Svc/BufferAccumulator |
88.16 | 94.12 | 74.75 |
Svc/BufferLogger |
92.76 | 86.96 | 81.32 |
Svc/BufferManager |
99.05 | 100.00 | 83.64 |
Svc/BufferRepeater |
91.67 | 100.00 | 75.00 |
Svc/ChronoTime |
100.00 | 100.00 | 100.00 |
Svc/CmdDispatcher |
96.97 | 91.67 | 91.75 |
Svc/CmdSequencer |
93.89 | 97.12 | 84.57 |
Svc/CmdSplitter |
100.00 | 100.00 | 100.00 |
Svc/ComLogger |
97.37 | 91.67 | 83.91 |
Svc/ComSplitter |
100.00 | 100.00 | 100.00 |
Svc/ComStub |
98.51 | 100.00 | 85.19 |
Svc/DpCatalog |
77.56 | 100.00 | 65.80 |
Svc/DpManager |
97.44 | 100.00 | 100.00 |
Svc/DpWriter |
97.58 | 90.00 | 97.22 |
Svc/FileDownlink |
84.15 | 90.91 | 71.90 |
Svc/FileManager |
88.41 | 93.33 | 82.44 |
Svc/FileUplink |
92.35 | 96.55 | 80.95 |
Svc/FileWorker |
90.29 | 100.00 | 84.87 |
Svc/FprimeDeframer |
100.00 | 100.00 | 97.92 |
Svc/FprimeFramer |
100.00 | 100.00 | 95.45 |
Svc/FprimeRouter |
88.89 | 100.00 | 78.26 |
Svc/FpySequencer |
86.76 | 99.04 | 76.85 |
Svc/GenericHub |
100.00 | 100.00 | 85.56 |
Svc/Health |
100.00 | 100.00 | 88.66 |
Svc/LinuxTimer |
97.06 | 100.00 | 82.35 |
Svc/OsTime |
70.00 | 83.33 | 60.98 |
Svc/PassiveRateGroup |
100.00 | 100.00 | 89.47 |
Svc/PolyDb |
100.00 | 100.00 | 53.57 |
Svc/PosixTime |
100.00 | 100.00 | 75.00 |
Svc/PrmDb |
92.75 | 89.47 | 88.11 |
Svc/RateGroupDriver |
100.00 | 100.00 | 68.75 |
Svc/SeqDispatcher |
73.08 | 80.00 | 71.05 |
Svc/StaticMemory |
100.00 | 100.00 | 100.00 |
Svc/SystemResources |
98.63 | 100.00 | 76.19 |
Svc/TlmChan |
77.59 | 85.71 | 63.03 |
Svc/TlmPacketizer |
92.18 | 100.00 | 77.08 |
Svc/Version |
96.10 | 100.00 | 86.96 |
Utils |
20.04 | 26.44 | 24.07 |
Utils/Types |
92.11 | 95.83 | 77.08 |
Modules without UTs
CFDP/Checksum/GTest, Drv/ByteStreamDriverModel, Drv/Interfaces, Drv/LinuxGpioDriver, Drv/LinuxI2cDriver, Drv/LinuxSpiDriver, Drv/LinuxUartDriver, Drv/Ports, Drv/Ports/DataTypes, FppTestProject/FppTest/interfaces, FppTestProject/FppTest/topology/async, FppTestProject/FppTest/topology/components/Comp, FppTestProject/FppTest/topology/components/Framework, FppTestProject/FppTest/topology/components/Receiver, FppTestProject/FppTest/topology/components/Sender, FppTestProject/FppTest/topology/guarded, FppTestProject/FppTest/topology/ports, FppTestProject/FppTest/topology/sync, FppTestProject/FppTest/topology/top_ports, FppTestProject/FppTest/topology/types, Fw/Cmd, Fw/Com, Fw/Comp, Fw/FilePacket/GTest, Fw/Fpy, Fw/Interfaces, Fw/Obj, Fw/Port, Fw/Ports/CompletionStatus, Fw/Ports/Ready, Fw/Ports/Signal, Fw/Ports/SuccessCondition, Fw/Prm, Fw/SerializableFile/test/TestSerializable, Fw/Sm, Fw/Test, Fw/Types/GTest, Os/Models, Svc/Cycle, Svc/DpPorts, Svc/Fatal, Svc/FatalHandler, Svc/FileDownlinkPorts, Svc/FprimeProtocol, Svc/Interfaces, Svc/PassiveConsoleTextLogger, Svc/Ping, Svc/PolyIf, Svc/Ports/CommsPorts, Svc/Ports/FilePorts, Svc/Ports/OsTimeEpoch, Svc/Ports/TlmPacketizerPorts, Svc/Ports/VersionPorts, Svc/Sched, Svc/Seq, Svc/Subtopologies/CdhCore, Svc/Subtopologies/ComCcsds, Svc/Subtopologies/ComFprime, Svc/Subtopologies/ComLoggerTee, Svc/Subtopologies/DataProducts, Svc/Subtopologies/FileHandling, Svc/Types/TlmPacketizerTypes, Svc/WatchDog, TestDeploymentsProject/Ref/PingReceiver, TestDeploymentsProject/Ref/RecvBuffApp, TestDeploymentsProject/Ref/SendBuffApp, TestDeploymentsProject/Ref/Top, TestDeploymentsProject/Ref/TypeDemo, cmake/test/data/TestDeployment/TestBuildAutocoder, cmake/test/data/TestDeployment/TestChainedAutocoder, cmake/test/data/TestDeployment/TestHeaderAutocoder, cmake/test/data/TestDeployment/TestTargetAutocoder, cmake/test/data/test-fprime-library/TestLibrary/TestComponent, cmake/test/data/test-fprime-library2/TestLibrary2/TestComponent
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
| integration_binary_args: | ||
| description: "Arguments passed to the FSW binary." | ||
| required: false | ||
| type: string | ||
| default: "-a 127.0.0.1 -p 50000" |
There was a problem hiding this comment.
🔍 Default binary-args may override the action's own default behavior
The integration_binary_args input defaults to -a 127.0.0.1 -p 50000 and is always passed through to the run-integration-tests action as binary-args. In ref.yml:110-118, the same action is called without any binary-args parameter, relying on the action's own default. If the action's default differs from -a 127.0.0.1 -p 50000, callers of this reusable workflow that don't explicitly set integration_binary_args will get different behavior than the Ref deployment's integration tests. This should be verified against the nasa/fprime-actions/run-integration-tests action's action.yml.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Verified against run-integration-tests/action.yml: its binary-args default is -a 127.0.0.1 -p 50000 — identical to this input's default, so there's no behavioral difference from ref.yml (which relies on that same action default). I kept an explicit default here rather than an empty string because the reusable workflow always forwards binary-args, and forwarding "" would override (blank out) the action's default rather than fall back to it.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Change Description
Integration tests were not being exercised for
nasa/fprime-examplesin F´ CI — theext-build-examples-repo.ymlworkflow only ran build + unit tests. This adds the ability to run integration tests (InTs) and turns them on for fprime-examples.reusable-project-builder.yml: new optionalrunIntegrationjob, gated on a newrun_integration_testsinput (defaultfalse, so the other callers — hello-world, math-comp, led-blinker — are unaffected). The job checks out the target repo, overlays the current F´ revision, installs requirements, upgradesfprime-gdsto the in-development branch, builds the deployment, makes the FSW binary executable, then delegates tonasa/fprime-actions/run-integration-tests@devel(same action used byref.yml). New passthrough inputs parametrize it per-deployment:integration_gds_working_directory,integration_test_working_directory,integration_binary,integration_binary_args,integration_gds_args,integration_pytest_args<build_location>/requirements.txtwhen present (rather than only the F´ submodule's) so the target project's GDS plugins are available tofprime-gds— fprime-examples ships a decaf custom-framing plugin inGdsExamples/gds-pluginsthat the GDS needs to talk to the deployment. It first upgradespip/setuptools/wheel, because the runner's stock build tooling builds that local plugin as a brokenUNKNOWN-0.0.0wheel with no entry points (the plugin'spyproject.tomlusesdynamic = ["version"]with thesetuptools_scmtable disabled), which silently drops thedecafframing plugin and makesfprime-gdsfail with--framing-selection: invalid choice: 'decaf'.nasa/fprime-actions/upgrade-package@devel,repository: nasa/fprime-gds) matchesref.yml/reusable-project-ci.ymlso the examples InTs run against this PR's in-development GDS and catch GDS regressions.ext-build-examples-repo.yml: opts in withrun_integration_tests: trueand points the InTs atExamplesDeployment:fprime-gdsis started from the deployment dir so it picks upfprime-gds.yml(decaf framing,no-zmq); pytest is given explicit test dirs because a barepytestfromFlightExamplesrecurses intolib/and hangs.This pairs with a fprime-examples PR that adds a
DataProductcompression integration test (DataProduct/test/int/test_dp_compression.py) exercising theDpCompressionsubtopology.Rationale
Give the examples repo real integration-test coverage in CI (commanding + telemetry/event verification against a running deployment), not just build + UTs.
Testing/Review Recommendations
Verified locally (all 5 InTs pass:
DataProductcompression + 4ManagerWorker) and in CI. The CIrun / Integration Testsjob now: builds the plugin correctly (no moreUNKNOWNwheel), upgrades GDS to the in-developmentfprime-gds(log showsfprime-gds-4.2.2a2.devNN+g…), starts GDS with decaf framing and the FSW binary successfully, then runs pytest.Note on cross-repo dependency: the job checks out
nasa/fprime-examples@devel, which does not yet containDataProduct/test/int(added in the paired fprime-examples PR), so pytest currently fails withfile or directory not found: DataProduct/test/int. This will go green once the fprime-examples changes are onnasa/fprime-examples/devel(or co-developed via a matching branch name, whichget-pr-branchresolves). Please sanity-check the glob paths and thatrun-integration-tests@develinputs match its current interface.Future Work
Consider a matrix (e.g. macOS) once Linux InTs are stable.
AI Usage (see policy)
Used for code generation (workflow edits), CI debugging, and local + CI verification of the integration-test invocation.
IAMAI
Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/51e2b5a0a13340d6b2db328c7c6c36e8