-
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7b70aaf
commit 0074084
Showing
16 changed files
with
469 additions
and
279 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
name: Test | ||
on: [push] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/cache@v4 | ||
with: | ||
path: | | ||
~/.cache/pip | ||
~/.platformio/.cache | ||
key: ${{ runner.os }}-pio | ||
- name: Install dependencies | ||
run: sudo apt-get update && sudo apt-get install -y libsdl2-2.0-0 | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.12' | ||
- name: Install PlatformIO Core | ||
run: pip install --upgrade platformio | ||
- name: Set up QEMU | ||
id: setup-qemu | ||
run: | | ||
if [[ "$(uname -m)" == "x86_64" ]]; then | ||
QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-linux-gnu.tar.xz" | ||
elif [[ "$(uname -m)" == "aarch64" ]]; then | ||
QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-aarch64-linux-gnu.tar.xz" | ||
else | ||
echo "Unsupported architecture: $(uname -m)" | ||
exit 1 | ||
fi | ||
wget $QEMU_URL -O qemu.tar.xz | ||
mkdir -p qemu | ||
tar -xf qemu.tar.xz -C qemu --strip-components=1 | ||
sudo mv qemu /usr/local/qemu | ||
- name: Add QEMU to PATH | ||
run: echo "/usr/local/qemu/bin" >> $GITHUB_PATH | ||
|
||
- name: Run unit tests | ||
run: pio test --without-uploading --project-conf=platformio-test.ini | ||
|
||
static-analysis: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/cache@v4 | ||
with: | ||
path: | | ||
~/.cache/pip | ||
~/.platformio/.cache | ||
key: ${{ runner.os }}-pio | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.12' | ||
|
||
- name: Install PlatformIO Core | ||
run: pip install --upgrade platformio | ||
|
||
- name: Run static analysis | ||
run: pio check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#!/usr/bin/python3 | ||
|
||
# Adds PlatformIO post-processing to merge all the ESP flash images into a single image. | ||
|
||
import os | ||
|
||
Import("env", "projenv") | ||
|
||
board_config = env.BoardConfig() | ||
firmware_bin = "${BUILD_DIR}/${PROGNAME}.bin" | ||
merged_bin = os.environ.get("MERGED_BIN_PATH", "${BUILD_DIR}/${PROGNAME}-merged.bin") | ||
|
||
|
||
def merge_bin_action(source, target, env): | ||
flash_images = [ | ||
*env.Flatten(env.get("FLASH_EXTRA_IMAGES", [])), | ||
"$ESP32_APP_OFFSET", | ||
source[0].get_abspath(), | ||
] | ||
merge_cmd = " ".join( | ||
[ | ||
'"$PYTHONEXE"', | ||
'"$OBJCOPY"', | ||
"--chip", | ||
board_config.get("build.mcu", "esp32"), | ||
"merge_bin", | ||
"-o", | ||
merged_bin, | ||
"--flash_mode", | ||
board_config.get("build.flash_mode", "dio"), | ||
"--flash_freq", | ||
"${__get_board_f_flash(__env__)}", | ||
"--flash_size", | ||
board_config.get("upload.flash_size", "4MB"), | ||
"--fill-flash-size", | ||
board_config.get("upload.flash_size", "4MB"), | ||
*flash_images, | ||
] | ||
) | ||
env.Execute(merge_cmd) | ||
|
||
|
||
env.AddPostAction("buildprog", merge_bin_action) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[env:esp32dev] | ||
platform = espressif32 | ||
framework = arduino | ||
board = esp32dev | ||
extra_scripts = post:merge-bin.py | ||
|
||
lib_deps = | ||
davetcc/IoAbstraction@^4.0.2 | ||
TaskManagerIO | ||
|
||
test_testing_command = | ||
qemu-system-xtensa | ||
-nographic | ||
-machine | ||
esp32 | ||
-drive | ||
file=${platformio.build_dir}/${this.__env__}/firmware-merged.bin,if=mtd,format=raw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
tests/taskMgrTests/avrClockRollTests.cpp → test/avrClockRollTests/avrClockRollTests.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
|
||
// Note: AVR test. Not supported in CI/CD. | ||
#ifdef __AVR__ | ||
|
||
#include <testing/SimpleTest.h> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
#include <Arduino.h> | ||
#include <unity.h> | ||
#include <ExecWithParameter.h> | ||
#include <IoLogging.h> | ||
#include "TaskManagerIO.h" | ||
#include "../utils/test_utils.h" | ||
|
||
TimingHelpFixture fixture; | ||
|
||
void setUp() { | ||
fixture.setup(); | ||
} | ||
|
||
void tearDown() {} | ||
|
||
// these variables are set during test runs to time and verify tasks are run. | ||
bool scheduled = false; | ||
bool scheduled2ndJob = false; | ||
unsigned long microsStarted = 0, microsExecuted = 0, microsExecuted2ndJob = 0; | ||
int count1 = 0, count2 = 0; | ||
uint8_t pinNo = 0; | ||
|
||
void recordingJob() { | ||
microsExecuted = micros(); | ||
count1++; | ||
scheduled = true; | ||
} | ||
|
||
void recordingJob2() { | ||
microsExecuted2ndJob = micros(); | ||
count2++; | ||
scheduled2ndJob = true; | ||
} | ||
|
||
|
||
class TestingExec : public Executable { | ||
public: | ||
int noOfTimesRun; | ||
|
||
TestingExec() { | ||
noOfTimesRun = 0; | ||
} | ||
|
||
void exec() override { | ||
noOfTimesRun++; | ||
} | ||
}; | ||
|
||
TestingExec exec; | ||
|
||
void testRunningUsingExecutorClass() { | ||
taskManager.scheduleFixedRate(10, &::exec); | ||
taskManager.scheduleOnce(250, recordingJob); | ||
|
||
fixture.assertThatTaskRunsOnTime(250000L, MILLIS_ALLOWANCE); | ||
TEST_ASSERT_GREATER_THAN(10, ::exec.noOfTimesRun); | ||
} | ||
|
||
void testSchedulingTaskOnceInMicroseconds() { | ||
taskManager.scheduleOnce(800, recordingJob, TIME_MICROS); | ||
fixture.assertThatTaskRunsOnTime(800, MICROS_ALLOWANCE); | ||
fixture.assertTasksSpacesTaken(0); | ||
} | ||
|
||
void testSchedulingTaskOnceInMilliseconds() { | ||
taskManager.scheduleOnce(20, recordingJob, TIME_MILLIS); | ||
fixture.assertThatTaskRunsOnTime(19500, MILLIS_ALLOWANCE); | ||
fixture.assertTasksSpacesTaken(0); | ||
} | ||
|
||
void testSchedulingTaskOnceInSeconds() { | ||
taskManager.scheduleOnce(2, recordingJob, TIME_SECONDS); | ||
// Second scheduling is not as granular, we need to allow +- 100mS. | ||
fixture.assertThatTaskRunsOnTime(2000000L, MILLIS_ALLOWANCE); | ||
fixture.assertTasksSpacesTaken(0); | ||
} | ||
|
||
void testScheduleManyJobsAtOnce() { | ||
taskManager.scheduleOnce(1, [] {}, TIME_SECONDS); | ||
taskManager.scheduleOnce(200, recordingJob, TIME_MILLIS); | ||
taskManager.scheduleOnce(250, recordingJob2, TIME_MICROS); | ||
|
||
fixture.assertThatTaskRunsOnTime(199500, MILLIS_ALLOWANCE); | ||
fixture.assertThatSecondJobRan(250, MICROS_ALLOWANCE); | ||
fixture.assertTasksSpacesTaken(1); | ||
} | ||
|
||
void testEnableAndDisableSupport() { | ||
static int myTaskCounter = 0; | ||
auto myTaskId = taskManager.scheduleFixedRate(1, [] { myTaskCounter++; }, TIME_MILLIS); | ||
taskManager.yieldForMicros(20000); | ||
TEST_ASSERT_NOT_EQUAL(0, myTaskCounter); | ||
|
||
// "turn off" the task | ||
taskManager.setTaskEnabled(myTaskId, false); | ||
|
||
// It can take one cycle for the task to switch enablement state. | ||
taskManager.yieldForMicros(2000); | ||
auto oldTaskCount = myTaskCounter; | ||
|
||
// Now run the task for some time, it should never get scheduled. | ||
taskManager.yieldForMicros(20000); | ||
TEST_ASSERT_EQUAL(myTaskCounter, oldTaskCount); | ||
|
||
// "turn on" the task and see if it increases again | ||
taskManager.setTaskEnabled(myTaskId, true); | ||
taskManager.yieldForMicros(20000); | ||
TEST_ASSERT_NOT_EQUAL(myTaskCounter, oldTaskCount); | ||
} | ||
|
||
void testScheduleFixedRate() { | ||
TEST_ASSERT_EQUAL(nullptr, taskManager.getFirstTask()); | ||
|
||
auto taskId1 = taskManager.scheduleFixedRate(10, recordingJob, TIME_MILLIS); | ||
auto taskId2 = taskManager.scheduleFixedRate(100, recordingJob2, TIME_MICROS); | ||
|
||
// Now check the task registration in detail. | ||
TEST_ASSERT_NOT_EQUAL(TASKMGR_INVALIDID, taskId1); | ||
TimerTask* task = taskManager.getFirstTask(); | ||
TEST_ASSERT_NOT_EQUAL(nullptr, task); | ||
TEST_ASSERT_FALSE(task->isMillisSchedule()); | ||
TEST_ASSERT_TRUE(task->isMicrosSchedule()); | ||
|
||
// Now check the task registration in detail. | ||
TEST_ASSERT_NOT_EQUAL(TASKMGR_INVALIDID, taskId2); | ||
task = task->getNext(); | ||
TEST_ASSERT_NOT_EQUAL(nullptr, task); | ||
TEST_ASSERT_TRUE(task->isMillisSchedule()); | ||
TEST_ASSERT_FALSE(task->isMicrosSchedule()); | ||
|
||
dumpTasks(); | ||
|
||
uint32_t timeStartYield = millis(); | ||
taskManager.yieldForMicros(secondsToMillis(22)); | ||
uint32_t timeTaken = millis() - timeStartYield; | ||
|
||
dumpTasks(); | ||
|
||
// Make sure the yield timings were in range. | ||
TEST_ASSERT_LESS_THAN(25U, timeTaken); | ||
TEST_ASSERT_GREATER_THAN(19U, timeTaken); | ||
|
||
// Now make sure that we got in the right ballpark of calls. | ||
TEST_ASSERT_GREATER_THAN(1, count1); | ||
TEST_ASSERT_GREATER_THAN(150, count2); | ||
} | ||
|
||
void testCancellingAJobAfterCreation() { | ||
TEST_ASSERT_EQUAL(nullptr, taskManager.getFirstTask()); | ||
|
||
auto taskId = taskManager.scheduleFixedRate(10, recordingJob, TIME_MILLIS); | ||
|
||
// Now check the task registration in detail. | ||
TEST_ASSERT_NOT_EQUAL(TASKMGR_INVALIDID, taskId); | ||
TimerTask* task = taskManager.getFirstTask(); | ||
TEST_ASSERT_NOT_EQUAL(nullptr, task); | ||
TEST_ASSERT_TRUE(task->isMillisSchedule()); | ||
TEST_ASSERT_FALSE(task->isMicrosSchedule()); | ||
TEST_ASSERT_GREATER_THAN(8000UL, task->microsFromNow()); | ||
|
||
fixture.assertThatTaskRunsOnTime(10000, MILLIS_ALLOWANCE); | ||
|
||
// Cancel the task and make sure everything is cleared down | ||
fixture.assertTasksSpacesTaken(1); | ||
taskManager.cancelTask(taskId); | ||
taskManager.yieldForMicros(100); // Needs to run the cancellation task. | ||
fixture.assertTasksSpacesTaken(0); | ||
|
||
TEST_ASSERT_EQUAL(nullptr, taskManager.getFirstTask()); | ||
} | ||
|
||
void setup() { | ||
UNITY_BEGIN(); | ||
RUN_TEST(testRunningUsingExecutorClass); | ||
RUN_TEST(testSchedulingTaskOnceInMicroseconds); | ||
RUN_TEST(testSchedulingTaskOnceInMilliseconds); | ||
RUN_TEST(testSchedulingTaskOnceInSeconds); | ||
RUN_TEST(testScheduleManyJobsAtOnce); | ||
RUN_TEST(testEnableAndDisableSupport); | ||
RUN_TEST(testScheduleFixedRate); | ||
RUN_TEST(testCancellingAJobAfterCreation); | ||
UNITY_END(); | ||
} | ||
|
||
void loop() {} |
Oops, something went wrong.