Merge pull request #53 from n1tehawk/20160530_fextest
Extend continous integration by adding tests framework
This commit is contained in:
commit
dfce2034df
@ -37,9 +37,9 @@ before_install:
|
||||
export TARGET=all;
|
||||
fi
|
||||
|
||||
# build using the Makefile
|
||||
# build (and test) using the Makefile, with a single overall status
|
||||
script:
|
||||
- make ${TARGET} && make misc
|
||||
- make ${TARGET} && make misc && make check
|
||||
|
||||
# run/simulate a test install
|
||||
after_success:
|
||||
|
||||
5
Makefile
5
Makefile
@ -58,6 +58,7 @@ PREFIX ?= /usr/local
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
|
||||
.PHONY: all clean tools target-tools install install-tools install-target-tools
|
||||
.PHONY: check
|
||||
|
||||
tools: $(TOOLS) $(FEXC_LINKS)
|
||||
target-tools: $(TARGET_TOOLS)
|
||||
@ -94,6 +95,7 @@ install-misc: $(MISC_TOOLS)
|
||||
|
||||
|
||||
clean:
|
||||
make -C tests/ clean
|
||||
@rm -vf $(TOOLS) $(FEXC_LINKS) $(TARGET_TOOLS) $(MISC_TOOLS)
|
||||
@rm -vf version.h *.o *.elf *.sunxi *.bin *.nm *.orig
|
||||
|
||||
@ -186,3 +188,6 @@ version.h:
|
||||
@for x in $(TOOLS) $(FEXC_LINKS) $(TARGET_TOOLS) version.h '*.o' '*.swp'; do \
|
||||
echo "$$x"; \
|
||||
done | sort -V > $@
|
||||
|
||||
check: $(FEXC_LINKS)
|
||||
make -C tests/
|
||||
|
||||
48
tests/Makefile
Normal file
48
tests/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# tests/Makefile
|
||||
#
|
||||
|
||||
BOARDS_URL := https://github.com/linux-sunxi/sunxi-boards/archive/master.zip
|
||||
BOARDS_DIR := sunxi-boards
|
||||
|
||||
check: check_all_fex coverage
|
||||
|
||||
# Conversion cycle (.fex -> .bin -> .fex) test for all sunxi-boards
|
||||
check_all_fex: $(BOARDS_DIR)/README unify-fex
|
||||
./test_all_fex.sh $(BOARDS_DIR)
|
||||
|
||||
coverage:
|
||||
# Usage help / invocation with no args
|
||||
../sunxi-fexc -? 2> /dev/null ; exit 0
|
||||
# Improve code coverage for corner cases (e.g. erroneous parameters)
|
||||
./test_fex2bin_corner_cases.sh
|
||||
./test_bin2fex_corner_cases.sh
|
||||
|
||||
# Retrieve and extract sunxi-boards archive (containing all .fex)
|
||||
$(BOARDS_DIR).zip:
|
||||
curl -fLsS -o $@ $(BOARDS_URL)
|
||||
$(BOARDS_DIR)/README: $(BOARDS_DIR).zip
|
||||
@echo Extracting $< ...
|
||||
unzip -q $<
|
||||
mv sunxi-boards-master $(BOARDS_DIR)
|
||||
touch -r $(BOARDS_DIR) $<
|
||||
cat patches/*.patch | patch -p1
|
||||
|
||||
unify-fex: unify-fex.c
|
||||
$(CC) -Wall -Werror -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(BOARDS_DIR).zip $(BOARDS_DIR) unify-fex
|
||||
|
||||
#
|
||||
# Dedicated rule for Travis CI test of sunxi-boards. This assumes that the
|
||||
# sunxi-tools source (archive) was extracted into a subdir below the working
|
||||
# directory, meaning that BOARDS_DIR should be "../.."
|
||||
#
|
||||
sunxi-boards_CI: unify-fex
|
||||
# compile sunxi-fexc, link bin2fex and fex2bin
|
||||
make -C .. bin2fex fex2bin
|
||||
# apply patches to BOARDS_DIR, ignore mismatches
|
||||
cat patches/*.patch | patch --forward -r- -p2 -d $(BOARDS_DIR) || true
|
||||
# and finally run the tests
|
||||
./test_all_fex.sh $(BOARDS_DIR)
|
||||
19
tests/fextest.sh
Executable file
19
tests/fextest.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
echo $0 $*
|
||||
FEX2BIN=../fex2bin
|
||||
BIN2FEX=../bin2fex
|
||||
FEX=$1
|
||||
BIN=${FEX/%.fex/.bin}
|
||||
REVERSE=${FEX/%.fex/.new}
|
||||
${FEX2BIN} ${FEX} ${BIN}
|
||||
${BIN2FEX} ${BIN} ${REVERSE}
|
||||
# preprocess .fex, compare it to the bin2fex output
|
||||
if ./unify-fex ${FEX} | diff -uwB - ${REVERSE}; then
|
||||
# if successful, clean up the output files
|
||||
rm -f ${BIN} ${REVERSE}
|
||||
else
|
||||
echo '***'
|
||||
echo "*** ERROR processing ${FEX}"
|
||||
echo '***'
|
||||
exit 1
|
||||
fi
|
||||
55
tests/patches/a-star_kv49l.patch
Normal file
55
tests/patches/a-star_kv49l.patch
Normal file
@ -0,0 +1,55 @@
|
||||
See https://github.com/linux-sunxi/sunxi-boards/issues/51
|
||||
|
||||
--- orig/sunxi-boards/sys_config/a33/a-star_kv49l.fex
|
||||
+++ new/sunxi-boards/sys_config/a33/a-star_kv49l.fex
|
||||
@@ -830,25 +830,25 @@
|
||||
|
||||
[Vdevice]
|
||||
Vdevice_used = 0
|
||||
-Vdevice_0 = port:P@00<0><0><0><0>
|
||||
-Vdevice_1 = port:P@00<0><0><0><0>
|
||||
+;Vdevice_0 = port:P@00<0><0><0><0>
|
||||
+;Vdevice_1 = port:P@00<0><0><0><0>
|
||||
|
||||
[s_uart0]
|
||||
s_uart_used = 0
|
||||
-s_uart_tx = port:P@00<0><0><0><0>
|
||||
-s_uart_rx = port:P@00<0><0><0><0>
|
||||
+;s_uart_tx = port:P@00<0><0><0><0>
|
||||
+;s_uart_rx = port:P@00<0><0><0><0>
|
||||
|
||||
[s_rsb0]
|
||||
s_rsb_used = 0
|
||||
-s_rsb_sck = port:P@00<0><0><0><0>
|
||||
-s_rsb_sda = port:P@00<0><0><0><0>
|
||||
+;s_rsb_sck = port:P@00<0><0><0><0>
|
||||
+;s_rsb_sda = port:P@00<0><0><0><0>
|
||||
|
||||
[s_jtag0]
|
||||
s_jtag_used = 0
|
||||
-s_jtag_tms = port:P@00<0><0><0><0>
|
||||
-s_jtag_tck = port:P@00<0><0><0><0>
|
||||
-s_jtag_tdo = port:P@00<0><0><0><0>
|
||||
-s_jtag_tdi = port:P@00<0><0><0><0>
|
||||
+;s_jtag_tms = port:P@00<0><0><0><0>
|
||||
+;s_jtag_tck = port:P@00<0><0><0><0>
|
||||
+;s_jtag_tdo = port:P@00<0><0><0><0>
|
||||
+;s_jtag_tdi = port:P@00<0><0><0><0>
|
||||
|
||||
[s_powchk]
|
||||
s_powchk_used = 0
|
||||
@@ -875,9 +875,9 @@
|
||||
|
||||
[leds_para]
|
||||
leds_used = 0
|
||||
-;red_led = port:P@00<0><0><0><0>
|
||||
-;red_led_active_low = 0
|
||||
-;green_led_active_low = 0
|
||||
-;blue_led =
|
||||
-;blue_led_active_low = 0
|
||||
+;red_led = port:P@00<0><0><0><0>
|
||||
+;red_led_active_low = 0
|
||||
+;green_led_active_low = 0
|
||||
+;blue_led =
|
||||
+;blue_led_active_low = 0
|
||||
|
||||
7
tests/test_all_fex.sh
Executable file
7
tests/test_all_fex.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
FEXFILES=fexfiles.lst
|
||||
find $1 -name '*.fex' > ${FEXFILES}
|
||||
while read fex; do
|
||||
./fextest.sh ${fex} || exit
|
||||
done <${FEXFILES}
|
||||
rm -f ${FEXFILES}
|
||||
13
tests/test_bin2fex_corner_cases.sh
Executable file
13
tests/test_bin2fex_corner_cases.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# === Test errors / corner cases of "bin2fex", improving on code coverage ===
|
||||
#
|
||||
BIN2FEX=../bin2fex
|
||||
TESTFILE=sunxi-boards/sys_config/a10/a10-olinuxino-lime
|
||||
# use sunxi-fexc in "fex2bin" mode, testing explicit parameters at the same time
|
||||
FEX2BIN="../sunxi-fexc -v -q -I fex -O bin"
|
||||
|
||||
${FEX2BIN} ${TESTFILE}.fex ${TESTFILE}.bin
|
||||
# have bin2fex explicitly read /dev/stdin, to force use of fexc.c's "read_all()"
|
||||
cat ${TESTFILE}.bin | ${BIN2FEX} /dev/stdin > /dev/null
|
||||
rm -f ${TESTFILE}.bin
|
||||
74
tests/test_fex2bin_corner_cases.sh
Executable file
74
tests/test_fex2bin_corner_cases.sh
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# === Test errors / corner cases of "fex2bin", improving on code coverage ===
|
||||
#
|
||||
FEX2BIN=../fex2bin
|
||||
|
||||
function expect () {
|
||||
OUT=`${FEX2BIN} 2>&1`
|
||||
if (! echo ${OUT} | grep -q "$1"); then
|
||||
echo ERROR: Expected substring \"$1\" not found in output:
|
||||
echo ${OUT}
|
||||
exit 1
|
||||
fi
|
||||
#echo ${OUT}
|
||||
}
|
||||
|
||||
# missing section, CRLF line ending
|
||||
echo -e "foobar\r\n" | expect "data must follow a section"
|
||||
|
||||
# malformed sections
|
||||
expect "incomplete section declaration" <<-EOF
|
||||
[foobar
|
||||
EOF
|
||||
expect "invalid character at 5" <<-EOF
|
||||
[foo#bar]
|
||||
EOF
|
||||
|
||||
# invalid entry
|
||||
expect "invalid character at 4" <<-EOF
|
||||
[foo]
|
||||
bar
|
||||
EOF
|
||||
|
||||
# bad port specifiers
|
||||
expect "parse error at 12" <<-EOF
|
||||
[foo]
|
||||
bar = port:P@0
|
||||
EOF
|
||||
expect "invalid character at 14" <<-EOF
|
||||
[foo]
|
||||
bar = port:PA*
|
||||
EOF
|
||||
expect "port out of range at 14" <<-EOF
|
||||
[foo]
|
||||
bar = port:PA666
|
||||
EOF
|
||||
expect "value out of range at 17" <<-EOF
|
||||
[foo]
|
||||
bar = port:PA00<-1>
|
||||
EOF
|
||||
expect "invalid character at 18" <<-EOF
|
||||
[foo]
|
||||
bar = port:PA00<0 >
|
||||
EOF
|
||||
|
||||
# bad <key> = <value> pairs
|
||||
expect "invalid character at 8" <<-EOF
|
||||
[foo]
|
||||
bar = 0*
|
||||
EOF
|
||||
expect "value out of range" <<-EOF
|
||||
[foo]
|
||||
bar = 4294967296
|
||||
EOF
|
||||
expect "unquoted value 'bad', assuming string" <<-EOF
|
||||
[foo]
|
||||
bar = bad
|
||||
EOF
|
||||
|
||||
# test truncation of very long identifiers
|
||||
${FEX2BIN} > /dev/null <<-EOF
|
||||
[an_overly_long_section_name_to_truncate]
|
||||
an_overly_long_entry_name_to_truncate = 0
|
||||
EOF
|
||||
143
tests/unify-fex.c
Normal file
143
tests/unify-fex.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bernhard Nortmann <bernhard.nortmann@web.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* unify-fex.c
|
||||
*
|
||||
* A utility program to do some standard transformations on .fex files,
|
||||
* to allow simpler (diff) comparison with the output of bin2fex.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* string macro to determine if str starts with a given literal */
|
||||
#define starts(str, literal) \
|
||||
(strncmp(str, "" literal, sizeof(literal) - 1) == 0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *input = stdin;
|
||||
char line[1024];
|
||||
char *c, *p;
|
||||
long long num;
|
||||
|
||||
if (argc >= 2) {
|
||||
input = fopen(argv[1], "r");
|
||||
if (!input) {
|
||||
perror("failed to open input file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* loop over all input lines, output goes to stdout */
|
||||
while (fgets(line, sizeof(line), input)) {
|
||||
|
||||
/* strip all whitespace (even CR/LF) from the input line */
|
||||
for (c = p = line; *p; p++) {
|
||||
if (!isspace(*p))
|
||||
*c++ = *p;
|
||||
}
|
||||
*c = '\0';
|
||||
|
||||
if (*line == ';' || *line == '#')
|
||||
/* This is a comment line, simply ignore it */
|
||||
continue;
|
||||
if (*line == ':')
|
||||
continue; /* suspect malformed comment, ignore */
|
||||
|
||||
if ((p = strchr(line, '='))) {
|
||||
/* This is a <key> = <value> line, reformat it */
|
||||
c = strdup(p + 1);
|
||||
sprintf(p, " = %s", c);
|
||||
free(c);
|
||||
p += 3; /* have p point to the beginning of <value> */
|
||||
|
||||
if (starts(p, "port:")) {
|
||||
if (p[5] == 'P') { /* port:P... */
|
||||
/* get pin number (including bank) */
|
||||
num = ((p[6] - 'A') << 5) + strtoll(p + 7, &c, 10);
|
||||
c = strdup(c);
|
||||
sprintf(p, "port:P%c%02lld%s", 'A' + (int)(num >> 5), (num & 0x1F), c);
|
||||
free(c);
|
||||
|
||||
/* check angle brackets to determine options count */
|
||||
num = 0;
|
||||
for (c = p + 9; *c; c++) {
|
||||
if (*c == '<')
|
||||
num++;
|
||||
}
|
||||
/* append "<default>" for missing options */
|
||||
c = strrchr(p, '\0');
|
||||
while (num < 4) {
|
||||
c += sprintf(c, "<default>");
|
||||
num++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* fix formatting of numeric values, depending on the keyword
|
||||
* these are a bit nasty, since they vary wildly between hex
|
||||
* and decimal - see decompile_single_mode() in script_fex.c
|
||||
*/
|
||||
num = strtoll(p, NULL, 0);
|
||||
if (num || *p == '0') {
|
||||
int hex = starts(line, "csi_twi_addr");
|
||||
hex |= starts(line, "ctp_twi_addr");
|
||||
hex |= starts(line, "dram_baseaddr");
|
||||
hex |= starts(line, "dram_emr");
|
||||
hex |= starts(line, "dram_tpr");
|
||||
hex |= starts(line, "dram_zq");
|
||||
hex |= starts(line, "g2d_size");
|
||||
hex |= starts(line, "gsensor_twi_addr");
|
||||
hex |= starts(line, "lcd_gamma_tbl_");
|
||||
hex |= starts(line, "rtp_press_threshold ");
|
||||
hex |= starts(line, "rtp_sensitive_level");
|
||||
hex |= starts(line, "tkey_twi_addr");
|
||||
|
||||
/* large decimals will be decompiled as negative */
|
||||
if (!hex && num >= 2147483648LL)
|
||||
num -= 4294967296LL;
|
||||
|
||||
sprintf(p, hex ? "0x%llx" : "%lld", num);
|
||||
} else {
|
||||
/*
|
||||
* We expect all other (= non-numeric) values
|
||||
* to be strings, always quote them.
|
||||
*/
|
||||
if (*p && (*p != '"')) {
|
||||
c = strdup(p);
|
||||
sprintf(p, "\"%s\"", c);
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts(line);
|
||||
}
|
||||
|
||||
if (ferror(input)) {
|
||||
perror("file read error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user