Skip to content

Commit

Permalink
Initial working version of Makefile, test.sh -> pytest,unit-tests
Browse files Browse the repository at this point in the history
This commit adds initial working version of Makefile using
which we can now 'make' main.c + single_file_prog_test.c
to create bin/unit_test . Following should work:

export CC=gcc
export LD=gcc
make clean
make                    # release binary
BUILD_MODE=debug make

The binary to test is at: ./build/{release,debug}/bin/unit_test

Extend test.sh to support --list and to run individual test-fn-name
Add run_unit_tests(), works in release & debug build modes.

$ ./test.sh run_pytests | run_unit_tests    # should work now.
  • Loading branch information
Aditya Gurajada committed May 21, 2023
1 parent 3dce4eb commit 7d058c7
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ dkms.conf
*.pyc
*.py.swp
*.swp

# Ignore build/ outputs from make
build/
165 changes: 165 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# #############################################################################
# LOC: Line-Of-Code: Makefile: build tests, example programs, run pytests
# Developed based on SplinterDB (https://github.com/vmware/splinterdb) Makefile
# #############################################################################

.DEFAULT_GOAL := all

help::
@echo 'Usage: make [<target>]'
@echo 'Supported targets: clean all run-tests'

#
# Verbosity
#
ifndef BUILD_VERBOSE
BUILD_VERBOSE=0
endif

# Setup echo formatting for messages.
ifeq "$(BUILD_VERBOSE)" "1"
COMMAND=
PROLIX=@echo
BRIEF=@ >/dev/null echo
BRIEF_FORMATTED=@ >/dev/null echo
BRIEF_PARTIAL=@echo -n >/dev/null
else ifeq "$(BUILD_VERBOSE)" "0"
COMMAND=@
PROLIX=@ >/dev/null echo
BRIEF=@echo
BRIEF_FORMATTED=@printf
BRIEF_PARTIAL=@echo -n
else
$(error Unknown BUILD_VERBOSE mode "$(BUILD_VERBOSE)". Valid values are "0" or "1". Default is "0")
endif

# ###################################################################
# SOURCE DIRECTORIES AND FILES
#
SRCDIR = src
TESTSDIR = tests
UNITDIR = unit
UNIT_TESTSDIR = $(TESTSDIR)/$(UNITDIR)
INCDIR = $(UNIT_TESTSDIR)

# ------------------------------------------------------------------------
# Define a recursive wildcard function to 'find' all files under a sub-dir
# See https://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make/18258352#18258352
define rwildcard =
$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
endef

# ###################################################################
# BUILD DIRECTORIES AND FILES
#
ifndef BUILD_ROOT
BUILD_ROOT := build
endif

#
# Build mode
#
ifndef BUILD_MODE
BUILD_MODE=release
endif
BUILD_DIR := $(BUILD_MODE)

BUILD_PATH=$(BUILD_ROOT)/$(BUILD_DIR)

OBJDIR = $(BUILD_PATH)/obj
BINDIR = $(BUILD_PATH)/bin

# ###################################################################
# SOURCE DIRECTORIES AND FILES

# Symbol for all unit-test sources, from which we will build standalone
# unit-test binaries.
# UNIT_TESTSRC := $(call rwildcard,$(UNIT_TESTSDIR),*.c)
UNIT_TESTSRC := $(shell find $(TESTSDIR)/$(UNITDIR) -type f -name *.c -print)
$(info $$UNIT_TESTSRC is [${UNIT_TESTSRC}])

# Objects from unit-test sources in tests/unit/ sub-dir, for unit-tests
# Resolves to a list: obj/tests/unit/a.o obj/tests/unit/b.o obj/tests/unit/c.o
UNIT_TESTOBJS := $(UNIT_TESTSRC:%.c=$(OBJDIR)/%.o)
$(info $$UNIT_TESTOBJS is [${UNIT_TESTOBJS}])

####################################################################
# The main targets
#
all: all-tests
all-tests: $(BINDIR)/unit_test

# ###################################################################
# CFLAGS, LDFLAGS, ETC
#
INCLUDE = -I $(INCDIR)

# use += here, so that extra flags can be provided via the environment

CFLAGS += -D_GNU_SOURCE -ggdb3 -Wall -Wfatal-errors -Werror

# ###################################################################
# Automatically create directories, based on
# http://ismail.badawi.io/blog/2017/03/28/automatic-directory-creation-in-make/
.SECONDEXPANSION:

.SECONDARY:

%/.:
$(COMMAND) mkdir -p $@

# These targets prevent circular dependencies arising from the
# recipe for building binaries
$(BINDIR)/.:
$(COMMAND) mkdir -p $@

$(BINDIR)/%/.:
$(COMMAND) mkdir -p $@

# ###################################################################
# Dependencies
#

$(BINDIR)/unit_test: $(UNIT_TESTOBJS)

# ###################################################################
# RECIPES:

# Dependencies for the main executables
COMPILE.c = $(CC) $(CFLAGS) $(INCLUDE) -c

# Compile each .c file into its .o
# Also define a dependency on the dir in which .o will be produced (@D).
# The secondary expansion will invoke mkdir to create output dirs first.
$(OBJDIR)/%.o: %.c | $$(@D)/.
$(BRIEF_FORMATTED) "%-20s %-50s [%s]\n" Compiling $< $@
$(COMMAND) $(COMPILE.c) $< -o $@
$(PROLIX) # blank line

# Link .o's to product running binary
# Define dependency on output dir existing, so secondary expansion will
# trigger mkdir to create bin/s output dir.
$(BINDIR)/%: | $$(@D)/.
$(BRIEF_FORMATTED) "%-20s %s\n" Linking $@
$(COMMAND) $(LD) $(LDFLAGS) $^ -o $@ $(LIBS)
$(PROLIX) # blank line

unit_test: $(BINDIR)/unit_test

# ###################################################################
# Report build machine details and compiler version for troubleshooting, so
# we see this output for clean builds, especially in CI-jobs.
.PHONY : clean tags
clean:
rm -rf $(BUILD_ROOT)
uname -a
$(CC) --version

#*************************************************************#
# Testing
#

.PHONY: install

run-tests:
./test.sh
Binary file removed test-code/single-file-program/single-file
Binary file not shown.
Binary file not shown.
Binary file removed test-code/two-files-program/.two-files-main.c.swp
Binary file not shown.
Binary file removed test-code/two-files-program/two-files-prog
Binary file not shown.
92 changes: 92 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# ##############################################################################
# test.sh - Driver script to invoke LOC test suites.
# ##############################################################################

Me=$(basename "$0")
set -euo pipefail

pushd "$(dirname "$0")" > /dev/null 2>&1
# shellcheck disable=SC2046
CurrDir="$(pwd)"
popd > /dev/null 2>&1

# Location of binaries, which live under $BUILD_ROOT, if set.
Build_dir="${BUILD_ROOT:-build}"
Build_mode="${BUILD_MODE:-release}"
Bindir="${BINDIR:-${Build_dir}/${Build_mode}/bin}"
Unit_test="${Bindir}/unit_test"

# ##################################################################
# Print help / usage
# ##################################################################
function usage() {

echo "Usage: $Me [--help | --list] | [ < test-name > ]"
echo "To run quick smoke tests : ./${Me}"
}

# ##################################################################
function run_pytests() {
set -x
pushd "${CurrDir}"/tests > /dev/null 2>&1

pytest -v

popd > /dev/null 2>&1
set +x
}

# ##################################################################
function run_unit_tests() {
set -x
${Unit_test}
set +x
}

# List of functions each driving one kind of test.
Tests=( "run_pytests"
"run_unit_tests"
)

# ##################################################################
# List the set of tests that can be run.
function list_tests() {
echo "${Me}: List of tests that can be run:"
list_items_in_array "${Tests[@]}"
}

# --------------------------------------------------------------------------
# Minion to print the contents of a step-array passed-in.
# Ref: https://askubuntu.com/questions/674333/how-to-pass-an-array-as-function-argument
function list_items_in_array() {
local tests_array=("$@")
for str in "${tests_array[@]}"; do
echo " ${str}"
done
}

# ##################################################################
# main() begins here
# ##################################################################

if [ $# -eq 1 ]; then
if [ "$1" == "--help" ]; then
usage
exit 0
fi

if [ "$1" == "--list" ]; then
list_tests
exit 0
fi

# Run the only arg provided, expecting it to be a valid test-fn-name
$1
exit 0
fi


echo "$Me: $(TZ="America/Los_Angeles" date) Start LOC Test Suite Execution."
run_pytests
echo "$Me: $(TZ="America/Los_Angeles" date) LOC Test Suite Execution completed."
Binary file removed tests/unit/single_file_program
Binary file not shown.

0 comments on commit 7d058c7

Please sign in to comment.