6 Commits 56a1ea211a ... 3187cbf871

Author SHA1 Message Date
  Michael Buesch 3187cbf871 fupcompiler/cmp: Fix regex string 6 years ago
  Michael Buesch 85d9d5bf64 tests: Add --quiet option 6 years ago
  Michael Buesch f9153bc122 tests/run: Less verbose output 6 years ago
  Michael Buesch 0617027874 sources: Add optional userData dict 6 years ago
  Michael Buesch 058346274b sources: Improve hashing 6 years ago
  Michael Buesch 1a2247bb86 Move deque import to common utils 6 years ago

+ 34 - 14
awlsim/common/sources.py

@@ -148,11 +148,24 @@ class GenericSource(object):
 		     name="",
 		     enabled=True,
 		     filepath="",
-		     sourceBytes=b""):
+		     sourceBytes=b"",
+		     userData={}):
+		"""Initialize a source code object.
+		name: Name string of the source.
+		enabled: True, if the source is active.
+		filepath: Path string to the source file, or an empty string.
+		sourceBytes: bytes object of the actual source code.
+		userData: Optional dict that may be filled with user data.
+		          The source code object will not touch this data.
+			  This data will _not_ be transferred to the core server.
+			  This data does _not_ contribute to the identHash.
+		"""
 		self.name = name
 		self.enabled = enabled
 		self.filepath = filepath
 		self.sourceBytes = sourceBytes
+		self.userData = userData.copy()
+
 		self.__identHash = None
 
 	@property
@@ -229,19 +242,25 @@ class GenericSource(object):
 
 	@property
 	def identHash(self):
-		if not self.__identHash:
+		identHash = self.__identHash
+		if not identHash:
 			# Calculate the ident hash
-			h = self.IDENT_HASH(self.SRCTYPE.encode(
-					self.ENCODING, "strict"))
-			if self.name is not None:
-				h.update(self.name.encode(self.ENCODING, "ignore"))
-			if not self.enabled:
-				h.update(b'disabled')
-			if self.filepath is not None:
-				h.update(self.filepath.encode(self.ENCODING, "ignore"))
-			h.update(self.sourceBytes)
-			self.__identHash = h.digest()
-		return self.__identHash
+			bd = deque()
+			bd.append(self.SRCTYPE.encode(self.ENCODING, "strict"))
+			if self.name is None:
+				bd.append(b'0')
+			else:
+				bd.append(b'1')
+				bd.append(self.name.encode(self.ENCODING, "ignore"))
+			bd.append(b'1' if self.enabled else b'0')
+			if self.filepath:
+				bd.append(b'1')
+				bd.append(self.filepath.encode(self.ENCODING, "ignore"))
+			else:
+				bd.append(b'0')
+			bd.append(self.sourceBytes)
+			identHash = self.__identHash = self.IDENT_HASH(b'|'.join(bd)).digest()
+		return identHash
 
 	@identHash.setter
 	def identHash(self, identHash):
@@ -256,7 +275,8 @@ class GenericSource(object):
 		return self.__class__(name=self.name,
 				      enabled=self.enabled,
 				      filepath=self.filepath,
-				      sourceBytes=self.sourceBytes[:])
+				      sourceBytes=self.sourceBytes[:],
+				      userData=self.userData)
 
 	def isFileBacked(self):
 		return bool(self.filepath)

+ 2 - 0
awlsim/common/util.py

@@ -33,11 +33,13 @@ import base64
 import binascii
 import functools
 import itertools
+from collections import deque
 
 
 __all__ = [
 	"functools",
 	"itertools",
+	"deque",
 	"Logging",
 	"printDebug",
 	"printVerbose",

+ 0 - 1
awlsim/core/cpu.py

@@ -25,7 +25,6 @@ from awlsim.common.compat import *
 import time
 import datetime
 import random
-from collections import deque
 
 from awlsim.common.util import *
 from awlsim.common.cpuspecs import * #+cimport

+ 1 - 1
awlsim/fupcompiler/elemcmp.py

@@ -172,7 +172,7 @@ class FupCompiler_ElemCmp(FupCompiler_Elem):
 								  toLoad=True,
 								  inverted=inverted)
 
-		if conn.textMatch("(ENO)|(OUT\d+)"):
+		if conn.textMatch(r"(ENO)|(OUT\d+)"):
 			self._compileConn_checkTarget(conn, desiredTarget, inverted,
 						      targetExpectVKE=True,
 						      allowInversion=True)

+ 3 - 3
tests/700-hardware/linuxcnc.sh

@@ -32,18 +32,18 @@ sh_test()
 
 	cd "$rootdir" || die "Failed to change to rootdir '$rootdir'"
 
-	echo ""
+	infomsg
 	for testfile in "000-base/empty.awl"\
 			"000-base/shutdown.awl"\
 			"000-base/EXAMPLE.awlpro"; do
-		echo "    Running linuxcnc test with: $testfile"
+		infomsg "    Running linuxcnc test with: $testfile"
 
 		__run_awlsim_linuxcnc_hal "$interpreter" "$test_dir" \
 			"$rootdir/tests/$testfile" \
 			--max-runtime 1.0
 	done
 
-	echo "    Running I/O test"
+	infomsg "    Running I/O test"
 	__run_awlsim_linuxcnc_hal "$interpreter" "$test_dir" \
 		"$test_dir/linuxcnc-iotest.awl__"
 }

+ 3 - 3
tests/800-coreserver/coreserver-cli.sh

@@ -4,13 +4,13 @@ sh_test()
 {
 	local interpreter="$1"
 
-	echo
-	echo "--- Running coreserver tests"
+	infomsg
+	infomsg "--- Running coreserver tests"
 	cd "$rootdir" || die "Failed to change to rootdir '$rootdir'"
 	for testfile in 000-base/shutdown.awl; do
 		run_test "$interpreter" "$basedir/$testfile" \
 			--spawn-backend --interpreter "$interpreter" \
 			--connect-to localhost:$(get_port)
 	done
-	echo -n "--- Finished coreserver tests "
+	infomsg -n "--- Finished coreserver tests "
 }

+ 87 - 60
tests/run.sh

@@ -16,9 +16,24 @@ failfile_write()
 	) 9< "$test_fail_file"
 }
 
+infomsg()
+{
+	[ -z "$AWLSIM_TEST_QUIET" ] && echo "$@"
+}
+
+warnmsg()
+{
+	echo "$@" >&2
+}
+
+errormsg()
+{
+	echo "$@" >&2
+}
+
 die()
 {
-	echo "$*"
+	errormsg "$*"
 
 	# We might be in a sub-job. So write to fail-file.
 	failfile_write "$*"
@@ -37,14 +52,14 @@ maketemp()
 # $1=message
 test_failed()
 {
-	echo "=== TEST FAILED ==="
+	errormsg "=== TEST FAILED ==="
 
 	if [ $opt_softfail -eq 0 ]; then
 		die "$@"
 	else
 		failfile_write "$*"
-		echo "$*"
-		echo "^^^ TEST FAILED ^^^"
+		errormsg "$*"
+		errormsg "^^^ TEST FAILED ^^^"
 		[ $global_retval -eq 0 ] && global_retval=1
 	fi
 }
@@ -315,7 +330,11 @@ run_awl_test()
 	# By default run once with all optimizers enabled.
 	local optimizer_runs="$(get_conf "$awl" optimizer_runs all)"
 
+	local first=1
 	for optimizers in $optimizer_runs; do
+		[ $first -eq 0 ] && infomsg -n " / "
+		local first=0
+
 		local test_time_file="$(maketemp time)"
 
 		local tries="$(get_conf "$awl" tries 1)"
@@ -347,7 +366,7 @@ run_awl_test()
 			[ $exit_code -eq $expected_exit_code ] || {
 				local ok=0
 				[ $tries -gt 0 ] &&\
-					echo "Test '$(basename "$awl")' FAILED, but retrying ($tries)..."
+					infomsg "Test '$(basename "$awl")' FAILED, but retrying ($tries)..."
 			}
 		done
 		if [ $ok -eq 0 ]; then
@@ -358,13 +377,13 @@ run_awl_test()
 				"\nExpected exit code = $expected_exit_code"
 		fi
 		if is_parallel_run; then
-			[ $ok -ne 0 ] && echo "[$(basename "$awl"): O=$optimizers t=$(cat "$test_time_file") -> OK]  "
+			[ $ok -ne 0 ] && infomsg "$(basename "$awl"): O=$optimizers t=$(cat "$test_time_file") -> OK"
 		else
-			[ $ok -ne 0 ] && echo -n "[O=$optimizers t=$(cat "$test_time_file") -> OK]  "
+			[ $ok -ne 0 ] && infomsg -n "O=$optimizers t=$(cat "$test_time_file") -> OK"
 		fi
 		rm "$test_time_file"
 	done
-	is_parallel_run || echo
+	is_parallel_run || infomsg
 
 	cleanup_test_environment
 }
@@ -397,9 +416,9 @@ run_sh_test()
 
 	[ $result -eq 0 ] || die "Test failed with error code $result"
 	if is_parallel_run; then
-		echo "[$(basename "$sh_file"): OK]"
+		infomsg "$(basename "$sh_file"): OK"
 	else
-		echo "[OK]"
+		infomsg "OK"
 	fi
 }
 
@@ -444,14 +463,17 @@ run_nose_test()
 
 	# Run the nose test case
 	cd "$rootdir" || die "Failed to cd to rootdir."
-	"$interpreter" "$nose" --no-byte-compile "$test_case" ||\
-		die "Nose test case '$(basename "$test_case")' failed."
-
-	if is_parallel_run; then
-		echo "[$(basename "$test_case"): OK]"
+	local opts="--no-byte-compile --verbosity=2"
+	if [ -n "$AWLSIM_TEST_QUIET" ]; then
+		"$interpreter" "$nose" $opts "$test_case" >/dev/null 2>&1 ||\
+			die "Nose test case '$(basename "$test_case")' failed."
 	else
-		echo "[nose OK]"
+		"$interpreter" "$nose" $opts "$test_case" ||\
+			die "Nose test case '$(basename "$test_case")' failed."
 	fi
+
+	infomsg "$(basename "$test_case"): OK"
+
 	cleanup_test_environment
 }
 
@@ -467,12 +489,10 @@ __run_test()
 	# Don't run the test helper library
 	[ "$(basename "$testfile")" = "awlsim_tstlib.py" ] && return
 
-	if is_parallel_run; then
-		local nl=
-	else
-		local nl="-n"
-	fi
-	echo $nl "Running test '$(basename "$testfile")' with '$(basename "$interpreter")' ... "
+	# Print test headline
+	local nl="-n"
+	is_parallel_run && local nl=
+	infomsg $nl "$(basename "$testfile") @ $(basename "$interpreter"): "
 
 	local prev_dir="$(pwd)"
 	cd "$rootdir" || die "cd to $rootdir failed"
@@ -512,7 +532,9 @@ run_test_directory()
 	local interpreter="$1"
 	local directory="$2"
 
-	echo "--- Entering directory '$directory'"
+	local prettydir="$(realpath -m --relative-base="$rootdir" "$directory")/"
+
+	infomsg ">>> entering $prettydir"
 	# run .awlpro tests
 	for entry in "$directory"/*; do
 		[ -d "$entry" ] && continue
@@ -551,7 +573,7 @@ run_test_directory()
 		[ -d "$entry" ] || continue
 		run_test_directory "$interpreter" "$entry"
 	done
-	echo "--- Leaving directory '$directory'"
+	infomsg "<<< leaving $prettydir"
 }
 
 # $1=interpreter
@@ -559,18 +581,18 @@ warn_skipped()
 {
 	local interpreter="$1"
 
-	echo "=== WARNING: '$interpreter' interpreter not found. Test skipped."
-	echo
+	warnmsg "=== WARNING: '$interpreter' interpreter not found. Test skipped."
+	warnmsg
 }
 
 build_cython2()
 {
 	have_prog cython && have_prog python2 || {
-		echo "=== WARNING: Cannot build cython2 modules"
+		warnmsg "=== WARNING: Cannot build cython2 modules"
 		return 1
 	}
 	cd "$rootdir" || die "cd to $rootdir failed"
-	echo "=== Building awlsim with python2"
+	infomsg "=== Building awlsim with python2"
 	CFLAGS= CPPFLAGS= CXXFLAGS= LDFLAGS= \
 	AWLSIM_CYTHON_PARALLEL=1 \
 	nice -n 5 \
@@ -581,11 +603,11 @@ build_cython2()
 build_cython3()
 {
 	have_prog cython3 && have_prog python3 || {
-		echo "=== WARNING: Cannot build cython3 modules"
+		warnmsg "=== WARNING: Cannot build cython3 modules"
 		return 1
 	}
 	cd "$rootdir" || die "cd to $rootdir failed"
-	echo "=== Building awlsim with python3"
+	infomsg "=== Building awlsim with python3"
 	CFLAGS= CPPFLAGS= CXXFLAGS= LDFLAGS= \
 	AWLSIM_CYTHON_PARALLEL=1 \
 	nice -n 5 \
@@ -678,7 +700,7 @@ do_tests()
 		[ "$interp_major" -eq 2 -a "$interp_minor" -lt 7 ] &&\
 			die "'$interpreter' interpreter version '$interp_ver_dot' too old."
 
-		echo "=== Running tests with '$interpreter'"
+		infomsg "=== Running tests with '$interpreter'"
 		if [ $# -eq 0 ]; then
 			run_test_directory "$interpreter" "$basedir"
 		else
@@ -692,7 +714,7 @@ do_tests()
 				check_job_failure && break
 			done
 		fi
-		echo
+		infomsg
 
 		check_job_failure && break
 		[ -n "$opt_interpreter" ] && break
@@ -700,56 +722,58 @@ do_tests()
 
 	if is_parallel_run; then
 		# This is a parallel run. Wait for all jobs.
-		echo "Waiting for background jobs..."
+		infomsg "Waiting for background jobs..."
 		wait
 		# Print the fail information.
 		if check_job_failure; then
-			echo
-			echo "===== FAILURES in parallel run: ====="
-			cat "$test_fail_file"
-			echo "====================================="
+			errormsg
+			errormsg "===== FAILURES in parallel run: ====="
+			cat "$test_fail_file" >&2
+			errormsg "====================================="
 			global_retval=1
 		fi
 	fi
 
 	# Print summary
-	echo
 	if [ $global_retval -eq 0 ]; then
-		echo -n "All tests succeeded"
+		infomsg
+		infomsg -n "All tests succeeded"
 	else
-		echo -n "Some tests FAILED"
+		errormsg
+		errormsg -n "Some tests FAILED"
 	fi
 	if [ -n "$opt_interpreter" ]; then
-		echo " (with interpreter '$opt_interpreter')"
+		infomsg " (with interpreter '$opt_interpreter')"
 	else
 		if [ $opt_quick -eq 0 ]; then
 			if [ $opt_extended -eq 0 ]; then
-				echo " (full run)"
+				infomsg " (full run)"
 			else
-				echo " (extended run)"
+				infomsg " (extended run)"
 			fi
 		else
-			echo " (quick run)"
+			infomsg " (quick run)"
 		fi
 	fi
 }
 
 show_help()
 {
-	echo "awlsim unit test script"
-	echo
-	echo "Usage: run.sh [OPTIONS] [testdirectory/testscript.awl/.awlpro/.sh/.py]"
-	echo
-	echo "Options:"
-	echo " -i|--interpreter INTER        Use INTER as interpreter for the tests"
-	echo " -s|--softfail                 Do not abort on single test failures"
-	echo " -j|--jobs NR                  Set the number of jobs to run in parallel."
-	echo "                               0 means number-of-CPUs"
-	echo "                               Default: 1"
-	echo " -q|--quick                    Only run python2 and python3 tests"
-	echo " -qq                           Shortcut for: -q -j 0"
-	echo " -g|--no-gui                   Avoid tests that need GUI libraries"
-	echo " -x|--extended                 Run tests on additional interpreters"
+	infomsg "awlsim unit test script"
+	infomsg
+	infomsg "Usage: run.sh [OPTIONS] [testdirectory/testscript.awl/.awlpro/.sh/.py]"
+	infomsg
+	infomsg "Options:"
+	infomsg " -i|--interpreter INTER        Use INTER as interpreter for the tests"
+	infomsg " -s|--softfail                 Do not abort on single test failures"
+	infomsg " -j|--jobs NR                  Set the number of jobs to run in parallel."
+	infomsg "                               0 means number-of-CPUs"
+	infomsg "                               Default: 1"
+	infomsg " -q|--quick                    Only run python2 and python3 tests"
+	infomsg " -qq                           Shortcut for: -q -j 0"
+	infomsg " -g|--no-gui                   Avoid tests that need GUI libraries"
+	infomsg " -x|--extended                 Run tests on additional interpreters"
+	infomsg " -Q|--quiet                    Less messages"
 }
 
 tmp_dir="/tmp/awlsim-test-$$"
@@ -811,8 +835,11 @@ while [ $# -ge 1 ]; do
 		shift
 		opt_renice="$1"
 		;;
+	-Q|--quiet)
+		export AWLSIM_TEST_QUIET=1
+		;;
 	*)
-		echo "Unknown option: $1"
+		errormsg "Unknown option: $1"
 		exit 1
 		;;
 	esac
@@ -831,7 +858,7 @@ fi
 
 do_renice()
 {
-	renice "$1" "$$"
+	renice "$1" "$$" >/dev/null
 }
 
 if [ -n "$opt_renice" ]; then