From 1a92c71c9699916f8502695da300f6bc4b356d8e Mon Sep 17 00:00:00 2001
From: "benjamin.franksen" <benjamin.franksen@helmholtz-berlin.de>
Date: Wed, 10 Jul 2013 15:31:55 +0000
Subject: [PATCH] added regression tests for pvGet/pvPut (SYNC) timeout
 recovery

---
 test/validate/Makefile        |  7 ++++-
 test/validate/pvGetSync.db    |  4 +++
 test/validate/pvGetSync.st    | 53 ++++++++++++++++++++++++++++++++++
 test/validate/pvPutAsync.st   | 54 +++++++++++++----------------------
 test/validate/testSupport.c   | 12 ++++++++
 test/validate/testSupport.dbd |  1 +
 6 files changed, 96 insertions(+), 35 deletions(-)
 create mode 100644 test/validate/pvGetSync.db
 create mode 100644 test/validate/pvGetSync.st
 create mode 100644 test/validate/testSupport.dbd

diff --git a/test/validate/Makefile b/test/validate/Makefile
index 238f53a3..4cac5ccb 100644
--- a/test/validate/Makefile
+++ b/test/validate/Makefile
@@ -52,13 +52,17 @@ REGRESSION_TESTS_WITHOUT_DB += safeMonitor
 REGRESSION_TESTS_WITHOUT_DB += sizeof
 REGRESSION_TESTS_WITHOUT_DB += userfunc
 
+REGRESSION_TESTS_REMOTE_ONLY += pvGetSync
+
 REGRESSION_TESTS += $(REGRESSION_TESTS_WITHOUT_DB)
 REGRESSION_TESTS += $(REGRESSION_TESTS_WITH_DB)
 
 ifeq '$(EPICS_HAS_UNIT_TEST)' '1'
 TESTPROD_HOST += $(REGRESSION_TESTS)
+TESTPROD_HOST += $(REGRESSION_TESTS_REMOTE_ONLY)
 TESTSCRIPTS_HOST += $(REGRESSION_TESTS:%=%.t)
 TESTSCRIPTS_HOST += $(REGRESSION_TESTS_WITH_DB:%=%Ioc.t)
+TESTSCRIPTS_HOST += $(REGRESSION_TESTS_REMOTE_ONLY:%=%Ioc.t)
 endif
 
 #TESTPROD_HOST += ctest
@@ -69,6 +73,7 @@ PROD_LIBS += $(EPICS_BASE_IOC_LIBS)
 
 DBD += seqSoftIoc.dbd
 seqSoftIoc_DBD += base.dbd
+seqSoftIoc_DBD += testSupport.dbd
 
 seqSoftIoc_SRCS += seqSoftIoc_registerRecordDeviceDriver.cpp
 
@@ -115,7 +120,7 @@ vxTestHarness.dbd$(DEP):
 	@echo "$(COMMON_DIR)/vxTestHarness.dbd: ../Makefile" > $@
 endif
 
-$(REGRESSION_TESTS_WITH_DB:%=%Ioc.t): %Ioc.t: %$(EXE) ../makeTestfile.pl
+$(REGRESSION_TESTS_WITH_DB:%=%Ioc.t) $(REGRESSION_TESTS_REMOTE_ONLY:%=%Ioc.t): %Ioc.t: %$(EXE) ../makeTestfile.pl
 	$(PERL) ../makeTestfile.pl $@ $* $< ioc $(USE_VALGRIND)
 
 $(REGRESSION_TESTS:%=%.t): %.t: %$(EXE) ../makeTestfile.pl
diff --git a/test/validate/pvGetSync.db b/test/validate/pvGetSync.db
new file mode 100644
index 00000000..281f5081
--- /dev/null
+++ b/test/validate/pvGetSync.db
@@ -0,0 +1,4 @@
+record(sub,"pvGetSync") {
+    field(SNAM,"subThreadSleep")
+    field(VAL,"1")
+}
diff --git a/test/validate/pvGetSync.st b/test/validate/pvGetSync.st
new file mode 100644
index 00000000..d768f50f
--- /dev/null
+++ b/test/validate/pvGetSync.st
@@ -0,0 +1,53 @@
+/*************************************************************************\
+Copyright (c) 2010-2012 Helmholtz-Zentrum Berlin f. Materialien
+                        und Energie GmbH, Germany (HZB)
+This file is distributed subject to a Software License Agreement found
+in the file LICENSE that is included with this distribution.
+\*************************************************************************/
+program pvGetSyncTest
+
+%%#include "../testSupport.h"
+
+%%extern double seq_sync_timeout;
+
+foreign seq_sync_timeout;
+
+entry {
+    seq_test_init(2);
+}
+
+ss sstest {
+    double x = 0;
+    assign x to "pvGetSync";
+    int p = 1;
+    assign p to "pvGetSync.PROC";
+
+    state stest1 {
+        when () {
+            int status;
+            seq_sync_timeout = 0.1;
+            pvPut(p, ASYNC);
+            testDiag("x=%f",x);
+            status = pvGet(x,SYNC);
+            testOk(status==pvStatTIMEOUT, "pvGet/SYNC, status=%d (%s)",
+                status, status ? pvMessage(x) : "");
+            testDiag("x=%f",x);
+        } state stest2
+    }
+    state stest2 {
+        when (pvPutComplete(p)) {
+            int status;
+            pvPut(p, ASYNC);
+            seq_sync_timeout = 10.0;
+            testDiag("x=%f",x);
+            status = pvGet(x,SYNC);
+            testOk(status==pvStatOK, "pvGet/SYNC, status=%d (%s)",
+                status, status ? pvMessage(x) : "");
+            testDiag("x=%f",x);
+        } exit
+    }
+}
+
+exit {
+    seq_test_done();
+}
diff --git a/test/validate/pvPutAsync.st b/test/validate/pvPutAsync.st
index 495c1529..df9ac9af 100644
--- a/test/validate/pvPutAsync.st
+++ b/test/validate/pvPutAsync.st
@@ -8,7 +8,9 @@ program pvPutAsyncTest
 
 %%#include "../testSupport.h"
 
-foreign pvStatOK;
+%%extern double seq_sync_timeout;
+
+foreign seq_sync_timeout;
 
 int x;
 assign x to "pvPutAsync1";
@@ -46,48 +48,32 @@ ss test1 {
     state put_sync {
         entry {
             int i = 0;
-            for (i=0; i<4; i++) {
-                int status = pvPut(x,SYNC);
-                /* should always succeed */
+            int status;
+            for (i=0; i<2; i++) {
+                status = pvPut(x,SYNC);
+                /* should succeed */
                 testOk(status==pvStatOK, "pvPut/SYNC %d, status=%d (%s)",
                     i, status, status ? pvMessage(x) : "");
             }
+            i = 2;
+            seq_sync_timeout = 1.0;
+            status = pvPut(x,SYNC);
+            /* should fail */
+            testOk(status==pvStatTIMEOUT, "pvPut/SYNC %d, status=%d (%s)",
+                i, status, status ? pvMessage(x) : "");
+
+            i = 3;
+            seq_sync_timeout = 10.0;
+            status = pvPut(x,SYNC);
+            /* should succeed */
+            testOk(status==pvStatOK, "pvPut/SYNC %d, status=%d (%s)",
+                i, status, status ? pvMessage(x) : "");
         }
         when (delay(1)) {
         } exit
     }
 }
 
-#if 0
-ss test2 {
-    int x;
-    assign x to "pvPutAsync2";
-    state wait {
-        when (delay(0.5)) {
-        } state put_async
-    }
-    state put_async {
-        when (pvPutComplete(x)) {
-            int status;
-            printf("test2: pvPut/ASYNC complete\n");
-            x = 1;
-            status = pvPut(x,ASYNC);
-            /* should always succeed */
-            if (status)
-                printf("test2: pvPut/ASYNC 1 failed, %s\n", pvMessage(x));
-            else
-                printf("test2: pvPut/ASYNC 1 issued\n");
-            /* should always fail */
-            status = pvPut(x,ASYNC);
-            if (status)
-                printf("test2: pvPut/ASYNC 2 failed, %s\n", pvMessage(x));
-            else
-                printf("test2: pvPut/ASYNC 2 issued\n");
-        } state wait
-    }
-}
-#endif
-
 exit {
     seq_test_done();
 }
diff --git a/test/validate/testSupport.c b/test/validate/testSupport.c
index f0518aab..3d23a671 100644
--- a/test/validate/testSupport.c
+++ b/test/validate/testSupport.c
@@ -54,3 +54,15 @@ void seq_test_done(void)
     exit(0);
 #endif
 }
+
+#include "subRecord.h"
+#include "registryFunction.h"
+#include "epicsExport.h"
+
+long subThreadSleep(struct subRecord *psub)
+{
+    epicsThreadSleep(1);
+    psub->val += 1.0;
+    return 0;
+}
+epicsRegisterFunction(subThreadSleep);
diff --git a/test/validate/testSupport.dbd b/test/validate/testSupport.dbd
new file mode 100644
index 00000000..aeed8304
--- /dev/null
+++ b/test/validate/testSupport.dbd
@@ -0,0 +1 @@
+function(subThreadSleep)
-- 
GitLab