Commit dfce2034 authored by NiteHawk's avatar NiteHawk Committed by GitHub
Browse files

Merge pull request #53 from n1tehawk/20160530_fextest

Extend continous integration by adding tests framework
parents d3e860b0 f957f89d
......@@ -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:
......
......@@ -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/
#
# 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)
#!/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
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
#!/bin/sh
FEXFILES=fexfiles.lst
find $1 -name '*.fex' > ${FEXFILES}
while read fex; do
./fextest.sh ${fex} || exit
done <${FEXFILES}
rm -f ${FEXFILES}
#!/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
#!/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
/*
* 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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment