Skip to content

Commit

Permalink
Merge pull request #953 from skliper/fix729-unit_test_action
Browse files Browse the repository at this point in the history
Fix #419 #729 #954, Adds local makefile and bundle/local unit test actions with coverage verification
  • Loading branch information
astrogeco authored Apr 28, 2021
2 parents c2dc403 + c2736b3 commit 8fad92d
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 10 deletions.
13 changes: 4 additions & 9 deletions .github/workflows/codeql-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
timeout-minutes: 15

steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout bundle
uses: actions/checkout@v2
with:
Expand All @@ -38,21 +37,17 @@ jobs:
languages: c
queries: +security-extended, security-and-quality

# Setup the build system
- name: Set up for build
run: |
cp ./cfe/cmake/Makefile.sample Makefile
cp -r ./cfe/cmake/sample_defs sample_defs
make prep
# Build the code
- name: Build
run: |
make osal
make native/default_cpu1/osal/tests/
make native/default_cpu1/osal/unit-test-coverage/
make native/default_cpu1/osal/unit-tests/
make native/default_cpu1/osal/ut-stubs/
run: make -j native/default_cpu1/osal/

- name: Run tests
run: (cd build/native/default_cpu1/osal && make test)

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
41 changes: 41 additions & 0 deletions .github/workflows/local_unit_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: "Local Unit Test"

on:
push:
pull_request:

jobs:

Local-Unit-Test:
runs-on: ubuntu-18.04
timeout-minutes: 15

steps:
- name: Install coverage tools
run: sudo apt-get install lcov -y

- name: Checkout submodule
uses: actions/checkout@v2

- name: Set up for build
run: |
cp Makefile.sample Makefile
make ENABLE_UNIT_TESTS=true PERMISSIVE_MODE=true prep
- name: Build the code
run: make -j

# Baseline lcov and run all tests
- name: Test
run: make test

- name: Calculate coverage
run: make lcov | tee lcov_out.txt

- name: Confirm 100% line coverage
run: |
if [[ `grep -A 3 "Overall coverage rate" lcov_out.txt | grep lines` != *"100.0%"* ]]; then
grep -A 3 "Overall coverage rate" lcov_out.txt
echo "Lacks 100.0% line unit test coverage"
exit -1
fi
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build/inc/
build
Makefile
152 changes: 152 additions & 0 deletions Makefile.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#
# Operating System Abstraction Layer CMake / GNU make wrapper
#
# ABOUT THIS MAKEFILE:
# It is a GNU-make wrapper that calls the CMake tools appropriately
# so that setting up a new build is fast and easy with no need to
# learn the CMake commands. It also makes it easier to integrate
# the build with IDE tools such as Eclipse by providing a default
# makefile that has the common targets such as all/clean/etc.
#
# Use of this file is optional.
#
# For _ALL_ targets defined in this file the build tree location may
# be specified via the "O" variable (i.e. make O=<my-build-dir> all).
# If not specified then the "build" subdirectory will be assumed.
#
# This wrapper defines the following major targets:
# prep -- Runs CMake to create a new or re-configure an existing build tree
# Note that multiple build trees can exist from a single source
# Other control options may be passed to CMake via
# make variables depending on the mission build scripts. These will be
# cached in the build tree so they do not need to be set again thereafter.
#
# all -- Build all targets in the CMake build tree
#
# install -- Copy all files to the installation tree and run packaging scripts
# The "DESTDIR" and "INSTALLPREFIX" environment variables control where the
# files are copied
#
# clean -- Clean all targets in the CMake build tree, but not the build tree itself.
#
# distclean -- Entirely remove the build directory specified by "O"
# Note that after this the "prep" step must be run again in order to build.
# Use caution with this as it does an rm -rf - don't set O to your home dir!
#
# test -- Run all unit tests defined in the build on the host. This will not
# work if the BSPTYPE selection is not compatible with the host.
# In that case it is up to the user to copy the executables to the target
# and run them.
#
# lcov -- Runs the "lcov" tool on the build tree to collect all code coverage
# analysis data and build the reports. Code coverage data may be created by
# the "make test" target above.
#

# Establish default values for critical variables. Any of these may be overridden
# on the command line or via the make environment configuration in an IDE
O ?= build
BSPTYPE ?= generic-linux
BUILDTYPE ?= debug
INSTALLPREFIX ?= /exe
DESTDIR ?= $(O)

# The "DESTDIR" variable is a bit more complicated because it should be an absolute
# path for CMake, but we want to accept either absolute or relative paths. So if
# the path does NOT start with "/", prepend it with the current directory.
ifeq ($(filter /%, $(DESTDIR)),)
DESTDIR := $(CURDIR)/$(DESTDIR)
endif

# The "LOCALTGTS" defines the top-level targets that are implemented in this makefile
# Any other target may also be given, in that case it will simply be passed through.
LOCALTGTS := prep all clean install distclean test lcov
OTHERTGTS := $(filter-out $(LOCALTGTS),$(MAKECMDGOALS))

# As this makefile does not build any real files, treat everything as a PHONY target
# This ensures that the rule gets executed even if a file by that name does exist
.PHONY: $(LOCALTGTS) $(OTHERTGTS)

# If the target name appears to be a directory (ends in /), do a make all in that directory
DIRTGTS := $(filter %/,$(OTHERTGTS))
ifneq ($(DIRTGTS),)
$(DIRTGTS):
$(MAKE) -C $(O)/$(patsubst $(O)/%,%,$(@)) all
endif

# For any other goal that is not one of the known local targets, pass it to the build
# as there might be a target by that name. For example, this is useful for rebuilding
# single unit test executable files while debugging from the IDE
FILETGTS := $(filter-out $(DIRTGTS),$(OTHERTGTS))
ifneq ($(FILETGTS),)
$(FILETGTS):
$(MAKE) -C $(O) $(@)
endif

# The "prep" step requires extra options that are specified via enviroment variables.
# Certain special ones should be passed via cache (-D) options to CMake.
# These are only needed for the "prep" target but they are computed globally anyway.
#
# Note this simple makefile just builds for one target, could trivally manage
# multiple targets by changing build directory. More complex target
# list examples are provide by cFE..
PREP_OPTS := -DOSAL_SYSTEM_BSPTYPE=$(BSPTYPE) -DINSTALL_TARGET_LIST=.

ifneq ($(INSTALLPREFIX),)
PREP_OPTS += -DCMAKE_INSTALL_PREFIX=$(INSTALLPREFIX)
endif

ifneq ($(VERBOSE),)
PREP_OPTS += --trace
endif

ifneq ($(OMIT_DEPRECATED),)
PREP_OPTS += -DOSAL_OMIT_DEPRECATED=$(OMIT_DEPRECATED)
endif

ifneq ($(BUILDTYPE),)
PREP_OPTS += -DCMAKE_BUILD_TYPE=$(BUILDTYPE)
endif

ifneq ($(ENABLE_UNIT_TESTS),)
PREP_OPTS += -DENABLE_UNIT_TESTS=$(ENABLE_UNIT_TESTS)
endif

ifneq ($(PERMISSIVE_MODE),)
PREP_OPTS += -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=$(PERMISSIVE_MODE)
endif

all:
$(MAKE) --no-print-directory -C "$(O)" all

install:
$(MAKE) --no-print-directory -C "$(O)" DESTDIR="${DESTDIR}" install

prep $(O)/.prep:
mkdir -p "$(O)"
(cd "$(O)" && cmake $(PREP_OPTS) "$(CURDIR)")
echo "$(PREP_OPTS)" > "$(O)/.prep"

clean:
$(MAKE) --no-print-directory -C "$(O)" clean

distclean:
rm -rf "$(O)"

# Grab lcov baseline before running tests
test:
lcov --capture --initial --directory $(O) --output-file $(O)/coverage_base.info
$(MAKE) --no-print-directory -C "$(O)" test

lcov:
lcov --capture --rc lcov_branch_coverage=1 --directory $(O) --output-file $(O)/coverage_test.info
lcov --rc lcov_branch_coverage=1 --add-tracefile $(O)/coverage_base.info --add-tracefile $(O)/coverage_test.info --output-file $(O)/coverage_total.info
genhtml $(O)/coverage_total.info --branch-coverage --output-directory $(O)/lcov
@/bin/echo -e "\n\nCoverage Report Link: file:$(CURDIR)/$(O)/lcov/index.html\n"


# Make all the commands that use the build tree depend on a flag file
# that is used to indicate the prep step has been done. This way
# the prep step does not need to be done explicitly by the user
# as long as the default options are sufficient.
$(filter-out prep distclean,$(LOCALTGTS)): $(O)/.prep
18 changes: 18 additions & 0 deletions src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,24 @@ void Test_OS_SocketAccept_Impl(void)

/* Success case */
OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_SUCCESS);

/* Failure in fcntl() GETFL */
UT_PortablePosixIOTest_ResetImpl(conn_token.obj_idx);
UT_ResetState(UT_KEY(OCS_fcntl));
UT_SetDeferredRetcode(UT_KEY(OCS_fcntl), 1, -1);
OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_SUCCESS);
UtAssert_STUB_COUNT(OCS_fcntl, 1);
UtAssert_True(!UT_PortablePosixIOTest_Get_Selectable(conn_token.obj_idx),
"Socket not selectable without O_NONBLOCK flag");

/* Failure in fcntl() SETFL */
UT_PortablePosixIOTest_ResetImpl(conn_token.obj_idx);
UT_ResetState(UT_KEY(OCS_fcntl));
UT_SetDeferredRetcode(UT_KEY(OCS_fcntl), 2, -1);
OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_SUCCESS);
UtAssert_STUB_COUNT(OCS_fcntl, 2);
UtAssert_True(!UT_PortablePosixIOTest_Get_Selectable(conn_token.obj_idx),
"Socket not selectable without O_NONBLOCK flag");
}

void Test_OS_SocketRecvFrom_Impl(void)
Expand Down

0 comments on commit 8fad92d

Please sign in to comment.