From 613eb07f3ac4a23d4f0af57df17ffe4a6712ddd2 Mon Sep 17 00:00:00 2001 From: Niall Mullane Date: Wed, 14 Jul 2021 10:10:55 -0400 Subject: [PATCH] Fix #289, Add RTEMS build and test workflows Add two workflows for building and testing cFS in both RTEMS 4.11 and 5 Add scripts folder into .github for running all unit tests inside QEMU Use dockerhub to store docker image containing all QEMU and RTEMS toolchain and dependencies Address PR comments by jphickey: Remove monitoring of stdout by correctly using batch-mode option Correctly use make SIMULATION variable instead of manually modifying targets.cmake during the actions workflow. Address PR comments by zanzaben: Remove forgotten targets.cmake target system Use makefile to run qemu tests and create qemu disk images instead of shell scripts Use wildcard matching to find and run all unit tests. Skip network tests that fail with the SKIP_NET_TESTS flag. Clean .mk scripts, ignore failing network tests Run network tests to see github failure behavior Remove from output failed tests step Update Workflow README --- .github/scripts/common-test.mk | 54 +++++++++ .github/scripts/rtems-test.mk | 63 +++++++++++ .github/workflows/README.md | 8 ++ .github/workflows/build-cfs-rtems4.11.yml | 127 ++++++++++++++++++++++ .github/workflows/build-cfs-rtems5.yml | 125 +++++++++++++++++++++ 5 files changed, 377 insertions(+) create mode 100644 .github/scripts/common-test.mk create mode 100644 .github/scripts/rtems-test.mk create mode 100644 .github/workflows/build-cfs-rtems4.11.yml create mode 100644 .github/workflows/build-cfs-rtems5.yml diff --git a/.github/scripts/common-test.mk b/.github/scripts/common-test.mk new file mode 100644 index 000000000..e96313ce0 --- /dev/null +++ b/.github/scripts/common-test.mk @@ -0,0 +1,54 @@ +CPUNAME ?= cpu1 +INSTALL_DIR ?= $(O)/exe + +ALL_TESTRUNNER_EXES := $(shell ls $(INSTALL_DIR)/$(CPUNAME)/*testrunner.exe) +ALL_UT_EXES := $(shell ls $(INSTALL_DIR)/$(CPUNAME)/*UT.exe) +ALL_FUNC_TEST_EXES := $(shell ls $(INSTALL_DIR)/$(CPUNAME)/*test.exe) + +# These functional tests require a network stack, +# so they can be skipped on platforms that may not have network +ifeq ($(SKIP_NET_TESTS), true) + SKIP_FUNC_TEST := \ + $(INSTALL_DIR)/$(CPUNAME)/network-api-test.exe \ + $(INSTALL_DIR)/$(CPUNAME)/select-test.exe + ALL_FUNC_TEST_EXES := $(filter-out $(SKIP_FUNC_TEST),$(ALL_FUNC_TEST_EXES)) +endif + +ALL_TESTRUNNER_TEST_LIST := $(basename $(ALL_TESTRUNNER_EXES)) +ALL_UT_TEST_LIST := $(basename $(ALL_UT_EXES)) +ALL_FUNC_TEST_LIST := $(basename $(ALL_FUNC_TEST_EXES)) + + +ALL_TEST_LIST := \ + $(ALL_TESTRUNNER_TEST_LIST) \ + $(ALL_UT_TEST_LIST) \ + $(ALL_FUNC_TEST_LIST) \ + +.PHONY: clean_logs \ + all_tests \ + all_logs \ + all_checks \ + all_testrunner_logs \ + all_ut_logs \ + all_func_test_logs \ + +clean_logs: + rm -f $(addsuffix .check,$(ALL_TEST_LIST)) \ + $(addsuffix .log,$(ALL_TEST_LIST)) + rm -f $(INSTALL_DIR)/$(CPUNAME)/failed-tests.log + +# run all tests without checking success +all_logs: $(addsuffix .log,$(ALL_TEST_LIST)) +# run all tests and check success +all_checks: $(addsuffix .check,$(ALL_TEST_LIST)) + +# run just tests with suffix *testrunner.exe +all_testrunner_logs: $(addsuffix .log,$(ALL_TESTRUNNER_TEST_LIST)) +# run just tests with suffix *UT.exe +all_ut_logs: $(addsuffix .log,$(ALL_UT_TEST_LIST)) +# run just tests with suffix *test.exe +all_func_test_logs: $(addsuffix .log,$(ALL_FUNC_TEST_LIST)) + +all_tests: all_checks + @echo '*** SUCCESS ***' + diff --git a/.github/scripts/rtems-test.mk b/.github/scripts/rtems-test.mk new file mode 100644 index 000000000..1fe1d5783 --- /dev/null +++ b/.github/scripts/rtems-test.mk @@ -0,0 +1,63 @@ +SKIP_NET_TESTS := true + +# At a minimum the variable O must be set by the caller +ifeq ($(O),) +$(error O must be set prior to native-test.mk) +endif + +CFE_IMG_MB ?= 32 +CFE_DISK_IMG ?= $(INSTALL_DIR)/$(CPUNAME)/nonvol-disk.img +CFE_FS_IMG ?= $(INSTALL_DIR)/$(CPUNAME)/nonvol-fs.img +QEMU_COMMAND ?= qemu-system-i386 -m 128 +MACADDR = 00:04:9F$(shell head -c 3 /dev/urandom | hexdump -v -e '/1 ":%02X"') +RTEMS_VERSION ?= i686-rtems5 + +# default rule to just create qemu disk image +all: cfe-disk + +# include list of all unit tests to run +include .github/scripts/common-test.mk + +.PHONY: run cfe-disk +.SECONDARY: $(addsuffix .log,$(ALL_TEST_LIST))) + +cfe-disk: $(CFE_DISK_IMG) + +$(CFE_DISK_IMG): FS_SIZE := $(shell echo $$(($(CFE_IMG_MB) * 1048576))) + +$(CFE_DISK_IMG): $(wildcard $(O)/$(RTEMS_VERSION)/default_cpu1/osal/unit-tests/osloader-test/utmod/*) $(wildcard $(INSTALL_DIR)/$(CPUNAME)/eeprom/*) + # Basic disk + truncate -s $(FS_SIZE) $(@) + parted -s $(@) -- mklabel msdos + parted -a none -s $(@) -- mkpart primary fat32 63s -1s + # File system partition + mkfs.fat --offset 63 $(@) + mcopy -i $(@)@@32256 -sv $(O)/$(RTEMS_VERSION)/default_cpu1/osal/unit-tests/osloader-test/utmod :: || /bin/true + mcopy -i $(@)@@32256 -sv $(INSTALL_DIR)/$(CPUNAME)/eeprom :: + +run: $(CFE_DISK_IMG) + $(QEMU_COMMAND) -display none -no-reboot -serial mon:stdio \ + -kernel $(INSTALL_DIR)/$(CPUNAME)/$(KERNEL_NAME).exe \ + -drive file=$(CFE_DISK_IMG),format=raw \ + -device i82557b,netdev=net0,mac=$(MACADDR) \ + -netdev user,id=net0,hostfwd=udp:127.0.0.1:1235-:1235 \ + -append '--console=/dev/com1' + +clean_img: + rm -f $(INSTALL_DIR)/$(CPUNAME)/*.img + +%.cow: $(CFE_DISK_IMG) + qemu-img create -o backing_file=$(notdir $(CFE_DISK_IMG)),backing_fmt=raw -f qcow2 $(@) + +%.log: %.exe %.cow + $(QEMU_COMMAND) -no-reboot -display none \ + -kernel $(<) \ + -append '--batch-mode --console=/dev/com1' \ + -drive file=$(*).cow,format=qcow2 \ + -device i82557b,netdev=net0,mac=$(MACADDR) \ + -netdev user,id=net0 \ + -serial file:$(@).tmp + @mv -v $(@).tmp $(@) + +%.check: %.log + @(grep -q '^Application exit status: SUCCESS' $(<)) || (echo $(*): ---FAIL--- | tee -a $(INSTALL_DIR)/$(CPUNAME)/failed-tests.log; /bin/false ) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 4a321cc83..2a7a43266 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -14,6 +14,14 @@ This action builds, tests, and runs the cFS bundle omitting deprecated code. Build, Test, and Run [OMIT_DEPRECATED=true] runs for every push and every pull request on all branches of cFS in Github Actions. For more information on the OMIT_DEPRECATED flag, see [global_build_options.cmake](https://github.com/nasa/cFE/blob/063b4d8a9c4a7e822af5f3e4017599159b985bb0/cmake/sample_defs/global_build_options.cmake). +## Build and Test in RTEMS [OMIT_DEPRECATED=true] +[![Build and Test rtems 4.11 [OMIT_DEPRECATED=true]](https://github.com/nasa/cFS/actions/workflows/build-cfs-rtems4.11.yml/badge.svg)](https://github.com/nasa/cFS/actions/workflows/build-cfs-rtems4.11.yml) +[![Build and Test rtems 5 [OMIT_DEPRECATED=true]](https://github.com/nasa/cFS/actions/workflows/build-cfs-rtems5.yml/badge.svg)](https://github.com/nasa/cFS/actions/workflows/build-cfs-rtems5.yml) + +This action builds and tests the cFS bundle omitting deprecated code in both RTEMS 4.11 and RTEMS 5. + +Build and Test in RTEMS 4.11 and 5 runs for every push and every pull request on all branches of cFS in Github Actions. + ## CodeQL Analysis [![CodeQL Analaysis](https://github.com/nasa/cfs/actions/workflows/codeql-build.yml/badge.svg)](https://github.com/nasa/cfs/actions/workflows/codeql-build.yml) diff --git a/.github/workflows/build-cfs-rtems4.11.yml b/.github/workflows/build-cfs-rtems4.11.yml new file mode 100644 index 000000000..16081bb75 --- /dev/null +++ b/.github/workflows/build-cfs-rtems4.11.yml @@ -0,0 +1,127 @@ +name: Build and Test rtems 4.11 [OMIT_DEPRECATED=true] + +# Run every time a new commit pushed or for pull requests +on: + push: + pull_request: + +env: + OMIT_DEPRECATED: true + +jobs: + #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. + check-for-duplicates: + runs-on: ubuntu-latest + # Map a step output to a job output + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content' + skip_after_successful_duplicate: 'true' + do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' + + build-cfs: + #Continue if check-for-duplicates found no duplicates. Always runs for pull-requests. + needs: check-for-duplicates + if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} + name: Build + runs-on: ubuntu-18.04 + container: nmullane/qemu_rtems:4.11 + + strategy: + fail-fast: false + matrix: + buildtype: [debug, release] + + # Set the type of machine to run on + env: + BUILDTYPE: ${{ matrix.buildtype }} + # Set home to where rtems is located + HOME: /root + + steps: + # Check out the cfs bundle + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: true + + # Setup the build system + - name: Copy Files + run: | + cp ./cfe/cmake/Makefile.sample Makefile + cp -r ./cfe/cmake/sample_defs sample_defs + + # Setup the build system + - name: Make Prep + run: make SIMULATION=i686-rtems4.11 prep + + - name: Make + run: make + + test-cfs: + name: Test + runs-on: ubuntu-18.04 + container: nmullane/qemu_rtems:4.11 + + needs: build-cfs + + strategy: + fail-fast: false + matrix: + buildtype: [debug, release] + + # Set the type of machine to run on + env: + BUILDTYPE: ${{ matrix.buildtype }} + ENABLE_UNIT_TESTS: true + # Set home to where rtems is located + HOME: /root + # Disable mcopy check otherwise disk image build fails + MTOOLS_SKIP_CHECK: 1 + + + steps: + # Checks out a copy of your repository on the ubuntu-latest machine + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: true + + # Setup the build system + - name: Copy Files + run: | + cp ./cfe/cmake/Makefile.sample Makefile + cp -r ./cfe/cmake/sample_defs sample_defs + + # Setup the build system + - name: Make + run: | + make SIMULATION=i686-rtems4.11 prep + make install + + - name: Test + #run: .github/scripts/qemu_test.sh && .github/scripts/log_failed_tests.sh + run: make O=build SKIP_NET_TESTS=true RTEMS_VERSION=i686-rtems4.11 -f .github/scripts/rtems-test.mk all_tests -k + + - name: Output Failed Tests + # Runs only if a previous step has failed + if: failure() + run: | + # Check if failed-tests is empty or not + if [ -s ./build/exe/cpu1/failed-tests.log ]; then + echo "Failing tests found:" + cat ./build/exe/cpu1/failed-tests.log + fi + + # Always archive test logs + - name: Archive cFS Test Artifacts + uses: actions/upload-artifact@v2 + # Runs even if previous steps have failed + if: always() + with: + name: cFS-rtems-log-summary-${{ matrix.buildtype }} + path: ./build/exe/cpu1/*.log diff --git a/.github/workflows/build-cfs-rtems5.yml b/.github/workflows/build-cfs-rtems5.yml new file mode 100644 index 000000000..9e8629f0b --- /dev/null +++ b/.github/workflows/build-cfs-rtems5.yml @@ -0,0 +1,125 @@ +name: Build and Test rtems 5 [OMIT_DEPRECATED=true] + +# Run every time a new commit pushed or for pull requests +on: + push: + pull_request: + +env: + OMIT_DEPRECATED: true + +jobs: + #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. + check-for-duplicates: + runs-on: ubuntu-latest + # Map a step output to a job output + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content' + skip_after_successful_duplicate: 'true' + do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' + + build-cfs: + #Continue if check-for-duplicates found no duplicates. Always runs for pull-requests. + needs: check-for-duplicates + if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} + name: Build + runs-on: ubuntu-18.04 + container: nmullane/qemu_rtems:5 + + strategy: + fail-fast: false + matrix: + buildtype: [debug, release] + + # Set the type of machine to run on + env: + BUILDTYPE: ${{ matrix.buildtype }} + # Set home to where rtems is located + HOME: /root + + steps: + # Check out the cfs bundle + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: true + + # Setup the build system + - name: Copy Files + run: | + cp ./cfe/cmake/Makefile.sample Makefile + cp -r ./cfe/cmake/sample_defs sample_defs + + # Setup the build system + - name: Make Prep + run: make SIMULATION=i686-rtems5 prep + + - name: Make + run: make + + test-cfs: + name: Test + runs-on: ubuntu-18.04 + container: nmullane/qemu_rtems:5 + + needs: build-cfs + + strategy: + fail-fast: false + matrix: + buildtype: [debug, release] + + # Set the type of machine to run on + env: + BUILDTYPE: ${{ matrix.buildtype }} + ENABLE_UNIT_TESTS: true + # Set home to where rtems is located + HOME: /root + # Disable mcopy check otherwise disk image build fails + MTOOLS_SKIP_CHECK: 1 + + + steps: + # Checks out a copy of your repository on the ubuntu-latest machine + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: true + + # Setup the build system + - name: Copy Files + run: | + cp ./cfe/cmake/Makefile.sample Makefile + cp -r ./cfe/cmake/sample_defs sample_defs + + # Setup the build system + - name: Make + run: | + make SIMULATION=i686-rtems5 prep + make install + + - name: Test + #run: .github/scripts/qemu_test.sh && .github/scripts/log_failed_tests.sh + run: make O=build SKIP_NET_TESTS=true RTEMS_VERSION=i686-rtems5 -f .github/scripts/rtems-test.mk all_tests -k + + - name: Output Failed Tests + run: | + # Check if failed-tests is empty or not + if [ -s ./build/exe/cpu1/failed-tests.log ]; then + echo "Failing tests found:" + cat ./build/exe/cpu1/failed-tests.log + fi + + # Always archive test logs + - name: Archive cFS Test Artifacts + uses: actions/upload-artifact@v2 + # Runs even if previous steps have failed + if: always() + with: + name: cFS-rtems-log-summary-${{ matrix.buildtype }} + path: ./build/exe/cpu1/*.log