From eeb93582a840353df0ffd75c44ebc3e2c46bcca2 Mon Sep 17 00:00:00 2001
From: Dietrich Rothe <dietrich.rothe@desy.de>
Date: Fri, 23 Jul 2021 12:33:31 +0200
Subject: [PATCH] improve test as requested by Martin; update xml validation
 script

---
 doc/mainpage.dox                              |  7 +--
 include/PropertyDescription.h                 |  4 +-
 ...stArrayPersistence-DoocsVariableConfig.xml |  6 ++-
 tests/src/serverTestArrayPersistence.cpp      | 48 +++++++++++--------
 tests/xml_schema_validation.sh                |  1 +
 xmlschema/doocs_variable_tree.xsd             |  4 ++
 6 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index 43af525..daae5be 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -85,10 +85,11 @@ in a property tag (or any tag for a special property, see Secion \ref special_pr
 - `macro_pulse_number_source`: Name of process variable which contains the macro pusle number which should be attached
                                to the properties.
 - `persist`: Controls behaviour of DOOCS persistency files. This is only important for writable arrays with more than MAX_CONF_LENGTH entries 
-             (usually 20). Possible values are `true` (the default) - always save the array,
-             `false` -  do not save the array,
+             (usually 20). Possible values are `true` (the default) - always save the array, where
+             long arrays are saved in separate files below `hist/` while short arrays go into the server config file;
+             `false` -  do not save the array;
              `auto` - default DOOCS behaviour, only arrays with up to 20 entries are saved, in server config file.
-             Long arrays are saved in separate files below `hist/` instead of the server config file.
+
 
 \subsection zeromq ZeroMQ publication
 
diff --git a/include/PropertyDescription.h b/include/PropertyDescription.h
index b53b600..b8a640a 100644
--- a/include/PropertyDescription.h
+++ b/include/PropertyDescription.h
@@ -24,10 +24,10 @@ namespace ChimeraTK {
 
     PersistConfig(std::string txt) {
       transform(txt.begin(), txt.end(), txt.begin(), ::tolower);
-      if(txt == "false" or txt == "0") {
+      if(txt == "false" or txt =="off" or txt == "0") {
         val = OFF;
       }
-      else if(txt == "true" or txt == "1") {
+      else if(txt == "true" or txt == "on" or txt == "1") {
         val = ON;
       }
       else if(txt == "auto") {
diff --git a/tests/serverTestArrayPersistence-DoocsVariableConfig.xml b/tests/serverTestArrayPersistence-DoocsVariableConfig.xml
index 2b37e88..6e0cd8f 100644
--- a/tests/serverTestArrayPersistence-DoocsVariableConfig.xml
+++ b/tests/serverTestArrayPersistence-DoocsVariableConfig.xml
@@ -2,15 +2,17 @@
 <device_server xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://github.com/ChimeraTK/ControlSystemAdapter-DoocsAdapter" 
 xsi:schemaLocation="https://github.com/ChimeraTK/ControlSystemAdapter-DoocsAdapter ../xmlschema/doocs_variable_tree.xsd">
   <!-- global default -->
-  <persist>false</persist>
+  <persist>auto</persist>
   <location name="INT">
      <!--default for this location -->
     <persist>true</persist>
     <D_array source="TO_DEVICE_ARRAY" type="int" />
-    <D_array source="FROM_DEVICE_ARRAY" name="MY_RENAMED_INTARRAY" type="int" />
+    <D_array source="FROM_DEVICE_ARRAY" type="int" />
   </location>
 
   <location name="DOUBLE">
+     <!--default for this location -->
+    <persist>false</persist>
     <D_array source="TO_DEVICE_ARRAY" type="double" >
       <persist>true</persist>
     </D_array>
diff --git a/tests/src/serverTestArrayPersistence.cpp b/tests/src/serverTestArrayPersistence.cpp
index 3a349bb..940e47a 100644
--- a/tests/src/serverTestArrayPersistence.cpp
+++ b/tests/src/serverTestArrayPersistence.cpp
@@ -35,7 +35,8 @@ void vectorFromFile(std::vector<T>& vec, const char* fname) {
 
 const int alen = 40;
 
-// slightly modified GlobalFixture from serverBasedTestTools.h
+// slightly modified GlobalFixture from serverBasedTestTools.h:
+// use longer arrays in ReferenceTestApplication, cleanup persistency files at startup
 struct GlobalFixture {
   GlobalFixture() {
     cleanupFiles();
@@ -75,7 +76,7 @@ CTK_BOOST_GLOBAL_FIXTURE(GlobalFixture)
 
 // the array must have testStartValue+i at index i.
 template<class T>
-static bool testArrayContent1(std::vector<T>& array, std::string const& propertyName, T testStartValue, T delta) {
+static bool testArrayContent(std::vector<T>& array, std::string const& propertyName, T testStartValue, T delta) {
   bool isOK = true;
   T currentTestValue = testStartValue;
   size_t index = 0;
@@ -93,20 +94,20 @@ static bool testArrayContent1(std::vector<T>& array, std::string const& property
   return isOK;
 }
 template<class T>
-static bool testArrayContent(std::string const& propertyName, T testStartValue, T delta) {
+static bool testArrayContentFromProperty(std::string const& propertyName, T testStartValue, T delta) {
   auto array = DoocsServerTestHelper::doocsGetArray<T>(propertyName);
-  return testArrayContent1(array, propertyName, testStartValue, delta);
+  return testArrayContent(array, propertyName, testStartValue, delta);
 }
 
 /// Using prepared persistence file, start server, check restored values, change values, trigger persisting, compare file with expectation
 BOOST_AUTO_TEST_CASE(testArrayWrite) {
   GlobalFixture::referenceTestApplication.runMainLoopOnce();
 
-  std::string const& propertyAddress = "//INT/MY_RENAMED_INTARRAY";
+  std::string const& propertyAddress = "//INT/FROM_DEVICE_ARRAY";
   checkDataType(propertyAddress, DATA_A_INT);
 
-  CHECK_WITH_TIMEOUT(testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 100, 1) == true);
-  CHECK_WITH_TIMEOUT(testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 200.1, 1) == true);
+  CHECK_WITH_TIMEOUT(testArrayContentFromProperty<float>("//INT/FROM_DEVICE_ARRAY", 100, 1) == true);
+  CHECK_WITH_TIMEOUT(testArrayContentFromProperty<float>("//DOUBLE/FROM_DEVICE_ARRAY", 200.1, 1) == true);
 
   std::vector<int> vint(alen);
   std::vector<double> vdouble(alen);
@@ -122,19 +123,28 @@ BOOST_AUTO_TEST_CASE(testArrayWrite) {
 
   // check changed values
   usleep(100000);
-  CHECK_WITH_TIMEOUT(testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 150, 1) == true);
-  CHECK_WITH_TIMEOUT(testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 250.3, 1) == true);
+  CHECK_WITH_TIMEOUT(testArrayContentFromProperty<float>("//INT/FROM_DEVICE_ARRAY", 150, 1) == true);
+  CHECK_WITH_TIMEOUT(testArrayContentFromProperty<float>("//DOUBLE/FROM_DEVICE_ARRAY", 250.3, 1) == true);
 
   // trigger array storing
   DoocsServerTestHelper::doocsSet<bool>("//ARRAY_PERSISTENCE_TEST._SVR/SVR.SAVE", true);
-  // wait till disk file written
-  usleep(500000);
-
-  // check persisted file against known values
-  std::vector<int> vint2(alen);
-  std::vector<double> vdouble2(alen);
-  vectorFromFile(vint2, "hist/INT-TO_DEVICE_ARRAY.intarray");
-  vectorFromFile(vdouble2, "hist/DOUBLE-TO_DEVICE_ARRAY.doublearray");
-  CHECK_WITH_TIMEOUT(testArrayContent1<int>(vint2, "//INT/MY_RENAMED_INTARRAY", 150, 1) == true);
-  CHECK_WITH_TIMEOUT(testArrayContent1<double>(vdouble2, "//DOUBLE/FROM_DEVICE_ARRAY", 250.3, 1) == true);
+
+  // check persisted file against known values. Try several times, reading from disk.
+  bool intArrayRestored = false;
+  bool doubleArrayRestored = false;
+  for(int count = 0; count < 100; ++count) {
+    usleep(100000);
+    std::vector<int> vint2(alen);
+    std::vector<double> vdouble2(alen);
+    vectorFromFile(vint2, "hist/INT-TO_DEVICE_ARRAY.intarray");
+    vectorFromFile(vdouble2, "hist/DOUBLE-TO_DEVICE_ARRAY.doublearray");
+    intArrayRestored = testArrayContent<int>(vint2, "//INT/TO_DEVICE_ARRAY from file", 150, 1);
+    doubleArrayRestored = testArrayContent<double>(vdouble2, "//DOUBLE/TO_DEVICE_ARRAY from file", 250.3, 1);
+    if(intArrayRestored && doubleArrayRestored) {
+      std::cout << "arrays recovered after read tries: " << count+1 << std::endl;
+      break;
+    }
+  }
+  BOOST_CHECK(intArrayRestored);
+  BOOST_CHECK(doubleArrayRestored);
 }
diff --git a/tests/xml_schema_validation.sh b/tests/xml_schema_validation.sh
index ac002f4..b089f6d 100755
--- a/tests/xml_schema_validation.sh
+++ b/tests/xml_schema_validation.sh
@@ -1,5 +1,6 @@
 #!/bin/bash 
 
 for f in *.xml variableTreeXml/*.xml; do
+    [[ $f = *codeIsNotInt.xml ]] && continue
     xmllint --noout --schema ../xmlschema/doocs_variable_tree.xsd $f
 done
diff --git a/xmlschema/doocs_variable_tree.xsd b/xmlschema/doocs_variable_tree.xsd
index 1e3bec8..2083d6f 100644
--- a/xmlschema/doocs_variable_tree.xsd
+++ b/xmlschema/doocs_variable_tree.xsd
@@ -148,7 +148,11 @@
   <xs:simpleType name="PersistDataType">
     <xs:restriction base="xs:string">
       <xs:enumeration value="false"/>
+      <xs:enumeration value="off"/>
+      <xs:enumeration value="0"/>
       <xs:enumeration value="true"/>
+      <xs:enumeration value="on"/>
+      <xs:enumeration value="1"/>
       <xs:enumeration value="auto"/>
     </xs:restriction>
   </xs:simpleType>
-- 
GitLab