diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 000000000..e4c5010cb
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,86 @@
+# AppVeyor configuration for EPICS Base
+
+# Ralph Lange
+# Copyright (c) 2016-2017 ITER Organization
+
+# Version format
+version: base-{branch}-{build}
+
+#---------------------------------#
+# repository cloning #
+#---------------------------------#
+
+# Called at very beginning, before repo cloning
+init:
+ # Set autocrlf to make batch files work
+ - git config --global core.autocrlf true
+
+# Set clone depth (do not fetch complete history)
+clone_depth: 2
+
+# Skipping commits affecting only specific files
+skip_commits:
+ files:
+ - 'documentation/*'
+ - 'templates/*'
+ - '**/*.html'
+ - '**/*.md'
+
+#---------------------------------#
+# build matrix configuration #
+#---------------------------------#
+
+# Build Configurations: dll/static, regular/debug
+configuration:
+ - dynamic
+ - static
+ - dynamic-debug
+ - static-debug
+
+# Environment variables: compiler toolchain
+environment:
+ matrix:
+ - TOOLCHAIN: 9.0
+ - TOOLCHAIN: 10.0
+ - TOOLCHAIN: 11.0
+ - TOOLCHAIN: 12.0
+ - TOOLCHAIN: 14.0
+ - TOOLCHAIN: cygwin
+ - TOOLCHAIN: mingw
+
+# Platform: architecture
+platform:
+ - x86
+ - x64
+
+# Matrix configuration: allow specific failing jobs
+matrix:
+ exclude:
+ # VS Express installs don't have the 64 bit compiler
+ - platform: x64
+ TOOLCHAIN: 9.0
+ - platform: x64
+ TOOLCHAIN: 10.0
+
+#---------------------------------#
+# building & testing #
+#---------------------------------#
+
+install:
+ - cmd: ci/appveyor-prepare.bat
+
+build_script:
+ - cmd: ci/appveyor-make.bat
+
+test_script:
+ - cmd: ci/appveyor-make.bat runtests
+
+#---------------------------------#
+# notifications #
+#---------------------------------#
+
+notifications:
+
+ - provider: Slack
+ incoming_webhook:
+ secure: RYOm3FIUYeZGjWKaeTVKwq+C3fzK54AKwbmAoECED45mex3lN+8HmrC845a6mg9xPUJ/ND51RopWVaKDD9/UzaM0SO195RQLKqUTIUafiuM=
diff --git a/ci/appveyor-make.bat b/ci/appveyor-make.bat
new file mode 100644
index 000000000..8ecf61dbe
--- /dev/null
+++ b/ci/appveyor-make.bat
@@ -0,0 +1,118 @@
+:: Universal build script for AppVeyor (https://ci.appveyor.com/)
+:: Environment:
+:: TOOLCHAIN - toolchain version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw]
+:: CONFIGURATION - determines EPICS build [dynamic/static]
+:: PLATFORM - architecture [x86/x64]
+::
+:: All command line args are passed to make
+
+Setlocal EnableDelayedExpansion
+
+set "ST="
+if /i "%CONFIGURATION%"=="static" set ST=-static
+
+set OS=64BIT
+if "%PLATFORM%"=="x86" set OS=32BIT
+
+echo [INFO] Platform: %OS%
+
+:: Use parallel make, except for 3.14
+set "MAKEARGS=-j2 -Otarget"
+if "%APPVEYOR_REPO_BRANCH%"=="3.14" set MAKEARGS=
+
+if "%TOOLCHAIN%"=="cygwin" (
+ set "MAKE=make"
+ if "%OS%"=="64BIT" (
+ set "EPICS_HOST_ARCH=cygwin-x86_64"
+ set "INCLUDE=C:\cygwin64\include;%INCLUDE%"
+ set "PATH=C:\cygwin64\bin;%PATH%"
+ echo [INFO] Cygwin Toolchain 64bit
+ ) else (
+ set "EPICS_HOST_ARCH=cygwin-x86"
+ set "INCLUDE=C:\cygwin\include;%INCLUDE%"
+ set "PATH=C:\cygwin\bin;%PATH%"
+ echo [INFO] Cygwin Toolchain 32bit
+ )
+ echo [INFO] Compiler Version
+ gcc -v
+ goto Finish
+)
+
+if "%TOOLCHAIN%"=="mingw" (
+ set "MAKE=mingw32-make"
+ if "%OS%"=="64BIT" (
+ set "EPICS_HOST_ARCH=windows-x64-mingw"
+ set "INCLUDE=C:\tools\mingw64\include;%INCLUDE%"
+ set "PATH=C:\tools\mingw64\bin;%PATH%"
+ echo [INFO] MinGW Toolchain 64bit
+ ) else (
+ set "EPICS_HOST_ARCH=win32-x86-mingw"
+ set "INCLUDE=C:\tools\mingw32\include;%INCLUDE%"
+ set "PATH=C:\tools\mingw32\bin;%PATH%"
+ echo [INFO] MinGW Toolchain 32bit
+ )
+ echo [INFO] Compiler Version
+ gcc -v
+ goto Finish
+)
+
+set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN%"
+set "MAKE=C:\tools\make"
+
+if "%OS%"=="64BIT" (
+ set EPICS_HOST_ARCH=windows-x64%ST%
+ if exist "%VSINSTALL%\VC\vcvarsall.bat" (
+ call "%VSINSTALL%\VC\vcvarsall.bat" amd64
+ where cl
+ if !ERRORLEVEL! NEQ 0 (
+ call "%VSINSTALL%\VC\vcvarsall.bat" x86_amd64
+ where cl
+ if !ERRORLEVEL! NEQ 0 goto MSMissing
+ )
+ goto MSFound
+ )
+ if exist "%VSINSTALL%\VC\bin\amd64\vcvars64.bat" (
+ call "%VSINSTALL%\VC\bin\amd64\vcvars64.bat"
+ where cl
+ if !ERRORLEVEL! NEQ 0 goto MSMissing
+ goto MSFound
+ )
+) else (
+ set EPICS_HOST_ARCH=win32-x86%ST%
+ if exist "%VSINSTALL%\VC\vcvarsall.bat" (
+ call "%VSINSTALL%\VC\vcvarsall.bat" x86
+ where cl
+ if !ERRORLEVEL! NEQ 0 goto MSMissing
+ goto MSFound
+ )
+ if exist "%VSINSTALL%\VC\bin\vcvars32.bat" (
+ call "%VSINSTALL%\VC\bin\vcvars32.bat"
+ where cl
+ if !ERRORLEVEL! NEQ 0 goto MSMissing
+ goto MSFound
+ )
+ if exist "%VSINSTALL%\Common7\Tools\vsvars32.bat" (
+ call "%VSINSTALL%\Common7\Tools\vsvars32.bat"
+ where cl
+ if !ERRORLEVEL! NEQ 0 goto MSMissing
+ goto MSFound
+ )
+)
+
+:MSMissing
+echo [INFO] Installation for MSVC Toolchain %TOOLCHAIN% / %OS% seems to be missing
+exit 1
+
+:MSFound
+echo [INFO] Microsoft Visual Studio Toolchain %TOOLCHAIN%
+echo [INFO] Compiler Version
+cl
+
+:Finish
+echo [INFO] EPICS_HOST_ARCH: %EPICS_HOST_ARCH%
+echo [INFO] Make version
+%MAKE% --version
+echo [INFO] Perl version
+perl --version
+
+%MAKE% %MAKEARGS% %*
diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat
new file mode 100644
index 000000000..6edb7b52f
--- /dev/null
+++ b/ci/appveyor-prepare.bat
@@ -0,0 +1,70 @@
+:: Build script for AppVeyor (https://ci.appveyor.com/)
+:: Environment:
+:: TOOLCHAIN - Toolchain Version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw]
+:: CONFIGURATION - determines EPICS build [dynamic/static, -debug]
+:: PLATFORM - "x86" -> use 32bit architecture
+::
+:: Prepares an Appveyor build by excuting the following steps
+:: - Set up configure\CONFIG_SITE for static vs. dynamic build
+:: - Install Cygwin / Mingw (TOOLCHAIN setting) in the in the appropriate flavor
+:: - Download and install Make-4.1 from EPICS download page
+
+Setlocal EnableDelayedExpansion
+
+set OS=64BIT
+if "%PLATFORM%"=="x86" set OS=32BIT
+
+echo [INFO] Platform: %OS%
+
+if "%TOOLCHAIN%"=="cygwin" (
+ echo.%CONFIGURATION% | findstr /C:"static">nul && (
+ echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE
+ echo STATIC_BUILD=YES>> configure\CONFIG_SITE
+ echo [INFO] EPICS set up for static build
+ ) || (
+ echo [INFO] EPICS set up for dynamic build
+ )
+ echo.%CONFIGURATION% | findstr /C:"debug">nul && (
+ echo HOST_OPT=NO>> configure\CONFIG_SITE
+ echo [INFO] EPICS set up for debug build
+ ) || (
+ echo [INFO] EPICS set up for optimized build
+ )
+ if "%OS%"=="64BIT" (
+ echo [INFO] Installing Cygwin 64bit and dependencies
+ @powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86_64.exe', 'C:\cygwin64\setup-x86_64.exe')"
+ C:\cygwin64\setup-x86_64.exe -q -P "libreadline-devel,libncursesw-devel"
+ ) else (
+ echo [INFO] Installing Cygwin 32bit and dependencies
+ @powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86.exe', 'C:\cygwin\setup-x86.exe')"
+ C:\cygwin\setup-x86.exe -q -P "libreadline-devel,libncursesw-devel"
+ )
+)
+
+if "%TOOLCHAIN%"=="mingw" (
+ echo.%CONFIGURATION% | findstr /C:"static">nul && (
+ echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE
+ echo STATIC_BUILD=YES>> configure\CONFIG_SITE
+ echo [INFO] EPICS set up for static build
+ ) || (
+ echo [INFO] EPICS set up for dynamic build
+ )
+ echo.%CONFIGURATION% | findstr /C:"debug">nul && (
+ echo HOST_OPT=NO>> configure\CONFIG_SITE
+ echo [INFO] EPICS set up for debug build
+ ) || (
+ echo [INFO] EPICS set up for optimized build
+ )
+ if "%OS%"=="64BIT" (
+ echo [INFO] Installing MinGW 64bit
+ cinst mingw || cinst mingw
+ ) else (
+ echo [INFO] Installing MinGW 32bit
+ cinst mingw --x86 || cinst mingw --x86
+ )
+)
+
+echo [INFO] Installing Make 4.1
+@powershell -Command "(new-object net.webclient).DownloadFile('https://www.aps.anl.gov/epics/download/tools/make-4.1-win64.zip', 'C:\tools\make-4.1.zip')"
+cd \tools
+"C:\Program Files\7-Zip\7z" e make-4.1.zip
diff --git a/configure/RULES.Db b/configure/RULES.Db
index c050f9411..8c5d99ed7 100644
--- a/configure/RULES.Db
+++ b/configure/RULES.Db
@@ -151,7 +151,7 @@ ACTIONS = inc
ACTIONS += build
ACTIONS += install
ACTIONS += buildInstall
-ACTIONS += runtests tapfiles junitfiles
+ACTIONS += runtests tapfiles clean-tests test-results junitfiles
actionArchTargets = $(foreach x, $(ACTIONS),\ $(foreach arch,$(BUILD_ARCHS), $(x)$(DIVIDER)$(arch)))
diff --git a/configure/RULES_ARCHS b/configure/RULES_ARCHS
index 6a77a6e9e..dc3fa04fe 100644
--- a/configure/RULES_ARCHS
+++ b/configure/RULES_ARCHS
@@ -14,7 +14,7 @@ ACTIONS = inc
ACTIONS += build
ACTIONS += install
ACTIONS += buildInstall
-ACTIONS += runtests tapfiles junitfiles
+ACTIONS += runtests tapfiles clean-tests test-results junitfiles
actionArchTargets = $(foreach action, $(ACTIONS), \
$(addprefix $(action)$(DIVIDER), $(BUILD_ARCHS)))
diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD
index 176b2743a..76765ed91 100644
--- a/configure/RULES_BUILD
+++ b/configure/RULES_BUILD
@@ -345,6 +345,21 @@ testspec: $(TESTSCRIPTS)
$(if $(TESTFILES), @echo Files: $(TESTFILES) >> $@)
$(if $(TESTSPEC_$(OS_CLASS)), @echo "Harness: $(TESTSPEC_$(OS_CLASS))" >> $@)
+test-results: tapfiles
+ifneq ($(TAPFILES),)
+ifdef RUNTESTS_ENABLED
+ prove --failures --ext .tap --exec cat --color $(TAPFILES)
+endif
+endif
+
+clean-tests:
+ifneq ($(TAPFILES),)
+ $(RM) $(TAPFILES)
+endif
+ifneq ($(JUNITFILES),)
+ $(RM) $(JUNITFILES)
+endif
+
tapfiles: $(TESTSCRIPTS) $(TAPFILES)
junitfiles: $(JUNITFILES)
@@ -501,7 +516,7 @@ $(INSTALL_TEMPLATES_SUBDIR)/%: %
.PRECIOUS: $(COMMON_INC)
.PHONY: all host inc build install clean rebuild buildInstall build_clean
-.PHONY: runtests tapfiles junitfiles
+.PHONY: runtests tapfiles clean-tests test-results junitfiles
.PHONY: checkRelease warnRelease noCheckRelease
endif # BASE_RULES_BUILD
diff --git a/configure/RULES_DIRS b/configure/RULES_DIRS
index 87c0e7318..37cea5e9a 100644
--- a/configure/RULES_DIRS
+++ b/configure/RULES_DIRS
@@ -9,7 +9,7 @@
ARCHS += $(BUILD_ARCHS)
ACTIONS += inc build install buildInstall clean realclean archclean
-ACTIONS += runtests tapfiles junitfiles
+ACTIONS += runtests tapfiles clean-tests test-results junitfiles
dirActionArchTargets = $(foreach dir, $(DIRS), \
$(foreach action, $(ACTIONS), \
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 0522b4b10..956c27957 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -29,13 +29,38 @@ tells git to ignore all configure/*.local files.
-Self-test JUnit XML Output
+New test-related make targets
-This release adds a new make target junitfiles which if necessary
-runs the self-tests and then converts the TAP (Perl Test-Anything-Protocol)
-output files (as generated by the tapfiles target) into the more
-commonly-recognized JUnit XML format. The program that performs this conversion
-needs the Perl module XML::Generator
to have been installed.
+This release adds several new make targets intended for use by developers
+and Continuous Integration systems which simplify the task of running the
+built-in self-test programs and viewing the results. Since these targets are
+intended for limited use they can have requirements for the build host which
+go beyond the standard minimum set needed to build and run Base.
+
+
+
+test-results — Summarize test results
+
+The new make target test-results will run the self-tests if
+necessary to generate a TAP file for each test, then summarizes the TAP output
+files in each test directory in turn, displaying the details of any failures.
+This step uses the program prove
which comes with Perl, but also needs
+cat
to be provided in the default search path so will not work on most
+Windows systems.
+
+junitfiles — Convert test results to JUnit XML Format
+
+The new make target junitfiles will run the self-tests if necessary
+and then convert the TAP output files into the more commonly-supported JUnit
+XML format. The program that performs this conversion needs the Perl module
+XML::Generator
to have been installed.
+
+clean-tests — Delete test result files
+
+The new make target clean-tests removes any test result files from
+previous test runs. It cleans both TAP and JUnit XML files.
+
+
Fix DNS related crash on exit