-
Notifications
You must be signed in to change notification settings - Fork 71
[WIP] Test framework #539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
[WIP] Test framework #539
Conversation
.github/workflows/ci-test.yml
Outdated
| - name: Install JDK25 | ||
| uses: sfesenko/setup-sdkman@v1 | ||
| with: | ||
| deps: java:25-amzn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
25-zulu please :-)
.github/workflows/ci-test.yml
Dismissed
| name: Build Snapshot | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install dependencies | ||
| # run: sudo apt-get install --yes build-essential linux-headers-$(uname -r) sudo libi2c-dev gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu libtool tree | ||
| run: | | ||
| sudo apt-get remove --purge man-db | ||
| sudo apt-get install --yes build-essential linux-headers-$(uname -r) sudo libi2c-dev | ||
| - name: Install JDK25 | ||
| uses: sfesenko/setup-sdkman@v1 | ||
| with: | ||
| deps: java:25-zulu | ||
| - name: Create and add current user to suitable groups | ||
| run: | | ||
| sudo addgroup spi | ||
| sudo adduser $USER spi | ||
| sudo adduser $USER i2c | ||
| sudo adduser $USER dialout | ||
| sudo -u $USER bash -c 'groups' | ||
| - name: Add proper udev rules and trigger udevadm | ||
| run: | | ||
| sudo cp udev.rules /etc/udev/rules.d/99-pi4j-io.rules | ||
| sudo udevadm control --reload-rules && sudo udevadm trigger | ||
| - name: Build entire Pi4J Project | ||
| run: | | ||
| sudo -u $USER bash -c 'source ~/.sdkman/bin/sdkman-init.sh && ./mvnw clean install -Pnative,cross-compile --batch-mode' |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 months ago
To fix this issue, add an explicit permissions block to the workflow. The best way is to set it at the workflow root level (immediately after the name: line, before on: or jobs:), so that it applies to all jobs unless jobs set their own block. For most CI workflows, the minimal permission necessary is contents: read, which enables jobs to checkout code but prevents writes to repository contents, avoiding privilege escalation. Insert the block immediately after the workflow name: entry, in .github/workflows/ci-test.yml at line 2. No imports or external dependencies are needed.
-
Copy modified lines R2-R3
| @@ -1,4 +1,6 @@ | ||
| name: ci-test.yml | ||
| permissions: | ||
| contents: read | ||
| on: | ||
| push: | ||
| branches: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does Github want here?
|
Some other fixes to build process I have done:
|
165a84b to
1076c9c
Compare
1076c9c to
9c95c02
Compare
eitch
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few points
.github/workflows/ci-test.yml
Dismissed
| name: Build Snapshot | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install dependencies | ||
| # run: sudo apt-get install --yes build-essential linux-headers-$(uname -r) sudo libi2c-dev gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu libtool tree | ||
| run: | | ||
| sudo apt-get remove --purge man-db | ||
| sudo apt-get install --yes build-essential linux-headers-$(uname -r) sudo libi2c-dev | ||
| - name: Install JDK25 | ||
| uses: sfesenko/setup-sdkman@v1 | ||
| with: | ||
| deps: java:25-zulu | ||
| - name: Create and add current user to suitable groups | ||
| run: | | ||
| sudo addgroup spi | ||
| sudo adduser $USER spi | ||
| sudo adduser $USER i2c | ||
| sudo adduser $USER dialout | ||
| sudo -u $USER bash -c 'groups' | ||
| - name: Add proper udev rules and trigger udevadm | ||
| run: | | ||
| sudo cp udev.rules /etc/udev/rules.d/99-pi4j-io.rules | ||
| sudo udevadm control --reload-rules && sudo udevadm trigger | ||
| - name: Build entire Pi4J Project | ||
| run: | | ||
| sudo -u $USER bash -c 'source ~/.sdkman/bin/sdkman-init.sh && ./mvnw clean install -Pnative,cross-compile --batch-mode' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does Github want here?
| @Override | ||
| public int writeRegister(int register, byte b) { | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, new byte[]{(byte) register, b})); | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, new byte[]{(byte) register, b})) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put the -1 in a new statement, so it does not get ignored.
| buffer[0] = (byte) register; | ||
| System.arraycopy(data, 0, buffer, 1, data.length); | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, buffer)); | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, buffer)) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dito
| System.arraycopy(register, 0, buffer, 0, register.length); | ||
| System.arraycopy(data, 0, buffer, register.length, data.length); | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, buffer)); | ||
| return i2CBus.execute(this, (i2cFileDescriptor) -> FILE.write(i2cFileDescriptor, buffer)) - register.length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dito
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In these checks, isn't it counter intuitive, that the user requested SMBUS, but we don't use it if it isn't supported? Shouldn't we throw an exception?
Thus if the user requests a specific impl, then we should use that and throw exceptions if something isn't as expected.
| spi.read(buffer); | ||
| pi4j.shutdown(); | ||
| } | ||
| // @Benchmark |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dito
| @@ -0,0 +1,7 @@ | |||
| #!/bin/sh | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping we could remove building with make from pi4j down the line... is there no better solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have answered you somewhere else - this is needed for testing only, there will be no runtime dependencies and cross-compile builds. It is running during test phase, only in linux with kernel headers as a single dependency. Very primitive and as simple as possible.
Unfortunately there is no "mock driver pack" for each interface, most of existing mock drivers are not the default part of kernel (and in CI we have prebuild custom azure kernel). But I still think it is important to have integrity kernel tests to check changes we make.
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <!-- <dependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's just remove the dependency block all together
| <!-- PROJECT MODULES <Pi4J PLUGINS> --> | ||
| <modules> | ||
| <module>../pi4j-plugin-mock</module> | ||
| <!-- <module>../pi4j-plugin-mock</module> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all of these should be activated again?
| <modules> | ||
| <!-- THE FOLLOWING ARE THE Pi4J MODULES --> | ||
| <module>libraries/pi4j-library</module> | ||
| <!--<module>libraries/pi4j-library</module>--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dito
|
@eitch this PR is work in progress, I am cleaning up the code on my way with todo list. |
|
Well, yes, the PR is ok with me. |
# Conflicts: # plugins/pi4j-plugin-ffm/src/main/java/com/pi4j/plugin/ffm/providers/pwm/PwmFFMHardware.java # plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/ffm/integration/SPITest.java # plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/ffm/unit/PWMTest.java # plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/jmh/GPIOPerformanceTest.java # plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/jmh/SPIPerformanceTest.java
Pi4J testing framework for the win
Overview
Pi4J lacks proper tests within it's usage. Not only unit in core tests (which are good to test some basic logic), but provider unit, integration and performance tests. Moreover, new FFM API relies on the kernel, that is run within Linux OS. That's essentially means we have to keep an eye on what is changing in kernel driver/syscall development. To keep all this in place, I propose the following framework.
Unit tests
We need to use mock approach to test raw methods, that they works as expected (e.g. Mockito in FFM https://github.com/Pi4J/pi4j/tree/develop/plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/ffm/mocks).
Several layers of unit testing approach:
In this scope, we need to remove
pi4j-testmodule and move corresponding unit and integration tests to core.Todo
Model tests
Model tests are needed to make sure any interop structure are not broken.
Same should be applied to any other plugins we offer.
Todo
Integration tests
This tests should check if interop and syscalls are not broken. Main idea is to write simple mock (or echo) drivers for each provider and test syscalls. I have created some drivers FFM provider within this PR:
This drivers requires a simple build with
makeand current loaded kernel headers (I have provided comments with source files, though there are really very simple). We can think of expanding this tests to all recent stable linux kernels in future.Each driver is built and loaded with the test in java and removed upon test completion. This works in linux machines only, so a special annotation is used not to run them on other systems.
Todo
Performance tests
Since we are planning to expand the support from RaspberryPi only to every linux driven SBC, It is very possible, that pi4j will be used in high concurrent and/or highload environment. So we have to control and measure periodically how our changes affects the performance of interop and overall software responsiveness. I suggest to use the same approach as in integration testing - use simple echo/mock drivers to measure how fast the communication go. JMH tests for FFM provider are located here -> https://github.com/Pi4J/pi4j/tree/test-framework/plugins/pi4j-plugin-ffm/src/test/java/com/pi4j/plugin/jmh
They include:
We have to think on comparing ourselves to other / similar libraries.
Todo
Hardware Tests
TBD