Update test runner
Build Dusk / build-linux (push) Successful in 5m36s
Build Dusk / build-psp (push) Successful in 1m15s
Build Dusk / build-knulli (push) Successful in 4m53s
Build Dusk / build-gamecube (push) Successful in 3m51s
Build Dusk / build-gamecube-iso (push) Successful in 3m52s
Build Dusk / build-wii (push) Successful in 3m17s
Build Dusk / build-wii-iso (push) Successful in 4m54s

This commit is contained in:
2026-07-02 19:20:17 -05:00
parent b4cdc4a64f
commit afc68bccc6
4 changed files with 59 additions and 56 deletions
-30
View File
@@ -4,36 +4,6 @@ on:
tags: tags:
- '*' - '*'
jobs: jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
python3 \
python3-pip \
python3-polib \
python3-pil \
libsdl2-dev \
libgl1-mesa-dev \
libzip-dev \
python3-dotenv \
python3-pyqt5 \
python3-opengl \
xz-utils \
liblzma-dev \
libbz2-dev \
zlib1g-dev \
git \
libssl-dev
- name: Run tests
run: ./scripts/test-linux.sh
build-linux: build-linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
+35
View File
@@ -0,0 +1,35 @@
name: Test Dusk
on:
pull_request:
branches:
- main
jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
python3 \
python3-pip \
python3-polib \
python3-pil \
libsdl2-dev \
libgl1-mesa-dev \
libzip-dev \
python3-dotenv \
python3-pyqt5 \
python3-opengl \
xz-utils \
liblzma-dev \
libbz2-dev \
zlib1g-dev \
git \
libssl-dev
- name: Run tests
run: ./scripts/test-linux.sh
@@ -506,6 +506,10 @@ errorret_t assetLocaleGetString(
sizeof(lineBuffer) sizeof(lineBuffer)
); );
// Prime the reader with the first line before scanning; outBuffer holds
// uninitialized memory until the first Next() call fills it.
errorChain(assetFileLineReaderNext(&reader));
// Skip blanks, comments, etc and start looking for msgid's // Skip blanks, comments, etc and start looking for msgid's
errorChain(assetLocaleLineSkipBlanks(&reader, lineBuffer)); errorChain(assetLocaleLineSkipBlanks(&reader, lineBuffer));
+20 -26
View File
@@ -133,21 +133,22 @@ static void test_update_entry_reaches_loaded(void **state) {
assert_int_equal(memoryGetAllocatedCount(), 0); assert_int_equal(memoryGetAllocatedCount(), 0);
} }
static void test_update_slot_occupied_after_first_update(void **state) { static void test_update_slot_cleared_after_first_update(void **state) {
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL); assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
assetEntryLock(entry); assetEntryLock(entry);
assetUpdate(); assetUpdate();
assert_int_equal(entry->state, ASSET_ENTRY_STATE_LOADED); assert_int_equal(entry->state, ASSET_ENTRY_STATE_LOADED);
// Slot not cleared until the second update processes the LOADED case. // A synchronous load clears its own loading slot in the same update call
assert_true(loading_slot_has_entry(entry)); // that completes it, so no second update is needed to free it.
assert_false(loading_slot_has_entry(entry));
assetEntryUnlock(entry); assetEntryUnlock(entry);
assert_int_equal(memoryGetAllocatedCount(), 0); assert_int_equal(memoryGetAllocatedCount(), 0);
} }
static void test_update_slot_cleared_after_second_update(void **state) { static void test_update_slot_stays_cleared_on_further_updates(void **state) {
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL); assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
assetEntryLock(entry); assetEntryLock(entry);
@@ -238,13 +239,17 @@ static void test_update_overflow_queues_entries(void **state) {
entries[i] = assetGetEntry(name, ASSET_LOADER_TYPE_LOCALE, NULL); entries[i] = assetGetEntry(name, ASSET_LOADER_TYPE_LOCALE, NULL);
} }
// Lock first batch so the reaper won't collect them before we check. // Lock every entry, including the overflow one, so the reaper won't
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) { // collect any of them - a synchronous load can reach LOADED and free its
// slot within the same update call the reaper runs in.
for(int i = 0; i < TOTAL; i++) {
assetEntryLock(entries[i]); assetEntryLock(entries[i]);
} }
// Update 1: fills all slots, first ASSET_LOADING_COUNT_MAX entries reach LOADED. // Update 1: fills all slots, first ASSET_LOADING_COUNT_MAX entries reach
// The overflow entry has no slot yet and stays NOT_STARTED. // LOADED and immediately free their slots. The overflow entry has no slot
// yet because dispatch ran before this update's turn began, so it stays
// NOT_STARTED.
errorret_t ret = assetUpdate(); errorret_t ret = assetUpdate();
assert_true(errorIsOk(ret)); assert_true(errorIsOk(ret));
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) { for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
@@ -252,26 +257,15 @@ static void test_update_overflow_queues_entries(void **state) {
} }
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED); assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED);
// Unlock first batch - the reaper can collect them in update 2. // Update 2: the slots freed during update 1 are now available, so the
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) { // overflow entry is dispatched and loaded in this pass.
assetEntryUnlock(entries[i]);
}
// Update 2: LOADED slots are freed. Overflow entry still NOT_STARTED because
// the dispatch phase ran before the slots were cleared this turn.
ret = assetUpdate();
assert_true(errorIsOk(ret));
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED);
// Lock overflow entry so it stays LOADED after update 3.
assetEntryLock(entries[ASSET_LOADING_COUNT_MAX]);
// Update 3: now a slot is available; the overflow entry is dispatched and loaded.
ret = assetUpdate(); ret = assetUpdate();
assert_true(errorIsOk(ret)); assert_true(errorIsOk(ret));
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_LOADED); assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_LOADED);
assetEntryUnlock(entries[ASSET_LOADING_COUNT_MAX]); for(int i = 0; i < TOTAL; i++) {
assetEntryUnlock(entries[i]);
}
assert_int_equal(memoryGetAllocatedCount(), 0); assert_int_equal(memoryGetAllocatedCount(), 0);
} }
@@ -492,8 +486,8 @@ int main(void) {
// assetUpdate - state machine // assetUpdate - state machine
cmocka_unit_test_setup_teardown(test_update_noop_on_empty_table, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_noop_on_empty_table, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_entry_reaches_loaded, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_entry_reaches_loaded, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_slot_occupied_after_first_update, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_slot_cleared_after_first_update, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_slot_cleared_after_second_update, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_slot_stays_cleared_on_further_updates, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_four_slots_fill_independently, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_four_slots_fill_independently, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_loaded_entry_not_redispatched, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_loaded_entry_not_redispatched, asset_setup, asset_teardown),
cmocka_unit_test_setup_teardown(test_update_overflow_queues_entries, asset_setup, asset_teardown), cmocka_unit_test_setup_teardown(test_update_overflow_queues_entries, asset_setup, asset_teardown),