diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 000000000..3151391d0 --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,24 @@ +name: sync + +# Controls when the workflow will run +on: + # Trigger the workflow on all pushes + push: + branches: + - "**" + tags: + - "**" + + # Trigger the workflow when a branch or tag is deleted + delete: ~ + +jobs: + # Calls a reusable CI workflow to sync the current with a remote repository. + # It will correctly handle addition of any new and removal of existing Git objects. + sync: + name: sync + uses: ecmwf-actions/reusable-workflows/.github/workflows/sync.yml@v2 + secrets: + target_repository: ecflow/ecflow + target_username: ClonedDuck + target_token: ${{ secrets.BITBUCKET_PAT }} diff --git a/.gitignore b/.gitignore index 0f3f8cba4..3d7b81afa 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ ecflow_*.files ecflow_*.cflags ecflow_*.cxxflags CMakeLists.txt.user +.qtc_clangd/ #vscode .vscode diff --git a/3rdparty/cereal/include/cereal/details/polymorphic_impl.hpp b/3rdparty/cereal/include/cereal/details/polymorphic_impl.hpp index bee13ab40..df510ffd6 100644 --- a/3rdparty/cereal/include/cereal/details/polymorphic_impl.hpp +++ b/3rdparty/cereal/include/cereal/details/polymorphic_impl.hpp @@ -186,7 +186,14 @@ namespace cereal template inline static const Derived * downcast( const void * dptr, std::type_info const & baseInfo ) { +#pragma GCC diagnostic push +#if defined(__GNUC__) && (__GNUC__ >= 13) +#pragma GCC diagnostic ignored "-Wdangling-reference" +#endif + // Without the warning suppression, the following source line generates a warning in GNU GCC 13.x + // The warning is a false positive, reported as a GCC compiler regression: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532 auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(save) } ); +#pragma GCC diagnostic pop for( auto const * dmap : mapping ) dptr = dmap->downcast( dptr ); @@ -200,7 +207,15 @@ namespace cereal template inline static void * upcast( Derived * const dptr, std::type_info const & baseInfo ) { +#pragma GCC diagnostic push +#pragma GCC diagnostic push +#if defined(__GNUC__) && (__GNUC__ >= 13) + #pragma GCC diagnostic ignored "-Wdangling-reference" +#endif + // Without the warning suppression, the following source line generates a warning in GNU GCC 13.x + // The warning is a false positive, reported as a GCC compiler regression: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532 auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(load) } ); +#pragma GCC diagnostic pop void * uptr = dptr; for( auto mIter = mapping.rbegin(), mEnd = mapping.rend(); mIter != mEnd; ++mIter ) @@ -213,7 +228,15 @@ namespace cereal template inline static std::shared_ptr upcast( std::shared_ptr const & dptr, std::type_info const & baseInfo ) { +#pragma GCC diagnostic push +#pragma GCC diagnostic push +#if defined(__GNUC__) && (__GNUC__ >= 13) + #pragma GCC diagnostic ignored "-Wdangling-reference" +#endif + // Without the warning suppression, the following source line generates a warning in GNU GCC 13.x + // The warning is a false positive, reported as a GCC compiler regression: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532 auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(load) } ); +#pragma GCC diagnostic pop std::shared_ptr uptr = dptr; for( auto mIter = mapping.rbegin(), mEnd = mapping.rend(); mIter != mEnd; ++mIter ) diff --git a/ACore/CMakeLists.txt b/ACore/CMakeLists.txt deleted file mode 100644 index f2fbe3f2c..000000000 --- a/ACore/CMakeLists.txt +++ /dev/null @@ -1,191 +0,0 @@ -# -# Copyright 2009- ECMWF. -# -# This software is licensed under the terms of the Apache Licence version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. -# In applying this licence, ECMWF does not waive the privileges and immunities -# granted to it by virtue of its status as an intergovernmental organisation -# nor does it submit to any jurisdiction. -# - -configure_file( - src/ecflow/core/ecflow_version.h.in - ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_version.h) -configure_file( - src/ecflow/core/ecflow_source_build_dir.h.in - ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_source_build_dir.h) - -set(srcs - # Headers - ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_version.h - ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_source_build_dir.h - src/ecflow/core/AssertTimer.hpp - src/ecflow/core/Cal.hpp - src/ecflow/core/Calendar.hpp - src/ecflow/core/CalendarUpdateParams.hpp - src/ecflow/core/CheckPt.hpp - src/ecflow/core/Child.hpp - src/ecflow/core/Chrono.hpp - src/ecflow/core/CommandLine.hpp - src/ecflow/core/DState.hpp - src/ecflow/core/DebugPerf.hpp - src/ecflow/core/DurationTimer.hpp - src/ecflow/core/Ecf.hpp - src/ecflow/core/EcfPortLock.hpp - src/ecflow/core/Extract.hpp - src/ecflow/core/File.hpp - src/ecflow/core/File_r.hpp - src/ecflow/core/Filesystem.hpp - src/ecflow/core/Host.hpp - src/ecflow/core/Indentor.hpp - src/ecflow/core/Log.hpp - src/ecflow/core/LogVerification.hpp - src/ecflow/core/NOrder.hpp - src/ecflow/core/NState.hpp - src/ecflow/core/NodePath.hpp - src/ecflow/core/Overload.hpp - src/ecflow/core/Passwd.hpp - src/ecflow/core/PasswdFile.hpp - src/ecflow/core/PasswordEncryption.hpp - src/ecflow/core/Pid.hpp - src/ecflow/core/PrintStyle.hpp - src/ecflow/core/SState.hpp - src/ecflow/core/Serialization.hpp - src/ecflow/core/Stl.hpp - src/ecflow/core/Str.hpp - src/ecflow/core/StringSplitter.hpp - src/ecflow/core/TimeSeries.hpp - src/ecflow/core/TimeSlot.hpp - src/ecflow/core/TimeStamp.hpp - src/ecflow/core/User.hpp - src/ecflow/core/Version.hpp - src/ecflow/core/WhiteListFile.hpp - src/ecflow/core/cereal_boost_time.hpp - src/ecflow/core/cereal_optional_nvp.hpp - src/ecflow/core/perf_timer.hpp - # Sources - src/ecflow/core/AssertTimer.cpp - src/ecflow/core/Cal.cpp - src/ecflow/core/Calendar.cpp - src/ecflow/core/Child.cpp - src/ecflow/core/Chrono.cpp - src/ecflow/core/CommandLine.cpp - src/ecflow/core/DState.cpp - src/ecflow/core/DurationTimer.cpp - src/ecflow/core/Ecf.cpp - src/ecflow/core/Extract.cpp - src/ecflow/core/File.cpp - src/ecflow/core/File_r.cpp - src/ecflow/core/Filesystem.cpp - src/ecflow/core/Host.cpp - src/ecflow/core/Indentor.cpp - src/ecflow/core/Log.cpp - src/ecflow/core/LogVerification.cpp - src/ecflow/core/NOrder.cpp - src/ecflow/core/NState.cpp - src/ecflow/core/NodePath.cpp - src/ecflow/core/Passwd.cpp - src/ecflow/core/PasswdFile.cpp - src/ecflow/core/Pid.cpp - src/ecflow/core/PrintStyle.cpp - src/ecflow/core/SState.cpp - src/ecflow/core/Str.cpp - src/ecflow/core/StringSplitter.cpp - src/ecflow/core/TimeSeries.cpp - src/ecflow/core/TimeSlot.cpp - src/ecflow/core/TimeStamp.cpp - src/ecflow/core/User.cpp - src/ecflow/core/Version.cpp - src/ecflow/core/WhiteListFile.cpp -) - -ecbuild_add_library( - TARGET - core - NOINSTALL - TYPE STATIC - SOURCES - ${srcs} - PUBLIC_INCLUDES - src - ${CMAKE_BINARY_DIR}/generated/src - PUBLIC_LIBS - cereal::cereal # this needs to be public as it appears in public header files used downstream - $<$:Boost::system> - Boost::filesystem - Boost::date_time - Boost::program_options - $<$>:crypt> - DEFINITIONS - CMAKE -) -target_clangformat(core) - -## -## Notice: test_support is an INTERFACE-only test utility library. -## - -ecbuild_add_library( - TARGET - test_support - NOINSTALL - TYPE INTERFACE - SOURCES - test/TestSerialisation.hpp - PUBLIC_INCLUDES - test -) -target_clangformat(test_support) - -set(test_srcs - # Headers - test/TestVersioning.hpp - # Sources - test/TestCalendar.cpp - test/TestCereal.cpp - test/TestCerealOptionalNVP.cpp - test/TestCerealWithHierarchy.cpp - test/TestChrono.cpp - test/TestClassDataMemberInit.cpp - test/TestCommandLine.cpp - test/TestCore_main.cpp # contains main() function for test driver - test/TestExtract.cpp - test/TestFile.cpp - test/TestGetUserDetails.cpp - test/TestLog.cpp - test/TestMigration.cpp - test/TestNodePath.cpp - test/TestPasswdFile.cpp - test/TestPasswordEncryption.cpp - test/TestPerfTimer.cpp - test/TestRealCalendar.cpp - test/TestSanitizerAS.cpp - test/TestSanitizerUB.cpp - test/TestSerialisation.cpp - test/TestStr.cpp - test/TestStringSplitPerf.cpp - test/TestStringSplitter.cpp - test/TestTimeSeries.cpp - test/TestTimeSlot.cpp - test/TestVersion.cpp - test/TestVersioning.cpp - test/TestWhiteListFile.cpp -) - -ecbuild_add_test( - TARGET - u_core - LABELS - unit - nightly - SOURCES - ${test_srcs} - LIBS - test_support - core - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - Boost::timer -) -target_clangformat(u_core - CONDITION ENABLE_TESTS -) diff --git a/ANattr/CMakeLists.txt b/ANattr/CMakeLists.txt deleted file mode 100644 index 76b56b3a6..000000000 --- a/ANattr/CMakeLists.txt +++ /dev/null @@ -1,102 +0,0 @@ -# -# Copyright 2009- ECMWF. -# -# This software is licensed under the terms of the Apache Licence version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. -# In applying this licence, ECMWF does not waive the privileges and immunities -# granted to it by virtue of its status as an intergovernmental organisation -# nor does it submit to any jurisdiction. -# - -set(srcs - # Headers - src/ecflow/attribute/AutoArchiveAttr.hpp - src/ecflow/attribute/AutoCancelAttr.hpp - src/ecflow/attribute/ClockAttr.hpp - src/ecflow/attribute/CronAttr.hpp - src/ecflow/attribute/DateAttr.hpp - src/ecflow/attribute/DayAttr.hpp - src/ecflow/attribute/GenericAttr.hpp - src/ecflow/attribute/LateAttr.hpp - src/ecflow/attribute/NodeAttr.hpp - src/ecflow/attribute/QueueAttr.hpp - src/ecflow/attribute/RepeatAttr.hpp - src/ecflow/attribute/TimeAttr.hpp - src/ecflow/attribute/TodayAttr.hpp - src/ecflow/attribute/Variable.hpp - src/ecflow/attribute/VerifyAttr.hpp - src/ecflow/attribute/Zombie.hpp - src/ecflow/attribute/ZombieAttr.hpp - # Sources - src/ecflow/attribute/AutoArchiveAttr.cpp - src/ecflow/attribute/AutoCancelAttr.cpp - src/ecflow/attribute/ClockAttr.cpp - src/ecflow/attribute/CronAttr.cpp - src/ecflow/attribute/DateAttr.cpp - src/ecflow/attribute/DayAttr.cpp - src/ecflow/attribute/GenericAttr.cpp - src/ecflow/attribute/LateAttr.cpp - src/ecflow/attribute/NodeAttr.cpp - src/ecflow/attribute/QueueAttr.cpp - src/ecflow/attribute/RepeatAttr.cpp - src/ecflow/attribute/TimeAttr.cpp - src/ecflow/attribute/TodayAttr.cpp - src/ecflow/attribute/Variable.cpp - src/ecflow/attribute/VerifyAttr.cpp - src/ecflow/attribute/Zombie.cpp - src/ecflow/attribute/ZombieAttr.cpp -) - -ecbuild_add_library( - TARGET - attributes - NOINSTALL - TYPE STATIC - SOURCES - ${srcs} - PUBLIC_INCLUDES - src - PUBLIC_LIBS - core - Boost::date_time -) -target_clangformat(attributes) - - -set(test_srcs - # Sources - test/TestAttributes_main.cpp - test/TestAttrSerialization.cpp - test/TestCron.cpp - test/TestDateAttr.cpp - test/TestDayAttr.cpp - test/TestLabel.cpp - test/TestLateAttr.cpp - test/TestMigration.cpp - test/TestRepeat.cpp - test/TestSizeOf.cpp - test/TestTimeAttr.cpp - test/TestTodayAttr.cpp - test/TestVariable.cpp - test/TestVariableMap.cpp - test/TestZombieAttr.cpp -) - -ecbuild_add_test( - TARGET - u_attributes - LABELS - unit - nightly - SOURCES - ${test_srcs} - LIBS - test_support - attributes - TEST_DEPENDS - u_core - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) -) -target_clangformat(u_attributes - CONDITION ENABLE_TESTS -) diff --git a/ANode/CMakeLists.txt b/ANode/CMakeLists.txt deleted file mode 100644 index 7b193d44f..000000000 --- a/ANode/CMakeLists.txt +++ /dev/null @@ -1,389 +0,0 @@ -# -# Copyright 2009- ECMWF. -# -# This software is licensed under the terms of the Apache Licence version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. -# In applying this licence, ECMWF does not waive the privileges and immunities -# granted to it by virtue of its status as an intergovernmental organisation -# nor does it submit to any jurisdiction. -# - -set(srcs - # Headers - src/ecflow/node/AbstractObserver.hpp - src/ecflow/node/Alias.hpp - src/ecflow/node/Aspect.hpp - src/ecflow/node/Attr.hpp - src/ecflow/node/AutoRestoreAttr.hpp - src/ecflow/node/ClientSuiteMgr.hpp - src/ecflow/node/ClientSuites.hpp - src/ecflow/node/CmdContext.hpp - src/ecflow/node/Defs.hpp - src/ecflow/node/DefsDelta.hpp - src/ecflow/node/DefsTreeVisitor.hpp - src/ecflow/node/EcfFile.hpp - src/ecflow/node/ExprAst.hpp - src/ecflow/node/ExprAstVisitor.hpp - src/ecflow/node/ExprDuplicate.hpp - src/ecflow/node/ExprParser.hpp - src/ecflow/node/Expression.hpp - src/ecflow/node/Family.hpp - src/ecflow/node/Flag.hpp - src/ecflow/node/InLimit.hpp - src/ecflow/node/InLimitMgr.hpp - src/ecflow/node/JobCreationCtrl.hpp - src/ecflow/node/JobProfiler.hpp - src/ecflow/node/Jobs.hpp - src/ecflow/node/JobsParam.hpp - src/ecflow/node/Limit.hpp - src/ecflow/node/LimitFwd.hpp - src/ecflow/node/Memento.hpp - src/ecflow/node/MiscAttrs.hpp - src/ecflow/node/Node.hpp - src/ecflow/node/NodeContainer.hpp - src/ecflow/node/NodeFwd.hpp - src/ecflow/node/NodeState.hpp - src/ecflow/node/NodeStats.hpp - src/ecflow/node/NodeTreeVisitor.hpp - src/ecflow/node/ResolveExternsVisitor.hpp - src/ecflow/node/ServerState.hpp - src/ecflow/node/Signal.hpp - src/ecflow/node/Submittable.hpp - src/ecflow/node/Suite.hpp - src/ecflow/node/SuiteChanged.hpp - src/ecflow/node/System.hpp - src/ecflow/node/Task.hpp - src/ecflow/node/TaskScriptGenerator.hpp - src/ecflow/node/move_peer.hpp - src/ecflow/node/parser/AutoArchiveParser.hpp - src/ecflow/node/parser/AutoCancelParser.hpp - src/ecflow/node/parser/AutoRestoreParser.hpp - src/ecflow/node/parser/CalendarParser.hpp - src/ecflow/node/parser/ClockParser.hpp - src/ecflow/node/parser/CronParser.hpp - src/ecflow/node/parser/DateParser.hpp - src/ecflow/node/parser/DayParser.hpp - src/ecflow/node/parser/DefsParser.hpp - src/ecflow/node/parser/DefsStateParser.hpp - src/ecflow/node/parser/DefsStatusParser.hpp - src/ecflow/node/parser/DefsStructureParser.hpp - src/ecflow/node/parser/EventParser.hpp - src/ecflow/node/parser/ExternParser.hpp - src/ecflow/node/parser/GenericParser.hpp - src/ecflow/node/parser/InlimitParser.hpp - src/ecflow/node/parser/LabelParser.hpp - src/ecflow/node/parser/LateParser.hpp - src/ecflow/node/parser/LimitParser.hpp - src/ecflow/node/parser/MeterParser.hpp - src/ecflow/node/parser/Parser.hpp - src/ecflow/node/parser/QueueParser.hpp - src/ecflow/node/parser/RepeatParser.hpp - src/ecflow/node/parser/TimeParser.hpp - src/ecflow/node/parser/TodayParser.hpp - src/ecflow/node/parser/TriggerParser.hpp - src/ecflow/node/parser/VariableParser.hpp - src/ecflow/node/parser/VerifyParser.hpp - src/ecflow/node/parser/ZombieAttrParser.hpp - # Sources - src/ecflow/node/Alias.cpp - src/ecflow/node/Attr.cpp - src/ecflow/node/AutoRestoreAttr.cpp - src/ecflow/node/ClientSuiteMgr.cpp - src/ecflow/node/ClientSuites.cpp - src/ecflow/node/CmdContext.cpp - src/ecflow/node/Defs.cpp - src/ecflow/node/DefsDelta.cpp - src/ecflow/node/EcfFile.cpp - src/ecflow/node/ExprAst.cpp - src/ecflow/node/ExprAstVisitor.cpp - src/ecflow/node/ExprDuplicate.cpp - src/ecflow/node/ExprParser.cpp - src/ecflow/node/Expression.cpp - src/ecflow/node/Family.cpp - src/ecflow/node/Flag.cpp - src/ecflow/node/InLimit.cpp - src/ecflow/node/InLimitMgr.cpp - src/ecflow/node/JobCreationCtrl.cpp - src/ecflow/node/JobProfiler.cpp - src/ecflow/node/Jobs.cpp - src/ecflow/node/JobsParam.cpp - src/ecflow/node/Limit.cpp - src/ecflow/node/Memento.cpp - src/ecflow/node/MiscAttrs.cpp - src/ecflow/node/Node.cpp - src/ecflow/node/NodeAdd.cpp - src/ecflow/node/NodeChange.cpp - src/ecflow/node/NodeContainer.cpp - src/ecflow/node/NodeDelete.cpp - src/ecflow/node/NodeFind.cpp - src/ecflow/node/NodeMemento.cpp - src/ecflow/node/NodeStats.cpp - src/ecflow/node/NodeTime.cpp - src/ecflow/node/NodeTreeVisitor.cpp - src/ecflow/node/ResolveExternsVisitor.cpp - src/ecflow/node/ServerState.cpp - src/ecflow/node/Signal.cpp - src/ecflow/node/Submittable.cpp - src/ecflow/node/Suite.cpp - src/ecflow/node/SuiteChanged.cpp - src/ecflow/node/System.cpp - src/ecflow/node/Task.cpp - src/ecflow/node/TaskScriptGenerator.cpp - src/ecflow/node/parser/AutoArchiveParser.cpp - src/ecflow/node/parser/AutoCancelParser.cpp - src/ecflow/node/parser/AutoRestoreParser.cpp - src/ecflow/node/parser/CalendarParser.cpp - src/ecflow/node/parser/ClockParser.cpp - src/ecflow/node/parser/CronParser.cpp - src/ecflow/node/parser/DateParser.cpp - src/ecflow/node/parser/DayParser.cpp - src/ecflow/node/parser/DefsParser.cpp - src/ecflow/node/parser/DefsStateParser.cpp - src/ecflow/node/parser/DefsStatusParser.cpp - src/ecflow/node/parser/DefsStructureParser.cpp - src/ecflow/node/parser/EventParser.cpp - src/ecflow/node/parser/ExternParser.cpp - src/ecflow/node/parser/GenericParser.cpp - src/ecflow/node/parser/InlimitParser.cpp - src/ecflow/node/parser/LabelParser.cpp - src/ecflow/node/parser/LateParser.cpp - src/ecflow/node/parser/LimitParser.cpp - src/ecflow/node/parser/MeterParser.cpp - src/ecflow/node/parser/Parser.cpp - src/ecflow/node/parser/QueueParser.cpp - src/ecflow/node/parser/RepeatParser.cpp - src/ecflow/node/parser/TimeParser.cpp - src/ecflow/node/parser/TodayParser.cpp - src/ecflow/node/parser/TriggerParser.cpp - src/ecflow/node/parser/VariableParser.cpp - src/ecflow/node/parser/VerifyParser.cpp - src/ecflow/node/parser/ZombieAttrParser.cpp -) - -ecbuild_add_library( - TARGET - node - NOINSTALL - TYPE STATIC - SOURCES - ${srcs} - PUBLIC_INCLUDES - src - PUBLIC_LIBS - attributes -) -target_clangformat(node) - - -set(test_srcs - # Headers - test/MyDefsFixture.hpp - # Sources - test/TestAdd.cpp - test/TestAlias.cpp - test/TestAssignmentOperator.cpp - test/TestChangeMgrSingleton.cpp - test/TestClientSuiteMgr.cpp - test/TestCopyConstructor.cpp - test/TestDefStatus.cpp - test/TestDefs.cpp - test/TestEcfFile.cpp - test/TestEcfFileLocator.cpp - test/TestEnviromentSubstitution.cpp - test/TestExprParser.cpp - test/TestExprRepeatDateArithmetic.cpp - test/TestExprRepeatDateListArithmetic.cpp - test/TestFindAbsNodePath.cpp - test/TestFlag.cpp - test/TestHistoryParser.cpp - test/TestInLimit.cpp - test/TestJobCreator.cpp - test/TestJobProfiler.cpp - test/TestLimit.cpp - test/TestMigration.cpp - test/TestMissNextTimeSlot.cpp - test/TestMovePeer.cpp - test/TestNodeBeginRequeue.cpp - test/TestNodeState.cpp - test/TestNode_main.cpp # test entry point - test/TestOrder.cpp - test/TestPersistence.cpp - test/TestPreProcessing.cpp - test/TestRepeatWithTimeDependencies.cpp - test/TestReplace.cpp - test/TestSetState.cpp - test/TestSpecificIssues.cpp - test/TestSystem.cpp - test/TestTaskScriptGenerator.cpp - test/TestTimeDependencies.cpp - test/TestVariableGeneration.cpp - test/TestVariableInheritance.cpp - test/TestVariableSubstitution.cpp - test/TestVariableSubstitutionDefs.cpp - test/TestZombies.cpp -) - -ecbuild_add_test( - TARGET - u_node - LABELS - unit - nightly - SOURCES - ${test_srcs} - LIBS - test_support - node - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - TEST_DEPENDS - u_attributes -) -target_clangformat(u_node - CONDITION ENABLE_TESTS) - - -set(test_srcs - # Headers - test/parser/PersistHelper.hpp - test/parser/TemporaryFile.hpp - # Sources - test/parser/PersistHelper.cpp - test/parser/TemporaryFile.cpp - test/parser/TestAutoAddExterns.cpp - test/parser/TestDefsStructurePersistAndReload.cpp - test/parser/TestMementoPersistAndReload.cpp - test/parser/TestMigration.cpp - test/parser/TestParser.cpp - test/parser/TestParser_main.cpp # test entry point - test/parser/TestVariableParsing.cpp -) -ecbuild_add_test( - TARGET - u_parser - LABELS - unit - nightly - SOURCES - ${test_srcs} - INCLUDES - test - test/parser - LIBS - node - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - TEST_DEPENDS - u_node -) -target_clangformat(u_parser - CONDITION ENABLE_TESTS -) - -if (ENABLE_ALL_TESTS) - set(test_srcs - test/TestSingleExprParse.cpp - test/TestSingleExprParse_main.cpp # test entry point - ) - - ecbuild_add_test( - TARGET - u_node_single - LABELS - unit - nightly - SOURCES - ${test_srcs} - LIBS - node - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - TEST_DEPENDS - u_anattr - ) - target_clangformat(u_node_single - CONDITION ENABLE_TESTS - ) - - - set(test_srcs - # Headers - test/parser/PersistHelper.hpp - test/parser/TemporaryFile.hpp - # Sources - test/parser/PersistHelper.cpp - test/parser/TemporaryFile.cpp - test/parser/TestParserPerformance_main.cpp # test entry point - test/parser/TestSingleDefsFile.cpp - ) - - ecbuild_add_test( - TARGET - p_parser - LABELS - performance - nightly - SOURCES - ${test_srcs} - LIBS - node - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - Boost::timer - ) - target_clangformat(p_parser - CONDITION ENABLE_TESTS - ) - - - set(test_srcs - # Headers - test/parser/PersistHelper.hpp - test/parser/TemporaryFile.hpp - # Sources - test/parser/ParseTimer.cpp - test/parser/PersistHelper.cpp - test/parser/TemporaryFile.cpp - ) - - # The following is not technically a test (as it makes no checks), - # but a tool to measure the time it takes to parse 'mega.def' file - ecbuild_add_test( - TARGET - p_parser_timer - LABELS - performance - nightly - ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/test/parser/data/single_defs/mega.def - SOURCES - ${test_srcs} - LIBS - node - Boost::boost # Boost header-only libraries must be available - Boost::timer - ) - target_clangformat(p_parser_timer - CONDITION ENABLE_TESTS - ) - - # The following is not technically a test (as it makes no checks), - # but a tool to parse 'mega.def' file - set(test_srcs - test/parser/ParseOnly.cpp - ) - ecbuild_add_test( - TARGET - p_parser_only - LABELS - performance - nightly - ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/test/parser/data/single_defs/mega.def - SOURCES - ${test_srcs} - LIBS - node - Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) - ) - target_clangformat(p_parser_only - CONDITION ENABLE_TESTS - ) - -endif() diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt deleted file mode 100644 index 062a67fb9..000000000 --- a/Base/CMakeLists.txt +++ /dev/null @@ -1,254 +0,0 @@ -# -# Copyright 2009- ECMWF. -# -# This software is licensed under the terms of the Apache Licence version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. -# In applying this licence, ECMWF does not waive the privileges and immunities -# granted to it by virtue of its status as an intergovernmental organisation -# nor does it submit to any jurisdiction. -# - -set(srcs - # Headers - src/ecflow/base/AbstractClientEnv.hpp - src/ecflow/base/AbstractServer.hpp - src/ecflow/base/Client.hpp - src/ecflow/base/ClientOptionsParser.hpp - src/ecflow/base/ClientToServerRequest.hpp - src/ecflow/base/Cmd.hpp - src/ecflow/base/Connection.hpp - src/ecflow/base/Gnuplot.hpp - src/ecflow/base/ServerReply.hpp - src/ecflow/base/ServerToClientResponse.hpp - src/ecflow/base/Stats.hpp - src/ecflow/base/WhyCmd.hpp - src/ecflow/base/ZombieCtrl.hpp - $<$:src/ecflow/base/Openssl.hpp> - $<$:src/ecflow/base/ssl_connection.hpp> - $<$:src/ecflow/base/SslClient.hpp> - src/ecflow/base/cts/ClientToServerCmd.hpp - src/ecflow/base/cts/CtsCmdRegistry.hpp - src/ecflow/base/cts/EditHistoryMgr.hpp - src/ecflow/base/cts/task/AbortCmd.hpp - src/ecflow/base/cts/task/CompleteCmd.hpp - src/ecflow/base/cts/task/CtsWaitCmd.hpp - src/ecflow/base/cts/task/EventCmd.hpp - src/ecflow/base/cts/task/InitCmd.hpp - src/ecflow/base/cts/task/LabelCmd.hpp - src/ecflow/base/cts/task/MeterCmd.hpp - src/ecflow/base/cts/task/QueueCmd.hpp - src/ecflow/base/cts/task/TaskApi.hpp - src/ecflow/base/cts/task/TaskCmd.hpp - src/ecflow/base/cts/user/AlterCmd.hpp - src/ecflow/base/cts/user/BeginCmd.hpp - src/ecflow/base/cts/user/CFileCmd.hpp - src/ecflow/base/cts/user/CheckPtCmd.hpp - src/ecflow/base/cts/user/ClientHandleCmd.hpp - src/ecflow/base/cts/user/CSyncCmd.hpp - src/ecflow/base/cts/user/CtsApi.hpp - src/ecflow/base/cts/user/CtsCmd.hpp - src/ecflow/base/cts/user/CtsNodeCmd.hpp - src/ecflow/base/cts/user/DeleteCmd.hpp - src/ecflow/base/cts/user/EditScriptCmd.hpp - src/ecflow/base/cts/user/ForceCmd.hpp - src/ecflow/base/cts/user/FreeDepCmd.hpp - src/ecflow/base/cts/user/GroupCTSCmd.hpp - src/ecflow/base/cts/user/LoadDefsCmd.hpp - src/ecflow/base/cts/user/LogCmd.hpp - src/ecflow/base/cts/user/LogMessageCmd.hpp - src/ecflow/base/cts/user/MoveCmd.hpp - src/ecflow/base/cts/user/OrderNodeCmd.hpp - src/ecflow/base/cts/user/PathsCmd.hpp - src/ecflow/base/cts/user/PlugCmd.hpp - src/ecflow/base/cts/user/QueryCmd.hpp - src/ecflow/base/cts/user/ReplaceNodeCmd.hpp - src/ecflow/base/cts/user/RequeueNodeCmd.hpp - src/ecflow/base/cts/user/RunNodeCmd.hpp - src/ecflow/base/cts/user/ServerVersionCmd.hpp - src/ecflow/base/cts/user/ShowCmd.hpp - src/ecflow/base/cts/user/UserCmd.hpp - src/ecflow/base/cts/user/ZombieCmd.hpp - src/ecflow/base/stc/BlockClientZombieCmd.hpp - src/ecflow/base/stc/DefsCache.hpp - src/ecflow/base/stc/DefsCmd.hpp - src/ecflow/base/stc/ErrorCmd.hpp - src/ecflow/base/stc/GroupSTCCmd.hpp - src/ecflow/base/stc/PreAllocatedReply.hpp - src/ecflow/base/stc/SClientHandleCmd.hpp - src/ecflow/base/stc/SClientHandleSuitesCmd.hpp - src/ecflow/base/stc/SNewsCmd.hpp - src/ecflow/base/stc/SNodeCmd.hpp - src/ecflow/base/stc/SServerLoadCmd.hpp - src/ecflow/base/stc/SStatsCmd.hpp - src/ecflow/base/stc/SStringCmd.hpp - src/ecflow/base/stc/SStringVecCmd.hpp - src/ecflow/base/stc/SSuitesCmd.hpp - src/ecflow/base/stc/SSyncCmd.hpp - src/ecflow/base/stc/ServerToClientCmd.hpp - src/ecflow/base/stc/StcCmd.hpp - src/ecflow/base/stc/ZombieGetCmd.hpp - # Sources - src/ecflow/base/Client.cpp - src/ecflow/base/ClientOptionsParser.cpp - src/ecflow/base/ClientToServerRequest.cpp - src/ecflow/base/Connection.cpp - src/ecflow/base/Gnuplot.cpp - src/ecflow/base/ServerReply.cpp - src/ecflow/base/ServerToClientResponse.cpp - src/ecflow/base/Stats.cpp - src/ecflow/base/WhyCmd.cpp - src/ecflow/base/ZombieCtrl.cpp - $<$:src/ecflow/base/Openssl.cpp> - $<$:src/ecflow/base/ssl_connection.cpp> - $<$:src/ecflow/base/SslClient.cpp> - src/ecflow/base/cts/ClientToServerCmd.cpp - src/ecflow/base/cts/CtsCmdRegistry.cpp - src/ecflow/base/cts/EditHistoryMgr.cpp - src/ecflow/base/cts/task/AbortCmd.cpp - src/ecflow/base/cts/task/CompleteCmd.cpp - src/ecflow/base/cts/task/CtsWaitCmd.cpp - src/ecflow/base/cts/task/EventCmd.cpp - src/ecflow/base/cts/task/InitCmd.cpp - src/ecflow/base/cts/task/LabelCmd.cpp - src/ecflow/base/cts/task/MeterCmd.cpp - src/ecflow/base/cts/task/QueueCmd.cpp - src/ecflow/base/cts/task/TaskApi.cpp - src/ecflow/base/cts/task/TaskCmd.cpp - src/ecflow/base/cts/user/AlterCmd.cpp - src/ecflow/base/cts/user/BeginCmd.cpp - src/ecflow/base/cts/user/CFileCmd.cpp - src/ecflow/base/cts/user/CSyncCmd.cpp - src/ecflow/base/cts/user/CheckPtCmd.cpp - src/ecflow/base/cts/user/ClientHandleCmd.cpp - src/ecflow/base/cts/user/CtsApi.cpp - src/ecflow/base/cts/user/CtsCmd.cpp - src/ecflow/base/cts/user/CtsNodeCmd.cpp - src/ecflow/base/cts/user/DeleteCmd.cpp - src/ecflow/base/cts/user/EditScriptCmd.cpp - src/ecflow/base/cts/user/ForceCmd.cpp - src/ecflow/base/cts/user/FreeDepCmd.cpp - src/ecflow/base/cts/user/GroupCTSCmd.cpp - src/ecflow/base/cts/user/LoadDefsCmd.cpp - src/ecflow/base/cts/user/LogCmd.cpp - src/ecflow/base/cts/user/LogMessageCmd.cpp - src/ecflow/base/cts/user/MoveCmd.cpp - src/ecflow/base/cts/user/OrderNodeCmd.cpp - src/ecflow/base/cts/user/PathsCmd.cpp - src/ecflow/base/cts/user/PlugCmd.cpp - src/ecflow/base/cts/user/QueryCmd.cpp - src/ecflow/base/cts/user/ReplaceNodeCmd.cpp - src/ecflow/base/cts/user/RequeueNodeCmd.cpp - src/ecflow/base/cts/user/RunNodeCmd.cpp - src/ecflow/base/cts/user/ServerVersionCmd.cpp - src/ecflow/base/cts/user/ShowCmd.cpp - src/ecflow/base/cts/user/UserCmd.cpp - src/ecflow/base/cts/user/ZombieCmd.cpp - src/ecflow/base/stc/BlockClientZombieCmd.cpp - src/ecflow/base/stc/DefsCache.cpp - src/ecflow/base/stc/DefsCmd.cpp - src/ecflow/base/stc/ErrorCmd.cpp - src/ecflow/base/stc/GroupSTCCmd.cpp - src/ecflow/base/stc/PreAllocatedReply.cpp - src/ecflow/base/stc/SClientHandleCmd.cpp - src/ecflow/base/stc/SClientHandleSuitesCmd.cpp - src/ecflow/base/stc/SNewsCmd.cpp - src/ecflow/base/stc/SNodeCmd.cpp - src/ecflow/base/stc/SServerLoadCmd.cpp - src/ecflow/base/stc/SStatsCmd.cpp - src/ecflow/base/stc/SStringCmd.cpp - src/ecflow/base/stc/SStringVecCmd.cpp - src/ecflow/base/stc/SSuitesCmd.cpp - src/ecflow/base/stc/SSyncCmd.cpp - src/ecflow/base/stc/ServerToClientCmd.cpp - src/ecflow/base/stc/StcCmd.cpp - src/ecflow/base/stc/ZombieGetCmd.cpp -) - -ecbuild_add_library( - TARGET - base - NOINSTALL - TYPE STATIC - SOURCES - ${srcs} - PUBLIC_INCLUDES - src - PUBLIC_LIBS - node - Boost::boost # Boost header-only libraries must be available (namely asio) -) -target_clangformat(base) - - -set(test_srcs - # Headers - test/MockServer.hpp - test/TestHelper.hpp - # Sources - test/TestAlterCmd.cpp - test/TestArchiveAndRestoreCmd.cpp - test/TestBase_main.cpp # test entry point - test/TestClientHandleCmd.cpp - test/TestCmd.cpp - test/TestDeleteNodeCmd.cpp - test/TestForceCmd.cpp - test/TestFreeDepCmd.cpp - test/TestInLimitAndLimit.cpp - test/TestLogCmd.cpp - test/TestMeterCmd.cpp - test/TestProgramOptions.cpp - test/TestQueryCmd.cpp - test/TestQueueCmd.cpp - test/TestRequest.cpp - test/TestRequeueNodeCmd.cpp - test/TestResolveDependencies.cpp - test/TestSpecificIssues.cpp - test/TestSSyncCmd.cpp - test/TestSSyncCmdOrder.cpp - test/TestSSyncCmd_CH1.cpp - test/TestStatsCmd.cpp -) - -ecbuild_add_test( - TARGET - u_base - LABELS - unit nightly - SOURCES - ${test_srcs} - INCLUDES - ../ANode/test - LIBS - base - Threads::Threads - $<$:OpenSSL::SSL> - TEST_DEPENDS - u_parser -) -target_clangformat(u_base - CONDITION ENABLE_TESTS -) - -# The following is not technically a test (as it makes no checks), -# but a tool to measure the time it takes to generate a job file -if (ENABLE_ALL_TESTS) - set(test_srcs - # Sources - test/TestJobGenPerf.cpp - ) - - ecbuild_add_test( - TARGET - p_job_gen - LABELS - performance - SOURCES - ${test_srcs} - LIBS - base - Threads::Threads - ) - target_clangformat(p_job_gen - CONDITION ENABLE_TESTS - ) -endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b5c8a498..c3a49bb0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,10 +22,10 @@ if (NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build Configuration type" FORCE) endif() -find_package( ecbuild 3.4 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild ) # Before project() +find_package( ecbuild 3.4 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild /workspace/ecbuild) # Before project() # this will generate variables, see ACore/ecflow_version.h.in -project( ecflow LANGUAGES CXX VERSION 5.12.4 ) +project( ecflow LANGUAGES CXX VERSION 5.13.0 ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) @@ -348,24 +348,10 @@ find_package(ClangFormat) # ========================================================================================= # build source code # ========================================================================================= -add_subdirectory( ACore ) -add_subdirectory( ANattr ) -add_subdirectory( ANode ) -add_subdirectory( Base ) -add_subdirectory( CSim ) -add_subdirectory( Client ) +add_subdirectory( libs ) if (ENABLE_SERVER) - add_subdirectory( Server ) add_subdirectory( tools ) - add_subdirectory( Test ) -endif() - -if (ENABLE_PYTHON) - if ( ENABLE_PYTHON_PTR_REGISTER ) - add_definitions( -DECF_ENABLE_PYTHON_PTR_REGISTER ) - endif() - add_subdirectory( Pyext ) endif() if (ENABLE_UI) @@ -373,14 +359,6 @@ if (ENABLE_UI) add_subdirectory( share ) endif() -if (ENABLE_HTTP) - add_subdirectory( Http ) -endif() - -if (ENABLE_UDP) - add_subdirectory( Udp ) -endif() - # ========================================================================================= # DOXYGEN to use: make doxygen -> ${CMAKE_CURRENT_BINARY_DIR}/Doc/doxygen/html/index.html # ========================================================================================= @@ -417,15 +395,17 @@ endif() # ========================================================================================= ecbuild_dont_pack( DIRS + .scratch + .git .settings bamboo - ACore/doc - ANattr/doc - ANode/doc - Client/doc - CSim/doc - Pyext/doc - Server/doc + libs/core/doc + libs/attributes/doc + libs/node/doc + libs/client/doc + libs/simulator/doc + libs/pyext/doc + libs/server/doc ecbuild SCRATCH CUSTOMER diff --git a/CSim/test/data/good_defs/operations/xde.def.glog b/CSim/test/data/good_defs/operations/xde.def.glog deleted file mode 100644 index ce4bd3aee..000000000 --- a/CSim/test/data/good_defs/operations/xde.def.glog +++ /dev/null @@ -1,4 +0,0 @@ -DBG:[14:20:32 3.11.2009] state change /dfo unknown --> queued duration_(00:00:00) initTime_(2009-Nov-03 14:20:32) suiteTime_(2009-Nov-03 14:20:32) -DBG:[14:20:32 3.11.2009] state change /dfo queued --> complete duration_(00:00:00) initTime_(2009-Nov-03 14:20:32) suiteTime_(2009-Nov-03 14:20:32) -DBG:[14:20:32 3.11.2009] state change /dfi unknown --> queued duration_(00:00:00) initTime_(2009-Nov-03 14:20:32) suiteTime_(2009-Nov-03 14:20:32) -DBG:[14:20:32 3.11.2009] state change /dfi queued --> complete duration_(00:00:00) initTime_(2009-Nov-03 14:20:32) suiteTime_(2009-Nov-03 14:20:32) diff --git a/Client/test/data/ref_analysis.dat b/Client/test/data/ref_analysis.dat deleted file mode 100644 index e75eea0a3..000000000 --- a/Client/test/data/ref_analysis.dat +++ /dev/null @@ -1,33 +0,0 @@ -Command count min average max std -localhost:3141 --begin 49 562 1530 6932 1146 -localhost:3141 --ch_add 1 514 -localhost:3141 --ch_drop 8 472 491 513 12 -localhost:3141 --ch_register 9 503 533 578 22 -localhost:3141 --ch_rem 1 511 -localhost:3141 --ch_suites 11 486 538 601 37 -localhost:3141 --check_pt 3 689 854 1161 216 -localhost:3141 --delete 56 516 756 1000 133 -localhost:3141 --file 25 575 875 1013 94 -localhost:3141 --force 4 544 554 572 10 -localhost:3141 --get 83 889 2256 3926 519 -localhost:3141 --halt 1 691 -localhost:3141 --kill 2 1051 1062 1073 11 -localhost:3141 --load 50 1462 2566 7291 1103 -localhost:3141 --log 98 510 733 950 106 -localhost:3141 --news 60 481 982 1537 196 -localhost:3141 --order 33 502 549 795 82 -localhost:3141 --ping 1 1594 -localhost:3141 --requeue 1 2281 -localhost:3141 --restart 50 483 676 2204 246 -localhost:3141 --restore_from_checkpt 3 716 888 1208 226 -localhost:3141 --resume 1 2183 -localhost:3141 --shutdown 1 680 -localhost:3141 --stats 1 989 -localhost:3141 --suites 2 492 622 752 130 -localhost:3141 --suspend 2 511 517 524 6 -localhost:3141 --sync 103 520 1610 4363 671 -localhost:3141 --sync_full 25 1155 2085 6717 1152 -localhost:3141 --terminate 1 1247 -localhost:3141 --zombie_get 68 484 729 917 105 - -total round trip time 00:00:00.942435 for 753 requests diff --git a/Client/test/data/rtt.dat b/Client/test/data/rtt.dat deleted file mode 100644 index 5aebe167f..000000000 --- a/Client/test/data/rtt.dat +++ /dev/null @@ -1,753 +0,0 @@ -localhost:3141 --ping :ma0 rtt:00:00:00.001594 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000818 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_repeat_integer/test_repeat_integer.def_log :ma0 rtt:00:00:00.000851 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000761 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000780 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_repeat_integer/test_repeat_integer.def :ma0 rtt:00:00:00.002748 -localhost:3141 --restart :ma0 rtt:00:00:00.000755 -localhost:3141 --begin=test_repeat_integer :ma0 rtt:00:00:00.002220 -localhost:3141 --get :ma0 rtt:00:00:00.002406 -localhost:3141 --news=0 140 1 :ma0 rtt:00:00:00.001107 -localhost:3141 --sync=0 140 1 :ma0 rtt:00:00:00.002342 -localhost:3141 --get :ma0 rtt:00:00:00.002121 -localhost:3141 --news=0 271 2 :ma0 rtt:00:00:00.001044 -localhost:3141 --sync=0 140 1 :ma0 rtt:00:00:00.002141 -localhost:3141 --get :ma0 rtt:00:00:00.001929 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000723 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000725 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_repeat_date/test_repeat_date.def_log :ma0 rtt:00:00:00.000769 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000772 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000823 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_repeat_date/test_repeat_date.def :ma0 rtt:00:00:00.002388 -localhost:3141 --restart :ma0 rtt:00:00:00.000733 -localhost:3141 --begin=test_repeat_date :ma0 rtt:00:00:00.002114 -localhost:3141 --get :ma0 rtt:00:00:00.002349 -localhost:3141 --news=0 451 6 :ma0 rtt:00:00:00.000838 -localhost:3141 --sync=0 451 6 :ma0 rtt:00:00:00.001649 -localhost:3141 --get :ma0 rtt:00:00:00.001388 -localhost:3141 --news=0 591 6 :ma0 rtt:00:00:00.001537 -localhost:3141 --sync=0 591 6 :ma0 rtt:00:00:00.002285 -localhost:3141 --get :ma0 rtt:00:00:00.002288 -localhost:3141 --news=0 661 6 :ma0 rtt:00:00:00.001085 -localhost:3141 --sync=0 661 6 :ma0 rtt:00:00:00.002283 -localhost:3141 --get :ma0 rtt:00:00:00.002007 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000829 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000724 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_repeat_enumerator/test_repeat_enumerator.def_log :ma0 rtt:00:00:00.000778 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000785 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000823 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_repeat_enumerator/test_repeat_enumerator.def :ma0 rtt:00:00:00.002341 -localhost:3141 --restart :ma0 rtt:00:00:00.000717 -localhost:3141 --begin=test_repeat_enumerator :ma0 rtt:00:00:00.001677 -localhost:3141 --get :ma0 rtt:00:00:00.002288 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000807 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000725 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_repeat_defstatus/test_repeat_defstatus.def_log :ma0 rtt:00:00:00.000795 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000744 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000811 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_repeat_defstatus/test_repeat_defstatus.def :ma0 rtt:00:00:00.002400 -localhost:3141 --restart :ma0 rtt:00:00:00.000700 -localhost:3141 --begin=test_repeat_defstatus :ma0 rtt:00:00:00.000835 -localhost:3141 --get :ma0 rtt:00:00:00.002359 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000810 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000707 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_handle/test_handle.def_log :ma0 rtt:00:00:00.000799 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000787 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000807 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_handle/test_handle.def :ma0 rtt:00:00:00.004505 -localhost:3141 --restart :ma0 rtt:00:00:00.000501 -localhost:3141 --begin :ma0 rtt:00:00:00.000770 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000555 -localhost:3141 --sync_full=1 :ma0 rtt:00:00:00.001948 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000586 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000495 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000486 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000532 -localhost:3141 --sync=1 1006 32 :ma0 rtt:00:00:00.001916 -localhost:3141 --ch_add=1 s3 s4 :ma0 rtt:00:00:00.000514 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000564 -localhost:3141 --sync=1 1006 32 :ma0 rtt:00:00:00.002695 -localhost:3141 --ch_rem=1 s3 s4 :ma0 rtt:00:00:00.000511 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000552 -localhost:3141 --sync=1 1006 34 :ma0 rtt:00:00:00.001899 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000486 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000503 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000506 -localhost:3141 --ch_register=false s3 s4 :ma0 rtt:00:00:00.000537 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000549 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000502 -localhost:3141 --ch_drop=2 :ma0 rtt:00:00:00.000472 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000498 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000561 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000552 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_handle_sync/test_handle_sync.def_log :ma0 rtt:00:00:00.000546 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000528 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000582 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_handle_sync/test_handle_sync.def :ma0 rtt:00:00:00.003888 -localhost:3141 --restart :ma0 rtt:00:00:00.000484 -localhost:3141 --begin :ma0 rtt:00:00:00.000720 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000540 -localhost:3141 --news=1 0 0 :ma0 rtt:00:00:00.000496 -localhost:3141 --sync_full=1 :ma0 rtt:00:00:00.001951 -localhost:3141 --suspend /s3 :ma0 rtt:00:00:00.000524 -localhost:3141 --news=1 1126 54 :ma0 rtt:00:00:00.000481 -localhost:3141 --force=complete /s3 :ma0 rtt:00:00:00.000553 -localhost:3141 --news=1 1126 54 :ma0 rtt:00:00:00.000481 -localhost:3141 --sync=1 1126 54 :ma0 rtt:00:00:00.000631 -localhost:3141 --force=complete /s0 :ma0 rtt:00:00:00.000549 -localhost:3141 --news=1 1136 54 :ma0 rtt:00:00:00.000493 -localhost:3141 --sync=1 1136 54 :ma0 rtt:00:00:00.000898 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000498 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000515 -localhost:3141 --news=1 1146 54 :ma0 rtt:00:00:00.000499 -localhost:3141 --sync=1 1146 54 :ma0 rtt:00:00:00.001963 -localhost:3141 --force=complete /s1 :ma0 rtt:00:00:00.000544 -localhost:3141 --sync=1 1146 54 :ma0 rtt:00:00:00.000894 -localhost:3141 --order=/s0 alpha :ma0 rtt:00:00:00.000539 -localhost:3141 --sync=1 1155 54 :ma0 rtt:00:00:00.000874 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000481 -localhost:3141 --suites :ma0 rtt:00:00:00.000492 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000503 -localhost:3141 --news=1 1157 54 :ma0 rtt:00:00:00.000496 -localhost:3141 --sync=1 1157 54 :ma0 rtt:00:00:00.001895 -localhost:3141 --force=unknown /s1 :ma0 rtt:00:00:00.000572 -localhost:3141 --sync=1 1157 54 :ma0 rtt:00:00:00.000892 -localhost:3141 --delete force yes /s2 :ma0 rtt:00:00:00.000524 -localhost:3141 --news=1 1166 54 :ma0 rtt:00:00:00.000482 -localhost:3141 --sync=1 1166 54 :ma0 rtt:00:00:00.001520 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000601 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000513 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000490 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000495 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000484 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_handle_sync/test_handle_sync.def_log :ma0 rtt:00:00:00.000544 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000523 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000557 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_handle_sync/test_handle_sync.def :ma0 rtt:00:00:00.002196 -localhost:3141 --restart :ma0 rtt:00:00:00.000498 -localhost:3141 --begin :ma0 rtt:00:00:00.000596 -localhost:3141 --ch_register=false s0 s1 s2 :ma0 rtt:00:00:00.000534 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000550 -localhost:3141 --sync_full=1 :ma0 rtt:00:00:00.001931 -localhost:3141 --delete yes /s0 :ma0 rtt:00:00:00.000535 -localhost:3141 --delete yes /s1 :ma0 rtt:00:00:00.000519 -localhost:3141 --delete yes /s2 :ma0 rtt:00:00:00.000516 -localhost:3141 --sync=1 1224 69 :ma0 rtt:00:00:00.000834 -localhost:3141 --ch_suites :ma0 rtt:00:00:00.000541 -localhost:3141 --load= :ma0 rtt:00:00:00.001792 -localhost:3141 --sync=1 1230 72 :ma0 rtt:00:00:00.001890 -localhost:3141 --ch_drop=1 :ma0 rtt:00:00:00.000481 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000486 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000485 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_reque/test_reque.def_log :ma0 rtt:00:00:00.000535 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000516 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000546 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_reque/test_reque.def :ma0 rtt:00:00:00.001593 -localhost:3141 --restart :ma0 rtt:00:00:00.000496 -localhost:3141 --begin=test_reque :ma0 rtt:00:00:00.001472 -localhost:3141 --get :ma0 rtt:00:00:00.002323 -localhost:3141 --news=0 1412 83 :ma0 rtt:00:00:00.000997 -localhost:3141 --sync=0 1412 83 :ma0 rtt:00:00:00.002161 -localhost:3141 --get :ma0 rtt:00:00:00.002035 -localhost:3141 --news=0 1520 83 :ma0 rtt:00:00:00.001032 -localhost:3141 --sync=0 1520 83 :ma0 rtt:00:00:00.002325 -localhost:3141 --get :ma0 rtt:00:00:00.002004 -localhost:3141 --requeue /test_reque :ma0 rtt:00:00:00.002281 -localhost:3141 --get :ma0 rtt:00:00:00.002302 -localhost:3141 --news=0 1714 85 :ma0 rtt:00:00:00.000983 -localhost:3141 --sync=0 1714 85 :ma0 rtt:00:00:00.002194 -localhost:3141 --get :ma0 rtt:00:00:00.002009 -localhost:3141 --news=0 1822 85 :ma0 rtt:00:00:00.001008 -localhost:3141 --sync=0 1822 85 :ma0 rtt:00:00:00.002332 -localhost:3141 --get :ma0 rtt:00:00:00.002077 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000764 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000729 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_kill_cmd/test_kill_cmd.def_log :ma0 rtt:00:00:00.000776 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000759 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000807 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_kill_cmd/test_kill_cmd.def :ma0 rtt:00:00:00.001838 -localhost:3141 --restart :ma0 rtt:00:00:00.000500 -localhost:3141 --begin=test_kill_task :ma0 rtt:00:00:00.001078 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001403 -localhost:3141 --sync=0 1884 89 :ma0 rtt:00:00:00.002116 -localhost:3141 --kill /test_kill_task/family/t0 :ma0 rtt:00:00:00.001073 -localhost:3141 --sync=0 1897 89 :ma0 rtt:00:00:00.001359 -localhost:3141 --sync=0 1899 89 :ma0 rtt:00:00:00.002039 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000814 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000712 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_kill_cmd/test_kill_cmd.def_log :ma0 rtt:00:00:00.000781 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000753 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000854 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_kill_cmd/test_kill_cmd.def :ma0 rtt:00:00:00.002131 -localhost:3141 --restart :ma0 rtt:00:00:00.000726 -localhost:3141 --begin=test_kill_suite :ma0 rtt:00:00:00.001499 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001974 -localhost:3141 --sync=0 1944 93 :ma0 rtt:00:00:00.002119 -localhost:3141 --kill /test_kill_suite :ma0 rtt:00:00:00.001051 -localhost:3141 --sync=0 1957 93 :ma0 rtt:00:00:00.001405 -localhost:3141 --sync=0 1959 93 :ma0 rtt:00:00:00.002062 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000766 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000713 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_change_order/test_change_order.def_log :ma0 rtt:00:00:00.000826 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000836 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000820 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_change_order/test_change_order.def :ma0 rtt:00:00:00.005046 -localhost:3141 --restart :ma0 rtt:00:00:00.000489 -localhost:3141 --begin :ma0 rtt:00:00:00.000771 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.004407 -localhost:3141 --order=/a order :ma0 rtt:00:00:00.000540 -localhost:3141 --sync=0 2163 103 :ma0 rtt:00:00:00.000903 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000509 -localhost:3141 --sync=0 2165 103 :ma0 rtt:00:00:00.000844 -localhost:3141 --order=/a bottom :ma0 rtt:00:00:00.000504 -localhost:3141 --sync=0 2167 103 :ma0 rtt:00:00:00.000845 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000531 -localhost:3141 --order=/a down :ma0 rtt:00:00:00.000502 -localhost:3141 --sync=0 2169 103 :ma0 rtt:00:00:00.000857 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000515 -localhost:3141 --order=/c up :ma0 rtt:00:00:00.000506 -localhost:3141 --sync=0 2173 103 :ma0 rtt:00:00:00.001106 -localhost:3141 --order=/a/a order :ma0 rtt:00:00:00.000532 -localhost:3141 --sync=0 2177 103 :ma0 rtt:00:00:00.000849 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000506 -localhost:3141 --sync=0 2179 103 :ma0 rtt:00:00:00.000846 -localhost:3141 --order=/a/a bottom :ma0 rtt:00:00:00.000532 -localhost:3141 --sync=0 2181 103 :ma0 rtt:00:00:00.000841 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000505 -localhost:3141 --order=/a/a down :ma0 rtt:00:00:00.000524 -localhost:3141 --sync=0 2183 103 :ma0 rtt:00:00:00.000927 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000513 -localhost:3141 --order=/a/c up :ma0 rtt:00:00:00.000508 -localhost:3141 --sync=0 2187 103 :ma0 rtt:00:00:00.000918 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000506 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000497 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_change_order/test_change_order.def_log :ma0 rtt:00:00:00.000545 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000529 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000592 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_change_order/test_change_order.def :ma0 rtt:00:00:00.007291 -localhost:3141 --restart :ma0 rtt:00:00:00.000501 -localhost:3141 --begin :ma0 rtt:00:00:00.000935 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.006717 -localhost:3141 --ch_register=false a b c :ma0 rtt:00:00:00.000578 -localhost:3141 --sync=1 2514 119 :ma0 rtt:00:00:00.004363 -localhost:3141 --sync=1 2514 117 :ma0 rtt:00:00:00.000520 -localhost:3141 --order=/a order :ma0 rtt:00:00:00.000537 -localhost:3141 --sync=1 2514 117 :ma0 rtt:00:00:00.000907 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000514 -localhost:3141 --sync=1 2516 117 :ma0 rtt:00:00:00.000870 -localhost:3141 --order=/a bottom :ma0 rtt:00:00:00.000521 -localhost:3141 --sync=1 2518 117 :ma0 rtt:00:00:00.000848 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000525 -localhost:3141 --order=/a down :ma0 rtt:00:00:00.000503 -localhost:3141 --sync=1 2520 117 :ma0 rtt:00:00:00.000867 -localhost:3141 --order=/a alpha :ma0 rtt:00:00:00.000524 -localhost:3141 --order=/c up :ma0 rtt:00:00:00.000522 -localhost:3141 --sync=1 2524 117 :ma0 rtt:00:00:00.001098 -localhost:3141 --order=/a/a order :ma0 rtt:00:00:00.000514 -localhost:3141 --sync=1 2528 117 :ma0 rtt:00:00:00.000847 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000520 -localhost:3141 --sync=1 2530 117 :ma0 rtt:00:00:00.000846 -localhost:3141 --order=/a/a bottom :ma0 rtt:00:00:00.000519 -localhost:3141 --sync=1 2532 117 :ma0 rtt:00:00:00.000880 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000519 -localhost:3141 --order=/a/a down :ma0 rtt:00:00:00.000505 -localhost:3141 --sync=1 2534 117 :ma0 rtt:00:00:00.000862 -localhost:3141 --order=/a/a alpha :ma0 rtt:00:00:00.000505 -localhost:3141 --order=/a/c up :ma0 rtt:00:00:00.000552 -localhost:3141 --sync=1 2538 117 :ma0 rtt:00:00:00.000916 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000514 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000550 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_limit/test_limit.def_log :ma0 rtt:00:00:00.000533 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000516 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000589 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_limit/test_limit.def :ma0 rtt:00:00:00.002230 -localhost:3141 --restart :ma0 rtt:00:00:00.000503 -localhost:3141 --begin=test_limit :ma0 rtt:00:00:00.002060 -localhost:3141 --get :ma0 rtt:00:00:00.003202 -localhost:3141 --news=0 2768 123 :ma0 rtt:00:00:00.001038 -localhost:3141 --sync=0 2768 123 :ma0 rtt:00:00:00.001993 -localhost:3141 --get :ma0 rtt:00:00:00.002829 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000853 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000725 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_today_single_slot/test_today_single_slot.def_log :ma0 rtt:00:00:00.000794 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000746 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000819 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_today_single_slot/test_today_single_slot.def :ma0 rtt:00:00:00.002144 -localhost:3141 --restart :ma0 rtt:00:00:00.000716 -localhost:3141 --begin=test_today_single_slot :ma0 rtt:00:00:00.001863 -localhost:3141 --get :ma0 rtt:00:00:00.002164 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000783 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000722 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_today_relative_time_series/test_today_relative_time_series.def_log :ma0 rtt:00:00:00.000785 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000753 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000806 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_today_relative_time_series/test_today_relative_time_series.def :ma0 rtt:00:00:00.002235 -localhost:3141 --restart :ma0 rtt:00:00:00.000733 -localhost:3141 --begin=test_today_relative_time_series :ma0 rtt:00:00:00.000786 -localhost:3141 --get :ma0 rtt:00:00:00.002183 -localhost:3141 --news=0 2942 131 :ma0 rtt:00:00:00.001012 -localhost:3141 --sync=0 2942 131 :ma0 rtt:00:00:00.001338 -localhost:3141 --get :ma0 rtt:00:00:00.001887 -localhost:3141 --news=0 2943 131 :ma0 rtt:00:00:00.001040 -localhost:3141 --sync=0 2943 131 :ma0 rtt:00:00:00.001342 -localhost:3141 --get :ma0 rtt:00:00:00.001948 -localhost:3141 --news=0 2944 131 :ma0 rtt:00:00:00.000995 -localhost:3141 --sync=0 2944 131 :ma0 rtt:00:00:00.001923 -localhost:3141 --get :ma0 rtt:00:00:00.001860 -localhost:3141 --news=0 2990 131 :ma0 rtt:00:00:00.001043 -localhost:3141 --sync=0 2990 131 :ma0 rtt:00:00:00.001330 -localhost:3141 --get :ma0 rtt:00:00:00.001863 -localhost:3141 --news=0 2991 131 :ma0 rtt:00:00:00.001036 -localhost:3141 --sync=0 2991 131 :ma0 rtt:00:00:00.001339 -localhost:3141 --get :ma0 rtt:00:00:00.001856 -localhost:3141 --news=0 2992 131 :ma0 rtt:00:00:00.000989 -localhost:3141 --sync=0 2992 131 :ma0 rtt:00:00:00.001931 -localhost:3141 --get :ma0 rtt:00:00:00.001831 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000780 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000763 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_today_real_time_series/test_today_real_time_series.def_log :ma0 rtt:00:00:00.000823 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000767 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000849 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_today_real_time_series/test_today_real_time_series.def :ma0 rtt:00:00:00.002284 -localhost:3141 --restart :ma0 rtt:00:00:00.000712 -localhost:3141 --begin=test_today_real_time_series :ma0 rtt:00:00:00.000800 -localhost:3141 --get :ma0 rtt:00:00:00.002248 -localhost:3141 --news=0 3104 135 :ma0 rtt:00:00:00.001324 -localhost:3141 --news=0 3104 135 :ma0 rtt:00:00:00.001037 -localhost:3141 --news=0 3104 135 :ma0 rtt:00:00:00.001011 -localhost:3141 --sync=0 3104 135 :ma0 rtt:00:00:00.001937 -localhost:3141 --get :ma0 rtt:00:00:00.001925 -localhost:3141 --news=0 3149 135 :ma0 rtt:00:00:00.001022 -localhost:3141 --news=0 3149 135 :ma0 rtt:00:00:00.001019 -localhost:3141 --news=0 3149 135 :ma0 rtt:00:00:00.001017 -localhost:3141 --sync=0 3149 135 :ma0 rtt:00:00:00.002064 -localhost:3141 --get :ma0 rtt:00:00:00.001955 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000796 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000889 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_events/test_events.def_log :ma0 rtt:00:00:00.000794 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000782 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000808 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_events/test_events.def :ma0 rtt:00:00:00.003309 -localhost:3141 --restart :ma0 rtt:00:00:00.000500 -localhost:3141 --begin=test_events :ma0 rtt:00:00:00.002266 -localhost:3141 --get :ma0 rtt:00:00:00.002928 -localhost:3141 --news=0 3298 139 :ma0 rtt:00:00:00.001039 -localhost:3141 --sync=0 3298 139 :ma0 rtt:00:00:00.001313 -localhost:3141 --get :ma0 rtt:00:00:00.002571 -localhost:3141 --news=0 3301 139 :ma0 rtt:00:00:00.001035 -localhost:3141 --sync=0 3301 139 :ma0 rtt:00:00:00.001922 -localhost:3141 --get :ma0 rtt:00:00:00.002557 -localhost:3141 --news=0 3324 139 :ma0 rtt:00:00:00.001105 -localhost:3141 --sync=0 3324 139 :ma0 rtt:00:00:00.002705 -localhost:3141 --get :ma0 rtt:00:00:00.002523 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000732 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000742 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_complete/test_complete.def_log :ma0 rtt:00:00:00.000784 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000786 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000815 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_complete/test_complete.def :ma0 rtt:00:00:00.003330 -localhost:3141 --restart :ma0 rtt:00:00:00.000719 -localhost:3141 --begin=test_complete :ma0 rtt:00:00:00.002345 -localhost:3141 --get :ma0 rtt:00:00:00.002671 -localhost:3141 --news=0 3507 143 :ma0 rtt:00:00:00.001112 -localhost:3141 --sync=0 3507 143 :ma0 rtt:00:00:00.002612 -localhost:3141 --get :ma0 rtt:00:00:00.002276 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000744 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_complete_does_not_hold/test_complete_does_not_hold.def_log :ma0 rtt:00:00:00.000826 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000745 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000821 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_complete_does_not_hold/test_complete_does_not_hold.def :ma0 rtt:00:00:00.002355 -localhost:3141 --restart :ma0 rtt:00:00:00.000716 -localhost:3141 --begin=test_complete_does_not_hold :ma0 rtt:00:00:00.001561 -localhost:3141 --get :ma0 rtt:00:00:00.002340 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_complete_with_empty_family/test_complete_with_empty_family.def_log :ma0 rtt:00:00:00.000878 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000783 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000886 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_complete_with_empty_family/test_complete_with_empty_family.def :ma0 rtt:00:00:00.002763 -localhost:3141 --restart :ma0 rtt:00:00:00.000707 -localhost:3141 --begin=test_complete_with_empty_family :ma0 rtt:00:00:00.002443 -localhost:3141 --get :ma0 rtt:00:00:00.002457 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000884 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_abort_cmd/test_abort_cmd.def_log :ma0 rtt:00:00:00.000796 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000749 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000965 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_abort_cmd/test_abort_cmd.def :ma0 rtt:00:00:00.002040 -localhost:3141 --restart :ma0 rtt:00:00:00.000804 -localhost:3141 --begin=test_abort_cmd :ma0 rtt:00:00:00.001465 -localhost:3141 --get :ma0 rtt:00:00:00.002093 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000760 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000722 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_shutdown/test_shutdown.def_log :ma0 rtt:00:00:00.000799 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000758 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000807 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_shutdown/test_shutdown.def :ma0 rtt:00:00:00.002494 -localhost:3141 --restart :ma0 rtt:00:00:00.000726 -localhost:3141 --begin=test_shutdown :ma0 rtt:00:00:00.000824 -localhost:3141 --shutdown=yes :ma0 rtt:00:00:00.000680 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.002101 -localhost:3141 --sync=0 3969 159 :ma0 rtt:00:00:00.001582 -localhost:3141 --sync=0 3970 159 :ma0 rtt:00:00:00.001078 -localhost:3141 --sync=0 3970 159 :ma0 rtt:00:00:00.001101 -localhost:3141 --sync=0 3970 159 :ma0 rtt:00:00:00.001619 -localhost:3141 --restart :ma0 rtt:00:00:00.002204 -localhost:3141 --get :ma0 rtt:00:00:00.002526 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000805 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000721 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_suspend_node/test_suspend_node.def_log :ma0 rtt:00:00:00.000795 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000748 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000812 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_suspend_node/test_suspend_node.def :ma0 rtt:00:00:00.002633 -localhost:3141 --restart :ma0 rtt:00:00:00.000505 -localhost:3141 --begin=test_suspend_node :ma0 rtt:00:00:00.000566 -localhost:3141 --suspend /test_suspend_node/family :ma0 rtt:00:00:00.000511 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001683 -localhost:3141 --sync=0 4077 163 :ma0 rtt:00:00:00.001114 -localhost:3141 --sync=0 4077 163 :ma0 rtt:00:00:00.001066 -localhost:3141 --sync=0 4077 163 :ma0 rtt:00:00:00.002114 -localhost:3141 --sync=0 4098 163 :ma0 rtt:00:00:00.001920 -localhost:3141 --sync=0 4107 163 :ma0 rtt:00:00:00.001134 -localhost:3141 --sync=0 4107 163 :ma0 rtt:00:00:00.002167 -localhost:3141 --resume /test_suspend_node/family :ma0 rtt:00:00:00.002183 -localhost:3141 --get :ma0 rtt:00:00:00.002853 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000768 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000723 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_cron_time_series/test_cron_time_series.def_log :ma0 rtt:00:00:00.000786 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000759 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000851 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_cron_time_series/test_cron_time_series.def :ma0 rtt:00:00:00.002216 -localhost:3141 --restart :ma0 rtt:00:00:00.000736 -localhost:3141 --begin=test_cron_time_series :ma0 rtt:00:00:00.000794 -localhost:3141 --get :ma0 rtt:00:00:00.002235 -localhost:3141 --news=0 4258 167 :ma0 rtt:00:00:00.001067 -localhost:3141 --news=0 4258 167 :ma0 rtt:00:00:00.001010 -localhost:3141 --sync=0 4258 167 :ma0 rtt:00:00:00.001992 -localhost:3141 --get :ma0 rtt:00:00:00.001889 -localhost:3141 --news=0 4303 167 :ma0 rtt:00:00:00.001011 -localhost:3141 --news=0 4303 167 :ma0 rtt:00:00:00.001005 -localhost:3141 --sync=0 4303 167 :ma0 rtt:00:00:00.001989 -localhost:3141 --get :ma0 rtt:00:00:00.001898 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000748 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000703 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_file_cmd/test_file_cmd.def_log :ma0 rtt:00:00:00.000767 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000755 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000857 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_file_cmd/test_file_cmd.def :ma0 rtt:00:00:00.002238 -localhost:3141 --restart :ma0 rtt:00:00:00.000722 -localhost:3141 --begin=test_file_cmd :ma0 rtt:00:00:00.002131 -localhost:3141 --get :ma0 rtt:00:00:00.001859 -localhost:3141 --file=/test_file_cmd script 10000 :ma0 rtt:00:00:00.000734 -localhost:3141 --file=/test_file_cmd job 10000 :ma0 rtt:00:00:00.000575 -localhost:3141 --file=/test_file_cmd jobout 10000 :ma0 rtt:00:00:00.000808 -localhost:3141 --file=/test_file_cmd manual 10000 :ma0 rtt:00:00:00.000954 -localhost:3141 --file=/test_file_cmd kill 10000 :ma0 rtt:00:00:00.000872 -localhost:3141 --file=/test_file_cmd stat 10000 :ma0 rtt:00:00:00.000810 -localhost:3141 --file=/test_file_cmd/family script 10000 :ma0 rtt:00:00:00.000926 -localhost:3141 --file=/test_file_cmd/family job 10000 :ma0 rtt:00:00:00.000939 -localhost:3141 --file=/test_file_cmd/family jobout 10000 :ma0 rtt:00:00:00.000952 -localhost:3141 --file=/test_file_cmd/family manual 10000 :ma0 rtt:00:00:00.000865 -localhost:3141 --file=/test_file_cmd/family kill 10000 :ma0 rtt:00:00:00.000794 -localhost:3141 --file=/test_file_cmd/family stat 10000 :ma0 rtt:00:00:00.000895 -localhost:3141 --file=/test_file_cmd/family/t0 script 10000 :ma0 rtt:00:00:00.000787 -localhost:3141 --file=/test_file_cmd/family/t0 job 10000 :ma0 rtt:00:00:00.000948 -localhost:3141 --file=/test_file_cmd/family/t0 jobout 10000 :ma0 rtt:00:00:00.000908 -localhost:3141 --file=/test_file_cmd/family/t0 manual 10000 :ma0 rtt:00:00:00.000993 -localhost:3141 --file=/test_file_cmd/family/t0 kill 10000 :ma0 rtt:00:00:00.000818 -localhost:3141 --file=/test_file_cmd/family/t0 stat 10000 :ma0 rtt:00:00:00.000896 -localhost:3141 --file=/test_file_cmd/family/t1 script 10000 :ma0 rtt:00:00:00.000827 -localhost:3141 --file=/test_file_cmd/family/t1 job 10000 :ma0 rtt:00:00:00.000830 -localhost:3141 --file=/test_file_cmd/family/t1 jobout 10000 :ma0 rtt:00:00:00.000950 -localhost:3141 --file=/test_file_cmd/family/t1 manual 10000 :ma0 rtt:00:00:00.001013 -localhost:3141 --file=/test_file_cmd/family/t1 kill 10000 :ma0 rtt:00:00:00.000931 -localhost:3141 --file=/test_file_cmd/family/t1 stat 10000 :ma0 rtt:00:00:00.000987 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000917 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000856 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_triggers_and_meters/test_triggers_and_meters.def_log :ma0 rtt:00:00:00.000870 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000825 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.001000 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_triggers_and_meters/test_triggers_and_meters.def :ma0 rtt:00:00:00.006511 -localhost:3141 --restart :ma0 rtt:00:00:00.000536 -localhost:3141 --begin=test_triggers_and_meters :ma0 rtt:00:00:00.006932 -localhost:3141 --get :ma0 rtt:00:00:00.003926 -localhost:3141 --news=0 4594 175 :ma0 rtt:00:00:00.001023 -localhost:3141 --sync=0 4594 175 :ma0 rtt:00:00:00.002577 -localhost:3141 --get :ma0 rtt:00:00:00.003520 -localhost:3141 --news=0 4660 175 :ma0 rtt:00:00:00.001043 -localhost:3141 --sync=0 4660 175 :ma0 rtt:00:00:00.002591 -localhost:3141 --get :ma0 rtt:00:00:00.003536 -localhost:3141 --news=0 4726 175 :ma0 rtt:00:00:00.001038 -localhost:3141 --sync=0 4726 175 :ma0 rtt:00:00:00.002202 -localhost:3141 --get :ma0 rtt:00:00:00.003526 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000790 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000756 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_day/test_why_day.def_log :ma0 rtt:00:00:00.000783 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000750 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000879 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_day/test_why_day.def :ma0 rtt:00:00:00.002096 -localhost:3141 --restart :ma0 rtt:00:00:00.000718 -localhost:3141 --begin=test_why_day :ma0 rtt:00:00:00.000780 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001765 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000916 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_date/test_why_date.def_log :ma0 rtt:00:00:00.000793 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000765 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000889 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_date/test_why_date.def :ma0 rtt:00:00:00.002029 -localhost:3141 --restart :ma0 rtt:00:00:00.000697 -localhost:3141 --begin=test_why_date :ma0 rtt:00:00:00.000787 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001839 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_time/test_why_time.def_log :ma0 rtt:00:00:00.000800 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000802 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000797 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_time/test_why_time.def :ma0 rtt:00:00:00.002091 -localhost:3141 --restart :ma0 rtt:00:00:00.000718 -localhost:3141 --begin=test_why_time :ma0 rtt:00:00:00.000778 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001753 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_today/test_why_today.def_log :ma0 rtt:00:00:00.000764 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000746 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000775 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_today/test_why_today.def :ma0 rtt:00:00:00.002027 -localhost:3141 --restart :ma0 rtt:00:00:00.000718 -localhost:3141 --begin=test_why_today :ma0 rtt:00:00:00.000798 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001773 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_cron/test_why_cron.def_log :ma0 rtt:00:00:00.000815 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000785 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000944 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_cron/test_why_cron.def :ma0 rtt:00:00:00.002163 -localhost:3141 --restart :ma0 rtt:00:00:00.000714 -localhost:3141 --begin=test_why_cron :ma0 rtt:00:00:00.000853 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001839 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_limit/test_why_limit.def_log :ma0 rtt:00:00:00.000950 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000764 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000550 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_limit/test_why_limit.def :ma0 rtt:00:00:00.001851 -localhost:3141 --restart :ma0 rtt:00:00:00.000491 -localhost:3141 --begin=test_why_limit :ma0 rtt:00:00:00.001091 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001767 -localhost:3141 --get :ma0 rtt:00:00:00.001970 -localhost:3141 --get :ma0 rtt:00:00:00.002742 -localhost:3141 --get :ma0 rtt:00:00:00.002792 -localhost:3141 --get :ma0 rtt:00:00:00.002725 -localhost:3141 --get :ma0 rtt:00:00:00.002751 -localhost:3141 --get :ma0 rtt:00:00:00.002718 -localhost:3141 --get :ma0 rtt:00:00:00.002756 -localhost:3141 --get :ma0 rtt:00:00:00.002724 -localhost:3141 --get :ma0 rtt:00:00:00.002835 -localhost:3141 --get :ma0 rtt:00:00:00.002715 -localhost:3141 --get :ma0 rtt:00:00:00.002782 -localhost:3141 --get :ma0 rtt:00:00:00.002761 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_trigger/test_why_trigger.def_log :ma0 rtt:00:00:00.000829 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000767 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000850 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_trigger/test_why_trigger.def :ma0 rtt:00:00:00.002027 -localhost:3141 --restart :ma0 rtt:00:00:00.000734 -localhost:3141 --begin=test_why_trigger :ma0 rtt:00:00:00.000829 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001716 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_meter/test_why_meter.def_log :ma0 rtt:00:00:00.000784 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000739 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000789 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_meter/test_why_meter.def :ma0 rtt:00:00:00.002763 -localhost:3141 --restart :ma0 rtt:00:00:00.000854 -localhost:3141 --begin=test_why_meter :ma0 rtt:00:00:00.001467 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001438 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_event/test_why_event.def_log :ma0 rtt:00:00:00.000560 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000515 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000541 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_event/test_why_event.def :ma0 rtt:00:00:00.002027 -localhost:3141 --restart :ma0 rtt:00:00:00.000488 -localhost:3141 --begin=test_why_event :ma0 rtt:00:00:00.001042 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001318 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_user_var/test_why_user_var.def_log :ma0 rtt:00:00:00.000566 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000522 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000556 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_user_var/test_why_user_var.def :ma0 rtt:00:00:00.001786 -localhost:3141 --restart :ma0 rtt:00:00:00.000488 -localhost:3141 --begin=test_why_user_var :ma0 rtt:00:00:00.000972 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001155 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_gen_var/test_why_gen_var.def_log :ma0 rtt:00:00:00.000547 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000512 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000536 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_gen_var/test_why_gen_var.def :ma0 rtt:00:00:00.001831 -localhost:3141 --restart :ma0 rtt:00:00:00.000486 -localhost:3141 --begin=test_why_gen_var :ma0 rtt:00:00:00.001012 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001184 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_why_repeat/test_why_repeat.def_log :ma0 rtt:00:00:00.000596 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000511 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000536 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_why_repeat/test_why_repeat.def :ma0 rtt:00:00:00.002163 -localhost:3141 --restart :ma0 rtt:00:00:00.000504 -localhost:3141 --begin=test_why_repeat :ma0 rtt:00:00:00.001293 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001210 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000557 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_time_single_slot/test_time_single_slot.def_log :ma0 rtt:00:00:00.000519 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000510 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000535 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_time_single_slot/test_time_single_slot.def :ma0 rtt:00:00:00.001462 -localhost:3141 --restart :ma0 rtt:00:00:00.000483 -localhost:3141 --begin=test_time_single_slot :ma0 rtt:00:00:00.000562 -localhost:3141 --get :ma0 rtt:00:00:00.002240 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000812 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000747 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_time_multiple_single_slot/test_time_multiple_single_slot.def_log :ma0 rtt:00:00:00.000792 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000779 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000847 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_time_multiple_single_slot/test_time_multiple_single_slot.def :ma0 rtt:00:00:00.002199 -localhost:3141 --restart :ma0 rtt:00:00:00.000729 -localhost:3141 --begin=test_time_multiple_single_slot :ma0 rtt:00:00:00.000829 -localhost:3141 --get :ma0 rtt:00:00:00.002265 -localhost:3141 --news=0 5429 231 :ma0 rtt:00:00:00.001035 -localhost:3141 --news=0 5429 231 :ma0 rtt:00:00:00.001046 -localhost:3141 --news=0 5429 231 :ma0 rtt:00:00:00.001050 -localhost:3141 --sync=0 5429 231 :ma0 rtt:00:00:00.002064 -localhost:3141 --get :ma0 rtt:00:00:00.001902 -localhost:3141 --news=0 5476 231 :ma0 rtt:00:00:00.001045 -localhost:3141 --news=0 5476 231 :ma0 rtt:00:00:00.001037 -localhost:3141 --news=0 5476 231 :ma0 rtt:00:00:00.001031 -localhost:3141 --sync=0 5476 231 :ma0 rtt:00:00:00.001942 -localhost:3141 --get :ma0 rtt:00:00:00.001908 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000767 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000727 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_time_relative_time_series/test_time_relative_time_series.def_log :ma0 rtt:00:00:00.000803 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000751 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000812 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_time_relative_time_series/test_time_relative_time_series.def :ma0 rtt:00:00:00.002174 -localhost:3141 --restart :ma0 rtt:00:00:00.000747 -localhost:3141 --begin=test_time_relative_time_series :ma0 rtt:00:00:00.000923 -localhost:3141 --get :ma0 rtt:00:00:00.002217 -localhost:3141 --news=0 5586 235 :ma0 rtt:00:00:00.001040 -localhost:3141 --sync=0 5586 235 :ma0 rtt:00:00:00.001332 -localhost:3141 --get :ma0 rtt:00:00:00.001847 -localhost:3141 --news=0 5587 235 :ma0 rtt:00:00:00.001036 -localhost:3141 --sync=0 5587 235 :ma0 rtt:00:00:00.001330 -localhost:3141 --get :ma0 rtt:00:00:00.001862 -localhost:3141 --news=0 5588 235 :ma0 rtt:00:00:00.001030 -localhost:3141 --sync=0 5588 235 :ma0 rtt:00:00:00.001907 -localhost:3141 --get :ma0 rtt:00:00:00.001864 -localhost:3141 --news=0 5634 235 :ma0 rtt:00:00:00.001043 -localhost:3141 --sync=0 5634 235 :ma0 rtt:00:00:00.001330 -localhost:3141 --get :ma0 rtt:00:00:00.001869 -localhost:3141 --news=0 5635 235 :ma0 rtt:00:00:00.001084 -localhost:3141 --sync=0 5635 235 :ma0 rtt:00:00:00.001336 -localhost:3141 --get :ma0 rtt:00:00:00.001866 -localhost:3141 --news=0 5636 235 :ma0 rtt:00:00:00.001042 -localhost:3141 --sync=0 5636 235 :ma0 rtt:00:00:00.001944 -localhost:3141 --get :ma0 rtt:00:00:00.001866 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000753 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000728 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_time_real_series/test_time_real_series.def_log :ma0 rtt:00:00:00.000776 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000767 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000843 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_time_real_series/test_time_real_series.def :ma0 rtt:00:00:00.002184 -localhost:3141 --restart :ma0 rtt:00:00:00.000749 -localhost:3141 --begin=test_time_real_series :ma0 rtt:00:00:00.000790 -localhost:3141 --get :ma0 rtt:00:00:00.001729 -localhost:3141 --news=0 5746 239 :ma0 rtt:00:00:00.001022 -localhost:3141 --news=0 5746 239 :ma0 rtt:00:00:00.001054 -localhost:3141 --news=0 5746 239 :ma0 rtt:00:00:00.001027 -localhost:3141 --sync=0 5746 239 :ma0 rtt:00:00:00.001934 -localhost:3141 --get :ma0 rtt:00:00:00.001898 -localhost:3141 --news=0 5791 239 :ma0 rtt:00:00:00.001034 -localhost:3141 --news=0 5791 239 :ma0 rtt:00:00:00.001043 -localhost:3141 --news=0 5791 239 :ma0 rtt:00:00:00.001034 -localhost:3141 --sync=0 5791 239 :ma0 rtt:00:00:00.001973 -localhost:3141 --get :ma0 rtt:00:00:00.001872 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000810 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000747 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_late/test_late.def_log :ma0 rtt:00:00:00.000780 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000768 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000834 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_late/test_late.def :ma0 rtt:00:00:00.001888 -localhost:3141 --restart :ma0 rtt:00:00:00.000714 -localhost:3141 --begin=test_late :ma0 rtt:00:00:00.001453 -localhost:3141 --get :ma0 rtt:00:00:00.001910 -localhost:3141 --news=0 5868 243 :ma0 rtt:00:00:00.001042 -localhost:3141 --sync=0 5868 243 :ma0 rtt:00:00:00.001371 -localhost:3141 --get :ma0 rtt:00:00:00.001607 -localhost:3141 --news=0 5870 243 :ma0 rtt:00:00:00.001032 -localhost:3141 --sync=0 5870 243 :ma0 rtt:00:00:00.001619 -localhost:3141 --get :ma0 rtt:00:00:00.001537 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.001516 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000770 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000741 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_server_job_submission/test_server_job_submission.def_log :ma0 rtt:00:00:00.000797 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000762 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000810 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_server_job_submission/test_server_job_submission.def :ma0 rtt:00:00:00.002509 -localhost:3141 --restart :ma0 rtt:00:00:00.000717 -localhost:3141 --begin=test_server_job_submission :ma0 rtt:00:00:00.002936 -localhost:3141 --get :ma0 rtt:00:00:00.002446 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000778 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000705 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_restore_defs_from_check_pt/test_restore_defs_from_check_pt.def_log :ma0 rtt:00:00:00.000782 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000763 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000826 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_restore_defs_from_check_pt/test_restore_defs_from_check_pt.def :ma0 rtt:00:00:00.001965 -localhost:3141 --restart :ma0 rtt:00:00:00.000718 -localhost:3141 --begin=test_restore_defs_from_check_pt :ma0 rtt:00:00:00.001473 -localhost:3141 --get :ma0 rtt:00:00:00.001889 -localhost:3141 --check_pt=never :ma0 rtt:00:00:00.000714 -localhost:3141 --get :ma0 rtt:00:00:00.001421 -localhost:3141 --check_pt :ma0 rtt:00:00:00.001161 -localhost:3141 --restore_from_checkpt :ma0 rtt:00:00:00.000741 -localhost:3141 --halt=yes :ma0 rtt:00:00:00.000691 -localhost:3141 --restore_from_checkpt :ma0 rtt:00:00:00.000716 -localhost:3141 --delete _all_ yes :ma0 rtt:00:00:00.000851 -localhost:3141 --get :ma0 rtt:00:00:00.000889 -localhost:3141 --restore_from_checkpt :ma0 rtt:00:00:00.001208 -localhost:3141 --get :ma0 rtt:00:00:00.001442 -localhost:3141 --check_pt=on_time:120 :ma0 rtt:00:00:00.000689 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000737 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000723 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_wait_cmd/test_wait_cmd.def_log :ma0 rtt:00:00:00.000797 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000765 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000770 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_wait_cmd/test_wait_cmd.def :ma0 rtt:00:00:00.002531 -localhost:3141 --restart :ma0 rtt:00:00:00.000509 -localhost:3141 --begin=test_wait_cmd :ma0 rtt:00:00:00.002830 -localhost:3141 --get :ma0 rtt:00:00:00.002840 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000860 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_wait_cmd_parse_fail/test_wait_cmd_parse_fail.def_log :ma0 rtt:00:00:00.000800 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000767 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000847 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_wait_cmd_parse_fail/test_wait_cmd_parse_fail.def :ma0 rtt:00:00:00.002834 -localhost:3141 --restart :ma0 rtt:00:00:00.000726 -localhost:3141 --begin=test_wait_cmd_parse_fail :ma0 rtt:00:00:00.004206 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.002854 -localhost:3141 --sync=0 6337 261 :ma0 rtt:00:00:00.002927 -localhost:3141 --sync=0 6408 261 :ma0 rtt:00:00:00.002610 -localhost:3141 --sync=0 6438 261 :ma0 rtt:00:00:00.000789 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_wait_cmd_non_existant_paths/test_wait_cmd_non_existant_paths.def_log :ma0 rtt:00:00:00.000822 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000759 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000844 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_wait_cmd_non_existant_paths/test_wait_cmd_non_existant_paths.def :ma0 rtt:00:00:00.002826 -localhost:3141 --restart :ma0 rtt:00:00:00.000727 -localhost:3141 --begin=test_wait_cmd_non_existant_paths :ma0 rtt:00:00:00.004255 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.002858 -localhost:3141 --sync=0 6541 265 :ma0 rtt:00:00:00.002904 -localhost:3141 --sync=0 6584 265 :ma0 rtt:00:00:00.002972 -localhost:3141 --sync=0 6648 265 :ma0 rtt:00:00:00.000773 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000767 -localhost:3141 --log=new Test/data/ECF_HOME_debug/test_alias/test_alias.def_log :ma0 rtt:00:00:00.000773 -localhost:3141 --log=clear :ma0 rtt:00:00:00.000775 -localhost:3141 --delete _all_ force yes :ma0 rtt:00:00:00.000824 -localhost:3141 --load=Test/data/ECF_HOME_debug/test_alias/test_alias.def :ma0 rtt:00:00:00.001962 -localhost:3141 --restart :ma0 rtt:00:00:00.000772 -localhost:3141 --begin=test_alias :ma0 rtt:00:00:00.001498 -localhost:3141 --get :ma0 rtt:00:00:00.001978 -localhost:3141 --file=/test_alias/task_a script 10000 :ma0 rtt:00:00:00.000870 -localhost:3141 --sync_full=0 :ma0 rtt:00:00:00.002039 -localhost:3141 --sync=0 6723 269 :ma0 rtt:00:00:00.001990 -localhost:3141 --sync=0 6744 269 :ma0 rtt:00:00:00.002100 -localhost:3141 --order=/test_alias/task_a/alias0 down :ma0 rtt:00:00:00.000795 -localhost:3141 --sync=0 6750 269 :ma0 rtt:00:00:00.001277 -localhost:3141 --order=/test_alias/task_a/alias0 up :ma0 rtt:00:00:00.000739 -localhost:3141 --sync=0 6752 269 :ma0 rtt:00:00:00.001272 -localhost:3141 --order=/test_alias/task_a/alias0 order :ma0 rtt:00:00:00.000768 -localhost:3141 --sync=0 6754 269 :ma0 rtt:00:00:00.001300 -localhost:3141 --order=/test_alias/task_a/alias0 alpha :ma0 rtt:00:00:00.000769 -localhost:3141 --sync=0 6756 269 :ma0 rtt:00:00:00.001274 -localhost:3141 --delete yes /test_alias/task_a/alias0 :ma0 rtt:00:00:00.000748 -localhost:3141 --delete yes /test_alias/task_a/alias1 :ma0 rtt:00:00:00.000741 -localhost:3141 --sync=0 6758 269 :ma0 rtt:00:00:00.001274 -localhost:3141 --zombie_get :ma0 rtt:00:00:00.000768 -localhost:3141 --suites :ma0 rtt:00:00:00.000752 -localhost:3141 --stats :ma0 rtt:00:00:00.000989 -localhost:3141 --terminate=yes :ma0 rtt:00:00:00.001247 diff --git a/Viewer/ecflowUI/images/aviso.svg b/Viewer/ecflowUI/images/aviso.svg new file mode 100644 index 000000000..14bbd4def --- /dev/null +++ b/Viewer/ecflowUI/images/aviso.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + ECMWF + + + en-GB + + + ecFlowUI icon + + + ecFlowUI icon + + + + + + + A + + + + + + + diff --git a/Viewer/ecflowUI/images/icon_no_access.svg b/Viewer/ecflowUI/images/icon_no_access.svg new file mode 100644 index 000000000..d6b27c5b1 --- /dev/null +++ b/Viewer/ecflowUI/images/icon_no_access.svg @@ -0,0 +1,10 @@ + + + no_access + + + diff --git a/Viewer/ecflowUI/images/remote.svg b/Viewer/ecflowUI/images/remote.svg new file mode 100644 index 000000000..0fb5e036c --- /dev/null +++ b/Viewer/ecflowUI/images/remote.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + ECMWF + + + en-GB + + + ecFlowUI icon + + + ecFlowUI icon + + + + + + + E + + + + + + + diff --git a/Viewer/ecflowUI/src/CMakeLists.txt b/Viewer/ecflowUI/src/CMakeLists.txt index 7f4441a5f..8632d273c 100644 --- a/Viewer/ecflowUI/src/CMakeLists.txt +++ b/Viewer/ecflowUI/src/CMakeLists.txt @@ -215,6 +215,7 @@ set(viewer_srcs VAutoArchiveAttr.hpp VAutoCancelAttr.hpp VAutoRestoreAttr.hpp + VAvisoAttr.hpp VConfig.hpp VConfigLoader.hpp VDateAttr.hpp @@ -235,6 +236,7 @@ set(viewer_srcs VLimitAttr.hpp VLimiterAttr.hpp VMeterAttr.hpp + VMirrorAttr.hpp VModelData.hpp VNState.hpp VNode.hpp @@ -491,6 +493,7 @@ set(viewer_srcs VAutoArchiveAttr.cpp VAutoCancelAttr.cpp VAutoRestoreAttr.cpp + VAvisoAttr.cpp VConfig.cpp VConfigLoader.cpp VDateAttr.cpp @@ -510,6 +513,7 @@ set(viewer_srcs VLimitAttr.cpp VLimiterAttr.cpp VMeterAttr.cpp + VMirrorAttr.cpp VModelData.cpp VNode.cpp VNodeList.cpp @@ -811,9 +815,7 @@ ecbuild_add_executable( ${CMAKE_CURRENT_BINARY_DIR} LIBS viewer - libclient - base - node + ecflow_all Threads::Threads m dl diff --git a/Viewer/ecflowUI/src/NodeExpression.cpp b/Viewer/ecflowUI/src/NodeExpression.cpp index 8c630ccfd..39ca237c7 100644 --- a/Viewer/ecflowUI/src/NodeExpression.cpp +++ b/Viewer/ecflowUI/src/NodeExpression.cpp @@ -59,19 +59,8 @@ NodeExpressionParser::NodeExpressionParser() { } QStringList attrNames; - attrNames << "meter" - << "event" - << "repeat" - << "trigger" - << "label" - << "time" - << "date" - << "late" - << "limit" - << "limit" - << "limiter" - << "var" - << "genvar"; + attrNames << "meter" << "event" << "repeat" << "trigger" << "label" << "time" << "date" << "late" << "limit" + << "limiter" << "var" << "genvar" << "mirror" << "aviso"; Q_FOREACH (QString s, attrNames) { VAttributeType* t = VAttributeType::find(s.toStdString()); Q_ASSERT(t); @@ -121,10 +110,8 @@ bool NodeExpressionParser::isEnvVar(const std::string& str) const { } bool NodeExpressionParser::isNodeHasAttribute(const std::string& str) const { - if (str == "has_triggers" || str == "has_time" || str == "has_date" || str == "locked") - return true; - - return false; + constexpr std::array searchable = {"has_triggers", "has_time", "has_date", "locked", "has_aviso", "has_mirror"}; + return std::find(searchable.begin(), searchable.end(), str) != searchable.end(); } bool NodeExpressionParser::isNodeFlag(const std::string& str) const { @@ -137,18 +124,30 @@ bool NodeExpressionParser::isNodeFlag(const std::string& str) const { } bool NodeExpressionParser::isWhatToSearchIn(const std::string& str, bool& isAttr) const { - // list of non-attribute items that we can search in - if (str == "node_name" || str == "node_path") { + + constexpr auto is_searchable_nonattribute = [](const std::string& str) { + static constexpr std::array searchable = {"node_name", "node_path"}; + return std::find(searchable.begin(), searchable.end(), str) != searchable.end(); + }; + + constexpr auto is_searchable_attribute = [](const std::string& str) { + static constexpr std::array searchable = { + "var_name", "var_value", "var_type", "label_name", "label_value", + "meter_name", "meter_value", "event_name", "event_value", "date_name", + "time_name", "limit_name", "limit_value", "limit_max", "limiter_name", + "repeat_name", "repeat_value", "trigger_expression", "mirror_name", "mirror_remote_path", + "mirror_remote_host", "mirror_remote_port", "mirror_polling", "aviso_name", "aviso_listener", + "aviso_url", "aviso_schema", "aviso_polling", "aviso_auth"}; + return std::find(searchable.begin(), searchable.end(), str) != searchable.end(); + }; + + if (is_searchable_nonattribute(str)) { isAttr = false; return true; } // list of attributes that we can search in - else if (str == "var_name" || str == "var_value" || str == "var_type" || str == "label_name" || - str == "label_value" || str == "meter_name" || str == "meter_value" || str == "event_name" || - str == "event_value" || str == "date_name" || str == "time_name" || str == "limit_name" || - str == "limit_value" || str == "limit_max" || str == "limiter_name" || str == "repeat_name" || - str == "repeat_value" || str == "trigger_expression") { + else if (is_searchable_attribute(str)) { isAttr = true; return true; } @@ -818,6 +817,12 @@ bool NodeAttributeCondition::execute(VItem* item) { else if (nodeAttrName_ == "has_triggers") { return (node->triggerAst() || node->completeAst()); } + else if (nodeAttrName_ == "has_aviso") { + return !node->avisos().empty(); + } + else if (nodeAttrName_ == "has_mirror") { + return !node->mirrors().empty(); + } } return false; diff --git a/Viewer/ecflowUI/src/NodeExpression.hpp b/Viewer/ecflowUI/src/NodeExpression.hpp index b4637449d..9845d01c4 100644 --- a/Viewer/ecflowUI/src/NodeExpression.hpp +++ b/Viewer/ecflowUI/src/NodeExpression.hpp @@ -45,6 +45,8 @@ class NodeExpressionParser { LIMITER, VAR, GENVAR, + AVISO, + MIRROR, BADATTRIBUTE }; diff --git a/Viewer/ecflowUI/src/NodeViewDelegate.cpp b/Viewer/ecflowUI/src/NodeViewDelegate.cpp index 03baff8cb..21256cda0 100644 --- a/Viewer/ecflowUI/src/NodeViewDelegate.cpp +++ b/Viewer/ecflowUI/src/NodeViewDelegate.cpp @@ -84,6 +84,9 @@ NodeViewDelegate::NodeViewDelegate(QWidget* parent) : QStyledItemDelegate(parent errPix_ = QPixmap(QPixmap::fromImage(img)); } + avisoPixId_ = IconProvider::add(":/viewer/aviso.svg", "aviso"); + mirrorPixId_ = IconProvider::add(":/viewer/remote.svg", "mirror"); + grad_.setCoordinateMode(QGradient::ObjectBoundingMode); grad_.setStart(0, 0); grad_.setFinalStop(0, 1); @@ -120,6 +123,8 @@ NodeViewDelegate::NodeViewDelegate(QWidget* parent) : QStyledItemDelegate(parent attrRenderers_["meter"] = &NodeViewDelegate::renderMeter; attrRenderers_["label"] = &NodeViewDelegate::renderLabel; + attrRenderers_["aviso"] = &NodeViewDelegate::renderAviso; + attrRenderers_["mirror"] = &NodeViewDelegate::renderMirror; attrRenderers_["event"] = &NodeViewDelegate::renderEvent; attrRenderers_["var"] = &NodeViewDelegate::renderVar; attrRenderers_["genvar"] = &NodeViewDelegate::renderGenvar; @@ -661,6 +666,324 @@ void NodeViewDelegate::renderLabel(QPainter* painter, size = QSize(totalWidth, labelHeight(multiCnt + 1)); } +void NodeViewDelegate::renderAviso(QPainter* painter, + QStringList data, + const QStyleOptionViewItem& option, + QSize& size) const { + + int totalWidth = 0; + size = QSize(totalWidth, attrBox_->fullHeight); + + if (data.count() < 2) + return; + + QString name = data.at(1); // + ":"; + QString val; + if (data.count() > 2) + val = data.at(2); + + bool selected = option.state & QStyle::State_Selected; + + // The border rect (we will adjust its width) + QRect contRect = option.rect.adjusted(attrBox_->leftMargin, + attrBox_->topMargin + attrBox_->topPadding, + 0, + -attrBox_->bottomMargin - attrBox_->bottomPadding); + + int currentRight = contRect.x(); + int multiCnt = val.count('\n'); + + QRect avisoRect; + QRect nameRect; + QRect valRect, valRestRect; + + QFont nameFont = attrFont_; + nameFont.setBold(true); + QFont valFont = attrFont_; + QString valFirst, valRest; + QString full; + + auto avisoPix = IconProvider::pixmapToHeight(avisoPixId_, contRect.height()); + avisoRect = contRect.adjusted(attrBox_->leftPadding, 0, 0, 0); + avisoRect.setWidth(avisoPix.width()); + + if (multiCnt == 0) { + // The text rectangle + QFontMetrics fm(nameFont); + int nameWidth = ViewerUtil::textWidth(fm, name); + nameRect = contRect; + nameRect.setX(avisoRect.x() + avisoRect.width() + attrBox_->spacing); + nameRect.setWidth(nameWidth); + + // The value rectangle + fm = QFontMetrics(valFont); + int valWidth = ViewerUtil::textWidth(fm, val); + valRect = nameRect; + valRect.setX(nameRect.x() + nameRect.width() + attrBox_->spacing); + valRect.setWidth(valWidth); + + // Adjust the filled rect width + currentRight = valRect.x() + valRect.width(); + } + else { + // The text rectangle + QFontMetrics fm(nameFont); + int nameWidth = ViewerUtil::textWidth(fm, name); + nameRect = contRect; + nameRect.setX(avisoRect.x() + avisoRect.width() + attrBox_->spacing); + nameRect.setWidth(nameWidth); + nameRect.setHeight(attrBox_->height - attrBox_->topPadding - attrBox_->bottomPadding); + + // The value rectangles + fm = QFontMetrics(valFont); + + // First row comes after the name rect! + QStringList valLst = val.split("\n"); + Q_ASSERT(valLst.count() > 0); + valFirst = valLst[0]; + + valRect = nameRect; + valRect.setX(nameRect.x() + nameRect.width() + attrBox_->spacing); + valRect.setWidth(ViewerUtil::textWidth(fm, valFirst)); + + // The rest of the rows + valLst.takeFirst(); + valRest = valLst.join("\n"); + QSize valSize = fm.size(0, valRest); + + valRestRect = QRect(nameRect.x(), nameRect.y() + nameRect.height() + 2, valSize.width(), valSize.height()); + + currentRight = qMax(valRect.x() + valRect.width(), valRestRect.x() + valRestRect.width()); + + val = valFirst + " " + valRest; + } + + // Define clipping + int rightPos = currentRight + attrBox_->rightPadding + attrBox_->rightMargin; + totalWidth = rightPos - option.rect.left(); + const bool setClipRect = rightPos > option.rect.right(); + if (setClipRect) { + painter->save(); + painter->setClipRect(option.rect); + } + + QPen fontPen(Qt::black); + LabelStyle* labelStyle = labelStyle_[DefaultLabel]; + QList types; + types << ErrorLabel << WarningLabel << InfoLabel; + full = name + " " + val; + Q_FOREACH (LabelType t, types) { + if (labelStyle_[t]->enabled_) { + if (full.contains(labelStyle_[t]->regex_)) { + labelStyle = labelStyle_[t]; + break; + } + } + } + + if (labelStyle) { + if (labelStyle->enabled_) { + fontPen = labelStyle->fontPen_; + // draw bg + if (labelStyle->enabledBg_) { + QRect sr = option.rect; + sr.setWidth(rightPos - sr.x()); + painter->fillRect(attrBox_->adjustSelectionRect(sr), labelStyle->bgBrush_); + } + } + } + + // aviso pixmap + painter->drawPixmap(avisoRect, avisoPix); + + // Draw name + painter->setPen(fontPen); + painter->setFont(nameFont); + painter->drawText(attrBox_->adjustTextRect(nameRect), Qt::AlignLeft | Qt::AlignVCenter, name); + + // Draw value + painter->setPen(fontPen); + painter->setFont(valFont); + + if (multiCnt == 0) + painter->drawText(attrBox_->adjustTextRect(valRect), Qt::AlignLeft | Qt::AlignVCenter, val); + else { + painter->drawText(attrBox_->adjustTextRect(valRect), Qt::AlignLeft | Qt::AlignVCenter, valFirst); + painter->drawText(valRestRect, Qt::AlignLeft | Qt::AlignVCenter, valRest); + } + + if (selected && drawAttrSelectionRect_) { + QRect sr = option.rect; + sr.setWidth(rightPos - sr.x()); + renderSelectionRect(painter, attrBox_->adjustSelectionRect(sr)); + } + + if (setClipRect) { + painter->restore(); + } + + size = QSize(totalWidth, labelHeight(multiCnt + 1)); +} + +void NodeViewDelegate::renderMirror(QPainter* painter, + QStringList data, + const QStyleOptionViewItem& option, + QSize& size) const { + + int totalWidth = 0; + size = QSize(totalWidth, attrBox_->fullHeight); + + if (data.count() < 2) + return; + + QString name = data.at(1); // + ":"; + QString val; + if (data.count() > 2) + val = data.at(2); + + bool selected = option.state & QStyle::State_Selected; + + // The border rect (we will adjust its width) + QRect contRect = option.rect.adjusted(attrBox_->leftMargin, + attrBox_->topMargin + attrBox_->topPadding, + 0, + -attrBox_->bottomMargin - attrBox_->bottomPadding); + + int currentRight = contRect.x(); + int multiCnt = val.count('\n'); + + QRect mirrorRect; + QRect nameRect; + QRect valRect, valRestRect; + + QFont nameFont = attrFont_; + nameFont.setBold(true); + QFont valFont = attrFont_; + QString valFirst, valRest; + QString full; + + auto avisoPix = IconProvider::pixmapToHeight(mirrorPixId_, contRect.height()); + mirrorRect = contRect.adjusted(attrBox_->leftPadding, 0, 0, 0); + mirrorRect.setWidth(avisoPix.width()); + + if (multiCnt == 0) { + // The text rectangle + QFontMetrics fm(nameFont); + int nameWidth = ViewerUtil::textWidth(fm, name); + nameRect = contRect; + nameRect.setX(mirrorRect.x() + mirrorRect.width() + attrBox_->spacing); + nameRect.setWidth(nameWidth); + + // The value rectangle + fm = QFontMetrics(valFont); + int valWidth = ViewerUtil::textWidth(fm, val); + valRect = nameRect; + valRect.setX(nameRect.x() + nameRect.width() + attrBox_->spacing); + valRect.setWidth(valWidth); + + // Adjust the filled rect width + currentRight = valRect.x() + valRect.width(); + } + else { + // The text rectangle + QFontMetrics fm(nameFont); + int nameWidth = ViewerUtil::textWidth(fm, name); + nameRect = contRect; + nameRect.setX(mirrorRect.x() + mirrorRect.width() + attrBox_->spacing); + nameRect.setWidth(nameWidth); + nameRect.setHeight(attrBox_->height - attrBox_->topPadding - attrBox_->bottomPadding); + + // The value rectangles + fm = QFontMetrics(valFont); + + // First row comes after the name rect! + QStringList valLst = val.split("\n"); + Q_ASSERT(valLst.count() > 0); + valFirst = valLst[0]; + + valRect = nameRect; + valRect.setX(nameRect.x() + nameRect.width() + attrBox_->spacing); + valRect.setWidth(ViewerUtil::textWidth(fm, valFirst)); + + // The rest of the rows + valLst.takeFirst(); + valRest = valLst.join("\n"); + QSize valSize = fm.size(0, valRest); + + valRestRect = QRect(nameRect.x(), nameRect.y() + nameRect.height() + 2, valSize.width(), valSize.height()); + + currentRight = qMax(valRect.x() + valRect.width(), valRestRect.x() + valRestRect.width()); + + val = valFirst + " " + valRest; + } + + // Define clipping + int rightPos = currentRight + attrBox_->rightPadding + attrBox_->rightMargin; + totalWidth = rightPos - option.rect.left(); + const bool setClipRect = rightPos > option.rect.right(); + if (setClipRect) { + painter->save(); + painter->setClipRect(option.rect); + } + + QPen fontPen(Qt::black); + LabelStyle* labelStyle = labelStyle_[DefaultLabel]; + QList types; + types << ErrorLabel << WarningLabel << InfoLabel; + full = name + " " + val; + Q_FOREACH (LabelType t, types) { + if (labelStyle_[t]->enabled_) { + if (full.contains(labelStyle_[t]->regex_)) { + labelStyle = labelStyle_[t]; + break; + } + } + } + + if (labelStyle) { + if (labelStyle->enabled_) { + fontPen = labelStyle->fontPen_; + // draw bg + if (labelStyle->enabledBg_) { + QRect sr = option.rect; + sr.setWidth(rightPos - sr.x()); + painter->fillRect(attrBox_->adjustSelectionRect(sr), labelStyle->bgBrush_); + } + } + } + + // aviso pixmap + painter->drawPixmap(mirrorRect, avisoPix); + + // Draw name + painter->setPen(fontPen); + painter->setFont(nameFont); + painter->drawText(attrBox_->adjustTextRect(nameRect), Qt::AlignLeft | Qt::AlignVCenter, name); + + // Draw value + painter->setPen(fontPen); + painter->setFont(valFont); + + if (multiCnt == 0) + painter->drawText(attrBox_->adjustTextRect(valRect), Qt::AlignLeft | Qt::AlignVCenter, val); + else { + painter->drawText(attrBox_->adjustTextRect(valRect), Qt::AlignLeft | Qt::AlignVCenter, valFirst); + painter->drawText(valRestRect, Qt::AlignLeft | Qt::AlignVCenter, valRest); + } + + if (selected && drawAttrSelectionRect_) { + QRect sr = option.rect; + sr.setWidth(rightPos - sr.x()); + renderSelectionRect(painter, attrBox_->adjustSelectionRect(sr)); + } + + if (setClipRect) { + painter->restore(); + } + + size = QSize(totalWidth, labelHeight(multiCnt + 1)); +} + void NodeViewDelegate::labelSize(QStringList data, int& totalWidth, int& totalHeight) const { if (data.count() < 2) return; diff --git a/Viewer/ecflowUI/src/NodeViewDelegate.hpp b/Viewer/ecflowUI/src/NodeViewDelegate.hpp index b3dc11144..fb7a28afa 100644 --- a/Viewer/ecflowUI/src/NodeViewDelegate.hpp +++ b/Viewer/ecflowUI/src/NodeViewDelegate.hpp @@ -172,6 +172,8 @@ class NodeViewDelegate : public QStyledItemDelegate, public VPropertyObserver { virtual void renderMeter(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; virtual void renderLabel(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; + virtual void renderAviso(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; + virtual void renderMirror(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; virtual void renderEvent(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; virtual void renderVar(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; virtual void renderGenvar(QPainter* painter, QStringList data, const QStyleOptionViewItem& option, QSize&) const; @@ -245,6 +247,8 @@ class NodeViewDelegate : public QStyledItemDelegate, public VPropertyObserver { QPen holdingTimeFontPen_; QPen holdingDateFontPen_; + int avisoPixId_; + int mirrorPixId_; int holdingTimePixId_; int holdingDatePixId_; diff --git a/Viewer/ecflowUI/src/VAttributeType.cpp b/Viewer/ecflowUI/src/VAttributeType.cpp index 90a122570..9293d17ba 100644 --- a/Viewer/ecflowUI/src/VAttributeType.cpp +++ b/Viewer/ecflowUI/src/VAttributeType.cpp @@ -154,6 +154,7 @@ static SimpleLoader loader("attribute"); #include "VAutoArchiveAttr.hpp" #include "VAutoCancelAttr.hpp" #include "VAutoRestoreAttr.hpp" +#include "VAvisoAttr.hpp" #include "VDateAttr.hpp" #include "VEventAttr.hpp" #include "VGenVarAttr.hpp" @@ -162,6 +163,7 @@ static SimpleLoader loader("attribute"); #include "VLimitAttr.hpp" #include "VLimiterAttr.hpp" #include "VMeterAttr.hpp" +#include "VMirrorAttr.hpp" #include "VQueueAttr.hpp" #include "VRepeatAttr.hpp" #include "VTimeAttr.hpp" @@ -171,6 +173,8 @@ static SimpleLoader loader("attribute"); static VLabelAttrType labelAttrType; static VMeterAttrType meterAttType; static VEventAttrType eventAttrType; +static VAvisoAttrType avisoAttrType; +static VMirrorAttrType mirrorAttrType; static VLimitAttrType limitAttrType; static VLimiterAttrType limiterAttrType; static VRepeatAttrType repeatAttrType; diff --git a/Viewer/ecflowUI/src/VAvisoAttr.cpp b/Viewer/ecflowUI/src/VAvisoAttr.cpp new file mode 100644 index 000000000..6e38d594e --- /dev/null +++ b/Viewer/ecflowUI/src/VAvisoAttr.cpp @@ -0,0 +1,150 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "VAvisoAttr.hpp" + +#include "VAttributeType.hpp" +#include "VNode.hpp" +#include "ecflow/node/AvisoAttr.hpp" + +//================================ +// VAvisoAttrType +//================================ + +VAvisoAttrType::VAvisoAttrType() : VAttributeType("aviso") { + dataCount_ = 9; + searchKeyToData_["aviso_name"] = NameIndex; + searchKeyToData_["aviso_listener"] = ListenerIndex; + searchKeyToData_["aviso_url"] = UrlIndex; + searchKeyToData_["aviso_schema"] = SchemaIndex; + searchKeyToData_["aviso_polling"] = PollingIndex; + searchKeyToData_["aviso_revision"] = RevisionIndex; + searchKeyToData_["aviso_auth"] = AuthIndex; + searchKeyToData_["aviso_reason"] = ReasonIndex; + scanProc_ = VAvisoAttr::scan; +} + +QString VAvisoAttrType::toolTip(QStringList d) const { + QString t = "Type: Aviso
"; + if (d.count() == dataCount_) { + t += "Name: " + d[NameIndex] + "
"; + t += "Listener: " + d[ListenerIndex] + "
"; + t += "URL: " + d[UrlIndex] + "
"; + t += "Schema: " + d[SchemaIndex] + "
"; + t += "Polling: " + d[PollingIndex] + " s
"; + t += "Revision: " + d[RevisionIndex] + "
"; + t += "Auth: " + d[AuthIndex]; + if (auto& reason = d[ReasonIndex]; !reason.isEmpty()) { + t += "
Reason: " + d[ReasonIndex] + ""; + } + } + return t; +} + +QString VAvisoAttrType::definition(QStringList d) const { + QString t = "aviso"; + if (d.count() == dataCount_) { + t += " " + d[NameIndex] + " '" + d[ListenerIndex] + "'"; + } + return t; +} + +void VAvisoAttrType::encode(const ecf::AvisoAttr& aviso, QStringList& data, bool firstLine) const { + std::string val = aviso.listener(); + + if (firstLine) { + std::size_t pos = val.find("\n"); + if (pos != std::string::npos) { + val.resize(pos); + } + } + + data << qName_ // TypeIndex + << QString::fromStdString(aviso.name()) // NameIndex + << QString::fromStdString(val) // ListenerIndex + << QString::fromStdString(aviso.url()) // UrlIndex + << QString::fromStdString(aviso.schema()) // SchemaIndex + << QString::fromStdString(aviso.polling()) // PollingIndex + << QString::number(aviso.revision()) // Revision Index + << QString::fromStdString(aviso.auth()) // AuthIndex + << QString::fromStdString(aviso.reason()); // ReasonIndex +} + +void VAvisoAttrType::encode_empty(QStringList& data) const { + data << qName_; +} + +//===================================================== +// +// VAvisoAttr +// +//===================================================== + +VAvisoAttr::VAvisoAttr(VNode* parent, [[maybe_unused]] const ecf::AvisoAttr& aviso, int index) + : VAttribute(parent, index) { +} + +int VAvisoAttr::lineNum() const { + if (parent_->node_) { + const std::vector& v = parent_->node_->avisos(); + std::string val = v[index_].listener(); + return std::count(val.begin(), val.end(), '\n') + 1; + } + + return 1; +} + +VAttributeType* VAvisoAttr::type() const { + static VAttributeType* atype = VAttributeType::find("aviso"); + return atype; +} + +QStringList VAvisoAttr::data(bool firstLine) const { + static auto* atype = static_cast(type()); + QStringList s; + if (parent_->node_) { + const std::vector& v = parent_->node_->avisos(); + if (index_ < static_cast(v.size())) + atype->encode(v[index_], s, firstLine); + + // this can happen temporarily during update when: + // + // - an attribute was already deleted + // - the notification was emitted from the update thread, but + // has not yet reached the main thread + // - here, in the main thread, we still have the old (incorrect) attribute number + // + // * In this case, as safety measure, we encode an empty attribute. + // When the notification arrives all the attributes of the given node will be rescanned + // and will be set with the correct state. + else + atype->encode_empty(s); + } + return s; +} + +std::string VAvisoAttr::strName() const { + if (parent_->node_) { + const std::vector& v = parent_->node_->avisos(); + return v[index_].name(); + } + return {}; +} + +void VAvisoAttr::scan(VNode* vnode, std::vector& vec) { + if (vnode->node_) { + const std::vector& v = vnode->node_->avisos(); + + auto n = static_cast(v.size()); + for (int i = 0; i < n; i++) { + vec.push_back(new VAvisoAttr(vnode, v[i], i)); + } + } +} diff --git a/Viewer/ecflowUI/src/VAvisoAttr.hpp b/Viewer/ecflowUI/src/VAvisoAttr.hpp new file mode 100644 index 000000000..bd7a3a2f4 --- /dev/null +++ b/Viewer/ecflowUI/src/VAvisoAttr.hpp @@ -0,0 +1,64 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_viewer_VAvisoAttr_HPP +#define ecflow_viewer_VAvisoAttr_HPP + +#include +#include + +#include + +#include "VAttribute.hpp" +#include "VAttributeType.hpp" + +class AttributeFilter; +class VAttributeType; +class VNode; + +namespace ecf { +class AvisoAttr; +} + +class VAvisoAttrType : public VAttributeType { +public: + explicit VAvisoAttrType(); + QString toolTip(QStringList d) const override; + QString definition(QStringList d) const override; + void encode(const ecf::AvisoAttr& aviso, QStringList& data, bool firstLine) const; + void encode_empty(QStringList& data) const; + +private: + enum DataIndex { + TypeIndex = 0, + NameIndex = 1, + ListenerIndex = 2, + UrlIndex = 3, + SchemaIndex = 4, + PollingIndex = 5, + RevisionIndex = 6, + AuthIndex = 7, + ReasonIndex = 8 + }; +}; + +class VAvisoAttr : public VAttribute { +public: + VAvisoAttr(VNode* parent, const ecf::AvisoAttr&, int index); + + int lineNum() const override; + VAttributeType* type() const override; + QStringList data(bool firstLine) const override; + std::string strName() const override; + + static void scan(VNode* vnode, std::vector& vec); +}; + +#endif /* ecflow_viewer_VAvisoAttr_HPP */ diff --git a/Viewer/ecflowUI/src/VIcon.cpp b/Viewer/ecflowUI/src/VIcon.cpp index 11c066f71..7d82c1893 100644 --- a/Viewer/ecflowUI/src/VIcon.cpp +++ b/Viewer/ecflowUI/src/VIcon.cpp @@ -139,6 +139,12 @@ class VCheckpointErrorIcon : public VIcon { bool show(VNode*) override; }; +class VRemoteErrorIcon : public VIcon { +public: + explicit VRemoteErrorIcon(const std::string& name) : VIcon(name) {} + bool show(VNode*) override; +}; + //========================================================== // // Create VIcon instances @@ -162,6 +168,7 @@ static VRestoredIcon restoredIcon("restored"); static VSlowJobCreationIcon slowJobCreationIcon("slow_job"); static VNoLogIcon noLog("no_log"); static VCheckpointErrorIcon noCheckptIcon("checkpt_err"); +static VRemoteErrorIcon remoteErrorIcon("remote_err"); //========================================================== // @@ -557,3 +564,11 @@ bool VCheckpointErrorIcon::show(VNode* n) { return n->isFlagSet(ecf::Flag::CHECKPT_ERROR); } + +bool VRemoteErrorIcon::show(VNode* n) { + if (!n || n->isServer()) { + return false; + } + + return n->isFlagSet(ecf::Flag::REMOTE_ERROR); +} diff --git a/Viewer/ecflowUI/src/VMirrorAttr.cpp b/Viewer/ecflowUI/src/VMirrorAttr.cpp new file mode 100644 index 000000000..789b2415f --- /dev/null +++ b/Viewer/ecflowUI/src/VMirrorAttr.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "VMirrorAttr.hpp" + +#include "VAttributeType.hpp" +#include "VNode.hpp" +#include "ecflow/node/MirrorAttr.hpp" + +//================================ +// VMirrorAttrType +//================================ + +VMirrorAttrType::VMirrorAttrType() : VAttributeType("mirror") { + dataCount_ = 9; + searchKeyToData_["mirror_name"] = NameIndex; + searchKeyToData_["mirror_remote_path"] = RemotePathIndex; + searchKeyToData_["mirror_remote_host"] = RemoteHostIndex; + searchKeyToData_["mirror_remote_port"] = RemotePortIndex; + searchKeyToData_["mirror_polling"] = PollingIndex; + scanProc_ = VMirrorAttr::scan; +} + +QString VMirrorAttrType::toolTip(QStringList d) const { + QString t = "Type: Mirror
"; + if (d.count() == dataCount_) { + t += "Name: " + d[NameIndex] + "
"; + t += "Remote Path: " + d[RemotePathIndex] + "
"; + t += "Remote Host: " + d[RemoteHostIndex] + "
"; + t += "Remote Port: " + d[RemotePortIndex] + "
"; + t += "Polling: " + d[PollingIndex] + "
"; + t += "SSL: " + d[SslIndex] + "
"; + t += "Auth: " + d[AuthIndex]; + if (const auto& reason = d[ReasonIndex]; !reason.isEmpty()) { + t += "
Reason: " + d[ReasonIndex] + ""; + } + } + return t; +} + +QString VMirrorAttrType::definition(QStringList d) const { + QString t = "mirror"; + if (d.count() == dataCount_) { + t += " " + d[NameIndex] + " '" + d[RemoteHostIndex] + ":" + d[RemotePortIndex] + "' at '" + d[RemotePathIndex] + + "'"; + } + return t; +} + +void VMirrorAttrType::encode(const ecf::MirrorAttr& mirror, QStringList& data, bool firstLine) const { + + data << qName_ // TypeIndex + << QString::fromStdString(mirror.name()) // NameIndex + << QString::fromStdString(mirror.remote_path()) // RemotePathIndex + << QString::fromStdString(mirror.remote_host()) // RemoteHostIndex + << QString::fromStdString(mirror.remote_port()) // RemotePortIndex + << QString::fromStdString(mirror.polling()) // PollingIndex + << QString::fromStdString(mirror.ssl() ? "true" : "false") // SslIndex + << QString::fromStdString(mirror.auth()) // AuthIndex + << QString::fromStdString(mirror.reason()); // ReasonIndex +} + +void VMirrorAttrType::encode_empty(QStringList& data) const { + data << qName_; +} + +//===================================================== +// +// VMirrorAttr +// +//===================================================== + +VMirrorAttr::VMirrorAttr(VNode* parent, [[maybe_unused]] const ecf::MirrorAttr& mirror, int index) + : VAttribute(parent, index) { +} + +int VMirrorAttr::lineNum() const { + return 1; +} + +VAttributeType* VMirrorAttr::type() const { + static VAttributeType* atype = VAttributeType::find("mirror"); + return atype; +} + +QStringList VMirrorAttr::data(bool firstLine) const { + static auto* atype = static_cast(type()); + QStringList s; + if (parent_->node_) { + const std::vector& v = parent_->node_->mirrors(); + if (index_ < static_cast(v.size())) + atype->encode(v[index_], s, firstLine); + + // this can happen temporarily during update when: + // + // - an attribute was already deleted + // - the notification was emitted from the update thread, but + // has not yet reached the main thread + // - here, in the main thread, we still have the old (incorrect) attribute number + // + // * In this case, as safety measure, we encode an empty attribute. + // When the notification arrives all the attributes of the given node will be rescanned + // and will be set with the correct state. + else + atype->encode_empty(s); + } + return s; +} + +std::string VMirrorAttr::strName() const { + if (parent_->node_) { + const std::vector& v = parent_->node_->mirrors(); + return v[index_].name(); + } + return {}; +} + +void VMirrorAttr::scan(VNode* vnode, std::vector& vec) { + if (vnode->node_) { + const std::vector& v = vnode->node_->mirrors(); + + auto n = static_cast(v.size()); + for (int i = 0; i < n; i++) { + vec.push_back(new VMirrorAttr(vnode, v[i], i)); + } + } +} diff --git a/Viewer/ecflowUI/src/VMirrorAttr.hpp b/Viewer/ecflowUI/src/VMirrorAttr.hpp new file mode 100644 index 000000000..e94a99ed7 --- /dev/null +++ b/Viewer/ecflowUI/src/VMirrorAttr.hpp @@ -0,0 +1,64 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_viewer_VMirrorAttr_HPP +#define ecflow_viewer_VMirrorAttr_HPP + +#include +#include + +#include + +#include "VAttribute.hpp" +#include "VAttributeType.hpp" + +class AttributeFilter; +class VAttributeType; +class VNode; + +namespace ecf { +class MirrorAttr; +} + +class VMirrorAttrType : public VAttributeType { +public: + explicit VMirrorAttrType(); + QString toolTip(QStringList d) const override; + QString definition(QStringList d) const override; + void encode(const ecf::MirrorAttr& mirror, QStringList& data, bool firstLine) const; + void encode_empty(QStringList& data) const; + +private: + enum DataIndex { + TypeIndex = 0, + NameIndex = 1, + RemotePathIndex = 2, + RemoteHostIndex = 3, + RemotePortIndex = 4, + PollingIndex = 5, + SslIndex = 6, + AuthIndex = 7, + ReasonIndex = 8 + }; +}; + +class VMirrorAttr : public VAttribute { +public: + VMirrorAttr(VNode* parent, const ecf::MirrorAttr&, int index); + + int lineNum() const override; + VAttributeType* type() const override; + QStringList data(bool firstLine) const override; + std::string strName() const override; + + static void scan(VNode* vnode, std::vector& vec); +}; + +#endif /* ecflow_viewer_VMirrorAttr_HPP */ diff --git a/Viewer/ecflowUI/src/VModelData.cpp b/Viewer/ecflowUI/src/VModelData.cpp index 75b1c17b7..446fa2cea 100644 --- a/Viewer/ecflowUI/src/VModelData.cpp +++ b/Viewer/ecflowUI/src/VModelData.cpp @@ -319,7 +319,8 @@ void VTreeServer::notifyBeginNodeChange(const VNode* vnode, it == ecf::Aspect::LIMIT || it == ecf::Aspect::EXPR_TRIGGER || it == ecf::Aspect::EXPR_COMPLETE || it == ecf::Aspect::REPEAT || it == ecf::Aspect::REPEAT_INDEX || it == ecf::Aspect::NODE_VARIABLE || it == ecf::Aspect::LATE || it == ecf::Aspect::TODAY || it == ecf::Aspect::TIME || - it == ecf::Aspect::DAY || it == ecf::Aspect::CRON || it == ecf::Aspect::DATE) { + it == ecf::Aspect::DAY || it == ecf::Aspect::CRON || it == ecf::Aspect::DATE || + it == ecf::Aspect::AVISO || it == ecf::Aspect::MIRROR) { if (node && node->isAttrInitialised()) { Q_EMIT attributesChanged(this, node); } diff --git a/Viewer/ecflowUI/src/VNode.hpp b/Viewer/ecflowUI/src/VNode.hpp index 3cd23fd5c..b2feb65ed 100644 --- a/Viewer/ecflowUI/src/VNode.hpp +++ b/Viewer/ecflowUI/src/VNode.hpp @@ -87,7 +87,9 @@ class VNode : public VItem { friend class VServer; friend class VLabelAttr; friend class VMeterAttr; + friend class VMirrorAttr; friend class VEventAttr; + friend class VAvisoAttr; friend class VRepeatAttr; friend class VTriggerAttr; friend class VLimitAttr; diff --git a/Viewer/ecflowUI/src/Viewer.hpp b/Viewer/ecflowUI/src/Viewer.hpp index 61e6c17d4..5cdeadf05 100644 --- a/Viewer/ecflowUI/src/Viewer.hpp +++ b/Viewer/ecflowUI/src/Viewer.hpp @@ -31,6 +31,8 @@ enum AttributeType { LabelAttribute, MeterAttribute, EventAttribute, + AvisoAttribute, + MirrorAttribute, RepeatAttribute, TimeAttribute, DateAttribute, diff --git a/Viewer/ecflowUI/src/viewer.qrc b/Viewer/ecflowUI/src/viewer.qrc index afb1bd856..3a0dd87f9 100644 --- a/Viewer/ecflowUI/src/viewer.qrc +++ b/Viewer/ecflowUI/src/viewer.qrc @@ -14,6 +14,7 @@ ../images/icon_archived.svg ../images/icon_calendar.svg ../images/icon_checkpt_err.svg + ../images/icon_no_access.svg ../images/icon_clock.svg ../images/icon_clock_free.svg ../images/icon_complete.svg @@ -43,6 +44,7 @@ ../images/add_tab.svg ../images/add_variable_column.svg ../images/attribute.svg + ../images/aviso.svg ../images/autoscroll.svg ../images/autoscroll_off.svg ../images/chain.svg @@ -127,6 +129,7 @@ ../images/reload.svg ../images/reload_green.svg ../images/reload_one.svg + ../images/remote.svg ../images/remove.svg ../images/rescue.svg ../images/reset_to_default.svg diff --git a/Viewer/libViewer/src/CMakeLists.txt b/Viewer/libViewer/src/CMakeLists.txt index 89aa2cc49..9663a8e15 100644 --- a/Viewer/libViewer/src/CMakeLists.txt +++ b/Viewer/libViewer/src/CMakeLists.txt @@ -80,7 +80,7 @@ ecbuild_add_library( PRIVATE_DEFINITIONS ECFLOW_SHARED_DIR="${CMAKE_INSTALL_PREFIX}/share/ecflow" PRIVATE_LIBS - core + ecflow_all Boost::boost $<$:OpenSSL::SSL> # Qt5 diff --git a/Viewer/libViewer/src/IconProvider.cpp b/Viewer/libViewer/src/IconProvider.cpp index 44e6b4ea8..3a04d750e 100644 --- a/Viewer/libViewer/src/IconProvider.cpp +++ b/Viewer/libViewer/src/IconProvider.cpp @@ -63,6 +63,32 @@ QPixmap IconItem::pixmap(int size) { return {}; } + +QPixmap IconItem::pixmapToHeight(int size) { + auto it = pixmapsByHeight_.find(size); + if (it != pixmapsByHeight_.end()) + return it->second; + else { + QPixmap pix; + QImageReader imgR(path_); + if (imgR.canRead()) { + int w = imgR.size().width(); + int h = imgR.size().height(); + float r = static_cast(w)/static_cast(h); + imgR.setScaledSize(QSize(size*r, size)); + QImage img = imgR.read(); + pix = QPixmap::fromImage(img); + } + else { + pix = unknown(size); + } + + pixmapsByHeight_[size] = pix; + return pix; + } + return {}; +} + QPixmap IconItem::unknown(int size) { return unknownIcon.pixmap(size); } @@ -126,6 +152,10 @@ QPixmap IconProvider::pixmap(int id, int size) { return icon(id)->pixmap(size); } +QPixmap IconProvider::pixmapToHeight(int id, int size) { + return icon(id)->pixmapToHeight(size); +} + QPixmap IconProvider::lockPixmap(int size) { return lockIcon.pixmap(size); } diff --git a/Viewer/libViewer/src/IconProvider.hpp b/Viewer/libViewer/src/IconProvider.hpp index 4bca01db1..0e4c7a601 100644 --- a/Viewer/libViewer/src/IconProvider.hpp +++ b/Viewer/libViewer/src/IconProvider.hpp @@ -21,6 +21,7 @@ class IconItem { virtual ~IconItem() = default; QPixmap pixmap(int); + QPixmap pixmapToHeight(int size); int id() const { return id_; } QString path() const { return path_; } @@ -29,6 +30,7 @@ class IconItem { QString path_; std::map pixmaps_; + std::map pixmapsByHeight_; int id_; }; @@ -49,6 +51,7 @@ class IconProvider { static QString path(int id); static QPixmap pixmap(QString name, int size); static QPixmap pixmap(int id, int size); + static QPixmap pixmapToHeight(int id, int size); static QPixmap lockPixmap(int); static QPixmap warningPixmap(int); diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index f9aefcae3..397009696 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -61,12 +61,18 @@ if (HAVE_WARNINGS) $<$,$>:-Wno-deprecated-declarations> $<$,$>:-Wno-unused-result> $<$,$>:-Wno-unused-parameter> - ## Clang (MacOS AppleClang + Homebrew, AMD Clang-base) + ## Clang (MacOS Homebrew, AMD Clang-base) $<$,$>:-Wno-deprecated-copy-with-user-provided-copy> # silence warnings in Qt5 related headers $<$,$>:-Wno-deprecated-declarations> $<$,$>:-Wno-missing-field-initializers> # silence warning in Boost.Python related headers $<$,$>:-Wno-overloaded-virtual> $<$,$>:-Wno-unused-parameter> + ## Clang (MacOS AppleClang) + $<$,$>:-Wno-deprecated-copy-with-user-provided-copy> # silence warnings in Qt5 related headers + $<$,$>:-Wno-deprecated-declarations> + $<$,$>:-Wno-missing-field-initializers> # silence warning in Boost.Python related headers + $<$,$>:-Wno-overloaded-virtual> + $<$,$>:-Wno-unused-parameter> ## Clang (Intel Clang-based) $<$,$>:-Wno-deprecated-copy-with-user-provided-copy> # silence warnings in Qt5 related headers $<$,$>:-Wno-deprecated-declarations> diff --git a/cmake/FindClangFormat.cmake b/cmake/FindClangFormat.cmake index d4b873a86..724f09d23 100644 --- a/cmake/FindClangFormat.cmake +++ b/cmake/FindClangFormat.cmake @@ -32,13 +32,17 @@ function(target_clangformat TARGET) set(options "") - set(single_value_args CONDITION) - set(multi_value_args "") + set(single_value_args "") + set(multi_value_args CONDITION) cmake_parse_arguments( ARGS "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN} ) # Skip setup if condition supplied and FALSE - if (NOT ${ARGS_CONDITION}) - return() + if (DEFINED ARGS_CONDITION) + if (${${ARGS_CONDITION}}) + # Do nothing, just continue + else() + return() + endif() endif() # Skip setup if clang-format is not available... diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index fa7a910fa..a1c0c0ad1 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -58,7 +58,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_CURRENT_BINARY_DIR}/build_python_api/_build COMMAND - ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_BINARY_DIR}/Pyext/python3" + ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_BINARY_DIR}/libs/pyext/python3" ${SPHINX_EXECUTABLE} -M html ${CMAKE_CURRENT_SOURCE_DIR}/build_python_api ${CMAKE_CURRENT_BINARY_DIR}/build_python_api/_build @@ -88,7 +88,7 @@ add_custom_target(ecflow_python_docs DEPENDS generate_ecflow_python_docs) add_custom_command( OUTPUT generate_ecflow_docs COMMAND - ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_BINARY_DIR}/Pyext/python3" + ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_BINARY_DIR}/libs/pyext/python3" ${SPHINX_EXECUTABLE} -M html ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/_build diff --git a/docs/build_python_api/glossary.yaml b/docs/build_python_api/glossary.yaml index 5a001194e..72e01a8da 100644 --- a/docs/build_python_api/glossary.yaml +++ b/docs/build_python_api/glossary.yaml @@ -1,6 +1,7 @@ - active - aborted - autocancel +- aviso - complete expression - check point - child command @@ -25,6 +26,7 @@ - late - limit - meter +- mirror - node - pre-processing - queue diff --git a/docs/client_api/api/alter.rst b/docs/client_api/api/alter.rst index 062faf2b1..909f1305a 100644 --- a/docs/client_api/api/alter.rst +++ b/docs/client_api/api/alter.rst @@ -16,14 +16,15 @@ alter one option must be specified arg2 = For delete: [ variable | time | today | date | day | cron | event | meter | late | generic | queue | - label | trigger | complete | repeat | limit | inlimit | limit_path | zombie ] + label | trigger | complete | repeat | limit | inlimit | limit_path | zombie | aviso | mirror ] For change: [ variable | clock_type | clock_gain | clock_date | clock_sync | event | meter | label | - trigger | complete | repeat | limit_max | limit_value | defstatus | late | time | today ] + trigger | complete | repeat | limit_max | limit_value | defstatus | late | time | + today, aviso, mirror ] *NOTE* If the clock is changed, then the suite will need to be re-queued in order for the change to take effect fully. For add: - [ variable | time | today | date | day | zombie | late | limit | inlimit | label ] + [ variable | time | today | date | day | zombie | late | limit | inlimit | label | aviso | mirror ] For set_flag and clear_flag: [ force_aborted | user_edit | task_aborted | edit_failed | ecfcmd_failed statuscmd_failed | killcmd_failed | no_script | killed | status | late | message | @@ -32,13 +33,19 @@ alter For sort: [ event | meter | label | variable| limit | all ] arg3 = name/value - when changing, attributes like variable,meter,event,label,limits,late - we expect arguments to be quoted. For sort this argument can be called 'recursive' arg4 = new_value - specifies the new value only used for 'change'/'add' - values with spaces must be quoted arg5 = paths : At least one node path required.The paths must start with a leading '/' character + When adding or updating attributes, such as variable, meter, event, label, limits, or late, + the name (arg3) and value (arg4) must be quoted. + + When sorting attributes, 'recursive' can be used as the value (arg3) + + When adding or updating aviso and mirror attributes, the value (arg4) is expected to be a quoted list of + configuration options. For example: + * for aviso, "--remote_path /s1/f1/t2 --remote_host host --polling 20 --remote_port 3141 --ssl)" + * for mirror, "--listener '{ \"event\": \"mars\", \"request\": { \"class\": "od" } }' + --url http://aviso/ --schema /path/to/schema --polling 60" Usage: diff --git a/docs/conf.py b/docs/conf.py index ccfe41248..b32d14816 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -93,7 +93,7 @@ def get_ecflow_version(): - version = "5.12.4" + version = "5.13.0" ecflow_version = version.split(".") print("Extracted ecflow version '" + str(ecflow_version)) return ecflow_version diff --git a/docs/glossary.rst b/docs/glossary.rst index 685e424d1..3c879e84c 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -47,6 +47,46 @@ * - :ref:`grammar` - :token:`autocancel` + aviso + An aviso is an attribute of a :term:`Node` (typically a :term:`Task`), + and creates a dependency on an external Aviso server. + + A :term:`Node` with an aviso attribute is held from executing until a + notification matching the configured listener is received. When a + matching notification is received, the node then allowed to execute + following a behaviour similar to :term:`trigger` or time dependency e.g. + :term:`cron`). + + `Only one aviso attribute is allowed per node`, and each attribute is + defined by the following properties: + + - :code:`name`, an identifier + - :code:`listener`, the configuration for the Aviso listener + - :code:`url`, the base location of the Aviso server + - :code:`schema`, the location of the Aviso schema used to evaluate the notifications + - :code:`polling`, the value (in seconds) used to periodically contact the Aviso server + - :code:`auth`, the location to the Aviso authentication credentials file + + The value of the properties :code:`url`, :code:`schema`, :code:`polling`, + and :code:`auth` can be composed of :term:`Variables`. When + these properties are not provided, the following default values are used: + + - :code:`%ECF_AVISO_URL%`, for :code:`url` + - :code:`%ECF_AVISO_SCHEMA%`, for :code:`schema` + - :code:`%ECF_AVISO_POLLING%`, for :code:`polling` + - :code:`%ECF_AVISO_AUTH%`, for :code:`auth` + + .. important:: + + The variables :code:`ECF_AVISO_*` are not automatically provided at + server level, and must be defined at :term:`Suite` level by + the user. + + Each aviso attribute implies that a background thread is spawned whenever + the associated :term:`node` is (re)queued. This background thread is + responsible for polling the Aviso server, and periodically processing the + latest notifications. + check point The check point file is like the :term:`suite definition`, but includes all the state information. @@ -1317,7 +1357,49 @@ - :token:`meter` Meters can be referenced in :term:`trigger` and :term:`complete expression` expressions. - + + mirror + A mirror is an attribute of a :term:`Node` (typically a :term:`Task`), + and allows to synchronise the status of a node on a remote ecFlow server. + + A :term:`Node` with a mirror attribute will have its status periodically + synchronized with the :term:`status` of a node on a remote ecFlow server. + The synchronised status can be used to trigger the execution of local nodes. + + .. note:: + + Synchronised tasks don't need to be provided with :code:`.ecf` files + on the local ecFlow server, as the execution of a :term:`Task` + with a mirror attribute does not happen under the responsibility of the + local ecFlow server. + + Operations to execute synchronised Tasks have been disabled from the :term:`ecflow_ui`. + + `Only one mirror attribute is allowed per node`, and each attribute is + defined by the following properties: + + - :code:`name`, an identifier + - :code:`remote_path`, the path of the node on the remote ecFlow server + - :code:`remote_host`, the remote ecFlow server host + - :code:`remote_port`, the remote ecFlow server port + - :code:`ssl`, to connect to the ecFlow server using SSL + - :code:`polling`, the value (in seconds) used to periodically contact the remote ecFlow server + - :code:`auth`, the location to the Mirror authentication credentials file + + The value of the properties :code:`remote_host`, :code:`remote_port`, :code:`polling`, + and :code:`auth` can be composed of :term:`Variables`. When + these properties are not provided, the following default values are used: + + - :code:`%ECF_MIRROR_REMOTE_HOST%`, for :code:`remote_host` + - :code:`%ECF_MIRROR_REMOTE_PORT%`, for :code:`remote_port` + - :code:`%ECF_MIRROR_REMOTE_POLLING%`, for :code:`polling` + - :code:`%ECF_MIRROR_REMOTE_AUTH%`, for :code:`auth` + + Each mirror attribute implies that a background thread is spawned whenever + the ecFlow server is :term:`running`. This background thread is + responsible for polling the remote ecFlow server, and periodically + synchronise node status. + node :term:`suite`, :term:`family` and :term:`task` form a hierarchy. Where a :term:`suite` serves as the root of the hierarchy. diff --git a/docs/python_api/AvisoAttr.rst b/docs/python_api/AvisoAttr.rst new file mode 100644 index 000000000..0aa7b6473 --- /dev/null +++ b/docs/python_api/AvisoAttr.rst @@ -0,0 +1,71 @@ +ecflow.AvisoAttr +//////////////// + + +.. py:class:: AvisoAttr + :module: ecflow + + Bases: :py:class:`~Boost.Python.instance` + +An :term:`aviso` attribute, assigned to a :term:`node`, represents an external trigger holding the node queued untilan Aviso notification matching the attribute configuration is detected. + +Although :term:`aviso` attributes can be set at any level (Suite, Family, Task), it only makes sense to assign aviso attributes to tasks, and only one aviso attribute per node is allowed. + + +Constructor:: + + AvisoAttr(name, listener, ...) + string name: The Aviso attribute name + string listener: The Aviso listener configuration (in JSON format) + string url: The URL used to contact the Aviso server + string schema: The path to the Aviso schema + string polling: The polling interval used to contact the Aviso server + string auth: The path to the Aviso Authentication credentials + + +Usage: + +.. code-block:: python + + t1 = Task('t1', + AvisoAttr('name', '{...}', 'http://aviso.com', '60', '/path/to/auth')) + + t2 = Task('t2') + t2.add_aviso('name', '{...}', 'http://aviso.com', '60', '/path/to/auth') + + +.. py:method:: AvisoAttr.auth( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns the path to Authentication credentials used to contact the Aviso server + + +.. py:method:: AvisoAttr.listener( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns the Aviso listener configuration + + +.. py:method:: AvisoAttr.name( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns the name of the Aviso attribute + + +.. py:method:: AvisoAttr.polling( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns polling interval used to contact the Aviso server + + +.. py:method:: AvisoAttr.schema( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns the path to the schema used to contact the Aviso server + + +.. py:method:: AvisoAttr.url( (AvisoAttr)arg1) -> str : + :module: ecflow + +Returns the URL used to contact the Aviso server + diff --git a/docs/python_api/FlagType.rst b/docs/python_api/FlagType.rst index 3d4ca2e1e..0ce429689 100644 --- a/docs/python_api/FlagType.rst +++ b/docs/python_api/FlagType.rst @@ -98,7 +98,7 @@ Flags store state associated with a node .. py:attribute:: FlagType.names :module: ecflow - :value: {'archived': ecflow.FlagType.archived, 'byrule': ecflow.FlagType.byrule, 'checkpt_error': ecflow.FlagType.checkpt_error, 'edit_failed': ecflow.FlagType.edit_failed, 'force_abort': ecflow.FlagType.force_abort, 'jobcmd_failed': ecflow.FlagType.jobcmd_failed, 'killcmd_failed': ecflow.FlagType.killcmd_failed, 'killed': ecflow.FlagType.killed, 'late': ecflow.FlagType.late, 'locked': ecflow.FlagType.locked, 'log_error': ecflow.FlagType.log_error, 'message': ecflow.FlagType.message, 'no_reque': ecflow.FlagType.no_reque, 'no_script': ecflow.FlagType.no_script, 'not_set': ecflow.FlagType.not_set, 'queuelimit': ecflow.FlagType.queuelimit, 'restored': ecflow.FlagType.restored, 'sigterm': ecflow.FlagType.sigterm, 'status': ecflow.FlagType.status, 'statuscmd_failed': ecflow.FlagType.statuscmd_failed, 'task_aborted': ecflow.FlagType.task_aborted, 'threshold': ecflow.FlagType.threshold, 'user_edit': ecflow.FlagType.user_edit, 'wait': ecflow.FlagType.wait, 'zombie': ecflow.FlagType.zombie} + :value: {'archived': ecflow.FlagType.archived, 'byrule': ecflow.FlagType.byrule, 'checkpt_error': ecflow.FlagType.checkpt_error, 'edit_failed': ecflow.FlagType.edit_failed, 'force_abort': ecflow.FlagType.force_abort, 'jobcmd_failed': ecflow.FlagType.jobcmd_failed, 'killcmd_failed': ecflow.FlagType.killcmd_failed, 'killed': ecflow.FlagType.killed, 'late': ecflow.FlagType.late, 'locked': ecflow.FlagType.locked, 'log_error': ecflow.FlagType.log_error, 'message': ecflow.FlagType.message, 'no_reque': ecflow.FlagType.no_reque, 'no_script': ecflow.FlagType.no_script, 'not_set': ecflow.FlagType.not_set, 'queuelimit': ecflow.FlagType.queuelimit, 'remote_error': ecflow.FlagType.remote_error, 'restored': ecflow.FlagType.restored, 'sigterm': ecflow.FlagType.sigterm, 'status': ecflow.FlagType.status, 'statuscmd_failed': ecflow.FlagType.statuscmd_failed, 'task_aborted': ecflow.FlagType.task_aborted, 'threshold': ecflow.FlagType.threshold, 'user_edit': ecflow.FlagType.user_edit, 'wait': ecflow.FlagType.wait, 'zombie': ecflow.FlagType.zombie} .. py:attribute:: FlagType.no_reque @@ -121,6 +121,11 @@ Flags store state associated with a node :value: ecflow.FlagType.queuelimit +.. py:attribute:: FlagType.remote_error + :module: ecflow + :value: ecflow.FlagType.remote_error + + .. py:attribute:: FlagType.restored :module: ecflow :value: ecflow.FlagType.restored @@ -158,7 +163,7 @@ Flags store state associated with a node .. py:attribute:: FlagType.values :module: ecflow - :value: {0: ecflow.FlagType.force_abort, 1: ecflow.FlagType.user_edit, 2: ecflow.FlagType.task_aborted, 3: ecflow.FlagType.edit_failed, 4: ecflow.FlagType.jobcmd_failed, 5: ecflow.FlagType.no_script, 6: ecflow.FlagType.killed, 7: ecflow.FlagType.late, 8: ecflow.FlagType.message, 9: ecflow.FlagType.byrule, 10: ecflow.FlagType.queuelimit, 11: ecflow.FlagType.wait, 12: ecflow.FlagType.locked, 13: ecflow.FlagType.zombie, 14: ecflow.FlagType.no_reque, 15: ecflow.FlagType.archived, 16: ecflow.FlagType.restored, 17: ecflow.FlagType.threshold, 18: ecflow.FlagType.sigterm, 19: ecflow.FlagType.not_set, 20: ecflow.FlagType.log_error, 21: ecflow.FlagType.checkpt_error, 22: ecflow.FlagType.killcmd_failed, 23: ecflow.FlagType.statuscmd_failed, 24: ecflow.FlagType.status} + :value: {0: ecflow.FlagType.force_abort, 1: ecflow.FlagType.user_edit, 2: ecflow.FlagType.task_aborted, 3: ecflow.FlagType.edit_failed, 4: ecflow.FlagType.jobcmd_failed, 5: ecflow.FlagType.no_script, 6: ecflow.FlagType.killed, 7: ecflow.FlagType.late, 8: ecflow.FlagType.message, 9: ecflow.FlagType.byrule, 10: ecflow.FlagType.queuelimit, 11: ecflow.FlagType.wait, 12: ecflow.FlagType.locked, 13: ecflow.FlagType.zombie, 14: ecflow.FlagType.no_reque, 15: ecflow.FlagType.archived, 16: ecflow.FlagType.restored, 17: ecflow.FlagType.threshold, 18: ecflow.FlagType.sigterm, 19: ecflow.FlagType.not_set, 20: ecflow.FlagType.log_error, 21: ecflow.FlagType.checkpt_error, 22: ecflow.FlagType.killcmd_failed, 23: ecflow.FlagType.statuscmd_failed, 24: ecflow.FlagType.status, 25: ecflow.FlagType.remote_error} .. py:attribute:: FlagType.wait diff --git a/docs/python_api/MirrorAttr.rst b/docs/python_api/MirrorAttr.rst new file mode 100644 index 000000000..0e613d7b8 --- /dev/null +++ b/docs/python_api/MirrorAttr.rst @@ -0,0 +1,78 @@ +ecflow.MirrorAttr +///////////////// + + +.. py:class:: MirrorAttr + :module: ecflow + + Bases: :py:class:`~Boost.Python.instance` + +A :term:`mirror` attribute, assigned to a :term:`node`, enables establishing an external link and locally replicate the state of a node executing on a remote ecFlow server. + +Although :term:`mirror` attributes can be set at any level (Suite, Family, Task), it only makes sense to assign mirror attributes to Tasks, and only one mirror attribute per node is allowed. + + +Constructor:: + + MirrorAttr(name, remote_path, ...) + string name: The Mirror attribute name + string remote_path: The path on the remote ecFlow server to the node being replicated + string remote_host: The host of the remote ecFlow server + string remote_port: The port of the remote ecFlow server + string polling: The polling interval used to contact the remote ecFlow server + Bool ssl: `true`, when using SSL to contact the remote ecFlow server; `false`, otherwise + string auth: The path to the Mirror Authentication credentials + + +Usage: + +.. code-block:: python + + t1 = Task('t1', + MirrorAttr('name', '/remote/task', 'remote-ecflow', '3141', '60', True, '/path/to/auth')) + + t2 = Task('t2') + t2.add_aviso('name', '/remote/task', 'remote-ecflow', '3141', '60', True, '/path/to/auth') + + +.. py:method:: MirrorAttr.auth( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the path to Authentication credentials used to contact the remote ecFlow server + + +.. py:method:: MirrorAttr.name( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the name of the Mirror attribute + + +.. py:method:: MirrorAttr.polling( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the polling interval used to contact the remove ecFlow server + + +.. py:method:: MirrorAttr.remote_host( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the host of the remote ecFlow server + + +.. py:method:: MirrorAttr.remote_path( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the path on the remote ecFlow server + + +.. py:method:: MirrorAttr.remote_port( (MirrorAttr)arg1) -> str : + :module: ecflow + +Returns the port of the remote ecFlow server + + +.. py:method:: MirrorAttr.ssl( (MirrorAttr)arg1) -> bool : + :module: ecflow + +Returns a boolean, where true means that SSL is enabled + diff --git a/docs/python_api/Node.rst b/docs/python_api/Node.rst index 7d947e3ad..b5064c647 100644 --- a/docs/python_api/Node.rst +++ b/docs/python_api/Node.rst @@ -200,6 +200,13 @@ Add a `autorestore` attribute. See :py:class:`ecflow.Autorestore` add_autorestore( (Node)arg1, (list)arg2) -> Node +.. py:method:: Node.add_aviso( (Node)arg1, (AvisoAttr)arg2) -> Node : + :module: ecflow + +Adds an :term:`aviso` to a :term:`node`. See :py:class:`ecflow.Aviso` + + + .. py:method:: Node.add_complete( (Node)arg1, (str)arg2) -> Node : :module: ecflow @@ -533,6 +540,13 @@ Add a :term:`meter`. See :py:class:`ecflow.Meter` add_meter( (Node)arg1, (str)arg2, (int)arg3, (int)arg4 [, (int)arg5]) -> Node +.. py:method:: Node.add_mirror( (Node)arg1, (MirrorAttr)arg2) -> Node : + :module: ecflow + +Adds a :term:`mirror` to a :term:`node`. See :py:class:`ecflow.Mirror` + + + .. py:method:: Node.add_part_complete( (Node)arg1, (PartExpression)arg2) -> Node : :module: ecflow @@ -978,6 +992,12 @@ Usage: ZombieAttr(ZombieType.ecf, child_list, ZombieUserActionType.fail)) +.. py:property:: Node.avisos + :module: ecflow + +Returns a list of :term:`aviso`\ s + + .. py:method:: Node.change_complete( (Node)arg1, (str)arg2) -> None :module: ecflow @@ -1292,6 +1312,12 @@ Returns a list of :term:`limit`\ s Returns a list of :term:`meter`\ s +.. py:property:: Node.mirrors + :module: ecflow + +Returns a list of :term:`mirror`\ s + + .. py:method:: Node.name( (Node)arg1) -> str :module: ecflow diff --git a/docs/release_notes/index.rst b/docs/release_notes/index.rst index 71628870d..f4d024256 100644 --- a/docs/release_notes/index.rst +++ b/docs/release_notes/index.rst @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 1 + version_5.13 version_5.12 version_5.11 version_5.10 diff --git a/docs/release_notes/version_5.13.rst b/docs/release_notes/version_5.13.rst new file mode 100644 index 000000000..87cd7209e --- /dev/null +++ b/docs/release_notes/version_5.13.rst @@ -0,0 +1,20 @@ +.. _version_5.13: + +Version 5.13 updates +//////////////////// + +.. role:: jiraissue + :class: hidden + + +Version 5.13.0 +============== + +* `Released `__\ on 2024-06-19 + +General +------- + +- **New Feature** enabled support for Aviso notifications :jiraissue:`ECFLOW-1931` +- **New Feature** enabled synchronisation of Node status between ecFlow servers :jiraissue:`ECFLOW-1931` +- **Improvement** improved structure/naming of ecFlow internal sources :jiraissue:`ECFLOW-1943` diff --git a/docs/ug/cookbook/how_to_mirror_a_remote_task_status.rst b/docs/ug/cookbook/how_to_mirror_a_remote_task_status.rst new file mode 100644 index 000000000..b389be5c2 --- /dev/null +++ b/docs/ug/cookbook/how_to_mirror_a_remote_task_status.rst @@ -0,0 +1,70 @@ +.. _how_to_mirror_a_remote_task_status: + +How to mirror a remote Task status? +----------------------------------- + +The following instructions describe the necessary steps to use the ability to +synchronise the status of a :term:`task` between a `remote` ecFlow server +and a `local` ecFlow server. The `remote` server is responsible for actually +executing the task, while the `local` server synchronizes the status of a +particular task, in order to trigger the execution of dependent tasks. + +The deployment of this feature has the following requirements: + - `local` ecFlow 5.13+, to host the dependent task(s) + - `remote` ecFlow 5+, to host the remote task + - Authentication credentials, stored as JSON file + +Setup the ecFlow Server +^^^^^^^^^^^^^^^^^^^^^^^ + +Deploy the `remote` ecFlow server, as per the :ref:`regular instructions` +and specifying username/password access configuration. + +Deploy the Authentication credentials so that the JSON file is accessible +to the `local` ecFlow server. Launch the server. + +Consider using SSL encription for the communication between ecFlow server and +client. + + +Define the Suite with a `mirrored` Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On the :term:`suite` definition file, create a :term:`task` (which will mirror +the remote task status) and assign it a :term:`mirror` attribute. The mirror +attribute must specify the path of the remote node, and the remote server +connection details. Using the mirrored task, other tasks can use triggers to +execute when the remote task becomes complete. + +Follow the recommended practice of defining ecFlow :term:`variables` +at :term:`suite` level: + + - ECF_MIRROR_REMOTE_HOST + - ECF_MIRROR_REMOTE_PORT + - ECF_MIRROR_REMOTE_POLLING + - ECF_MIRROR_REMOTE_AUTH + +**Example 1**: Example suite definition with mirror attributes + + .. code-block:: shell + + suite s + edit ECF_MIRROR_REMOTE_HOST 'remotehost' + edit ECF_MIRROR_REMOTE_PORT '3456' + edit ECF_MIRROR_REMOTE_POLLING '120' + edit ECF_MIRROR_REMOTE_AUTH '/path/to/mirror.auth' + family f + task Task + mirror --name A --remote_path /s1/f1/t1 --remote_host %ECF_MIRROR_REMOTE_HOST% --remote_port %ECF_MIRROR_REMOTE_PORT% --polling %ECF_MIRROR_REMOTE_POLLING% --ssl + task Dependent + trigger Task == complete + endfamily + endsuite + +Deploy the Suite with a `mirrored` Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Load the suite definition containing the :term:`mirror` attribute. + +Whenever the ecFlow server is in `RUNNING` state, the synchronisation between +`remote` and `local` servers is enabled automatically. diff --git a/docs/ug/cookbook/how_to_trigger_a_task_based_on_aviso_notification.rst b/docs/ug/cookbook/how_to_trigger_a_task_based_on_aviso_notification.rst new file mode 100644 index 000000000..b8628284e --- /dev/null +++ b/docs/ug/cookbook/how_to_trigger_a_task_based_on_aviso_notification.rst @@ -0,0 +1,65 @@ +.. _how_to_trigger_a_task_based_on_aviso_notification: + +How to trigger a Task based on Aviso notification? +-------------------------------------------------- + +The following instructions describe the necessary steps to use the ability to +trigger a :term:`task` based on an Aviso notification. The intended task must +be assigned an :term:`aviso` attribute, which provides the configuration to +periodically poll the Aviso server, and execution only happens when the +a matching Aviso notification is processed. + +The deployment of this feature has the following requirements: + - ecFlow 5.13+, to host the Aviso dependent task(s) + - Aviso event listener schema + - Authentication credentials, stored as JSON file + +Setup the ecFlow Server +^^^^^^^^^^^^^^^^^^^^^^^ + +Deploy the Authentication credentials and Aviso event listener schema files so +that these files are accessible to the ecFlow server. Launch the server, as per +the :ref:`regular instructions`. + +Define a Suite with an `Aviso` dependent Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On the :term:`suite` definition file, create a :term:`task` and assign it an +:term:`aviso` attribute. + +The :term:`aviso` attribute must specify the base URL to contact the Aviso server, +and the remote server connection details. Using the mirrored task, other tasks can use triggers to execute +when the remote task becomes complete. + +Follow the recommended practice of defining ecFlow :term:`variables` at :term:`suite` level: + + - ECF_AVISO_URL + - ECF_AVISO_SCHEMA + - ECF_AVISO_POLLING + - ECF_AVISO_AUTH + +**Example 1**: Example suite definition with mirror attributes + + .. code-block:: shell + + suite s + edit ECF_AVISO_URL 'http://aviso:2379' + edit ECF_AVISO_SCHEMA '/path/to/event_listener_schema.json' + edit ECF_AVISO_POLLING '120' + edit ECF_AVISO_AUTH '/path/to/aviso.auth' + family f + task Task + aviso --name A --listener '{ "event": "mars", "request": { "step": 0 } }' --url %ECF_AVISO_URL% --schema %ECF_AVISO_SCHEMA% --auth %ECF_AVISO_AUTH% --polling %ECF_AVISO_POLLING% + endfamily + endsuite + +Define a Suite with an `Aviso` dependent Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Load the suite definition containing the :term:`aviso` attribute. + +Whenever a task assigned with an :term:`aviso` attribute is (re)queued, +the Aviso will start to be periodically poll. The task is held from execution +until a notification matching the provided listener is found. +Once the task is allowed to execute the periodic polling is stopped, until the +task is requeued again. diff --git a/docs/ug/cookbook/index.rst b/docs/ug/cookbook/index.rst index d5d9d45b9..62eb2b6f3 100644 --- a/docs/ug/cookbook/index.rst +++ b/docs/ug/cookbook/index.rst @@ -7,7 +7,6 @@ Cookbook ============ - This cookbook will provide real examples of using the ecFlow :ref:`python_api`. **Contents** @@ -38,5 +37,5 @@ This cookbook will provide real examples of using the ecFlow :ref:`python_api`. native_python_task one_script_do_it_all python_client_for_fault_tolerance - - + how_to_mirror_a_remote_task_status + how_to_trigger_a_task_based_on_aviso_notification diff --git a/docs/ug/user_manual/definition_file_grammar.rst b/docs/ug/user_manual/definition_file_grammar.rst index 26d012819..893500d61 100644 --- a/docs/ug/user_manual/definition_file_grammar.rst +++ b/docs/ug/user_manual/definition_file_grammar.rst @@ -29,10 +29,13 @@ Definition file grammar family: "family" >> `familyName` >> !`leaf_ecf` >> *(`task` | `family`) : >> `endfamily` task: "task" >> `taskName` >> `leaf_ecf` >> !endtask - leaf_ecf: *( `variable` | `trigger` | `time` | `today` | - : `date` | `day` | `defstatus` | `complete` | `inlimit` | - : `label` | `event` | `late` | `limit` | `meter` | `repeat` | - : `cron` | `autocancel` | `zombie` ) + leaf_ecf: *( `variable` | `trigger` | `time` | `today` | + : `date` | `day` | `defstatus` | `complete` | `inlimit` | + : `label` | `event` | `late` | `limit` | `meter` | `repeat` | + : `cron` | `autocancel` | `zombie` + : ) + : | `aviso` + : | `mirror` clock: "clock" >> ( "real"| "hybrid" ) >> : ( ( `clock_date` >> !(`hh_mm` | int ) ) | (`hh_mm` | int )) : >> +`nextline` @@ -40,6 +43,23 @@ Definition file grammar complete: "complete" >> `expression` >> +`nextline` variable: "edit" >> `identifier` >> `varvalue` >> +`nextline` label: "label" >> `identifier` >> `quotedstring` >> +`nextline` + aviso: "aviso" >> + : *( "--name" >> `identifier` + : | "--listener" >> "'" >> `jsonstring` >> "'" + : | "--url" >> ( `varvalue` | `string` ) + : | "--polling" >> (`varvalue` | +(integer)) + : | "--schema" >> ( `varvalue` | `string` ) + : | "--auth" >> ( `varvalue` | `string` ) + : ) + mirror: "mirror" >> + : *( "--name" >> `identifier` + : | "--remote_path" >> `string` + : | "--remote_host" >> ( `varvalue` | `string` ) + : | "--remote_port" >> ( `varvalue` | `string` ) + : | "--polling" >> (`varvalue` | +(integer)) + : | "--auth" >> ( `varvalue` | `string` ) + : | --ssl + : ) time: "time" >> !'+ >> (`timeseries` | `two_int_p` >> : “:” `two_int_p`) >> +`nextline` today: "today" >> !'+ >> (`timeseries` | `two_int_p` >> @@ -119,7 +139,7 @@ Definition file grammar dotpath: ‘.’ >> +( ‘/’ >> `identifier` ) identifier: (alpha_numeric | ‘_’) >> *(alpha_numeric | ‘_’) nodePath: `absolutepath` | `dotdotpath` | `dotpath` - expression: printable chars >> !’\’ >> `nextline` + expression: `printable_chars` >> !’\’ >> `nextline` int_p: integer two_int_p: 2 digit integer theYear: 4 digit integer @@ -128,3 +148,6 @@ Definition file grammar : "T" >> `two_int_p` >> `two_int_p` >> `two_int_p` duration: `int_p` >> ":" >> `two_int_p` >> ":" >> `two_int_p` newline: \n + string: `printable_chars` >> *(`printable_chars`) + jsonstring : __ as per JSON format specification __ + printable_chars : "a-zA-Z" diff --git a/docs/ug/user_manual/node_attribute_overview.rst b/docs/ug/user_manual/node_attribute_overview.rst index ded2ef58b..e3e71dcba 100644 --- a/docs/ug/user_manual/node_attribute_overview.rst +++ b/docs/ug/user_manual/node_attribute_overview.rst @@ -15,165 +15,183 @@ Node attribute overview - Use in trigger - Process/Control - Structural - * - :term:`repeat` + * - :term:`aviso` - ❎ - - - - + - ❎ + - + - + - + - + - + - + * - :term:`autocancel` + - + - + - + - + - - - - ❎ + * - :term:`clock` + - + - - - - * - :term:`cron` - ❎ - - ❎ - - + - ❎ - - - - + * - :term:`complete` - + - ❎ - - * - :term:`time` / :term:`today` + - + - + - N/A + - + - + * - :term:`cron` + - ❎ - ❎ - - ❎ - - - - - - + - + - - - * - :term:`date` - ❎ - - ❎ - - + - ❎ + - + - - - - - - - * - :term:`day` - - - - ❎ - - - + - ❎ + - + - + - + - + - + - + * - :term:`defstatus` - - - - - - * - :term:`clock` - - - - - - - - - ❎ - ❎ - - - * - :term:`variable` - - - - - - + - + * - :term:`event` + - + - + - - ❎ - - ❎ - - - * - :term:`defstatus` - - - - - - + * - :term:`inlimit` - - ❎ - - - - - * - :term:`event` - - - - - - + - + - + - + - + * - :term:`label` + - + - + - ❎ - ❎ - + - + - + - + * - :term:`late` + - + - - ❎ - - - * - :term:`meter` - - - - - - - ❎ + - + - + * - :term:`limit` - - ❎ - - - * - :term:`label` - - - - - - ❎ + - - ❎ - - - + - + * - :term:`meter` + - - - - * - :term:`trigger` - - - ❎ - - - + - ❎ - - - N/A - + * - :term:`mirror` - - * - :term:`complete` - - - ❎ - - - - - - N/A - - - * - :term:`limit` - - + - + - + * - :term:`repeat` - ❎ + - - - - - ❎ - - - * - :term:`inlimit` - - + * - :term:`time` / :term:`today` - ❎ + - ❎ - - - - - - - * - :term:`late` - - - - + * - :term:`trigger` + - - ❎ - - - - ❎ - + - N/A - - * - :term:`zombie` - - + - + * - :term:`variable` - + - - + - ❎ - - - - - - ❎ - - * - :term:`autocancel` - - - + * - :term:`zombie` + - + - - - - - - - - ❎ + - diff --git a/docs/ug/user_manual/text_based_suite_definition/attributes/index.rst b/docs/ug/user_manual/text_based_suite_definition/attributes/index.rst index bcc7ca0ad..c9ed98039 100644 --- a/docs/ug/user_manual/text_based_suite_definition/attributes/index.rst +++ b/docs/ug/user_manual/text_based_suite_definition/attributes/index.rst @@ -1,7 +1,7 @@ .. _attributes: -Attributes -//////////// +Other Attributes +//////////////// This section describes commands that can be used to give attributes to nodes in a suite. @@ -17,4 +17,3 @@ nodes in a suite. extern late repeat_for_loop - diff --git a/docs/ug/user_manual/text_based_suite_definition/external/aviso.rst b/docs/ug/user_manual/text_based_suite_definition/external/aviso.rst new file mode 100644 index 000000000..56ee73cbe --- /dev/null +++ b/docs/ug/user_manual/text_based_suite_definition/external/aviso.rst @@ -0,0 +1,45 @@ +.. _text_based_def_aviso: + +aviso +///// + +This defines an :term:`aviso` attribute, and thus a node dependency on an Aviso +notification. The options defining the attribute can be provided in any order. + +.. code-block:: shell + + task t1 + aviso --name A --listener '{ ... }' --url http://aviso.ecmwf.int/ --schema /path/to/schema.json --polling 300 --auth /path/to/auth.json + + task t2 + aviso --name B --listener '{ ... }' + # when not provided, the following default options are used + # --url %ECF_AVISO_URL% + # --schema %ECF_AVISO_SCHEMA% + # --auth %ECF_AVISO_AUTH% + # --polling %ECF_AVISO_POLLING% + +Notice that the :code:`--listener` option must be surrounded by single quotes, +and is composed as a single line `JSON`. The `JSON` must define two fields: + + - :code:`event`, specifies the type of Aviso event + - :code:`request`, specifies a dictionary with the parameters used to check for matches of Aviso notifications + +The following are some examples: + +.. code-block:: shell + + '{ "event": "dissemination", "request": { "destination": "abc" } }' + + '{ "event": "mars", "request": { "class": "od", "expver": "0001", "domain": "g", "stream": "abcd", "step": 0 } }' + +The Authentication credentials, provided via option :code:`--auth`, are +provided in a `JSON` file with the following content: + +.. code-block:: json + + { + "url": "http://host.int:1234", + "key": "*******************************************************************", + "email": "user@host.int" + } diff --git a/docs/ug/user_manual/text_based_suite_definition/external/index.rst b/docs/ug/user_manual/text_based_suite_definition/external/index.rst new file mode 100644 index 000000000..8d49bd132 --- /dev/null +++ b/docs/ug/user_manual/text_based_suite_definition/external/index.rst @@ -0,0 +1,20 @@ +.. _external_dependencies: + +External Dependencies +///////////////////// + +In addition to attributes that allow defining the dependencies mentioned in +:ref:`dependencies`, ecFlow is able to specify dependencies based on external +entities, and thus allow "local" nodes to be triggered by remote events: + + - notifications disseminated by an Aviso server + - status changes on remote ecFlow + +The following sections present in detail the different external dependencies +currently supported. + +.. toctree:: + :maxdepth: 1 + + aviso + mirror diff --git a/docs/ug/user_manual/text_based_suite_definition/external/mirror.rst b/docs/ug/user_manual/text_based_suite_definition/external/mirror.rst new file mode 100644 index 000000000..a1b03a0c5 --- /dev/null +++ b/docs/ug/user_manual/text_based_suite_definition/external/mirror.rst @@ -0,0 +1,33 @@ +.. _text_based_def_mirror: + +mirror +////// + +This defines a :term:`mirror` attribute, which synchronizes the status of a +:term:`node` between a local and a remote ecFlow server. The options defining +the attribute can be provided in any order. + +.. code-block:: shell + + task t1 + mirror --name A --remote_path /s/f/tA --remote_host host --remote_port 3141 --polling 20 --ssl --auth /path/to/auth.json + + task t2 + aviso --name B --remote_path /s/f/tB + # when not provided, the following default options are used + # --remote_host %ECF_MIRROR_REMOTE_HOST% + # --remote_port %ECF_MIRROR_REMOTE_PORT% + # --polling %ECF_MIRROR_POLLING% + # --auth %ECF_MIRROR_AUTH% + +The Authentication credentials, provided via option :code:`--auth`, are +provided in a `JSON` file with the following content: + +.. code-block:: json + + { + "url": "http://host.int:1234", + "username": "user", + "password": "************", + "email": "user@host.int" + } diff --git a/docs/ug/user_manual/text_based_suite_definition/index.rst b/docs/ug/user_manual/text_based_suite_definition/index.rst index 81b76a636..ab19ac310 100644 --- a/docs/ug/user_manual/text_based_suite_definition/index.rst +++ b/docs/ug/user_manual/text_based_suite_definition/index.rst @@ -56,3 +56,4 @@ suite-definition file easier. There are two ways of defining a suite. suite_definition_file_format/index.rst dependencies/index.rst attributes/index.rst + external/index.rst diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 000000000..57caa08c5 --- /dev/null +++ b/libs/CMakeLists.txt @@ -0,0 +1,603 @@ +# +# Copyright 2009- ECMWF. +# +# This software is licensed under the terms of the Apache Licence version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. +# + +configure_file( + core/src/ecflow/core/ecflow_version.h.in + ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_version.h) +configure_file( + core/src/ecflow/core/ecflow_source_build_dir.h.in + ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_source_build_dir.h) + +set(srcs + # Attribute -- Headers + attribute/src/ecflow/attribute/AutoArchiveAttr.hpp + attribute/src/ecflow/attribute/AutoCancelAttr.hpp + attribute/src/ecflow/attribute/ClockAttr.hpp + attribute/src/ecflow/attribute/CronAttr.hpp + attribute/src/ecflow/attribute/DateAttr.hpp + attribute/src/ecflow/attribute/DayAttr.hpp + attribute/src/ecflow/attribute/GenericAttr.hpp + attribute/src/ecflow/attribute/LateAttr.hpp + attribute/src/ecflow/attribute/NodeAttr.hpp + attribute/src/ecflow/attribute/QueueAttr.hpp + attribute/src/ecflow/attribute/RepeatAttr.hpp + attribute/src/ecflow/attribute/TimeAttr.hpp + attribute/src/ecflow/attribute/TodayAttr.hpp + attribute/src/ecflow/attribute/Variable.hpp + attribute/src/ecflow/attribute/VerifyAttr.hpp + attribute/src/ecflow/attribute/Zombie.hpp + attribute/src/ecflow/attribute/ZombieAttr.hpp + # Attribute -- Sources + attribute/src/ecflow/attribute/AutoArchiveAttr.cpp + attribute/src/ecflow/attribute/AutoCancelAttr.cpp + attribute/src/ecflow/attribute/ClockAttr.cpp + attribute/src/ecflow/attribute/CronAttr.cpp + attribute/src/ecflow/attribute/DateAttr.cpp + attribute/src/ecflow/attribute/DayAttr.cpp + attribute/src/ecflow/attribute/GenericAttr.cpp + attribute/src/ecflow/attribute/LateAttr.cpp + attribute/src/ecflow/attribute/NodeAttr.cpp + attribute/src/ecflow/attribute/QueueAttr.cpp + attribute/src/ecflow/attribute/RepeatAttr.cpp + attribute/src/ecflow/attribute/TimeAttr.cpp + attribute/src/ecflow/attribute/TodayAttr.cpp + attribute/src/ecflow/attribute/Variable.cpp + attribute/src/ecflow/attribute/VerifyAttr.cpp + attribute/src/ecflow/attribute/Zombie.cpp + attribute/src/ecflow/attribute/ZombieAttr.cpp + + # Base -- Headers + base/src/ecflow/base/AbstractClientEnv.hpp + base/src/ecflow/base/AbstractServer.hpp + base/src/ecflow/base/Client.hpp + base/src/ecflow/base/ClientOptionsParser.hpp + base/src/ecflow/base/ClientToServerRequest.hpp + base/src/ecflow/base/Cmd.hpp + base/src/ecflow/base/Connection.hpp + base/src/ecflow/base/Gnuplot.hpp + base/src/ecflow/base/ServerReply.hpp + base/src/ecflow/base/ServerToClientResponse.hpp + base/src/ecflow/base/Stats.hpp + base/src/ecflow/base/WhyCmd.hpp + base/src/ecflow/base/ZombieCtrl.hpp + $<$:base/src/ecflow/base/Openssl.hpp> + $<$:base/src/ecflow/base/ssl_connection.hpp> + $<$:base/src/ecflow/base/SslClient.hpp> + base/src/ecflow/base/cts/ClientToServerCmd.hpp + base/src/ecflow/base/cts/CtsCmdRegistry.hpp + base/src/ecflow/base/cts/EditHistoryMgr.hpp + base/src/ecflow/base/cts/task/AbortCmd.hpp + base/src/ecflow/base/cts/task/CompleteCmd.hpp + base/src/ecflow/base/cts/task/CtsWaitCmd.hpp + base/src/ecflow/base/cts/task/EventCmd.hpp + base/src/ecflow/base/cts/task/InitCmd.hpp + base/src/ecflow/base/cts/task/LabelCmd.hpp + base/src/ecflow/base/cts/task/MeterCmd.hpp + base/src/ecflow/base/cts/task/QueueCmd.hpp + base/src/ecflow/base/cts/task/TaskApi.hpp + base/src/ecflow/base/cts/task/TaskCmd.hpp + base/src/ecflow/base/cts/user/AlterCmd.hpp + base/src/ecflow/base/cts/user/BeginCmd.hpp + base/src/ecflow/base/cts/user/CFileCmd.hpp + base/src/ecflow/base/cts/user/CheckPtCmd.hpp + base/src/ecflow/base/cts/user/ClientHandleCmd.hpp + base/src/ecflow/base/cts/user/CSyncCmd.hpp + base/src/ecflow/base/cts/user/CtsApi.hpp + base/src/ecflow/base/cts/user/CtsCmd.hpp + base/src/ecflow/base/cts/user/CtsNodeCmd.hpp + base/src/ecflow/base/cts/user/DeleteCmd.hpp + base/src/ecflow/base/cts/user/EditScriptCmd.hpp + base/src/ecflow/base/cts/user/ForceCmd.hpp + base/src/ecflow/base/cts/user/FreeDepCmd.hpp + base/src/ecflow/base/cts/user/GroupCTSCmd.hpp + base/src/ecflow/base/cts/user/LoadDefsCmd.hpp + base/src/ecflow/base/cts/user/LogCmd.hpp + base/src/ecflow/base/cts/user/LogMessageCmd.hpp + base/src/ecflow/base/cts/user/MoveCmd.hpp + base/src/ecflow/base/cts/user/OrderNodeCmd.hpp + base/src/ecflow/base/cts/user/PathsCmd.hpp + base/src/ecflow/base/cts/user/PlugCmd.hpp + base/src/ecflow/base/cts/user/QueryCmd.hpp + base/src/ecflow/base/cts/user/ReplaceNodeCmd.hpp + base/src/ecflow/base/cts/user/RequeueNodeCmd.hpp + base/src/ecflow/base/cts/user/RunNodeCmd.hpp + base/src/ecflow/base/cts/user/ServerVersionCmd.hpp + base/src/ecflow/base/cts/user/ShowCmd.hpp + base/src/ecflow/base/cts/user/UserCmd.hpp + base/src/ecflow/base/cts/user/ZombieCmd.hpp + base/src/ecflow/base/stc/BlockClientZombieCmd.hpp + base/src/ecflow/base/stc/DefsCache.hpp + base/src/ecflow/base/stc/DefsCmd.hpp + base/src/ecflow/base/stc/ErrorCmd.hpp + base/src/ecflow/base/stc/GroupSTCCmd.hpp + base/src/ecflow/base/stc/PreAllocatedReply.hpp + base/src/ecflow/base/stc/SClientHandleCmd.hpp + base/src/ecflow/base/stc/SClientHandleSuitesCmd.hpp + base/src/ecflow/base/stc/SNewsCmd.hpp + base/src/ecflow/base/stc/SNodeCmd.hpp + base/src/ecflow/base/stc/SServerLoadCmd.hpp + base/src/ecflow/base/stc/SStatsCmd.hpp + base/src/ecflow/base/stc/SStringCmd.hpp + base/src/ecflow/base/stc/SStringVecCmd.hpp + base/src/ecflow/base/stc/SSuitesCmd.hpp + base/src/ecflow/base/stc/SSyncCmd.hpp + base/src/ecflow/base/stc/ServerToClientCmd.hpp + base/src/ecflow/base/stc/StcCmd.hpp + base/src/ecflow/base/stc/ZombieGetCmd.hpp + # Base -- Sources + base/src/ecflow/base/Client.cpp + base/src/ecflow/base/ClientOptionsParser.cpp + base/src/ecflow/base/ClientToServerRequest.cpp + base/src/ecflow/base/Connection.cpp + base/src/ecflow/base/Gnuplot.cpp + base/src/ecflow/base/ServerReply.cpp + base/src/ecflow/base/ServerToClientResponse.cpp + base/src/ecflow/base/Stats.cpp + base/src/ecflow/base/WhyCmd.cpp + base/src/ecflow/base/ZombieCtrl.cpp + $<$:base/src/ecflow/base/Openssl.cpp> + $<$:base/src/ecflow/base/ssl_connection.cpp> + $<$:base/src/ecflow/base/SslClient.cpp> + base/src/ecflow/base/cts/ClientToServerCmd.cpp + base/src/ecflow/base/cts/CtsCmdRegistry.cpp + base/src/ecflow/base/cts/EditHistoryMgr.cpp + base/src/ecflow/base/cts/task/AbortCmd.cpp + base/src/ecflow/base/cts/task/CompleteCmd.cpp + base/src/ecflow/base/cts/task/CtsWaitCmd.cpp + base/src/ecflow/base/cts/task/EventCmd.cpp + base/src/ecflow/base/cts/task/InitCmd.cpp + base/src/ecflow/base/cts/task/LabelCmd.cpp + base/src/ecflow/base/cts/task/MeterCmd.cpp + base/src/ecflow/base/cts/task/QueueCmd.cpp + base/src/ecflow/base/cts/task/TaskApi.cpp + base/src/ecflow/base/cts/task/TaskCmd.cpp + base/src/ecflow/base/cts/user/AlterCmd.cpp + base/src/ecflow/base/cts/user/BeginCmd.cpp + base/src/ecflow/base/cts/user/CFileCmd.cpp + base/src/ecflow/base/cts/user/CSyncCmd.cpp + base/src/ecflow/base/cts/user/CheckPtCmd.cpp + base/src/ecflow/base/cts/user/ClientHandleCmd.cpp + base/src/ecflow/base/cts/user/CtsApi.cpp + base/src/ecflow/base/cts/user/CtsCmd.cpp + base/src/ecflow/base/cts/user/CtsNodeCmd.cpp + base/src/ecflow/base/cts/user/DeleteCmd.cpp + base/src/ecflow/base/cts/user/EditScriptCmd.cpp + base/src/ecflow/base/cts/user/ForceCmd.cpp + base/src/ecflow/base/cts/user/FreeDepCmd.cpp + base/src/ecflow/base/cts/user/GroupCTSCmd.cpp + base/src/ecflow/base/cts/user/LoadDefsCmd.cpp + base/src/ecflow/base/cts/user/LogCmd.cpp + base/src/ecflow/base/cts/user/LogMessageCmd.cpp + base/src/ecflow/base/cts/user/MoveCmd.cpp + base/src/ecflow/base/cts/user/OrderNodeCmd.cpp + base/src/ecflow/base/cts/user/PathsCmd.cpp + base/src/ecflow/base/cts/user/PlugCmd.cpp + base/src/ecflow/base/cts/user/QueryCmd.cpp + base/src/ecflow/base/cts/user/ReplaceNodeCmd.cpp + base/src/ecflow/base/cts/user/RequeueNodeCmd.cpp + base/src/ecflow/base/cts/user/RunNodeCmd.cpp + base/src/ecflow/base/cts/user/ServerVersionCmd.cpp + base/src/ecflow/base/cts/user/ShowCmd.cpp + base/src/ecflow/base/cts/user/UserCmd.cpp + base/src/ecflow/base/cts/user/ZombieCmd.cpp + base/src/ecflow/base/stc/BlockClientZombieCmd.cpp + base/src/ecflow/base/stc/DefsCache.cpp + base/src/ecflow/base/stc/DefsCmd.cpp + base/src/ecflow/base/stc/ErrorCmd.cpp + base/src/ecflow/base/stc/GroupSTCCmd.cpp + base/src/ecflow/base/stc/PreAllocatedReply.cpp + base/src/ecflow/base/stc/SClientHandleCmd.cpp + base/src/ecflow/base/stc/SClientHandleSuitesCmd.cpp + base/src/ecflow/base/stc/SNewsCmd.cpp + base/src/ecflow/base/stc/SNodeCmd.cpp + base/src/ecflow/base/stc/SServerLoadCmd.cpp + base/src/ecflow/base/stc/SStatsCmd.cpp + base/src/ecflow/base/stc/SStringCmd.cpp + base/src/ecflow/base/stc/SStringVecCmd.cpp + base/src/ecflow/base/stc/SSuitesCmd.cpp + base/src/ecflow/base/stc/SSyncCmd.cpp + base/src/ecflow/base/stc/ServerToClientCmd.cpp + base/src/ecflow/base/stc/StcCmd.cpp + base/src/ecflow/base/stc/ZombieGetCmd.cpp + + # Client -- Headers + client/src/ecflow/client/ClientCmdCache.hpp + client/src/ecflow/client/ClientEnvironment.hpp + client/src/ecflow/client/ClientInvoker.hpp + client/src/ecflow/client/ClientOptions.hpp + client/src/ecflow/client/Help.hpp + client/src/ecflow/client/Rtt.hpp + client/src/ecflow/client/UrlCmd.hpp + # Client -- Sources + client/src/ecflow/client/ClientCmdCache.cpp + client/src/ecflow/client/Rtt.cpp + client/src/ecflow/client/ClientEnvironment.cpp + client/src/ecflow/client/ClientInvoker.cpp + client/src/ecflow/client/Help.cpp + client/src/ecflow/client/Rtt.cpp + client/src/ecflow/client/ClientOptions.cpp + client/src/ecflow/client/UrlCmd.cpp + + # Core -- Headers + ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_version.h + ${CMAKE_BINARY_DIR}/generated/src/ecflow/core/ecflow_source_build_dir.h + core/src/ecflow/core/AssertTimer.hpp + core/src/ecflow/core/Cal.hpp + core/src/ecflow/core/Calendar.hpp + core/src/ecflow/core/CalendarUpdateParams.hpp + core/src/ecflow/core/CheckPt.hpp + core/src/ecflow/core/Child.hpp + core/src/ecflow/core/Chrono.hpp + core/src/ecflow/core/CommandLine.hpp + core/src/ecflow/core/DState.hpp + core/src/ecflow/core/DebugPerf.hpp + core/src/ecflow/core/DurationTimer.hpp + core/src/ecflow/core/Ecf.hpp + core/src/ecflow/core/EcfPortLock.hpp + core/src/ecflow/core/Extract.hpp + core/src/ecflow/core/File.hpp + core/src/ecflow/core/File_r.hpp + core/src/ecflow/core/Filesystem.hpp + core/src/ecflow/core/Host.hpp + core/src/ecflow/core/Indentor.hpp + core/src/ecflow/core/Log.hpp + core/src/ecflow/core/LogVerification.hpp + core/src/ecflow/core/Message.hpp + core/src/ecflow/core/NOrder.hpp + core/src/ecflow/core/NState.hpp + core/src/ecflow/core/NodePath.hpp + core/src/ecflow/core/Overload.hpp + core/src/ecflow/core/Passwd.hpp + core/src/ecflow/core/PasswdFile.hpp + core/src/ecflow/core/PasswordEncryption.hpp + core/src/ecflow/core/Pid.hpp + core/src/ecflow/core/PrintStyle.hpp + core/src/ecflow/core/SState.hpp + core/src/ecflow/core/Serialization.hpp + core/src/ecflow/core/Stl.hpp + core/src/ecflow/core/Str.hpp + core/src/ecflow/core/StringSplitter.hpp + core/src/ecflow/core/TimeSeries.hpp + core/src/ecflow/core/TimeSlot.hpp + core/src/ecflow/core/TimeStamp.hpp + core/src/ecflow/core/User.hpp + core/src/ecflow/core/Version.hpp + core/src/ecflow/core/WhiteListFile.hpp + core/src/ecflow/core/cereal_boost_time.hpp + core/src/ecflow/core/cereal_optional_nvp.hpp + core/src/ecflow/core/perf_timer.hpp + core/src/ecflow/core/exceptions/Exceptions.hpp + # Core -- Sources + core/src/ecflow/core/AssertTimer.cpp + core/src/ecflow/core/Cal.cpp + core/src/ecflow/core/Calendar.cpp + core/src/ecflow/core/Child.cpp + core/src/ecflow/core/Chrono.cpp + core/src/ecflow/core/CommandLine.cpp + core/src/ecflow/core/DState.cpp + core/src/ecflow/core/DurationTimer.cpp + core/src/ecflow/core/Ecf.cpp + core/src/ecflow/core/Extract.cpp + core/src/ecflow/core/File.cpp + core/src/ecflow/core/File_r.cpp + core/src/ecflow/core/Filesystem.cpp + core/src/ecflow/core/Host.cpp + core/src/ecflow/core/Indentor.cpp + core/src/ecflow/core/Log.cpp + core/src/ecflow/core/LogVerification.cpp + core/src/ecflow/core/NOrder.cpp + core/src/ecflow/core/NState.cpp + core/src/ecflow/core/NodePath.cpp + core/src/ecflow/core/Passwd.cpp + core/src/ecflow/core/PasswdFile.cpp + core/src/ecflow/core/Pid.cpp + core/src/ecflow/core/PrintStyle.cpp + core/src/ecflow/core/SState.cpp + core/src/ecflow/core/Str.cpp + core/src/ecflow/core/StringSplitter.cpp + core/src/ecflow/core/TimeSeries.cpp + core/src/ecflow/core/TimeSlot.cpp + core/src/ecflow/core/TimeStamp.cpp + core/src/ecflow/core/User.cpp + core/src/ecflow/core/Version.cpp + core/src/ecflow/core/WhiteListFile.cpp + + # Node -- Headers + node/src/ecflow/node/AbstractObserver.hpp + node/src/ecflow/node/Alias.hpp + node/src/ecflow/node/Aspect.hpp + node/src/ecflow/node/Attr.hpp + node/src/ecflow/node/AutoRestoreAttr.hpp + node/src/ecflow/node/AvisoAttr.hpp + node/src/ecflow/node/ClientSuiteMgr.hpp + node/src/ecflow/node/ClientSuites.hpp + node/src/ecflow/node/CmdContext.hpp + node/src/ecflow/node/Defs.hpp + node/src/ecflow/node/DefsDelta.hpp + node/src/ecflow/node/DefsTreeVisitor.hpp + node/src/ecflow/node/EcfFile.hpp + node/src/ecflow/node/ExprAst.hpp + node/src/ecflow/node/ExprAstVisitor.hpp + node/src/ecflow/node/ExprDuplicate.hpp + node/src/ecflow/node/ExprParser.hpp + node/src/ecflow/node/Expression.hpp + node/src/ecflow/node/Family.hpp + node/src/ecflow/node/Flag.hpp + node/src/ecflow/node/InLimit.hpp + node/src/ecflow/node/InLimitMgr.hpp + node/src/ecflow/node/JobCreationCtrl.hpp + node/src/ecflow/node/JobProfiler.hpp + node/src/ecflow/node/Jobs.hpp + node/src/ecflow/node/JobsParam.hpp + node/src/ecflow/node/Limit.hpp + node/src/ecflow/node/LimitFwd.hpp + node/src/ecflow/node/Memento.hpp + node/src/ecflow/node/MirrorAttr.hpp + node/src/ecflow/node/MiscAttrs.hpp + node/src/ecflow/node/Node.hpp + node/src/ecflow/node/NodeContainer.hpp + node/src/ecflow/node/NodeFwd.hpp + node/src/ecflow/node/NodeState.hpp + node/src/ecflow/node/NodeStats.hpp + node/src/ecflow/node/NodeTreeVisitor.hpp + node/src/ecflow/node/Operations.hpp + node/src/ecflow/node/ResolveExternsVisitor.hpp + node/src/ecflow/node/ServerState.hpp + node/src/ecflow/node/Signal.hpp + node/src/ecflow/node/Submittable.hpp + node/src/ecflow/node/Suite.hpp + node/src/ecflow/node/SuiteChanged.hpp + node/src/ecflow/node/System.hpp + node/src/ecflow/node/Task.hpp + node/src/ecflow/node/TaskScriptGenerator.hpp + node/src/ecflow/node/move_peer.hpp + node/src/ecflow/node/formatter/AvisoFormatter.hpp + node/src/ecflow/node/formatter/Format.hpp + node/src/ecflow/node/formatter/Formatter.hpp + node/src/ecflow/node/formatter/MirrorFormatter.hpp + node/src/ecflow/node/parser/AutoArchiveParser.hpp + node/src/ecflow/node/parser/AutoCancelParser.hpp + node/src/ecflow/node/parser/AutoRestoreParser.hpp + node/src/ecflow/node/parser/AvisoParser.hpp + node/src/ecflow/node/parser/CalendarParser.hpp + node/src/ecflow/node/parser/ClockParser.hpp + node/src/ecflow/node/parser/CronParser.hpp + node/src/ecflow/node/parser/DateParser.hpp + node/src/ecflow/node/parser/DayParser.hpp + node/src/ecflow/node/parser/DefsParser.hpp + node/src/ecflow/node/parser/DefsStateParser.hpp + node/src/ecflow/node/parser/DefsStatusParser.hpp + node/src/ecflow/node/parser/DefsStructureParser.hpp + node/src/ecflow/node/parser/EventParser.hpp + node/src/ecflow/node/parser/ExternParser.hpp + node/src/ecflow/node/parser/GenericParser.hpp + node/src/ecflow/node/parser/InlimitParser.hpp + node/src/ecflow/node/parser/LabelParser.hpp + node/src/ecflow/node/parser/LateParser.hpp + node/src/ecflow/node/parser/LimitParser.hpp + node/src/ecflow/node/parser/MeterParser.hpp + node/src/ecflow/node/parser/MirrorParser.cpp + node/src/ecflow/node/parser/Parser.hpp + node/src/ecflow/node/parser/QueueParser.hpp + node/src/ecflow/node/parser/RepeatParser.hpp + node/src/ecflow/node/parser/TimeParser.hpp + node/src/ecflow/node/parser/TodayParser.hpp + node/src/ecflow/node/parser/TriggerParser.hpp + node/src/ecflow/node/parser/VariableParser.hpp + node/src/ecflow/node/parser/VerifyParser.hpp + node/src/ecflow/node/parser/ZombieAttrParser.hpp + # Node -- Sources + node/src/ecflow/node/Alias.cpp + node/src/ecflow/node/Attr.cpp + node/src/ecflow/node/AutoRestoreAttr.cpp + node/src/ecflow/node/AvisoAttr.cpp + node/src/ecflow/node/ClientSuiteMgr.cpp + node/src/ecflow/node/ClientSuites.cpp + node/src/ecflow/node/CmdContext.cpp + node/src/ecflow/node/Defs.cpp + node/src/ecflow/node/DefsDelta.cpp + node/src/ecflow/node/EcfFile.cpp + node/src/ecflow/node/ExprAst.cpp + node/src/ecflow/node/ExprAstVisitor.cpp + node/src/ecflow/node/ExprDuplicate.cpp + node/src/ecflow/node/ExprParser.cpp + node/src/ecflow/node/Expression.cpp + node/src/ecflow/node/Family.cpp + node/src/ecflow/node/Flag.cpp + node/src/ecflow/node/InLimit.cpp + node/src/ecflow/node/InLimitMgr.cpp + node/src/ecflow/node/JobCreationCtrl.cpp + node/src/ecflow/node/JobProfiler.cpp + node/src/ecflow/node/Jobs.cpp + node/src/ecflow/node/JobsParam.cpp + node/src/ecflow/node/Limit.cpp + node/src/ecflow/node/Memento.cpp + node/src/ecflow/node/MirrorAttr.cpp + node/src/ecflow/node/MiscAttrs.cpp + node/src/ecflow/node/Node.cpp + node/src/ecflow/node/NodeAdd.cpp + node/src/ecflow/node/NodeChange.cpp + node/src/ecflow/node/NodeContainer.cpp + node/src/ecflow/node/NodeDelete.cpp + node/src/ecflow/node/NodeFind.cpp + node/src/ecflow/node/NodeMemento.cpp + node/src/ecflow/node/NodeStats.cpp + node/src/ecflow/node/NodeTime.cpp + node/src/ecflow/node/NodeTreeVisitor.cpp + node/src/ecflow/node/ResolveExternsVisitor.cpp + node/src/ecflow/node/ServerState.cpp + node/src/ecflow/node/Signal.cpp + node/src/ecflow/node/Submittable.cpp + node/src/ecflow/node/Suite.cpp + node/src/ecflow/node/SuiteChanged.cpp + node/src/ecflow/node/System.cpp + node/src/ecflow/node/Task.cpp + node/src/ecflow/node/TaskScriptGenerator.cpp + node/src/ecflow/node/parser/AutoArchiveParser.cpp + node/src/ecflow/node/parser/AutoCancelParser.cpp + node/src/ecflow/node/parser/AutoRestoreParser.cpp + node/src/ecflow/node/parser/AvisoParser.cpp + node/src/ecflow/node/parser/CalendarParser.cpp + node/src/ecflow/node/parser/ClockParser.cpp + node/src/ecflow/node/parser/CronParser.cpp + node/src/ecflow/node/parser/DateParser.cpp + node/src/ecflow/node/parser/DayParser.cpp + node/src/ecflow/node/parser/DefsParser.cpp + node/src/ecflow/node/parser/DefsStateParser.cpp + node/src/ecflow/node/parser/DefsStatusParser.cpp + node/src/ecflow/node/parser/DefsStructureParser.cpp + node/src/ecflow/node/parser/EventParser.cpp + node/src/ecflow/node/parser/ExternParser.cpp + node/src/ecflow/node/parser/GenericParser.cpp + node/src/ecflow/node/parser/InlimitParser.cpp + node/src/ecflow/node/parser/LabelParser.cpp + node/src/ecflow/node/parser/LateParser.cpp + node/src/ecflow/node/parser/LimitParser.cpp + node/src/ecflow/node/parser/MeterParser.cpp + node/src/ecflow/node/parser/MirrorParser.cpp + node/src/ecflow/node/parser/Parser.cpp + node/src/ecflow/node/parser/QueueParser.cpp + node/src/ecflow/node/parser/RepeatParser.cpp + node/src/ecflow/node/parser/TimeParser.cpp + node/src/ecflow/node/parser/TodayParser.cpp + node/src/ecflow/node/parser/TriggerParser.cpp + node/src/ecflow/node/parser/VariableParser.cpp + node/src/ecflow/node/parser/VerifyParser.cpp + node/src/ecflow/node/parser/ZombieAttrParser.cpp + + # Server -- Headers + server/src/ecflow/server/BaseServer.hpp + server/src/ecflow/server/CheckPtSaver.hpp + server/src/ecflow/server/NodeTreeTraverser.hpp + server/src/ecflow/server/PeriodicScheduler.hpp + server/src/ecflow/server/Server.hpp + server/src/ecflow/server/ServerEnvironment.hpp + server/src/ecflow/server/ServerOptions.hpp + server/src/ecflow/server/SslServer.hpp + server/src/ecflow/server/SslTcpServer.hpp + server/src/ecflow/server/TcpBaseServer.hpp + server/src/ecflow/server/TcpServer.hpp + $<$:server/src/ecflow/server/SslServer.hpp> + $<$:server/src/ecflow/server/SslTcpServer.hpp> + # Server -- Sources + server/src/ecflow/server/BaseServer.cpp + server/src/ecflow/server/CheckPtSaver.cpp + server/src/ecflow/server/NodeTreeTraverser.cpp + server/src/ecflow/server/PeriodicScheduler.cpp + server/src/ecflow/server/Server.cpp + server/src/ecflow/server/ServerEnvironment.cpp + server/src/ecflow/server/ServerOptions.cpp + server/src/ecflow/server/TcpBaseServer.cpp + server/src/ecflow/server/TcpServer.cpp + $<$:server/src/ecflow/server/SslServer.cpp> + $<$:server/src/ecflow/server/SslTcpServer.cpp> + + # Service -- Headers + service/src/ecflow/service/auth/Credentials.hpp + service/src/ecflow/service/aviso/Aviso.hpp + service/src/ecflow/service/aviso/AvisoService.hpp + service/src/ecflow/service/aviso/etcd/Client.hpp + service/src/ecflow/service/aviso/etcd/Range.hpp + service/src/ecflow/service/executor/PeriodicTaskExecutor.hpp + service/src/ecflow/service/mirror/Mirror.hpp + service/src/ecflow/service/mirror/MirrorClient.hpp + service/src/ecflow/service/mirror/MirrorService.hpp + service/src/ecflow/service/Controller.hpp + service/src/ecflow/service/Log.hpp + service/src/ecflow/service/Registry.hpp + # Service -- Sources + service/src/ecflow/service/auth/Credentials.cpp + service/src/ecflow/service/aviso/Aviso.cpp + service/src/ecflow/service/aviso/AvisoService.cpp + service/src/ecflow/service/aviso/etcd/Range.cpp + service/src/ecflow/service/aviso/etcd/Client.cpp + service/src/ecflow/service/mirror/Mirror.cpp + service/src/ecflow/service/mirror/MirrorClient.cpp + service/src/ecflow/service/mirror/MirrorService.cpp + service/src/ecflow/service/Controller.cpp + service/src/ecflow/service/Registry.cpp + + # UDP -- Headers + udp/src/ecflow/udp/ClientAPI.hpp + udp/src/ecflow/udp/RequestHandler.hpp + udp/src/ecflow/udp/Trace.hpp + udp/src/ecflow/udp/UDPServer.hpp + udp/src/ecflow/udp/UDPServerEnvironment.hpp + udp/src/ecflow/udp/UDPServerOptions.hpp + # UDP -- Sources + udp/src/ecflow/udp/ClientAPI.cpp + udp/src/ecflow/udp/RequestHandler.cpp + udp/src/ecflow/udp/Trace.cpp + udp/src/ecflow/udp/UDPServerEnvironment.cpp + udp/src/ecflow/udp/UDPServerOptions.cpp +) + + +ecbuild_add_library( + TARGET + ecflow_all + NOINSTALL + TYPE STATIC + SOURCES + ${srcs} + PUBLIC_INCLUDES + attribute/src + base/src + client/src + core/src + node/src + service/src + server/src + udp/src + ${CMAKE_BINARY_DIR}/generated/src + PUBLIC_LIBS + nlohmann::json + cereal::cereal # this needs to be public as it appears in public header files used downstream + httplib::httplib + $<$:Boost::system> + Boost::filesystem + Boost::date_time + Boost::program_options + $<$:OpenSSL::SSL> + $<$>:crypt> + Threads::Threads + DEFINITIONS + CMAKE +) +target_clangformat(ecflow_all) + + +add_subdirectory(core) +add_subdirectory(service) +add_subdirectory(attribute) +add_subdirectory(node) +add_subdirectory(base) +add_subdirectory(simulator) +add_subdirectory(client) + +if (ENABLE_SERVER) + add_subdirectory(server) + add_subdirectory(test) +endif () + +if (ENABLE_PYTHON) + if (ENABLE_PYTHON_PTR_REGISTER) + add_definitions(-DECF_ENABLE_PYTHON_PTR_REGISTER) + endif () + add_subdirectory(pyext) +endif () + +if (ENABLE_HTTP) + add_subdirectory(rest) +endif () + +if (ENABLE_UDP) + add_subdirectory(udp) +endif () diff --git a/libs/attribute/CMakeLists.txt b/libs/attribute/CMakeLists.txt new file mode 100644 index 000000000..240881fc4 --- /dev/null +++ b/libs/attribute/CMakeLists.txt @@ -0,0 +1,48 @@ +# +# Copyright 2009- ECMWF. +# +# This software is licensed under the terms of the Apache Licence version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. +# + +set(test_srcs + # Sources + test/TestAttributes_main.cpp + test/TestAttrSerialization.cpp + test/TestCron.cpp + test/TestDateAttr.cpp + test/TestDayAttr.cpp + test/TestLabel.cpp + test/TestLateAttr.cpp + test/TestMigration.cpp + test/TestRepeat.cpp + test/TestSizeOf.cpp + test/TestTimeAttr.cpp + test/TestTodayAttr.cpp + test/TestVariable.cpp + test/TestVariableMap.cpp + test/TestZombieAttr.cpp +) + +ecbuild_add_test( + TARGET + u_attributes + LABELS + unit + nightly + SOURCES + ${test_srcs} + INCLUDES + ../core/test + LIBS + ecflow_all + TEST_DEPENDS + u_core + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) +) +target_clangformat(u_attributes + CONDITION ENABLE_TESTS +) diff --git a/ANattr/src/ecflow/attribute/AutoArchiveAttr.cpp b/libs/attribute/src/ecflow/attribute/AutoArchiveAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/AutoArchiveAttr.cpp rename to libs/attribute/src/ecflow/attribute/AutoArchiveAttr.cpp diff --git a/ANattr/src/ecflow/attribute/AutoArchiveAttr.hpp b/libs/attribute/src/ecflow/attribute/AutoArchiveAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/AutoArchiveAttr.hpp rename to libs/attribute/src/ecflow/attribute/AutoArchiveAttr.hpp diff --git a/ANattr/src/ecflow/attribute/AutoCancelAttr.cpp b/libs/attribute/src/ecflow/attribute/AutoCancelAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/AutoCancelAttr.cpp rename to libs/attribute/src/ecflow/attribute/AutoCancelAttr.cpp diff --git a/ANattr/src/ecflow/attribute/AutoCancelAttr.hpp b/libs/attribute/src/ecflow/attribute/AutoCancelAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/AutoCancelAttr.hpp rename to libs/attribute/src/ecflow/attribute/AutoCancelAttr.hpp diff --git a/ANattr/src/ecflow/attribute/ClockAttr.cpp b/libs/attribute/src/ecflow/attribute/ClockAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/ClockAttr.cpp rename to libs/attribute/src/ecflow/attribute/ClockAttr.cpp diff --git a/ANattr/src/ecflow/attribute/ClockAttr.hpp b/libs/attribute/src/ecflow/attribute/ClockAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/ClockAttr.hpp rename to libs/attribute/src/ecflow/attribute/ClockAttr.hpp diff --git a/ANattr/src/ecflow/attribute/CronAttr.cpp b/libs/attribute/src/ecflow/attribute/CronAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/CronAttr.cpp rename to libs/attribute/src/ecflow/attribute/CronAttr.cpp diff --git a/ANattr/src/ecflow/attribute/CronAttr.hpp b/libs/attribute/src/ecflow/attribute/CronAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/CronAttr.hpp rename to libs/attribute/src/ecflow/attribute/CronAttr.hpp diff --git a/ANattr/src/ecflow/attribute/DateAttr.cpp b/libs/attribute/src/ecflow/attribute/DateAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/DateAttr.cpp rename to libs/attribute/src/ecflow/attribute/DateAttr.cpp diff --git a/ANattr/src/ecflow/attribute/DateAttr.hpp b/libs/attribute/src/ecflow/attribute/DateAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/DateAttr.hpp rename to libs/attribute/src/ecflow/attribute/DateAttr.hpp diff --git a/ANattr/src/ecflow/attribute/DayAttr.cpp b/libs/attribute/src/ecflow/attribute/DayAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/DayAttr.cpp rename to libs/attribute/src/ecflow/attribute/DayAttr.cpp diff --git a/ANattr/src/ecflow/attribute/DayAttr.hpp b/libs/attribute/src/ecflow/attribute/DayAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/DayAttr.hpp rename to libs/attribute/src/ecflow/attribute/DayAttr.hpp diff --git a/ANattr/src/ecflow/attribute/GenericAttr.cpp b/libs/attribute/src/ecflow/attribute/GenericAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/GenericAttr.cpp rename to libs/attribute/src/ecflow/attribute/GenericAttr.cpp diff --git a/ANattr/src/ecflow/attribute/GenericAttr.hpp b/libs/attribute/src/ecflow/attribute/GenericAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/GenericAttr.hpp rename to libs/attribute/src/ecflow/attribute/GenericAttr.hpp diff --git a/ANattr/src/ecflow/attribute/LateAttr.cpp b/libs/attribute/src/ecflow/attribute/LateAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/LateAttr.cpp rename to libs/attribute/src/ecflow/attribute/LateAttr.cpp diff --git a/ANattr/src/ecflow/attribute/LateAttr.hpp b/libs/attribute/src/ecflow/attribute/LateAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/LateAttr.hpp rename to libs/attribute/src/ecflow/attribute/LateAttr.hpp diff --git a/ANattr/src/ecflow/attribute/NodeAttr.cpp b/libs/attribute/src/ecflow/attribute/NodeAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/NodeAttr.cpp rename to libs/attribute/src/ecflow/attribute/NodeAttr.cpp diff --git a/ANattr/src/ecflow/attribute/NodeAttr.hpp b/libs/attribute/src/ecflow/attribute/NodeAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/NodeAttr.hpp rename to libs/attribute/src/ecflow/attribute/NodeAttr.hpp diff --git a/ANattr/src/ecflow/attribute/QueueAttr.cpp b/libs/attribute/src/ecflow/attribute/QueueAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/QueueAttr.cpp rename to libs/attribute/src/ecflow/attribute/QueueAttr.cpp diff --git a/ANattr/src/ecflow/attribute/QueueAttr.hpp b/libs/attribute/src/ecflow/attribute/QueueAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/QueueAttr.hpp rename to libs/attribute/src/ecflow/attribute/QueueAttr.hpp diff --git a/ANattr/src/ecflow/attribute/RepeatAttr.cpp b/libs/attribute/src/ecflow/attribute/RepeatAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/RepeatAttr.cpp rename to libs/attribute/src/ecflow/attribute/RepeatAttr.cpp diff --git a/ANattr/src/ecflow/attribute/RepeatAttr.hpp b/libs/attribute/src/ecflow/attribute/RepeatAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/RepeatAttr.hpp rename to libs/attribute/src/ecflow/attribute/RepeatAttr.hpp diff --git a/ANattr/src/ecflow/attribute/TimeAttr.cpp b/libs/attribute/src/ecflow/attribute/TimeAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/TimeAttr.cpp rename to libs/attribute/src/ecflow/attribute/TimeAttr.cpp diff --git a/ANattr/src/ecflow/attribute/TimeAttr.hpp b/libs/attribute/src/ecflow/attribute/TimeAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/TimeAttr.hpp rename to libs/attribute/src/ecflow/attribute/TimeAttr.hpp diff --git a/ANattr/src/ecflow/attribute/TodayAttr.cpp b/libs/attribute/src/ecflow/attribute/TodayAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/TodayAttr.cpp rename to libs/attribute/src/ecflow/attribute/TodayAttr.cpp diff --git a/ANattr/src/ecflow/attribute/TodayAttr.hpp b/libs/attribute/src/ecflow/attribute/TodayAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/TodayAttr.hpp rename to libs/attribute/src/ecflow/attribute/TodayAttr.hpp diff --git a/ANattr/src/ecflow/attribute/Variable.cpp b/libs/attribute/src/ecflow/attribute/Variable.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/Variable.cpp rename to libs/attribute/src/ecflow/attribute/Variable.cpp diff --git a/ANattr/src/ecflow/attribute/Variable.hpp b/libs/attribute/src/ecflow/attribute/Variable.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/Variable.hpp rename to libs/attribute/src/ecflow/attribute/Variable.hpp diff --git a/ANattr/src/ecflow/attribute/VerifyAttr.cpp b/libs/attribute/src/ecflow/attribute/VerifyAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/VerifyAttr.cpp rename to libs/attribute/src/ecflow/attribute/VerifyAttr.cpp diff --git a/ANattr/src/ecflow/attribute/VerifyAttr.hpp b/libs/attribute/src/ecflow/attribute/VerifyAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/VerifyAttr.hpp rename to libs/attribute/src/ecflow/attribute/VerifyAttr.hpp diff --git a/ANattr/src/ecflow/attribute/Zombie.cpp b/libs/attribute/src/ecflow/attribute/Zombie.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/Zombie.cpp rename to libs/attribute/src/ecflow/attribute/Zombie.cpp diff --git a/ANattr/src/ecflow/attribute/Zombie.hpp b/libs/attribute/src/ecflow/attribute/Zombie.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/Zombie.hpp rename to libs/attribute/src/ecflow/attribute/Zombie.hpp diff --git a/ANattr/src/ecflow/attribute/ZombieAttr.cpp b/libs/attribute/src/ecflow/attribute/ZombieAttr.cpp similarity index 100% rename from ANattr/src/ecflow/attribute/ZombieAttr.cpp rename to libs/attribute/src/ecflow/attribute/ZombieAttr.cpp diff --git a/ANattr/src/ecflow/attribute/ZombieAttr.hpp b/libs/attribute/src/ecflow/attribute/ZombieAttr.hpp similarity index 100% rename from ANattr/src/ecflow/attribute/ZombieAttr.hpp rename to libs/attribute/src/ecflow/attribute/ZombieAttr.hpp diff --git a/ANattr/test/TestAttrSerialization.cpp b/libs/attribute/test/TestAttrSerialization.cpp similarity index 100% rename from ANattr/test/TestAttrSerialization.cpp rename to libs/attribute/test/TestAttrSerialization.cpp diff --git a/ANattr/test/TestAttributes_main.cpp b/libs/attribute/test/TestAttributes_main.cpp similarity index 100% rename from ANattr/test/TestAttributes_main.cpp rename to libs/attribute/test/TestAttributes_main.cpp diff --git a/ANattr/test/TestCron.cpp b/libs/attribute/test/TestCron.cpp similarity index 100% rename from ANattr/test/TestCron.cpp rename to libs/attribute/test/TestCron.cpp diff --git a/ANattr/test/TestDateAttr.cpp b/libs/attribute/test/TestDateAttr.cpp similarity index 100% rename from ANattr/test/TestDateAttr.cpp rename to libs/attribute/test/TestDateAttr.cpp diff --git a/ANattr/test/TestDayAttr.cpp b/libs/attribute/test/TestDayAttr.cpp similarity index 100% rename from ANattr/test/TestDayAttr.cpp rename to libs/attribute/test/TestDayAttr.cpp diff --git a/ANattr/test/TestLabel.cpp b/libs/attribute/test/TestLabel.cpp similarity index 100% rename from ANattr/test/TestLabel.cpp rename to libs/attribute/test/TestLabel.cpp diff --git a/ANattr/test/TestLateAttr.cpp b/libs/attribute/test/TestLateAttr.cpp similarity index 100% rename from ANattr/test/TestLateAttr.cpp rename to libs/attribute/test/TestLateAttr.cpp diff --git a/ANattr/test/TestMigration.cpp b/libs/attribute/test/TestMigration.cpp similarity index 98% rename from ANattr/test/TestMigration.cpp rename to libs/attribute/test/TestMigration.cpp index 5a46d43f6..4649f31f3 100644 --- a/ANattr/test/TestMigration.cpp +++ b/libs/attribute/test/TestMigration.cpp @@ -49,7 +49,8 @@ BOOST_AUTO_TEST_SUITE(T_Migration) BOOST_AUTO_TEST_CASE(test_migration_restore_def_con) { cout << "ANattr:: ...test_migration_restore_def_con\n"; - std::string file_name = File::test_data("ANattr/test/data/migration/default_constructor_1_2_2/", "ANattr"); + std::string file_name = + File::test_data("libs/attribute/test/data/migration/default_constructor_1_2_2/", "libs/attribute"); // BOOST_CHECK_MESSAGE(File::createDirectories(file_name ),"Could not create directory " << file_name); // Create migration data @@ -104,7 +105,7 @@ BOOST_AUTO_TEST_CASE(test_migration_restore_def_con) { BOOST_AUTO_TEST_CASE(test_migration_restore) { cout << "ANattr:: ...test_migration_restore\n"; - std::string file_name = File::test_data("ANattr/test/data/migration/1_2_2/", "ANattr"); + std::string file_name = File::test_data("libs/attribute/test/data/migration/1_2_2/", "libs/attribute"); // BOOST_CHECK_MESSAGE(File::createDirectories(file_name ),"Could not create directory " << file_name); std::vector theVec; diff --git a/ANattr/test/TestRepeat.cpp b/libs/attribute/test/TestRepeat.cpp similarity index 100% rename from ANattr/test/TestRepeat.cpp rename to libs/attribute/test/TestRepeat.cpp diff --git a/ANattr/test/TestSizeOf.cpp b/libs/attribute/test/TestSizeOf.cpp similarity index 100% rename from ANattr/test/TestSizeOf.cpp rename to libs/attribute/test/TestSizeOf.cpp diff --git a/ANattr/test/TestTimeAttr.cpp b/libs/attribute/test/TestTimeAttr.cpp similarity index 100% rename from ANattr/test/TestTimeAttr.cpp rename to libs/attribute/test/TestTimeAttr.cpp diff --git a/ANattr/test/TestTodayAttr.cpp b/libs/attribute/test/TestTodayAttr.cpp similarity index 100% rename from ANattr/test/TestTodayAttr.cpp rename to libs/attribute/test/TestTodayAttr.cpp diff --git a/ANattr/test/TestVariable.cpp b/libs/attribute/test/TestVariable.cpp similarity index 100% rename from ANattr/test/TestVariable.cpp rename to libs/attribute/test/TestVariable.cpp diff --git a/ANattr/test/TestVariableMap.cpp b/libs/attribute/test/TestVariableMap.cpp similarity index 100% rename from ANattr/test/TestVariableMap.cpp rename to libs/attribute/test/TestVariableMap.cpp diff --git a/ANattr/test/TestZombieAttr.cpp b/libs/attribute/test/TestZombieAttr.cpp similarity index 100% rename from ANattr/test/TestZombieAttr.cpp rename to libs/attribute/test/TestZombieAttr.cpp diff --git a/ANattr/test/data/migration/1_2_2/AutoArchiveAttr b/libs/attribute/test/data/migration/1_2_2/AutoArchiveAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/AutoArchiveAttr rename to libs/attribute/test/data/migration/1_2_2/AutoArchiveAttr diff --git a/ANattr/test/data/migration/1_2_2/AutoArchiveAttr_1 b/libs/attribute/test/data/migration/1_2_2/AutoArchiveAttr_1 similarity index 100% rename from ANattr/test/data/migration/1_2_2/AutoArchiveAttr_1 rename to libs/attribute/test/data/migration/1_2_2/AutoArchiveAttr_1 diff --git a/ANattr/test/data/migration/1_2_2/AutoCancelAttr b/libs/attribute/test/data/migration/1_2_2/AutoCancelAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/AutoCancelAttr rename to libs/attribute/test/data/migration/1_2_2/AutoCancelAttr diff --git a/ANattr/test/data/migration/1_2_2/AutoCancelAttr_1 b/libs/attribute/test/data/migration/1_2_2/AutoCancelAttr_1 similarity index 100% rename from ANattr/test/data/migration/1_2_2/AutoCancelAttr_1 rename to libs/attribute/test/data/migration/1_2_2/AutoCancelAttr_1 diff --git a/ANattr/test/data/migration/1_2_2/ClockAttr b/libs/attribute/test/data/migration/1_2_2/ClockAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/ClockAttr rename to libs/attribute/test/data/migration/1_2_2/ClockAttr diff --git a/ANattr/test/data/migration/1_2_2/CronAttr b/libs/attribute/test/data/migration/1_2_2/CronAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/CronAttr rename to libs/attribute/test/data/migration/1_2_2/CronAttr diff --git a/ANattr/test/data/migration/1_2_2/DateAttr b/libs/attribute/test/data/migration/1_2_2/DateAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/DateAttr rename to libs/attribute/test/data/migration/1_2_2/DateAttr diff --git a/ANattr/test/data/migration/1_2_2/DayAttr b/libs/attribute/test/data/migration/1_2_2/DayAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/DayAttr rename to libs/attribute/test/data/migration/1_2_2/DayAttr diff --git a/ANattr/test/data/migration/1_2_2/Event_1 b/libs/attribute/test/data/migration/1_2_2/Event_1 similarity index 100% rename from ANattr/test/data/migration/1_2_2/Event_1 rename to libs/attribute/test/data/migration/1_2_2/Event_1 diff --git a/ANattr/test/data/migration/1_2_2/Event_2 b/libs/attribute/test/data/migration/1_2_2/Event_2 similarity index 100% rename from ANattr/test/data/migration/1_2_2/Event_2 rename to libs/attribute/test/data/migration/1_2_2/Event_2 diff --git a/ANattr/test/data/migration/1_2_2/Event_3 b/libs/attribute/test/data/migration/1_2_2/Event_3 similarity index 100% rename from ANattr/test/data/migration/1_2_2/Event_3 rename to libs/attribute/test/data/migration/1_2_2/Event_3 diff --git a/ANattr/test/data/migration/1_2_2/GenericAttr b/libs/attribute/test/data/migration/1_2_2/GenericAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/GenericAttr rename to libs/attribute/test/data/migration/1_2_2/GenericAttr diff --git a/ANattr/test/data/migration/1_2_2/Label b/libs/attribute/test/data/migration/1_2_2/Label similarity index 100% rename from ANattr/test/data/migration/1_2_2/Label rename to libs/attribute/test/data/migration/1_2_2/Label diff --git a/ANattr/test/data/migration/1_2_2/LateAttr b/libs/attribute/test/data/migration/1_2_2/LateAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/LateAttr rename to libs/attribute/test/data/migration/1_2_2/LateAttr diff --git a/ANattr/test/data/migration/1_2_2/Meter b/libs/attribute/test/data/migration/1_2_2/Meter similarity index 100% rename from ANattr/test/data/migration/1_2_2/Meter rename to libs/attribute/test/data/migration/1_2_2/Meter diff --git a/ANattr/test/data/migration/1_2_2/QueueAttr b/libs/attribute/test/data/migration/1_2_2/QueueAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/QueueAttr rename to libs/attribute/test/data/migration/1_2_2/QueueAttr diff --git a/ANattr/test/data/migration/1_2_2/RepeatDate b/libs/attribute/test/data/migration/1_2_2/RepeatDate similarity index 100% rename from ANattr/test/data/migration/1_2_2/RepeatDate rename to libs/attribute/test/data/migration/1_2_2/RepeatDate diff --git a/ANattr/test/data/migration/1_2_2/RepeatDateList b/libs/attribute/test/data/migration/1_2_2/RepeatDateList similarity index 100% rename from ANattr/test/data/migration/1_2_2/RepeatDateList rename to libs/attribute/test/data/migration/1_2_2/RepeatDateList diff --git a/ANattr/test/data/migration/1_2_2/RepeatEnumerated b/libs/attribute/test/data/migration/1_2_2/RepeatEnumerated similarity index 100% rename from ANattr/test/data/migration/1_2_2/RepeatEnumerated rename to libs/attribute/test/data/migration/1_2_2/RepeatEnumerated diff --git a/ANattr/test/data/migration/1_2_2/RepeatInteger b/libs/attribute/test/data/migration/1_2_2/RepeatInteger similarity index 100% rename from ANattr/test/data/migration/1_2_2/RepeatInteger rename to libs/attribute/test/data/migration/1_2_2/RepeatInteger diff --git a/ANattr/test/data/migration/1_2_2/RepeatString b/libs/attribute/test/data/migration/1_2_2/RepeatString similarity index 100% rename from ANattr/test/data/migration/1_2_2/RepeatString rename to libs/attribute/test/data/migration/1_2_2/RepeatString diff --git a/ANattr/test/data/migration/1_2_2/TimeAttr b/libs/attribute/test/data/migration/1_2_2/TimeAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/TimeAttr rename to libs/attribute/test/data/migration/1_2_2/TimeAttr diff --git a/ANattr/test/data/migration/1_2_2/TodayAttr b/libs/attribute/test/data/migration/1_2_2/TodayAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/TodayAttr rename to libs/attribute/test/data/migration/1_2_2/TodayAttr diff --git a/ANattr/test/data/migration/1_2_2/Variable b/libs/attribute/test/data/migration/1_2_2/Variable similarity index 100% rename from ANattr/test/data/migration/1_2_2/Variable rename to libs/attribute/test/data/migration/1_2_2/Variable diff --git a/ANattr/test/data/migration/1_2_2/VerifyAttr b/libs/attribute/test/data/migration/1_2_2/VerifyAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/VerifyAttr rename to libs/attribute/test/data/migration/1_2_2/VerifyAttr diff --git a/ANattr/test/data/migration/1_2_2/ZombieAttr b/libs/attribute/test/data/migration/1_2_2/ZombieAttr similarity index 100% rename from ANattr/test/data/migration/1_2_2/ZombieAttr rename to libs/attribute/test/data/migration/1_2_2/ZombieAttr diff --git a/ANattr/test/data/migration/1_2_2/ZombieAttr1 b/libs/attribute/test/data/migration/1_2_2/ZombieAttr1 similarity index 100% rename from ANattr/test/data/migration/1_2_2/ZombieAttr1 rename to libs/attribute/test/data/migration/1_2_2/ZombieAttr1 diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/AutoArchiveAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/AutoArchiveAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/AutoArchiveAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/AutoArchiveAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/AutoCancelAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/AutoCancelAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/AutoCancelAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/AutoCancelAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/ClockAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/ClockAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/ClockAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/ClockAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/CronAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/CronAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/CronAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/CronAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/DateAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/DateAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/DateAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/DateAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/DayAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/DayAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/DayAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/DayAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/Event b/libs/attribute/test/data/migration/default_constructor_1_2_2/Event similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/Event rename to libs/attribute/test/data/migration/default_constructor_1_2_2/Event diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/GenericAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/GenericAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/GenericAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/GenericAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/Label b/libs/attribute/test/data/migration/default_constructor_1_2_2/Label similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/Label rename to libs/attribute/test/data/migration/default_constructor_1_2_2/Label diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/LateAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/LateAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/LateAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/LateAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/Meter b/libs/attribute/test/data/migration/default_constructor_1_2_2/Meter similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/Meter rename to libs/attribute/test/data/migration/default_constructor_1_2_2/Meter diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/QueueAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/QueueAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/QueueAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/QueueAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/RepeatDate b/libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatDate similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/RepeatDate rename to libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatDate diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/RepeatDateList b/libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatDateList similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/RepeatDateList rename to libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatDateList diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/RepeatEnumerated b/libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatEnumerated similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/RepeatEnumerated rename to libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatEnumerated diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/RepeatInteger b/libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatInteger similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/RepeatInteger rename to libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatInteger diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/RepeatString b/libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatString similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/RepeatString rename to libs/attribute/test/data/migration/default_constructor_1_2_2/RepeatString diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/TimeAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/TimeAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/TimeAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/TimeAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/TodayAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/TodayAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/TodayAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/TodayAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/Variable b/libs/attribute/test/data/migration/default_constructor_1_2_2/Variable similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/Variable rename to libs/attribute/test/data/migration/default_constructor_1_2_2/Variable diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/VerifyAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/VerifyAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/VerifyAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/VerifyAttr diff --git a/ANattr/test/data/migration/default_constructor_1_2_2/ZombieAttr b/libs/attribute/test/data/migration/default_constructor_1_2_2/ZombieAttr similarity index 100% rename from ANattr/test/data/migration/default_constructor_1_2_2/ZombieAttr rename to libs/attribute/test/data/migration/default_constructor_1_2_2/ZombieAttr diff --git a/libs/base/CMakeLists.txt b/libs/base/CMakeLists.txt new file mode 100644 index 000000000..341cfe1aa --- /dev/null +++ b/libs/base/CMakeLists.txt @@ -0,0 +1,82 @@ +# +# Copyright 2009- ECMWF. +# +# This software is licensed under the terms of the Apache Licence version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. +# + +set(test_srcs + # Headers + test/MockServer.hpp + test/TestHelper.hpp + # Sources + test/TestAlterCmd.cpp + test/TestArchiveAndRestoreCmd.cpp + test/TestBase_main.cpp # test entry point + test/TestClientHandleCmd.cpp + test/TestCmd.cpp + test/TestDeleteNodeCmd.cpp + test/TestForceCmd.cpp + test/TestFreeDepCmd.cpp + test/TestInLimitAndLimit.cpp + test/TestLogCmd.cpp + test/TestMeterCmd.cpp + test/TestProgramOptions.cpp + test/TestQueryCmd.cpp + test/TestQueueCmd.cpp + test/TestRequest.cpp + test/TestRequeueNodeCmd.cpp + test/TestResolveDependencies.cpp + test/TestSpecificIssues.cpp + test/TestSSyncCmd.cpp + test/TestSSyncCmdOrder.cpp + test/TestSSyncCmd_CH1.cpp + test/TestStatsCmd.cpp +) + +ecbuild_add_test( + TARGET + u_base + LABELS + unit nightly + SOURCES + ${test_srcs} + INCLUDES + ../node/test + LIBS + ecflow_all + Threads::Threads + $<$:OpenSSL::SSL> + TEST_DEPENDS + u_parser +) +target_clangformat(u_base + CONDITION ENABLE_TESTS +) + +# The following is not technically a test (as it makes no checks), +# but a tool to measure the time it takes to generate a job file +if (ENABLE_ALL_TESTS) + set(test_srcs + # Sources + test/TestJobGenPerf.cpp + ) + + ecbuild_add_test( + TARGET + p_job_gen + LABELS + performance + SOURCES + ${test_srcs} + LIBS + ecflow_all + Threads::Threads + ) + target_clangformat(p_job_gen + CONDITION ENABLE_TESTS + ) +endif() diff --git a/Base/src/ecflow/base/AbstractClientEnv.hpp b/libs/base/src/ecflow/base/AbstractClientEnv.hpp similarity index 100% rename from Base/src/ecflow/base/AbstractClientEnv.hpp rename to libs/base/src/ecflow/base/AbstractClientEnv.hpp diff --git a/Base/src/ecflow/base/AbstractServer.hpp b/libs/base/src/ecflow/base/AbstractServer.hpp similarity index 99% rename from Base/src/ecflow/base/AbstractServer.hpp rename to libs/base/src/ecflow/base/AbstractServer.hpp index 3857b72a4..9346376a8 100644 --- a/Base/src/ecflow/base/AbstractServer.hpp +++ b/libs/base/src/ecflow/base/AbstractServer.hpp @@ -11,6 +11,7 @@ #ifndef ecflow_base_AbstractServer_HPP #define ecflow_base_AbstractServer_HPP +#include #include #include @@ -206,7 +207,7 @@ class AbstractServer { private: ZombieCtrl zombie_ctrl_; Stats stats_; - int job_gen_count_{0}; + std::atomic job_gen_count_{0}; }; #endif /* ecflow_base_AbstractServer_HPP */ diff --git a/Base/src/ecflow/base/Client.cpp b/libs/base/src/ecflow/base/Client.cpp similarity index 100% rename from Base/src/ecflow/base/Client.cpp rename to libs/base/src/ecflow/base/Client.cpp diff --git a/Base/src/ecflow/base/Client.hpp b/libs/base/src/ecflow/base/Client.hpp similarity index 100% rename from Base/src/ecflow/base/Client.hpp rename to libs/base/src/ecflow/base/Client.hpp diff --git a/Base/src/ecflow/base/ClientOptionsParser.cpp b/libs/base/src/ecflow/base/ClientOptionsParser.cpp similarity index 100% rename from Base/src/ecflow/base/ClientOptionsParser.cpp rename to libs/base/src/ecflow/base/ClientOptionsParser.cpp diff --git a/Base/src/ecflow/base/ClientOptionsParser.hpp b/libs/base/src/ecflow/base/ClientOptionsParser.hpp similarity index 100% rename from Base/src/ecflow/base/ClientOptionsParser.hpp rename to libs/base/src/ecflow/base/ClientOptionsParser.hpp diff --git a/Base/src/ecflow/base/ClientToServerRequest.cpp b/libs/base/src/ecflow/base/ClientToServerRequest.cpp similarity index 100% rename from Base/src/ecflow/base/ClientToServerRequest.cpp rename to libs/base/src/ecflow/base/ClientToServerRequest.cpp diff --git a/Base/src/ecflow/base/ClientToServerRequest.hpp b/libs/base/src/ecflow/base/ClientToServerRequest.hpp similarity index 100% rename from Base/src/ecflow/base/ClientToServerRequest.hpp rename to libs/base/src/ecflow/base/ClientToServerRequest.hpp diff --git a/Base/src/ecflow/base/Cmd.hpp b/libs/base/src/ecflow/base/Cmd.hpp similarity index 100% rename from Base/src/ecflow/base/Cmd.hpp rename to libs/base/src/ecflow/base/Cmd.hpp diff --git a/Base/src/ecflow/base/Connection.cpp b/libs/base/src/ecflow/base/Connection.cpp similarity index 100% rename from Base/src/ecflow/base/Connection.cpp rename to libs/base/src/ecflow/base/Connection.cpp diff --git a/Base/src/ecflow/base/Connection.hpp b/libs/base/src/ecflow/base/Connection.hpp similarity index 100% rename from Base/src/ecflow/base/Connection.hpp rename to libs/base/src/ecflow/base/Connection.hpp diff --git a/Base/src/ecflow/base/Gnuplot.cpp b/libs/base/src/ecflow/base/Gnuplot.cpp similarity index 100% rename from Base/src/ecflow/base/Gnuplot.cpp rename to libs/base/src/ecflow/base/Gnuplot.cpp diff --git a/Base/src/ecflow/base/Gnuplot.hpp b/libs/base/src/ecflow/base/Gnuplot.hpp similarity index 100% rename from Base/src/ecflow/base/Gnuplot.hpp rename to libs/base/src/ecflow/base/Gnuplot.hpp diff --git a/Base/src/ecflow/base/Openssl.cpp b/libs/base/src/ecflow/base/Openssl.cpp similarity index 100% rename from Base/src/ecflow/base/Openssl.cpp rename to libs/base/src/ecflow/base/Openssl.cpp diff --git a/Base/src/ecflow/base/Openssl.hpp b/libs/base/src/ecflow/base/Openssl.hpp similarity index 100% rename from Base/src/ecflow/base/Openssl.hpp rename to libs/base/src/ecflow/base/Openssl.hpp diff --git a/Base/src/ecflow/base/ServerReply.cpp b/libs/base/src/ecflow/base/ServerReply.cpp similarity index 100% rename from Base/src/ecflow/base/ServerReply.cpp rename to libs/base/src/ecflow/base/ServerReply.cpp diff --git a/Base/src/ecflow/base/ServerReply.hpp b/libs/base/src/ecflow/base/ServerReply.hpp similarity index 100% rename from Base/src/ecflow/base/ServerReply.hpp rename to libs/base/src/ecflow/base/ServerReply.hpp diff --git a/Base/src/ecflow/base/ServerToClientResponse.cpp b/libs/base/src/ecflow/base/ServerToClientResponse.cpp similarity index 100% rename from Base/src/ecflow/base/ServerToClientResponse.cpp rename to libs/base/src/ecflow/base/ServerToClientResponse.cpp diff --git a/Base/src/ecflow/base/ServerToClientResponse.hpp b/libs/base/src/ecflow/base/ServerToClientResponse.hpp similarity index 100% rename from Base/src/ecflow/base/ServerToClientResponse.hpp rename to libs/base/src/ecflow/base/ServerToClientResponse.hpp diff --git a/Base/src/ecflow/base/SslClient.cpp b/libs/base/src/ecflow/base/SslClient.cpp similarity index 100% rename from Base/src/ecflow/base/SslClient.cpp rename to libs/base/src/ecflow/base/SslClient.cpp diff --git a/Base/src/ecflow/base/SslClient.hpp b/libs/base/src/ecflow/base/SslClient.hpp similarity index 100% rename from Base/src/ecflow/base/SslClient.hpp rename to libs/base/src/ecflow/base/SslClient.hpp diff --git a/Base/src/ecflow/base/Stats.cpp b/libs/base/src/ecflow/base/Stats.cpp similarity index 100% rename from Base/src/ecflow/base/Stats.cpp rename to libs/base/src/ecflow/base/Stats.cpp diff --git a/Base/src/ecflow/base/Stats.hpp b/libs/base/src/ecflow/base/Stats.hpp similarity index 100% rename from Base/src/ecflow/base/Stats.hpp rename to libs/base/src/ecflow/base/Stats.hpp diff --git a/Base/src/ecflow/base/WhyCmd.cpp b/libs/base/src/ecflow/base/WhyCmd.cpp similarity index 100% rename from Base/src/ecflow/base/WhyCmd.cpp rename to libs/base/src/ecflow/base/WhyCmd.cpp diff --git a/Base/src/ecflow/base/WhyCmd.hpp b/libs/base/src/ecflow/base/WhyCmd.hpp similarity index 100% rename from Base/src/ecflow/base/WhyCmd.hpp rename to libs/base/src/ecflow/base/WhyCmd.hpp diff --git a/Base/src/ecflow/base/ZombieCtrl.cpp b/libs/base/src/ecflow/base/ZombieCtrl.cpp similarity index 100% rename from Base/src/ecflow/base/ZombieCtrl.cpp rename to libs/base/src/ecflow/base/ZombieCtrl.cpp diff --git a/Base/src/ecflow/base/ZombieCtrl.hpp b/libs/base/src/ecflow/base/ZombieCtrl.hpp similarity index 100% rename from Base/src/ecflow/base/ZombieCtrl.hpp rename to libs/base/src/ecflow/base/ZombieCtrl.hpp diff --git a/Base/src/ecflow/base/cts/ClientToServerCmd.cpp b/libs/base/src/ecflow/base/cts/ClientToServerCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/ClientToServerCmd.cpp rename to libs/base/src/ecflow/base/cts/ClientToServerCmd.cpp diff --git a/Base/src/ecflow/base/cts/ClientToServerCmd.hpp b/libs/base/src/ecflow/base/cts/ClientToServerCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/ClientToServerCmd.hpp rename to libs/base/src/ecflow/base/cts/ClientToServerCmd.hpp diff --git a/Base/src/ecflow/base/cts/CtsCmdRegistry.cpp b/libs/base/src/ecflow/base/cts/CtsCmdRegistry.cpp similarity index 100% rename from Base/src/ecflow/base/cts/CtsCmdRegistry.cpp rename to libs/base/src/ecflow/base/cts/CtsCmdRegistry.cpp diff --git a/Base/src/ecflow/base/cts/CtsCmdRegistry.hpp b/libs/base/src/ecflow/base/cts/CtsCmdRegistry.hpp similarity index 100% rename from Base/src/ecflow/base/cts/CtsCmdRegistry.hpp rename to libs/base/src/ecflow/base/cts/CtsCmdRegistry.hpp diff --git a/Base/src/ecflow/base/cts/EditHistoryMgr.cpp b/libs/base/src/ecflow/base/cts/EditHistoryMgr.cpp similarity index 100% rename from Base/src/ecflow/base/cts/EditHistoryMgr.cpp rename to libs/base/src/ecflow/base/cts/EditHistoryMgr.cpp diff --git a/Base/src/ecflow/base/cts/EditHistoryMgr.hpp b/libs/base/src/ecflow/base/cts/EditHistoryMgr.hpp similarity index 100% rename from Base/src/ecflow/base/cts/EditHistoryMgr.hpp rename to libs/base/src/ecflow/base/cts/EditHistoryMgr.hpp diff --git a/Base/src/ecflow/base/cts/task/AbortCmd.cpp b/libs/base/src/ecflow/base/cts/task/AbortCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/AbortCmd.cpp rename to libs/base/src/ecflow/base/cts/task/AbortCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/AbortCmd.hpp b/libs/base/src/ecflow/base/cts/task/AbortCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/AbortCmd.hpp rename to libs/base/src/ecflow/base/cts/task/AbortCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/CompleteCmd.cpp b/libs/base/src/ecflow/base/cts/task/CompleteCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/CompleteCmd.cpp rename to libs/base/src/ecflow/base/cts/task/CompleteCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/CompleteCmd.hpp b/libs/base/src/ecflow/base/cts/task/CompleteCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/CompleteCmd.hpp rename to libs/base/src/ecflow/base/cts/task/CompleteCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/CtsWaitCmd.cpp b/libs/base/src/ecflow/base/cts/task/CtsWaitCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/CtsWaitCmd.cpp rename to libs/base/src/ecflow/base/cts/task/CtsWaitCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/CtsWaitCmd.hpp b/libs/base/src/ecflow/base/cts/task/CtsWaitCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/CtsWaitCmd.hpp rename to libs/base/src/ecflow/base/cts/task/CtsWaitCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/EventCmd.cpp b/libs/base/src/ecflow/base/cts/task/EventCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/EventCmd.cpp rename to libs/base/src/ecflow/base/cts/task/EventCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/EventCmd.hpp b/libs/base/src/ecflow/base/cts/task/EventCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/EventCmd.hpp rename to libs/base/src/ecflow/base/cts/task/EventCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/InitCmd.cpp b/libs/base/src/ecflow/base/cts/task/InitCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/InitCmd.cpp rename to libs/base/src/ecflow/base/cts/task/InitCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/InitCmd.hpp b/libs/base/src/ecflow/base/cts/task/InitCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/InitCmd.hpp rename to libs/base/src/ecflow/base/cts/task/InitCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/LabelCmd.cpp b/libs/base/src/ecflow/base/cts/task/LabelCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/LabelCmd.cpp rename to libs/base/src/ecflow/base/cts/task/LabelCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/LabelCmd.hpp b/libs/base/src/ecflow/base/cts/task/LabelCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/LabelCmd.hpp rename to libs/base/src/ecflow/base/cts/task/LabelCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/MeterCmd.cpp b/libs/base/src/ecflow/base/cts/task/MeterCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/MeterCmd.cpp rename to libs/base/src/ecflow/base/cts/task/MeterCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/MeterCmd.hpp b/libs/base/src/ecflow/base/cts/task/MeterCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/MeterCmd.hpp rename to libs/base/src/ecflow/base/cts/task/MeterCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/QueueCmd.cpp b/libs/base/src/ecflow/base/cts/task/QueueCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/QueueCmd.cpp rename to libs/base/src/ecflow/base/cts/task/QueueCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/QueueCmd.hpp b/libs/base/src/ecflow/base/cts/task/QueueCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/QueueCmd.hpp rename to libs/base/src/ecflow/base/cts/task/QueueCmd.hpp diff --git a/Base/src/ecflow/base/cts/task/TaskApi.cpp b/libs/base/src/ecflow/base/cts/task/TaskApi.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/TaskApi.cpp rename to libs/base/src/ecflow/base/cts/task/TaskApi.cpp diff --git a/Base/src/ecflow/base/cts/task/TaskApi.hpp b/libs/base/src/ecflow/base/cts/task/TaskApi.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/TaskApi.hpp rename to libs/base/src/ecflow/base/cts/task/TaskApi.hpp diff --git a/Base/src/ecflow/base/cts/task/TaskCmd.cpp b/libs/base/src/ecflow/base/cts/task/TaskCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/task/TaskCmd.cpp rename to libs/base/src/ecflow/base/cts/task/TaskCmd.cpp diff --git a/Base/src/ecflow/base/cts/task/TaskCmd.hpp b/libs/base/src/ecflow/base/cts/task/TaskCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/task/TaskCmd.hpp rename to libs/base/src/ecflow/base/cts/task/TaskCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/AlterCmd.cpp b/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp similarity index 92% rename from Base/src/ecflow/base/cts/user/AlterCmd.cpp rename to libs/base/src/ecflow/base/cts/user/AlterCmd.cpp index 07f979347..517c736cc 100644 --- a/Base/src/ecflow/base/cts/user/AlterCmd.cpp +++ b/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp @@ -22,13 +22,19 @@ #include "ecflow/core/Enumerate.hpp" #include "ecflow/core/Extract.hpp" #include "ecflow/core/Log.hpp" +#include "ecflow/core/Message.hpp" #include "ecflow/core/Str.hpp" +#include "ecflow/core/exceptions/Exceptions.hpp" +#include "ecflow/node/AvisoAttr.hpp" #include "ecflow/node/Defs.hpp" #include "ecflow/node/Expression.hpp" #include "ecflow/node/Limit.hpp" +#include "ecflow/node/MirrorAttr.hpp" #include "ecflow/node/Node.hpp" #include "ecflow/node/Suite.hpp" #include "ecflow/node/SuiteChanged.hpp" +#include "ecflow/node/parser/AvisoParser.hpp" +#include "ecflow/node/parser/MirrorParser.hpp" using namespace ecf; using namespace std; @@ -75,7 +81,9 @@ struct EnumTraits std::make_pair(AlterCmd::DEL_ZOMBIE, "zombie"), std::make_pair(AlterCmd::DEL_LATE, "late"), std::make_pair(AlterCmd::DEL_QUEUE, "queue"), - std::make_pair(AlterCmd::DEL_GENERIC, "generic") + std::make_pair(AlterCmd::DEL_GENERIC, "generic"), + std::make_pair(AlterCmd::DEL_AVISO, "aviso"), + std::make_pair(AlterCmd::DEL_MIRROR, "mirror") // clang-format on }; static constexpr size_t size = map.size(); @@ -99,7 +107,9 @@ struct EnumTraits std::make_pair(AlterCmd::ADD_LATE, "late"), std::make_pair(AlterCmd::ADD_LIMIT, "limit"), std::make_pair(AlterCmd::ADD_INLIMIT, "inlimit"), - std::make_pair(AlterCmd::ADD_LABEL, "label") + std::make_pair(AlterCmd::ADD_LABEL, "label"), + std::make_pair(AlterCmd::ADD_AVISO, "aviso"), + std::make_pair(AlterCmd::ADD_MIRROR, "mirror") // clang-format on }; static constexpr size_t size = map.size(); @@ -130,7 +140,9 @@ struct EnumTraits std::make_pair(AlterCmd::DEFSTATUS, "defstatus"), std::make_pair(AlterCmd::LATE, "late"), std::make_pair(AlterCmd::TIME, "time"), - std::make_pair(AlterCmd::TODAY, "today") + std::make_pair(AlterCmd::TODAY, "today"), + std::make_pair(AlterCmd::AVISO, "aviso"), + std::make_pair(AlterCmd::MIRROR, "mirror") // clang-format on }; static constexpr size_t size = map.size(); @@ -398,6 +410,12 @@ STC_Cmd_ptr AlterCmd::doHandleRequest(AbstractServer* as) const { break; case AlterCmd::DELETE_ATTR_ND: break; + case AlterCmd::DEL_AVISO: + node->deleteAviso(name_); + break; + case AlterCmd::DEL_MIRROR: + node->deleteMirror(name_); + break; default: break; } @@ -432,6 +450,9 @@ STC_Cmd_ptr AlterCmd::doHandleRequest(AbstractServer* as) const { case AlterCmd::LABEL: node->changeLabel(name_, value_); break; + case AlterCmd::AVISO: + node->changeAviso(name_, value_); + break; case AlterCmd::TRIGGER: node->changeTrigger(name_); break; // expression must parse @@ -461,6 +482,9 @@ STC_Cmd_ptr AlterCmd::doHandleRequest(AbstractServer* as) const { break; case AlterCmd::CHANGE_ATTR_ND: break; + case AlterCmd::MIRROR: + node->changeMirror(name_, value_); + break; default: break; } @@ -483,6 +507,16 @@ STC_Cmd_ptr AlterCmd::doHandleRequest(AbstractServer* as) const { case AlterCmd::ADD_DAY: node->addDay(DayAttr::create(name_)); break; + case AlterCmd::ADD_AVISO: { + auto aviso = AvisoParser::parse_aviso_line(value_, name_, node.get()); + node->addAviso(aviso); + break; + } + case AlterCmd::ADD_MIRROR: { + auto mirror = MirrorParser::parse_mirror_line(value_, name_, node.get()); + node->addMirror(mirror); + break; + } case AlterCmd::ADD_ZOMBIE: node->addZombie(ZombieAttr::create(name_)); break; @@ -575,15 +609,15 @@ const char* AlterCmd::desc() { " one option must be specified\n" "arg2 = For delete:\n" " [ variable | time | today | date | day | cron | event | meter | late | generic | queue |\n" - " label | trigger | complete | repeat | limit | inlimit | limit_path | zombie ]\n" + " label | trigger | complete | repeat | limit | inlimit | limit_path | zombie | aviso | mirror ]\n" " For change:\n" " [ variable | clock_type | clock_gain | clock_date | clock_sync | event | meter | label |\n" - " trigger | complete | repeat | limit_max | limit_value | defstatus | late | time | today " - "]\n" + " trigger | complete | repeat | limit_max | limit_value | defstatus | late | time |\n" + " today, aviso, mirror ]\n" " *NOTE* If the clock is changed, then the suite will need to be re-queued in order for\n" " the change to take effect fully.\n" " For add:\n" - " [ variable | time | today | date | day | zombie | late | limit | inlimit | label ]\n" + " [ variable | time | today | date | day | zombie | late | limit | inlimit | label | aviso | mirror ]\n" " For set_flag and clear_flag:\n" " [ force_aborted | user_edit | task_aborted | edit_failed | ecfcmd_failed \n" " statuscmd_failed | killcmd_failed | no_script | killed | status | late | message | \n" @@ -592,13 +626,21 @@ const char* AlterCmd::desc() { " For sort:\n" " [ event | meter | label | variable| limit | all ]\n" "arg3 = name/value\n" - " when changing, attributes like variable,meter,event,label,limits,late\n" - " we expect arguments to be quoted. For sort this argument can be called 'recursive'\n" "arg4 = new_value\n" - " specifies the new value only used for 'change'/'add'\n" - " values with spaces must be quoted\n" - "arg5 = paths : At least one node path required.The paths must start with a leading '/' character\n\n" - "\nUsage:\n\n" + "arg5 = paths : At least one node path required.The paths must start with a leading '/' character\n" + "\n" + "When adding or updating attributes, such as variable, meter, event, label, limits, or late,\n" + " the name (arg3) and value (arg4) must be quoted.\n" + "\n" + "When sorting attributes, 'recursive' can be used as the value (arg3)\n" + "\n" + "When adding or updating aviso and mirror attributes, the value (arg4) is expected to be a quoted list of\n" + " configuration options. For example:\n" + " * for aviso, \"--remote_path /s1/f1/t2 --remote_host host --polling 20 --remote_port 3141 --ssl)\"\n" + " * for mirror, \"--listener '{ \\\"event\\\": \\\"mars\\\", \\\"request\\\": { \\\"class\\\": \"od\" } }'\n" + " --url http://aviso/ --schema /path/to/schema --polling 60\"\n" + "\n" + "Usage:\n\n" " ecflow_client --alter=add variable GLOBAL \"value\" / # add server variable\n" " ecflow_client --alter=add variable FRED \"value\" /path/to/node # add node variable\n" " ecflow_client --alter=add time \"+00:20\" /path/to/node\n" @@ -800,6 +842,25 @@ void AlterCmd::extract_name_and_value_for_add(AlterCmd::Add_attr_type theAttrTyp value = options[3]; break; } + case AlterCmd::ADD_AVISO: { + if (options.size() != 4 || paths.size() < 1) { + ss << "AlterCmd: add: Expected 'add aviso [ [...]]. Not enough arguments\n" + << dump_args(options, paths) << "\n"; + throw std::runtime_error(ss.str()); + } + value = options[3]; + break; + } + case AlterCmd::ADD_MIRROR: { + if (options.size() != 4 || paths.size() < 1) { + ss << "AlterCmd: add: Expected 'add mirror [ [...]]. Not enough arguments\n" + << dump_args(options, paths) << "\n"; + throw std::runtime_error(ss.str()); + } + value = options[3]; + break; + } + case AlterCmd::ADD_LIMIT: { if (options.size() < 4) { ss << "AlterCmd: add: Expected 'add limit int. Not enough arguments\n" @@ -852,6 +913,14 @@ void AlterCmd::check_for_add(AlterCmd::Add_attr_type theAttrType, case AlterCmd::ADD_DAY: (void)DayAttr::create(name); break; + case AlterCmd::ADD_AVISO: { + AvisoParser::parse_aviso_line(value, name); + break; + } + case AlterCmd::ADD_MIRROR: { + MirrorParser::parse_mirror_line(value, name); + break; + } case AlterCmd::ADD_ZOMBIE: (void)ZombieAttr::create(name); break; @@ -1041,6 +1110,18 @@ void AlterCmd::check_for_delete(AlterCmd::Delete_attr_type theAttrType, } break; } + case AlterCmd::DEL_AVISO: { + if (!AvisoAttr::is_valid_name(name)) { + throw ecf::InvalidArgument(ecf::Message("Invalid AvisoAttr name :", name_)); + } + break; + } + case AlterCmd::DEL_MIRROR: { + if (!MirrorAttr::is_valid_name(name)) { + throw ecf::InvalidArgument(ecf::Message("Invalid MirrorAttr name :", name_)); + } + break; + } case AlterCmd::DEL_EVENT: { if (!name.empty()) { Event check(name); // will throw if not valid @@ -1284,6 +1365,30 @@ void AlterCmd::extract_name_and_value_for_change(AlterCmd::Change_attr_type theA break; } + case AlterCmd::AVISO: { + if (options.size() != 4 || paths.size() < 1) { + ss << "AlterCmd: change: Expected 'change aviso [] [...]." + << "Incorrect number of arguments.\n" + << dump_args(options, paths) << "\n"; + throw std::runtime_error(ss.str()); + } + name = options[2]; + value = options[3]; + break; + } + + case AlterCmd::MIRROR: { + if (options.size() != 4 || paths.size() < 1) { + ss << "AlterCmd: change: Expected 'change mirror [] [...]." + << "Incorrect number of arguments.\n" + << dump_args(options, paths) << "\n"; + throw std::runtime_error(ss.str()); + } + name = options[2]; + value = options[3]; + break; + } + case AlterCmd::LATE: { if (options.size() != 3) { ss << "AlterCmd: change: expected three args: change late \"late -s +00:15 -a 20:00 -c +02:00\" " diff --git a/Base/src/ecflow/base/cts/user/AlterCmd.hpp b/libs/base/src/ecflow/base/cts/user/AlterCmd.hpp similarity index 98% rename from Base/src/ecflow/base/cts/user/AlterCmd.hpp rename to libs/base/src/ecflow/base/cts/user/AlterCmd.hpp index 38632e78a..606a0e23d 100644 --- a/Base/src/ecflow/base/cts/user/AlterCmd.hpp +++ b/libs/base/src/ecflow/base/cts/user/AlterCmd.hpp @@ -37,6 +37,8 @@ class AlterCmd final : public UserCmd { DEL_LATE, DEL_QUEUE, DEL_GENERIC, + DEL_AVISO, + DEL_MIRROR, }; enum Change_attr_type { @@ -58,6 +60,8 @@ class AlterCmd final : public UserCmd { LATE, TIME, TODAY, + AVISO, + MIRROR, }; enum Add_attr_type { @@ -72,6 +76,8 @@ class AlterCmd final : public UserCmd { ADD_LIMIT, ADD_INLIMIT, ADD_LABEL, + ADD_AVISO, + ADD_MIRROR, }; // Python diff --git a/Base/src/ecflow/base/cts/user/BeginCmd.cpp b/libs/base/src/ecflow/base/cts/user/BeginCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/BeginCmd.cpp rename to libs/base/src/ecflow/base/cts/user/BeginCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/BeginCmd.hpp b/libs/base/src/ecflow/base/cts/user/BeginCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/BeginCmd.hpp rename to libs/base/src/ecflow/base/cts/user/BeginCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/CFileCmd.cpp b/libs/base/src/ecflow/base/cts/user/CFileCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CFileCmd.cpp rename to libs/base/src/ecflow/base/cts/user/CFileCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/CFileCmd.hpp b/libs/base/src/ecflow/base/cts/user/CFileCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CFileCmd.hpp rename to libs/base/src/ecflow/base/cts/user/CFileCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/CSyncCmd.cpp b/libs/base/src/ecflow/base/cts/user/CSyncCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CSyncCmd.cpp rename to libs/base/src/ecflow/base/cts/user/CSyncCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/CSyncCmd.hpp b/libs/base/src/ecflow/base/cts/user/CSyncCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CSyncCmd.hpp rename to libs/base/src/ecflow/base/cts/user/CSyncCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/CheckPtCmd.cpp b/libs/base/src/ecflow/base/cts/user/CheckPtCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CheckPtCmd.cpp rename to libs/base/src/ecflow/base/cts/user/CheckPtCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/CheckPtCmd.hpp b/libs/base/src/ecflow/base/cts/user/CheckPtCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CheckPtCmd.hpp rename to libs/base/src/ecflow/base/cts/user/CheckPtCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ClientHandleCmd.cpp b/libs/base/src/ecflow/base/cts/user/ClientHandleCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ClientHandleCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ClientHandleCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ClientHandleCmd.hpp b/libs/base/src/ecflow/base/cts/user/ClientHandleCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ClientHandleCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ClientHandleCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/CtsApi.cpp b/libs/base/src/ecflow/base/cts/user/CtsApi.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsApi.cpp rename to libs/base/src/ecflow/base/cts/user/CtsApi.cpp diff --git a/Base/src/ecflow/base/cts/user/CtsApi.hpp b/libs/base/src/ecflow/base/cts/user/CtsApi.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsApi.hpp rename to libs/base/src/ecflow/base/cts/user/CtsApi.hpp diff --git a/Base/src/ecflow/base/cts/user/CtsCmd.cpp b/libs/base/src/ecflow/base/cts/user/CtsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsCmd.cpp rename to libs/base/src/ecflow/base/cts/user/CtsCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/CtsCmd.hpp b/libs/base/src/ecflow/base/cts/user/CtsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsCmd.hpp rename to libs/base/src/ecflow/base/cts/user/CtsCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/CtsNodeCmd.cpp b/libs/base/src/ecflow/base/cts/user/CtsNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsNodeCmd.cpp rename to libs/base/src/ecflow/base/cts/user/CtsNodeCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/CtsNodeCmd.hpp b/libs/base/src/ecflow/base/cts/user/CtsNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/CtsNodeCmd.hpp rename to libs/base/src/ecflow/base/cts/user/CtsNodeCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/DeleteCmd.cpp b/libs/base/src/ecflow/base/cts/user/DeleteCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/DeleteCmd.cpp rename to libs/base/src/ecflow/base/cts/user/DeleteCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/DeleteCmd.hpp b/libs/base/src/ecflow/base/cts/user/DeleteCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/DeleteCmd.hpp rename to libs/base/src/ecflow/base/cts/user/DeleteCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/EditScriptCmd.cpp b/libs/base/src/ecflow/base/cts/user/EditScriptCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/EditScriptCmd.cpp rename to libs/base/src/ecflow/base/cts/user/EditScriptCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/EditScriptCmd.hpp b/libs/base/src/ecflow/base/cts/user/EditScriptCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/EditScriptCmd.hpp rename to libs/base/src/ecflow/base/cts/user/EditScriptCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ForceCmd.cpp b/libs/base/src/ecflow/base/cts/user/ForceCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ForceCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ForceCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ForceCmd.hpp b/libs/base/src/ecflow/base/cts/user/ForceCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ForceCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ForceCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/FreeDepCmd.cpp b/libs/base/src/ecflow/base/cts/user/FreeDepCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/FreeDepCmd.cpp rename to libs/base/src/ecflow/base/cts/user/FreeDepCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/FreeDepCmd.hpp b/libs/base/src/ecflow/base/cts/user/FreeDepCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/FreeDepCmd.hpp rename to libs/base/src/ecflow/base/cts/user/FreeDepCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/GroupCTSCmd.cpp b/libs/base/src/ecflow/base/cts/user/GroupCTSCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/GroupCTSCmd.cpp rename to libs/base/src/ecflow/base/cts/user/GroupCTSCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/GroupCTSCmd.hpp b/libs/base/src/ecflow/base/cts/user/GroupCTSCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/GroupCTSCmd.hpp rename to libs/base/src/ecflow/base/cts/user/GroupCTSCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/LoadDefsCmd.cpp b/libs/base/src/ecflow/base/cts/user/LoadDefsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LoadDefsCmd.cpp rename to libs/base/src/ecflow/base/cts/user/LoadDefsCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/LoadDefsCmd.hpp b/libs/base/src/ecflow/base/cts/user/LoadDefsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LoadDefsCmd.hpp rename to libs/base/src/ecflow/base/cts/user/LoadDefsCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/LogCmd.cpp b/libs/base/src/ecflow/base/cts/user/LogCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LogCmd.cpp rename to libs/base/src/ecflow/base/cts/user/LogCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/LogCmd.hpp b/libs/base/src/ecflow/base/cts/user/LogCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LogCmd.hpp rename to libs/base/src/ecflow/base/cts/user/LogCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/LogMessageCmd.cpp b/libs/base/src/ecflow/base/cts/user/LogMessageCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LogMessageCmd.cpp rename to libs/base/src/ecflow/base/cts/user/LogMessageCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/LogMessageCmd.hpp b/libs/base/src/ecflow/base/cts/user/LogMessageCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/LogMessageCmd.hpp rename to libs/base/src/ecflow/base/cts/user/LogMessageCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/MoveCmd.cpp b/libs/base/src/ecflow/base/cts/user/MoveCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/MoveCmd.cpp rename to libs/base/src/ecflow/base/cts/user/MoveCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/MoveCmd.hpp b/libs/base/src/ecflow/base/cts/user/MoveCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/MoveCmd.hpp rename to libs/base/src/ecflow/base/cts/user/MoveCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/OrderNodeCmd.cpp b/libs/base/src/ecflow/base/cts/user/OrderNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/OrderNodeCmd.cpp rename to libs/base/src/ecflow/base/cts/user/OrderNodeCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/OrderNodeCmd.hpp b/libs/base/src/ecflow/base/cts/user/OrderNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/OrderNodeCmd.hpp rename to libs/base/src/ecflow/base/cts/user/OrderNodeCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/PathsCmd.cpp b/libs/base/src/ecflow/base/cts/user/PathsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/PathsCmd.cpp rename to libs/base/src/ecflow/base/cts/user/PathsCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/PathsCmd.hpp b/libs/base/src/ecflow/base/cts/user/PathsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/PathsCmd.hpp rename to libs/base/src/ecflow/base/cts/user/PathsCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/PlugCmd.cpp b/libs/base/src/ecflow/base/cts/user/PlugCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/PlugCmd.cpp rename to libs/base/src/ecflow/base/cts/user/PlugCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/PlugCmd.hpp b/libs/base/src/ecflow/base/cts/user/PlugCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/PlugCmd.hpp rename to libs/base/src/ecflow/base/cts/user/PlugCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/QueryCmd.cpp b/libs/base/src/ecflow/base/cts/user/QueryCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/QueryCmd.cpp rename to libs/base/src/ecflow/base/cts/user/QueryCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/QueryCmd.hpp b/libs/base/src/ecflow/base/cts/user/QueryCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/QueryCmd.hpp rename to libs/base/src/ecflow/base/cts/user/QueryCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ReplaceNodeCmd.cpp b/libs/base/src/ecflow/base/cts/user/ReplaceNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ReplaceNodeCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ReplaceNodeCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ReplaceNodeCmd.hpp b/libs/base/src/ecflow/base/cts/user/ReplaceNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ReplaceNodeCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ReplaceNodeCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/RequeueNodeCmd.cpp b/libs/base/src/ecflow/base/cts/user/RequeueNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/RequeueNodeCmd.cpp rename to libs/base/src/ecflow/base/cts/user/RequeueNodeCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/RequeueNodeCmd.hpp b/libs/base/src/ecflow/base/cts/user/RequeueNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/RequeueNodeCmd.hpp rename to libs/base/src/ecflow/base/cts/user/RequeueNodeCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/RunNodeCmd.cpp b/libs/base/src/ecflow/base/cts/user/RunNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/RunNodeCmd.cpp rename to libs/base/src/ecflow/base/cts/user/RunNodeCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/RunNodeCmd.hpp b/libs/base/src/ecflow/base/cts/user/RunNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/RunNodeCmd.hpp rename to libs/base/src/ecflow/base/cts/user/RunNodeCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ServerVersionCmd.cpp b/libs/base/src/ecflow/base/cts/user/ServerVersionCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ServerVersionCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ServerVersionCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ServerVersionCmd.hpp b/libs/base/src/ecflow/base/cts/user/ServerVersionCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ServerVersionCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ServerVersionCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ShowCmd.cpp b/libs/base/src/ecflow/base/cts/user/ShowCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ShowCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ShowCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ShowCmd.hpp b/libs/base/src/ecflow/base/cts/user/ShowCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ShowCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ShowCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/UserCmd.cpp b/libs/base/src/ecflow/base/cts/user/UserCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/UserCmd.cpp rename to libs/base/src/ecflow/base/cts/user/UserCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/UserCmd.hpp b/libs/base/src/ecflow/base/cts/user/UserCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/UserCmd.hpp rename to libs/base/src/ecflow/base/cts/user/UserCmd.hpp diff --git a/Base/src/ecflow/base/cts/user/ZombieCmd.cpp b/libs/base/src/ecflow/base/cts/user/ZombieCmd.cpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ZombieCmd.cpp rename to libs/base/src/ecflow/base/cts/user/ZombieCmd.cpp diff --git a/Base/src/ecflow/base/cts/user/ZombieCmd.hpp b/libs/base/src/ecflow/base/cts/user/ZombieCmd.hpp similarity index 100% rename from Base/src/ecflow/base/cts/user/ZombieCmd.hpp rename to libs/base/src/ecflow/base/cts/user/ZombieCmd.hpp diff --git a/Base/src/ecflow/base/ssl_connection.cpp b/libs/base/src/ecflow/base/ssl_connection.cpp similarity index 100% rename from Base/src/ecflow/base/ssl_connection.cpp rename to libs/base/src/ecflow/base/ssl_connection.cpp diff --git a/Base/src/ecflow/base/ssl_connection.hpp b/libs/base/src/ecflow/base/ssl_connection.hpp similarity index 100% rename from Base/src/ecflow/base/ssl_connection.hpp rename to libs/base/src/ecflow/base/ssl_connection.hpp diff --git a/Base/src/ecflow/base/stc/BlockClientZombieCmd.cpp b/libs/base/src/ecflow/base/stc/BlockClientZombieCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/BlockClientZombieCmd.cpp rename to libs/base/src/ecflow/base/stc/BlockClientZombieCmd.cpp diff --git a/Base/src/ecflow/base/stc/BlockClientZombieCmd.hpp b/libs/base/src/ecflow/base/stc/BlockClientZombieCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/BlockClientZombieCmd.hpp rename to libs/base/src/ecflow/base/stc/BlockClientZombieCmd.hpp diff --git a/Base/src/ecflow/base/stc/DefsCache.cpp b/libs/base/src/ecflow/base/stc/DefsCache.cpp similarity index 100% rename from Base/src/ecflow/base/stc/DefsCache.cpp rename to libs/base/src/ecflow/base/stc/DefsCache.cpp diff --git a/Base/src/ecflow/base/stc/DefsCache.hpp b/libs/base/src/ecflow/base/stc/DefsCache.hpp similarity index 100% rename from Base/src/ecflow/base/stc/DefsCache.hpp rename to libs/base/src/ecflow/base/stc/DefsCache.hpp diff --git a/Base/src/ecflow/base/stc/DefsCmd.cpp b/libs/base/src/ecflow/base/stc/DefsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/DefsCmd.cpp rename to libs/base/src/ecflow/base/stc/DefsCmd.cpp diff --git a/Base/src/ecflow/base/stc/DefsCmd.hpp b/libs/base/src/ecflow/base/stc/DefsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/DefsCmd.hpp rename to libs/base/src/ecflow/base/stc/DefsCmd.hpp diff --git a/Base/src/ecflow/base/stc/ErrorCmd.cpp b/libs/base/src/ecflow/base/stc/ErrorCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/ErrorCmd.cpp rename to libs/base/src/ecflow/base/stc/ErrorCmd.cpp diff --git a/Base/src/ecflow/base/stc/ErrorCmd.hpp b/libs/base/src/ecflow/base/stc/ErrorCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/ErrorCmd.hpp rename to libs/base/src/ecflow/base/stc/ErrorCmd.hpp diff --git a/Base/src/ecflow/base/stc/GroupSTCCmd.cpp b/libs/base/src/ecflow/base/stc/GroupSTCCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/GroupSTCCmd.cpp rename to libs/base/src/ecflow/base/stc/GroupSTCCmd.cpp diff --git a/Base/src/ecflow/base/stc/GroupSTCCmd.hpp b/libs/base/src/ecflow/base/stc/GroupSTCCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/GroupSTCCmd.hpp rename to libs/base/src/ecflow/base/stc/GroupSTCCmd.hpp diff --git a/Base/src/ecflow/base/stc/PreAllocatedReply.cpp b/libs/base/src/ecflow/base/stc/PreAllocatedReply.cpp similarity index 100% rename from Base/src/ecflow/base/stc/PreAllocatedReply.cpp rename to libs/base/src/ecflow/base/stc/PreAllocatedReply.cpp diff --git a/Base/src/ecflow/base/stc/PreAllocatedReply.hpp b/libs/base/src/ecflow/base/stc/PreAllocatedReply.hpp similarity index 100% rename from Base/src/ecflow/base/stc/PreAllocatedReply.hpp rename to libs/base/src/ecflow/base/stc/PreAllocatedReply.hpp diff --git a/Base/src/ecflow/base/stc/SClientHandleCmd.cpp b/libs/base/src/ecflow/base/stc/SClientHandleCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SClientHandleCmd.cpp rename to libs/base/src/ecflow/base/stc/SClientHandleCmd.cpp diff --git a/Base/src/ecflow/base/stc/SClientHandleCmd.hpp b/libs/base/src/ecflow/base/stc/SClientHandleCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SClientHandleCmd.hpp rename to libs/base/src/ecflow/base/stc/SClientHandleCmd.hpp diff --git a/Base/src/ecflow/base/stc/SClientHandleSuitesCmd.cpp b/libs/base/src/ecflow/base/stc/SClientHandleSuitesCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SClientHandleSuitesCmd.cpp rename to libs/base/src/ecflow/base/stc/SClientHandleSuitesCmd.cpp diff --git a/Base/src/ecflow/base/stc/SClientHandleSuitesCmd.hpp b/libs/base/src/ecflow/base/stc/SClientHandleSuitesCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SClientHandleSuitesCmd.hpp rename to libs/base/src/ecflow/base/stc/SClientHandleSuitesCmd.hpp diff --git a/Base/src/ecflow/base/stc/SNewsCmd.cpp b/libs/base/src/ecflow/base/stc/SNewsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SNewsCmd.cpp rename to libs/base/src/ecflow/base/stc/SNewsCmd.cpp diff --git a/Base/src/ecflow/base/stc/SNewsCmd.hpp b/libs/base/src/ecflow/base/stc/SNewsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SNewsCmd.hpp rename to libs/base/src/ecflow/base/stc/SNewsCmd.hpp diff --git a/Base/src/ecflow/base/stc/SNodeCmd.cpp b/libs/base/src/ecflow/base/stc/SNodeCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SNodeCmd.cpp rename to libs/base/src/ecflow/base/stc/SNodeCmd.cpp diff --git a/Base/src/ecflow/base/stc/SNodeCmd.hpp b/libs/base/src/ecflow/base/stc/SNodeCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SNodeCmd.hpp rename to libs/base/src/ecflow/base/stc/SNodeCmd.hpp diff --git a/Base/src/ecflow/base/stc/SServerLoadCmd.cpp b/libs/base/src/ecflow/base/stc/SServerLoadCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SServerLoadCmd.cpp rename to libs/base/src/ecflow/base/stc/SServerLoadCmd.cpp diff --git a/Base/src/ecflow/base/stc/SServerLoadCmd.hpp b/libs/base/src/ecflow/base/stc/SServerLoadCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SServerLoadCmd.hpp rename to libs/base/src/ecflow/base/stc/SServerLoadCmd.hpp diff --git a/Base/src/ecflow/base/stc/SStatsCmd.cpp b/libs/base/src/ecflow/base/stc/SStatsCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SStatsCmd.cpp rename to libs/base/src/ecflow/base/stc/SStatsCmd.cpp diff --git a/Base/src/ecflow/base/stc/SStatsCmd.hpp b/libs/base/src/ecflow/base/stc/SStatsCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SStatsCmd.hpp rename to libs/base/src/ecflow/base/stc/SStatsCmd.hpp diff --git a/Base/src/ecflow/base/stc/SStringCmd.cpp b/libs/base/src/ecflow/base/stc/SStringCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SStringCmd.cpp rename to libs/base/src/ecflow/base/stc/SStringCmd.cpp diff --git a/Base/src/ecflow/base/stc/SStringCmd.hpp b/libs/base/src/ecflow/base/stc/SStringCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SStringCmd.hpp rename to libs/base/src/ecflow/base/stc/SStringCmd.hpp diff --git a/Base/src/ecflow/base/stc/SStringVecCmd.cpp b/libs/base/src/ecflow/base/stc/SStringVecCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SStringVecCmd.cpp rename to libs/base/src/ecflow/base/stc/SStringVecCmd.cpp diff --git a/Base/src/ecflow/base/stc/SStringVecCmd.hpp b/libs/base/src/ecflow/base/stc/SStringVecCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SStringVecCmd.hpp rename to libs/base/src/ecflow/base/stc/SStringVecCmd.hpp diff --git a/Base/src/ecflow/base/stc/SSuitesCmd.cpp b/libs/base/src/ecflow/base/stc/SSuitesCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SSuitesCmd.cpp rename to libs/base/src/ecflow/base/stc/SSuitesCmd.cpp diff --git a/Base/src/ecflow/base/stc/SSuitesCmd.hpp b/libs/base/src/ecflow/base/stc/SSuitesCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SSuitesCmd.hpp rename to libs/base/src/ecflow/base/stc/SSuitesCmd.hpp diff --git a/Base/src/ecflow/base/stc/SSyncCmd.cpp b/libs/base/src/ecflow/base/stc/SSyncCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/SSyncCmd.cpp rename to libs/base/src/ecflow/base/stc/SSyncCmd.cpp diff --git a/Base/src/ecflow/base/stc/SSyncCmd.hpp b/libs/base/src/ecflow/base/stc/SSyncCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/SSyncCmd.hpp rename to libs/base/src/ecflow/base/stc/SSyncCmd.hpp diff --git a/Base/src/ecflow/base/stc/ServerToClientCmd.cpp b/libs/base/src/ecflow/base/stc/ServerToClientCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/ServerToClientCmd.cpp rename to libs/base/src/ecflow/base/stc/ServerToClientCmd.cpp diff --git a/Base/src/ecflow/base/stc/ServerToClientCmd.hpp b/libs/base/src/ecflow/base/stc/ServerToClientCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/ServerToClientCmd.hpp rename to libs/base/src/ecflow/base/stc/ServerToClientCmd.hpp diff --git a/Base/src/ecflow/base/stc/StcCmd.cpp b/libs/base/src/ecflow/base/stc/StcCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/StcCmd.cpp rename to libs/base/src/ecflow/base/stc/StcCmd.cpp diff --git a/Base/src/ecflow/base/stc/StcCmd.hpp b/libs/base/src/ecflow/base/stc/StcCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/StcCmd.hpp rename to libs/base/src/ecflow/base/stc/StcCmd.hpp diff --git a/Base/src/ecflow/base/stc/ZombieGetCmd.cpp b/libs/base/src/ecflow/base/stc/ZombieGetCmd.cpp similarity index 100% rename from Base/src/ecflow/base/stc/ZombieGetCmd.cpp rename to libs/base/src/ecflow/base/stc/ZombieGetCmd.cpp diff --git a/Base/src/ecflow/base/stc/ZombieGetCmd.hpp b/libs/base/src/ecflow/base/stc/ZombieGetCmd.hpp similarity index 100% rename from Base/src/ecflow/base/stc/ZombieGetCmd.hpp rename to libs/base/src/ecflow/base/stc/ZombieGetCmd.hpp diff --git a/Base/test/MockServer.hpp b/libs/base/test/MockServer.hpp similarity index 100% rename from Base/test/MockServer.hpp rename to libs/base/test/MockServer.hpp diff --git a/Base/test/TestAlterCmd.cpp b/libs/base/test/TestAlterCmd.cpp similarity index 100% rename from Base/test/TestAlterCmd.cpp rename to libs/base/test/TestAlterCmd.cpp diff --git a/Base/test/TestArchiveAndRestoreCmd.cpp b/libs/base/test/TestArchiveAndRestoreCmd.cpp similarity index 97% rename from Base/test/TestArchiveAndRestoreCmd.cpp rename to libs/base/test/TestArchiveAndRestoreCmd.cpp index 790cc17ff..1fd86c158 100644 --- a/Base/test/TestArchiveAndRestoreCmd.cpp +++ b/libs/base/test/TestArchiveAndRestoreCmd.cpp @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_restore_suite) { // We use Pid::unique_name, to allow multiple invocation of this test Defs theDefs; - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_restore_suite")); suite->add_family("f1")->add_task("t1"); @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_restore_family) { // task t1 Defs theDefs; - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_restore_family")); family_ptr f3 = suite->add_family("f1")->add_family("f2")->add_family("f3"); @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_restore_all) { Defs theDefs; { - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_restore_all")); family_ptr f1 = suite->add_family("f1"); @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_restore_overlap) { // task t1 Defs theDefs; - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_restore_overlap")); std::string f1_abs_node_path; @@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_delete_suite) { // We use Pid::unique_name, to allow multiple invocation of this test Defs theDefs; - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_delete_suite")); family_ptr family = suite->add_family("f1"); @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(test_archive_and_restore_errors) { // We use Pid::unique_name, to allow multiple invocation of this test Defs theDefs; - std::string ecf_home = File::test_data("Base/test", "Base"); + std::string ecf_home = File::test_data("libs/base/test", "libs/base"); theDefs.set_server().add_or_update_user_variables(Str::ECF_HOME(), ecf_home); suite_ptr suite = theDefs.add_suite(Pid::unique_name("test_archive_and_restore_errors")); family_ptr f1 = suite->add_family("f1"); diff --git a/Base/test/TestBase_main.cpp b/libs/base/test/TestBase_main.cpp similarity index 100% rename from Base/test/TestBase_main.cpp rename to libs/base/test/TestBase_main.cpp diff --git a/Base/test/TestClientHandleCmd.cpp b/libs/base/test/TestClientHandleCmd.cpp similarity index 100% rename from Base/test/TestClientHandleCmd.cpp rename to libs/base/test/TestClientHandleCmd.cpp diff --git a/Base/test/TestCmd.cpp b/libs/base/test/TestCmd.cpp similarity index 100% rename from Base/test/TestCmd.cpp rename to libs/base/test/TestCmd.cpp diff --git a/Base/test/TestDeleteNodeCmd.cpp b/libs/base/test/TestDeleteNodeCmd.cpp similarity index 100% rename from Base/test/TestDeleteNodeCmd.cpp rename to libs/base/test/TestDeleteNodeCmd.cpp diff --git a/Base/test/TestForceCmd.cpp b/libs/base/test/TestForceCmd.cpp similarity index 100% rename from Base/test/TestForceCmd.cpp rename to libs/base/test/TestForceCmd.cpp diff --git a/Base/test/TestFreeDepCmd.cpp b/libs/base/test/TestFreeDepCmd.cpp similarity index 100% rename from Base/test/TestFreeDepCmd.cpp rename to libs/base/test/TestFreeDepCmd.cpp diff --git a/Base/test/TestHelper.hpp b/libs/base/test/TestHelper.hpp similarity index 100% rename from Base/test/TestHelper.hpp rename to libs/base/test/TestHelper.hpp diff --git a/Base/test/TestInLimitAndLimit.cpp b/libs/base/test/TestInLimitAndLimit.cpp similarity index 100% rename from Base/test/TestInLimitAndLimit.cpp rename to libs/base/test/TestInLimitAndLimit.cpp diff --git a/Base/test/TestJobGenPerf.cpp b/libs/base/test/TestJobGenPerf.cpp similarity index 100% rename from Base/test/TestJobGenPerf.cpp rename to libs/base/test/TestJobGenPerf.cpp diff --git a/Base/test/TestLogCmd.cpp b/libs/base/test/TestLogCmd.cpp similarity index 93% rename from Base/test/TestLogCmd.cpp rename to libs/base/test/TestLogCmd.cpp index 64c6a41c9..05bf03739 100644 --- a/Base/test/TestLogCmd.cpp +++ b/libs/base/test/TestLogCmd.cpp @@ -59,12 +59,12 @@ BOOST_AUTO_TEST_CASE(test_log_cmd) { // Create a new log file, equivalent --log=new .../Base/test/new_logfile.txt // LogCmd::doHandleRequest needs log file to have been created first - std::string old_log_file = File::test_data("Base/test/old_logfile.txt", "Base"); + std::string old_log_file = File::test_data("libs/base/test/old_logfile.txt", "libs/base"); Log::instance()->create(old_log_file); std::string new_log_file = - File::test_data("Base/test/new_logfile.txt ", "Base"); // ECFLOW-377 note extra space at the end - std::string expected_new_log_file = File::test_data("Base/test/new_logfile.txt", "Base"); // space removed + File::test_data("libs/base/test/new_logfile.txt ", "libs/base"); // ECFLOW-377 note extra space at the end + std::string expected_new_log_file = File::test_data("libs/base/test/new_logfile.txt", "libs/base"); // space removed // ECFLOW-376 --log=new should be treated same as changing ECF_LOG from the gui. i.e added as a user // variable. hence visible in GUI diff --git a/Base/test/TestMeterCmd.cpp b/libs/base/test/TestMeterCmd.cpp similarity index 100% rename from Base/test/TestMeterCmd.cpp rename to libs/base/test/TestMeterCmd.cpp diff --git a/Base/test/TestProgramOptions.cpp b/libs/base/test/TestProgramOptions.cpp similarity index 100% rename from Base/test/TestProgramOptions.cpp rename to libs/base/test/TestProgramOptions.cpp diff --git a/Base/test/TestQueryCmd.cpp b/libs/base/test/TestQueryCmd.cpp similarity index 100% rename from Base/test/TestQueryCmd.cpp rename to libs/base/test/TestQueryCmd.cpp diff --git a/Base/test/TestQueueCmd.cpp b/libs/base/test/TestQueueCmd.cpp similarity index 100% rename from Base/test/TestQueueCmd.cpp rename to libs/base/test/TestQueueCmd.cpp diff --git a/Base/test/TestRequest.cpp b/libs/base/test/TestRequest.cpp similarity index 100% rename from Base/test/TestRequest.cpp rename to libs/base/test/TestRequest.cpp diff --git a/Base/test/TestRequeueNodeCmd.cpp b/libs/base/test/TestRequeueNodeCmd.cpp similarity index 99% rename from Base/test/TestRequeueNodeCmd.cpp rename to libs/base/test/TestRequeueNodeCmd.cpp index ab98b4991..bf10a5002 100644 --- a/Base/test/TestRequeueNodeCmd.cpp +++ b/libs/base/test/TestRequeueNodeCmd.cpp @@ -346,10 +346,10 @@ BOOST_AUTO_TEST_CASE(test_reque_with_repeat_and_defstatus_complete) { // Create a log file with a unique name, to avoid problems when running in paralle // This test relies on log file contents to be flushed. - std::string log_file = "Base/test/test_reque_with_repeat_and_defstatus_complete_"; + std::string log_file = "libs/base/test/test_reque_with_repeat_and_defstatus_complete_"; log_file += Pid::getpid(); // can throw log_file += ".log"; - log_file = File::test_data(log_file, "Base"); + log_file = File::test_data(log_file, "libs/base"); Log::create(log_file); diff --git a/Base/test/TestResolveDependencies.cpp b/libs/base/test/TestResolveDependencies.cpp similarity index 100% rename from Base/test/TestResolveDependencies.cpp rename to libs/base/test/TestResolveDependencies.cpp diff --git a/Base/test/TestSSyncCmd.cpp b/libs/base/test/TestSSyncCmd.cpp similarity index 100% rename from Base/test/TestSSyncCmd.cpp rename to libs/base/test/TestSSyncCmd.cpp diff --git a/Base/test/TestSSyncCmdOrder.cpp b/libs/base/test/TestSSyncCmdOrder.cpp similarity index 100% rename from Base/test/TestSSyncCmdOrder.cpp rename to libs/base/test/TestSSyncCmdOrder.cpp diff --git a/Base/test/TestSSyncCmd_CH1.cpp b/libs/base/test/TestSSyncCmd_CH1.cpp similarity index 100% rename from Base/test/TestSSyncCmd_CH1.cpp rename to libs/base/test/TestSSyncCmd_CH1.cpp diff --git a/Base/test/TestSpecificIssues.cpp b/libs/base/test/TestSpecificIssues.cpp similarity index 100% rename from Base/test/TestSpecificIssues.cpp rename to libs/base/test/TestSpecificIssues.cpp diff --git a/Base/test/TestStatsCmd.cpp b/libs/base/test/TestStatsCmd.cpp similarity index 100% rename from Base/test/TestStatsCmd.cpp rename to libs/base/test/TestStatsCmd.cpp diff --git a/Client/.gitignore b/libs/client/.gitignore similarity index 100% rename from Client/.gitignore rename to libs/client/.gitignore diff --git a/Client/CMakeLists.txt b/libs/client/CMakeLists.txt similarity index 83% rename from Client/CMakeLists.txt rename to libs/client/CMakeLists.txt index 4fd510563..2fc3f618c 100644 --- a/Client/CMakeLists.txt +++ b/libs/client/CMakeLists.txt @@ -8,41 +8,6 @@ # nor does it submit to any jurisdiction. # -set(srcs - # Headers - src/ecflow/client/ClientCmdCache.hpp - src/ecflow/client/ClientEnvironment.hpp - src/ecflow/client/ClientInvoker.hpp - src/ecflow/client/ClientOptions.hpp - src/ecflow/client/Help.hpp - src/ecflow/client/Rtt.hpp - src/ecflow/client/UrlCmd.hpp - # Sources - src/ecflow/client/ClientCmdCache.cpp - src/ecflow/client/Rtt.cpp - src/ecflow/client/ClientEnvironment.cpp - src/ecflow/client/ClientInvoker.cpp - src/ecflow/client/Help.cpp - src/ecflow/client/Rtt.cpp - src/ecflow/client/ClientOptions.cpp - src/ecflow/client/UrlCmd.cpp -) - -ecbuild_add_library( - TARGET - libclient - NOINSTALL - TYPE STATIC - SOURCES - ${srcs} - PUBLIC_INCLUDES - src - PUBLIC_LIBS - base - Threads::Threads -) -target_clangformat(libclient) - # ======================================================================== # EXE ecflow_client, if OpenSSL not enabled ${OPENSSL_LIBRARIES}, is empty @@ -52,7 +17,7 @@ ecbuild_add_executable( SOURCES src/ecflow/client/ClientMain.cpp LIBS - libclient + ecflow_all $<$:OpenSSL::SSL> ) target_clangformat(ecflow_client) @@ -132,10 +97,10 @@ ecbuild_add_test( SOURCES ${test_srcs} INCLUDES - ../Base/test - ../ANode/test + ../base/test + ../node/test LIBS - libclient + ecflow_all Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) Boost::timer $<$:OpenSSL::SSL> @@ -143,9 +108,11 @@ ecbuild_add_test( ecflow_server # the server is launched to support tests TEST_DEPENDS u_base + CONDITION + ENABLE_SERVER # AND ENABLE_TESTS ) target_clangformat(s_client - CONDITION ENABLE_TESTS + CONDITION ENABLE_SERVER AND ENABLE_TESTS ) if (ENABLE_ALL_TESTS AND ENABLE_SERVER) @@ -166,9 +133,9 @@ if (ENABLE_ALL_TESTS AND ENABLE_SERVER) test/TestSinglePerf.cpp test/TestSinglePerf_main.cpp # test entry point INCLUDES - ../Base/test + ../base/test LIBS - libclient + ecflow_all Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) $<$:OpenSSL::SSL> DEPENDS @@ -197,9 +164,9 @@ if (ENABLE_ALL_TESTS AND ENABLE_SERVER) test/TestMigration.cpp test/TestMigration_main.cpp # test entry point INCLUDES - ../Base/test + ../base/test LIBS - libclient + ecflow_all Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) $<$:OpenSSL::SSL> DEPENDS diff --git a/Client/ecf_hostsfile b/libs/client/ecf_hostsfile similarity index 100% rename from Client/ecf_hostsfile rename to libs/client/ecf_hostsfile diff --git a/Client/src/ecflow/client/ClientCmdCache.cpp b/libs/client/src/ecflow/client/ClientCmdCache.cpp similarity index 100% rename from Client/src/ecflow/client/ClientCmdCache.cpp rename to libs/client/src/ecflow/client/ClientCmdCache.cpp diff --git a/Client/src/ecflow/client/ClientCmdCache.hpp b/libs/client/src/ecflow/client/ClientCmdCache.hpp similarity index 100% rename from Client/src/ecflow/client/ClientCmdCache.hpp rename to libs/client/src/ecflow/client/ClientCmdCache.hpp diff --git a/Client/src/ecflow/client/ClientEnvironment.cpp b/libs/client/src/ecflow/client/ClientEnvironment.cpp similarity index 100% rename from Client/src/ecflow/client/ClientEnvironment.cpp rename to libs/client/src/ecflow/client/ClientEnvironment.cpp diff --git a/Client/src/ecflow/client/ClientEnvironment.hpp b/libs/client/src/ecflow/client/ClientEnvironment.hpp similarity index 100% rename from Client/src/ecflow/client/ClientEnvironment.hpp rename to libs/client/src/ecflow/client/ClientEnvironment.hpp diff --git a/Client/src/ecflow/client/ClientInvoker.cpp b/libs/client/src/ecflow/client/ClientInvoker.cpp similarity index 100% rename from Client/src/ecflow/client/ClientInvoker.cpp rename to libs/client/src/ecflow/client/ClientInvoker.cpp diff --git a/Client/src/ecflow/client/ClientInvoker.hpp b/libs/client/src/ecflow/client/ClientInvoker.hpp similarity index 100% rename from Client/src/ecflow/client/ClientInvoker.hpp rename to libs/client/src/ecflow/client/ClientInvoker.hpp diff --git a/Client/src/ecflow/client/ClientMain.cpp b/libs/client/src/ecflow/client/ClientMain.cpp similarity index 100% rename from Client/src/ecflow/client/ClientMain.cpp rename to libs/client/src/ecflow/client/ClientMain.cpp diff --git a/Client/src/ecflow/client/ClientOptions.cpp b/libs/client/src/ecflow/client/ClientOptions.cpp similarity index 100% rename from Client/src/ecflow/client/ClientOptions.cpp rename to libs/client/src/ecflow/client/ClientOptions.cpp diff --git a/Client/src/ecflow/client/ClientOptions.hpp b/libs/client/src/ecflow/client/ClientOptions.hpp similarity index 100% rename from Client/src/ecflow/client/ClientOptions.hpp rename to libs/client/src/ecflow/client/ClientOptions.hpp diff --git a/Client/src/ecflow/client/Help.cpp b/libs/client/src/ecflow/client/Help.cpp similarity index 100% rename from Client/src/ecflow/client/Help.cpp rename to libs/client/src/ecflow/client/Help.cpp diff --git a/Client/src/ecflow/client/Help.hpp b/libs/client/src/ecflow/client/Help.hpp similarity index 100% rename from Client/src/ecflow/client/Help.hpp rename to libs/client/src/ecflow/client/Help.hpp diff --git a/Client/src/ecflow/client/Rtt.cpp b/libs/client/src/ecflow/client/Rtt.cpp similarity index 100% rename from Client/src/ecflow/client/Rtt.cpp rename to libs/client/src/ecflow/client/Rtt.cpp diff --git a/Client/src/ecflow/client/Rtt.hpp b/libs/client/src/ecflow/client/Rtt.hpp similarity index 100% rename from Client/src/ecflow/client/Rtt.hpp rename to libs/client/src/ecflow/client/Rtt.hpp diff --git a/Client/src/ecflow/client/UrlCmd.cpp b/libs/client/src/ecflow/client/UrlCmd.cpp similarity index 100% rename from Client/src/ecflow/client/UrlCmd.cpp rename to libs/client/src/ecflow/client/UrlCmd.cpp diff --git a/Client/src/ecflow/client/UrlCmd.hpp b/libs/client/src/ecflow/client/UrlCmd.hpp similarity index 100% rename from Client/src/ecflow/client/UrlCmd.hpp rename to libs/client/src/ecflow/client/UrlCmd.hpp diff --git a/Client/test/InvokeServer.hpp b/libs/client/test/InvokeServer.hpp similarity index 100% rename from Client/test/InvokeServer.hpp rename to libs/client/test/InvokeServer.hpp diff --git a/Client/test/SCPort.cpp b/libs/client/test/SCPort.cpp similarity index 100% rename from Client/test/SCPort.cpp rename to libs/client/test/SCPort.cpp diff --git a/Client/test/SCPort.hpp b/libs/client/test/SCPort.hpp similarity index 100% rename from Client/test/SCPort.hpp rename to libs/client/test/SCPort.hpp diff --git a/Client/test/TestCheckPtDefsCmd.cpp b/libs/client/test/TestCheckPtDefsCmd.cpp similarity index 99% rename from Client/test/TestCheckPtDefsCmd.cpp rename to libs/client/test/TestCheckPtDefsCmd.cpp index 510f7e4e8..fc14015c8 100644 --- a/Client/test/TestCheckPtDefsCmd.cpp +++ b/libs/client/test/TestCheckPtDefsCmd.cpp @@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(test_check_pt_defs_cmd) { CtsApi::restartServer() << " should return 0 server not started, or connection refused\n" << theClient.errorMsg()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path) == 0, "load defs failed \n" << theClient.errorMsg()); @@ -322,7 +322,7 @@ BOOST_AUTO_TEST_CASE(test_check_pt_edit_history) { BOOST_REQUIRE_MESSAGE(theClient.restartServer() == 0, CtsApi::restartServer() << " should return 0 server not started, or connection refused\n" << theClient.errorMsg()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path) == 0, "load defs failed \n" << theClient.errorMsg()); BOOST_REQUIRE_MESSAGE(theClient.shutdownServer() == 0, CtsApi::shutdownServer() << " should return 0\n" diff --git a/Client/test/TestClientEnvironment.cpp b/libs/client/test/TestClientEnvironment.cpp similarity index 95% rename from Client/test/TestClientEnvironment.cpp rename to libs/client/test/TestClientEnvironment.cpp index 2da9e430c..2db46c38b 100644 --- a/Client/test/TestClientEnvironment.cpp +++ b/libs/client/test/TestClientEnvironment.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_SUITE(T_ClientEnvironment) BOOST_AUTO_TEST_CASE(test_client_environment_host_file_parsing) { std::cout << "Client:: ...test_client_environment_host_file_parsing" << endl; - std::string good_host_file = File::test_data("Client/test/data/good_hostfile", "Client"); + std::string good_host_file = File::test_data("libs/client/test/data/good_hostfile", "libs/client"); // local host should be implicitly added to internal host list std::string the_host = ClientEnvironment::hostSpecified(); @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(test_client_environment_host_file_defaults) { // config or environment. To test this correctly we need to specify a port // other than the default - std::string good_host_file = File::test_data("Client/test/data/good_hostfile", "Client"); + std::string good_host_file = File::test_data("libs/client/test/data/good_hostfile", "libs/client"); // local host should be implicitly added to internal host list std::vector> expectedHost; @@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(test_client_environment_host_file_defaults) { BOOST_AUTO_TEST_CASE(test_client_environment_empty_host_file) { std::cout << "Client:: ...test_client_environment_empty_host_file" << endl; - std::string empty_host_file = File::test_data("Client/test/data/empty_hostfile", "Client"); + std::string empty_host_file = File::test_data("libs/client/test/data/empty_hostfile", "libs/client"); std::string errormsg; BOOST_CHECK_MESSAGE(File::create(empty_host_file, "", errormsg), "Failed to create empty host file " << errormsg); diff --git a/Client/test/TestClientHandleCmd.cpp b/libs/client/test/TestClientHandleCmd.cpp similarity index 100% rename from Client/test/TestClientHandleCmd.cpp rename to libs/client/test/TestClientHandleCmd.cpp diff --git a/Client/test/TestClientInterface.cpp b/libs/client/test/TestClientInterface.cpp similarity index 99% rename from Client/test/TestClientInterface.cpp rename to libs/client/test/TestClientInterface.cpp index 15db534a0..1d60e7553 100644 --- a/Client/test/TestClientInterface.cpp +++ b/libs/client/test/TestClientInterface.cpp @@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE(test_client_interface) { CtsApi::to_string(CtsApi::run(paths, true)) << " should return 0\n" << theClient.errorMsg()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path) == 0, " should return 0\n" << theClient.errorMsg()); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path, true /*force*/) == 0, " should return 0\n" << theClient.errorMsg()); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path, true /*force*/, true /*check_only*/) == 0, @@ -408,7 +408,7 @@ BOOST_AUTO_TEST_CASE(test_client_interface) { CtsApi::get_log_path() << " should return 0\n" << theClient.errorMsg()); - std::string new_log_path = File::test_data("Client/test/data/new_log.log", "Client"); + std::string new_log_path = File::test_data("libs/client/test/data/new_log.log", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.new_log(new_log_path) == 0, " should return 0\n" << theClient.errorMsg()); BOOST_REQUIRE_MESSAGE(theClient.new_log("") == 0, " should return 0\n" << theClient.errorMsg()); } diff --git a/Client/test/TestClientOptions.cpp b/libs/client/test/TestClientOptions.cpp similarity index 100% rename from Client/test/TestClientOptions.cpp rename to libs/client/test/TestClientOptions.cpp diff --git a/Client/test/TestClientTimeout.cpp b/libs/client/test/TestClientTimeout.cpp similarity index 100% rename from Client/test/TestClientTimeout.cpp rename to libs/client/test/TestClientTimeout.cpp diff --git a/Client/test/TestClient_main.cpp b/libs/client/test/TestClient_main.cpp similarity index 100% rename from Client/test/TestClient_main.cpp rename to libs/client/test/TestClient_main.cpp diff --git a/Client/test/TestCustomUser.cpp b/libs/client/test/TestCustomUser.cpp similarity index 100% rename from Client/test/TestCustomUser.cpp rename to libs/client/test/TestCustomUser.cpp diff --git a/Client/test/TestGroupCmd.cpp b/libs/client/test/TestGroupCmd.cpp similarity index 99% rename from Client/test/TestGroupCmd.cpp rename to libs/client/test/TestGroupCmd.cpp index 35a172e13..fae38da6a 100644 --- a/Client/test/TestGroupCmd.cpp +++ b/libs/client/test/TestGroupCmd.cpp @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_client_group_lifecyle) { { // restart server, load lifecycle, and get the defs tree from the server std::string groupRequest = "--restart; load="; - groupRequest += File::test_data("Client/test/data/lifecycle.txt", "Client"); + groupRequest += File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); groupRequest += "; get"; BOOST_REQUIRE_MESSAGE(theClient.group(groupRequest) == 0, diff --git a/Client/test/TestInitAddVariables.cpp b/libs/client/test/TestInitAddVariables.cpp similarity index 100% rename from Client/test/TestInitAddVariables.cpp rename to libs/client/test/TestInitAddVariables.cpp diff --git a/Client/test/TestJobGenOnly.cpp b/libs/client/test/TestJobGenOnly.cpp similarity index 94% rename from Client/test/TestJobGenOnly.cpp rename to libs/client/test/TestJobGenOnly.cpp index e2c3489a0..9a094b44e 100644 --- a/Client/test/TestJobGenOnly.cpp +++ b/libs/client/test/TestJobGenOnly.cpp @@ -30,8 +30,8 @@ BOOST_AUTO_TEST_CASE(test_jobgenonly) { // Define paths to ECF_HOME and location of the defs file - std::string defsFile = File::test_data("Client/test/data/jobgenonly.def", "Client"); - std::string ecf_home = File::test_data("Client/test/data/ECF_HOME", "Client"); + std::string defsFile = File::test_data("libs/client/test/data/jobgenonly.def", "libs/client"); + std::string ecf_home = File::test_data("libs/client/test/data/ECF_HOME", "libs/client"); /// Remove existing job file if any. /// Job file location may NOT be same as ecf file. diff --git a/Client/test/TestLifeCycle.cpp b/libs/client/test/TestLifeCycle.cpp similarity index 99% rename from Client/test/TestLifeCycle.cpp rename to libs/client/test/TestLifeCycle.cpp index b68beb7cf..9c7cfdeba 100644 --- a/Client/test/TestLifeCycle.cpp +++ b/libs/client/test/TestLifeCycle.cpp @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(test_node_tree_lifecycle) { TestLog test_log( "test_node_tree_lifecycle.log"); // will create log file, and destroy log and remove file at end of scope - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); Defs defs; std::string errorMsg, warningMsg; diff --git a/Client/test/TestLoadDefsCmd.cpp b/libs/client/test/TestLoadDefsCmd.cpp similarity index 95% rename from Client/test/TestLoadDefsCmd.cpp rename to libs/client/test/TestLoadDefsCmd.cpp index 25f312e36..253370cc0 100644 --- a/Client/test/TestLoadDefsCmd.cpp +++ b/libs/client/test/TestLoadDefsCmd.cpp @@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(test_load_defs_cmd_handleRequest) { TestLog test_log("test_load_defs_cmd_handleRequest.log"); // will create log file, and destroy log and remove file // at end of scope - std::string firstDef = File::test_data("Client/test/data/first.def", "Client"); + std::string firstDef = File::test_data("libs/client/test/data/first.def", "libs/client"); // Load the FIRST file with a set of unresolved extrens defs_ptr firstDefs = Defs::create(); @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(test_load_defs_cmd_handleRequest) { size_t noOfSuites = firstDefs->suiteVec().size(); // load the SECOND file, which should resolve the externs - std::string secondDef = File::test_data("Client/test/data/second.def", "Client"); + std::string secondDef = File::test_data("libs/client/test/data/second.def", "libs/client"); Defs secondDefs; { std::string errorMsg, warningMsg; @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(test_load_defs_check_only) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); // Do not load the defs do a check only ClientInvoker theClient(invokeServer.host(), invokeServer.port()); @@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(test_load_defs_check_only) { << theClient.errorMsg()); } // provide path to definition that should fail to parse - std::string path_bad_def = File::test_data("Client/test/data/bad.def", "Client"); + std::string path_bad_def = File::test_data("libs/client/test/data/bad.def", "libs/client"); BOOST_REQUIRE_THROW(theClient.loadDefs(path_bad_def, false, true /* check only*/), std::runtime_error); } diff --git a/Client/test/TestLogAndCheckptErrors.cpp b/libs/client/test/TestLogAndCheckptErrors.cpp similarity index 98% rename from Client/test/TestLogAndCheckptErrors.cpp rename to libs/client/test/TestLogAndCheckptErrors.cpp index db2e99b87..2b91f3056 100644 --- a/Client/test/TestLogAndCheckptErrors.cpp +++ b/libs/client/test/TestLogAndCheckptErrors.cpp @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(test_log_and_checkpt_write_errors) { if (debug_me) cout << "->load a defs file to the server\n"; - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_CHECK_MESSAGE(theClient.loadDefs(path) == 0, "load defs failed \n" << theClient.errorMsg()); if (debug_me) { BOOST_CHECK_MESSAGE(theClient.sync_local() == 0, "sync_local failed \n" << theClient.errorMsg()); diff --git a/Client/test/TestMigration.cpp b/libs/client/test/TestMigration.cpp similarity index 100% rename from Client/test/TestMigration.cpp rename to libs/client/test/TestMigration.cpp diff --git a/Client/test/TestMigration_main.cpp b/libs/client/test/TestMigration_main.cpp similarity index 100% rename from Client/test/TestMigration_main.cpp rename to libs/client/test/TestMigration_main.cpp diff --git a/Client/test/TestPasswdFile.cpp b/libs/client/test/TestPasswdFile.cpp similarity index 100% rename from Client/test/TestPasswdFile.cpp rename to libs/client/test/TestPasswdFile.cpp diff --git a/Client/test/TestPlugCmd.cpp b/libs/client/test/TestPlugCmd.cpp similarity index 99% rename from Client/test/TestPlugCmd.cpp rename to libs/client/test/TestPlugCmd.cpp index 2b6c1d86d..bfe8e8aff 100644 --- a/Client/test/TestPlugCmd.cpp +++ b/libs/client/test/TestPlugCmd.cpp @@ -41,7 +41,7 @@ static void get_defs(Defs& defs) { // trigger ../family1/a:myMeter >= 50 || ../family1/a:myEvent // endfamily // endsuite - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); std::string errorMsg, warningMsg; bool parse = defs.restore(path, errorMsg, warningMsg); if (!parse) @@ -234,7 +234,7 @@ static void test_plug_on_multiple_server(const std::string& host1, // std::cout << " LOAD the defs into FIRST server(" << host1 << ":" << port1 << ") There is NO DEFS in the second // server." << endl; - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(server1Client.loadDefs(path) == 0, "load defs failed \n" << server1Client.errorMsg()); // cout << " Test the ERROR conditions in MoveCmd" << endl; diff --git a/Client/test/TestRtt.cpp b/libs/client/test/TestRtt.cpp similarity index 94% rename from Client/test/TestRtt.cpp rename to libs/client/test/TestRtt.cpp index f53531da3..144cd5169 100644 --- a/Client/test/TestRtt.cpp +++ b/libs/client/test/TestRtt.cpp @@ -25,7 +25,7 @@ BOOST_AUTO_TEST_SUITE(T_Rtt) BOOST_AUTO_TEST_CASE(test_client_invoker_round_trip_times) { cout << "Client:: ...test_client_invoker_round_trip_times" << endl; - std::string root_path = File::test_data("Client/test/data/", "Client"); + std::string root_path = File::test_data("libs/client/test/data/", "libs/client"); /// Open file rtt.dat and compute average round trip times std::string result = Rtt::analyis(root_path + "rtt.dat"); diff --git a/Client/test/TestServer.cpp b/libs/client/test/TestServer.cpp similarity index 98% rename from Client/test/TestServer.cpp rename to libs/client/test/TestServer.cpp index a05ff3465..0777c7dbd 100644 --- a/Client/test/TestServer.cpp +++ b/libs/client/test/TestServer.cpp @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(test_server_state_changes) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); ClientInvoker theClient(invokeServer.host(), invokeServer.port()); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path) == 0, "load defs failed \n" << theClient.errorMsg()); @@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(test_server_state_changes_with_auto_sync) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); ClientInvoker theClient(invokeServer.host(), invokeServer.port()); theClient.set_auto_sync(true); @@ -235,7 +235,7 @@ BOOST_AUTO_TEST_CASE(test_server_stress_test) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); ClientInvoker theClient(invokeServer.host(), invokeServer.port()); int load = 125; @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(test_server_group_stress_test) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); boost::timer::cpu_timer boost_timer; // measures CPU, replace with cpu_timer with boost > 1.51, measures cpu & elapsed @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(test_server_stress_test_2) { BOOST_REQUIRE_MESSAGE(invokeServer.server_started(), "Server failed to start on " << invokeServer.host() << ":" << invokeServer.port()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); Zombie z(Child::USER, ecf::Child::INIT, diff --git a/Client/test/TestServerAndLifeCycle.cpp b/libs/client/test/TestServerAndLifeCycle.cpp similarity index 99% rename from Client/test/TestServerAndLifeCycle.cpp rename to libs/client/test/TestServerAndLifeCycle.cpp index 6096c95fc..f7031e915 100644 --- a/Client/test/TestServerAndLifeCycle.cpp +++ b/libs/client/test/TestServerAndLifeCycle.cpp @@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(test_client_lifecyle) { // load the defs into the server { - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.delete_all() == 0, CtsApi::to_string(CtsApi::delete_node()) << " should return 0\n" << theClient.errorMsg()); diff --git a/Client/test/TestServerLoad.cpp b/libs/client/test/TestServerLoad.cpp similarity index 100% rename from Client/test/TestServerLoad.cpp rename to libs/client/test/TestServerLoad.cpp diff --git a/Client/test/TestSignalSIGTERM.cpp b/libs/client/test/TestSignalSIGTERM.cpp similarity index 98% rename from Client/test/TestSignalSIGTERM.cpp rename to libs/client/test/TestSignalSIGTERM.cpp index b8a9934bb..fbc077e79 100644 --- a/Client/test/TestSignalSIGTERM.cpp +++ b/libs/client/test/TestSignalSIGTERM.cpp @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(test_signal_SIGTERM) { CtsApi::restartServer() << " should return 0 server not started, or connection refused\n" << theClient.errorMsg()); - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); BOOST_REQUIRE_MESSAGE(theClient.loadDefs(path) == 0, "load defs failed \n" << theClient.errorMsg()); // Get the definition diff --git a/Client/test/TestSinglePerf.cpp b/libs/client/test/TestSinglePerf.cpp similarity index 100% rename from Client/test/TestSinglePerf.cpp rename to libs/client/test/TestSinglePerf.cpp diff --git a/Client/test/TestSinglePerf_main.cpp b/libs/client/test/TestSinglePerf_main.cpp similarity index 100% rename from Client/test/TestSinglePerf_main.cpp rename to libs/client/test/TestSinglePerf_main.cpp diff --git a/Client/test/TestUrlCmd.cpp b/libs/client/test/TestUrlCmd.cpp similarity index 94% rename from Client/test/TestUrlCmd.cpp rename to libs/client/test/TestUrlCmd.cpp index cc8e4edb8..87f07442b 100644 --- a/Client/test/TestUrlCmd.cpp +++ b/libs/client/test/TestUrlCmd.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE(T_UrlCmd) BOOST_AUTO_TEST_CASE(test_url_cmd) { cout << "Client:: ...test_url_cmd" << endl; - std::string path = File::test_data("Client/test/data/lifecycle.txt", "Client"); + std::string path = File::test_data("libs/client/test/data/lifecycle.txt", "libs/client"); defs_ptr defs = Defs::create(); diff --git a/Client/test/TestWhiteListFile.cpp b/libs/client/test/TestWhiteListFile.cpp similarity index 100% rename from Client/test/TestWhiteListFile.cpp rename to libs/client/test/TestWhiteListFile.cpp diff --git a/Client/test/data/ECF_HOME/includes/head.h b/libs/client/test/data/ECF_HOME/includes/head.h similarity index 100% rename from Client/test/data/ECF_HOME/includes/head.h rename to libs/client/test/data/ECF_HOME/includes/head.h diff --git a/Client/test/data/ECF_HOME/includes/tail.h b/libs/client/test/data/ECF_HOME/includes/tail.h similarity index 100% rename from Client/test/data/ECF_HOME/includes/tail.h rename to libs/client/test/data/ECF_HOME/includes/tail.h diff --git a/Client/test/data/ECF_HOME/suite/family/head.h b/libs/client/test/data/ECF_HOME/suite/family/head.h similarity index 100% rename from Client/test/data/ECF_HOME/suite/family/head.h rename to libs/client/test/data/ECF_HOME/suite/family/head.h diff --git a/Client/test/data/ECF_HOME/suite/family/t1.ecf b/libs/client/test/data/ECF_HOME/suite/family/t1.ecf similarity index 100% rename from Client/test/data/ECF_HOME/suite/family/t1.ecf rename to libs/client/test/data/ECF_HOME/suite/family/t1.ecf diff --git a/ANode/test/data/SMSHOME/suite/family/t2.ecf b/libs/client/test/data/ECF_HOME/suite/family/t2.ecf similarity index 100% rename from ANode/test/data/SMSHOME/suite/family/t2.ecf rename to libs/client/test/data/ECF_HOME/suite/family/t2.ecf diff --git a/ANode/test/data/SMSHOME/suite/family/t3.ecf b/libs/client/test/data/ECF_HOME/suite/family/t3.ecf old mode 100644 new mode 100755 similarity index 100% rename from ANode/test/data/SMSHOME/suite/family/t3.ecf rename to libs/client/test/data/ECF_HOME/suite/family/t3.ecf diff --git a/Client/test/data/ECF_HOME/suite/family/tail.h b/libs/client/test/data/ECF_HOME/suite/family/tail.h similarity index 100% rename from Client/test/data/ECF_HOME/suite/family/tail.h rename to libs/client/test/data/ECF_HOME/suite/family/tail.h diff --git a/Client/test/data/bad.def b/libs/client/test/data/bad.def similarity index 100% rename from Client/test/data/bad.def rename to libs/client/test/data/bad.def diff --git a/Client/test/data/first.def b/libs/client/test/data/first.def similarity index 100% rename from Client/test/data/first.def rename to libs/client/test/data/first.def diff --git a/Client/test/data/good_hostfile b/libs/client/test/data/good_hostfile similarity index 100% rename from Client/test/data/good_hostfile rename to libs/client/test/data/good_hostfile diff --git a/Client/test/data/jobgenonly.def b/libs/client/test/data/jobgenonly.def similarity index 100% rename from Client/test/data/jobgenonly.def rename to libs/client/test/data/jobgenonly.def diff --git a/Client/test/data/lifecycle.txt b/libs/client/test/data/lifecycle.txt similarity index 100% rename from Client/test/data/lifecycle.txt rename to libs/client/test/data/lifecycle.txt diff --git a/Client/test/data/second.def b/libs/client/test/data/second.def similarity index 100% rename from Client/test/data/second.def rename to libs/client/test/data/second.def diff --git a/libs/core/CMakeLists.txt b/libs/core/CMakeLists.txt new file mode 100644 index 000000000..ba0d1bce9 --- /dev/null +++ b/libs/core/CMakeLists.txt @@ -0,0 +1,79 @@ +# +# Copyright 2009- ECMWF. +# +# This software is licensed under the terms of the Apache Licence version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. +# + +## +## Notice: test_support is an INTERFACE-only test utility library. +## + +ecbuild_add_library( + TARGET + test_support + NOINSTALL + TYPE INTERFACE + SOURCES + test/TestSerialisation.hpp + PUBLIC_INCLUDES + test +) +target_clangformat(test_support) + +set(test_srcs + # Headers + test/TestVersioning.hpp + # Sources + test/TestCalendar.cpp + test/TestCereal.cpp + test/TestCerealOptionalNVP.cpp + test/TestCerealWithHierarchy.cpp + test/TestChrono.cpp + test/TestClassDataMemberInit.cpp + test/TestCommandLine.cpp + test/TestCore_main.cpp # contains main() function for test driver + test/TestExtract.cpp + test/TestFile.cpp + test/TestGetUserDetails.cpp + test/TestLog.cpp + test/TestMessage.cpp + test/TestMigration.cpp + test/TestNodePath.cpp + test/TestPasswdFile.cpp + test/TestPasswordEncryption.cpp + test/TestPerfTimer.cpp + test/TestRealCalendar.cpp + test/TestSanitizerAS.cpp + test/TestSanitizerUB.cpp + test/TestSerialisation.cpp + test/TestStr.cpp + test/TestStringSplitPerf.cpp + test/TestStringSplitter.cpp + test/TestTimeSeries.cpp + test/TestTimeSlot.cpp + test/TestVersion.cpp + test/TestVersioning.cpp + test/TestWhiteListFile.cpp +) + +ecbuild_add_test( + TARGET + u_core + LABELS + unit + nightly + SOURCES + ${test_srcs} + LIBS + test_support + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + Boost::timer +) +target_clangformat(u_core + CONDITION ENABLE_TESTS +) diff --git a/ACore/src/ecflow/core/AssertTimer.cpp b/libs/core/src/ecflow/core/AssertTimer.cpp similarity index 100% rename from ACore/src/ecflow/core/AssertTimer.cpp rename to libs/core/src/ecflow/core/AssertTimer.cpp diff --git a/ACore/src/ecflow/core/AssertTimer.hpp b/libs/core/src/ecflow/core/AssertTimer.hpp similarity index 100% rename from ACore/src/ecflow/core/AssertTimer.hpp rename to libs/core/src/ecflow/core/AssertTimer.hpp diff --git a/ACore/src/ecflow/core/Cal.cpp b/libs/core/src/ecflow/core/Cal.cpp similarity index 100% rename from ACore/src/ecflow/core/Cal.cpp rename to libs/core/src/ecflow/core/Cal.cpp diff --git a/ACore/src/ecflow/core/Cal.hpp b/libs/core/src/ecflow/core/Cal.hpp similarity index 100% rename from ACore/src/ecflow/core/Cal.hpp rename to libs/core/src/ecflow/core/Cal.hpp diff --git a/ACore/src/ecflow/core/Calendar.cpp b/libs/core/src/ecflow/core/Calendar.cpp similarity index 100% rename from ACore/src/ecflow/core/Calendar.cpp rename to libs/core/src/ecflow/core/Calendar.cpp diff --git a/ACore/src/ecflow/core/Calendar.hpp b/libs/core/src/ecflow/core/Calendar.hpp similarity index 100% rename from ACore/src/ecflow/core/Calendar.hpp rename to libs/core/src/ecflow/core/Calendar.hpp diff --git a/ACore/src/ecflow/core/CalendarUpdateParams.hpp b/libs/core/src/ecflow/core/CalendarUpdateParams.hpp similarity index 100% rename from ACore/src/ecflow/core/CalendarUpdateParams.hpp rename to libs/core/src/ecflow/core/CalendarUpdateParams.hpp diff --git a/ACore/src/ecflow/core/CheckPt.hpp b/libs/core/src/ecflow/core/CheckPt.hpp similarity index 100% rename from ACore/src/ecflow/core/CheckPt.hpp rename to libs/core/src/ecflow/core/CheckPt.hpp diff --git a/ACore/src/ecflow/core/Child.cpp b/libs/core/src/ecflow/core/Child.cpp similarity index 100% rename from ACore/src/ecflow/core/Child.cpp rename to libs/core/src/ecflow/core/Child.cpp diff --git a/ACore/src/ecflow/core/Child.hpp b/libs/core/src/ecflow/core/Child.hpp similarity index 100% rename from ACore/src/ecflow/core/Child.hpp rename to libs/core/src/ecflow/core/Child.hpp diff --git a/ACore/src/ecflow/core/Chrono.cpp b/libs/core/src/ecflow/core/Chrono.cpp similarity index 96% rename from ACore/src/ecflow/core/Chrono.cpp rename to libs/core/src/ecflow/core/Chrono.cpp index 37c4641c1..17ad3fc65 100644 --- a/ACore/src/ecflow/core/Chrono.cpp +++ b/libs/core/src/ecflow/core/Chrono.cpp @@ -10,6 +10,7 @@ #include "Chrono.hpp" +#include #include #include #include @@ -181,12 +182,12 @@ DurationOut parse_duration(const std::string& d) { // Extract tail std::string tail = d.substr(found + 1, std::string::npos); - // Important! - // The whole duration has the same sign as the first component - // e.g. -23:59:59, is interpreted as (-23 hours) + (-59 minutes) + (-59 seconds) = -86399 seconds - int sign = value >= FirstDuration{0} ? 1 : -1; - if constexpr (sizeof...(RestDurations) > 0) { + // Important! + // The whole duration has the same sign as the first component + // e.g. -23:59:59, is interpreted as (-23 hours) + (-59 minutes) + (-59 seconds) = -86399 seconds + int sign = value >= FirstDuration{0} ? 1 : -1; + out = out + (sign)*parse_duration(tail); } diff --git a/ACore/src/ecflow/core/Chrono.hpp b/libs/core/src/ecflow/core/Chrono.hpp similarity index 100% rename from ACore/src/ecflow/core/Chrono.hpp rename to libs/core/src/ecflow/core/Chrono.hpp diff --git a/ACore/src/ecflow/core/CommandLine.cpp b/libs/core/src/ecflow/core/CommandLine.cpp similarity index 100% rename from ACore/src/ecflow/core/CommandLine.cpp rename to libs/core/src/ecflow/core/CommandLine.cpp diff --git a/ACore/src/ecflow/core/CommandLine.hpp b/libs/core/src/ecflow/core/CommandLine.hpp similarity index 100% rename from ACore/src/ecflow/core/CommandLine.hpp rename to libs/core/src/ecflow/core/CommandLine.hpp diff --git a/ACore/src/ecflow/core/Converter.hpp b/libs/core/src/ecflow/core/Converter.hpp similarity index 100% rename from ACore/src/ecflow/core/Converter.hpp rename to libs/core/src/ecflow/core/Converter.hpp diff --git a/ACore/src/ecflow/core/DState.cpp b/libs/core/src/ecflow/core/DState.cpp similarity index 100% rename from ACore/src/ecflow/core/DState.cpp rename to libs/core/src/ecflow/core/DState.cpp diff --git a/ACore/src/ecflow/core/DState.hpp b/libs/core/src/ecflow/core/DState.hpp similarity index 100% rename from ACore/src/ecflow/core/DState.hpp rename to libs/core/src/ecflow/core/DState.hpp diff --git a/ACore/src/ecflow/core/DebugPerf.hpp b/libs/core/src/ecflow/core/DebugPerf.hpp similarity index 100% rename from ACore/src/ecflow/core/DebugPerf.hpp rename to libs/core/src/ecflow/core/DebugPerf.hpp diff --git a/ACore/src/ecflow/core/DurationTimer.cpp b/libs/core/src/ecflow/core/DurationTimer.cpp similarity index 100% rename from ACore/src/ecflow/core/DurationTimer.cpp rename to libs/core/src/ecflow/core/DurationTimer.cpp diff --git a/ACore/src/ecflow/core/DurationTimer.hpp b/libs/core/src/ecflow/core/DurationTimer.hpp similarity index 100% rename from ACore/src/ecflow/core/DurationTimer.hpp rename to libs/core/src/ecflow/core/DurationTimer.hpp diff --git a/ACore/src/ecflow/core/Ecf.cpp b/libs/core/src/ecflow/core/Ecf.cpp similarity index 92% rename from ACore/src/ecflow/core/Ecf.cpp rename to libs/core/src/ecflow/core/Ecf.cpp index b42e20658..4aabeb762 100644 --- a/ACore/src/ecflow/core/Ecf.cpp +++ b/libs/core/src/ecflow/core/Ecf.cpp @@ -13,8 +13,8 @@ bool Ecf::server_ = false; bool Ecf::debug_equality_ = false; unsigned int Ecf::debug_level_ = 0; -unsigned int Ecf::state_change_no_ = 0; -unsigned int Ecf::modify_change_no_ = 0; +thread_local Ecf::atomic_counter_t Ecf::state_change_no_ = 0; +thread_local Ecf::atomic_counter_t Ecf::modify_change_no_ = 0; bool DebugEquality::ignore_server_variables_ = false; const char* Ecf::SERVER_NAME() { @@ -59,7 +59,7 @@ const std::string& Ecf::CHECK_CMD() { return CHECK_CMD; } -// -remote has been removed form firefox, since version 39 +//-remote has been removed from firefox, since version 39 //-remote openfile(file) -> -file //-remote openurl(url) -> -url //-remote openurl(url,new-window) -> -new-window @@ -80,15 +80,14 @@ const std::string& Ecf::URL() { return URL; } -unsigned int Ecf::incr_state_change_no() { +Ecf::counter_t Ecf::incr_state_change_no() { if (server_) { return ++state_change_no_; } return state_change_no_; } -unsigned int Ecf::incr_modify_change_no() { - +Ecf::counter_t Ecf::incr_modify_change_no() { if (server_) { return ++modify_change_no_; } diff --git a/ACore/src/ecflow/core/Ecf.hpp b/libs/core/src/ecflow/core/Ecf.hpp similarity index 66% rename from ACore/src/ecflow/core/Ecf.hpp rename to libs/core/src/ecflow/core/Ecf.hpp index d0d391cd5..69f94f6ff 100644 --- a/ACore/src/ecflow/core/Ecf.hpp +++ b/libs/core/src/ecflow/core/Ecf.hpp @@ -15,20 +15,31 @@ /// \brief Provides globals used by server for determining change /// +#include #include -// class Ecf: This class is used in the server to determine incremental changes -// to the data model. Each Node/attribute stores a state change no -// When ever there is a change, we increment local state change -// number with this global. -// When making large scale changes, ie nodes added or deleted we use modify change no -// Note: The client will need to at some point copy over the full defs -// at this point the state change no add modify number is also copied. -// The client passes these two number back to server, the server then -// uses these two numbers to determine what's changed. -// +/** + * This class holds *global data*, and is used in the server to determine incremental changes to the data model. + * + * This data is composed of two parts: + * - `state_change_no_`: leads the number of node state changes on the currently loaded defs + * - `modify_change_no_`: leads the number of structural changes to the currently loaded defs + * + * Each Node/Attribute stores a local `state_change_no_`, and whenever there is a change, this local number is + * assigned based on the incremented value of the `global state_change_no_`. + * + * When making large scale changes (e.g. adding or deleting nodes), we increment the global `modify_change_no_`. + * + * The synchronization strategy is such that when the client eventually copies over the full defs, the state_change_no_ + * and modify_change_no_ are also copied. In future synchronization attempts, the client includes these two numbers in + * the sync request, and thus allows the server to determine what has changed. + */ + class Ecf { public: + using counter_t = unsigned int; + using atomic_counter_t = std::atomic; + // Disable default construction Ecf() = delete; // Disable copy (and move) semantics @@ -36,14 +47,14 @@ class Ecf { const Ecf& operator=(const Ecf&) = delete; /// Increment and then return state change no - static unsigned int incr_state_change_no(); - static unsigned int state_change_no() { return state_change_no_; } - static void set_state_change_no(unsigned int x) { state_change_no_ = x; } + static counter_t incr_state_change_no(); + static counter_t state_change_no() { return state_change_no_; } + static void set_state_change_no(counter_t x) { state_change_no_ = x; } /// The modify_change_no_ is used for node addition and deletion and re-ordering - static unsigned int incr_modify_change_no(); - static unsigned int modify_change_no() { return modify_change_no_; } - static void set_modify_change_no(unsigned int x) { modify_change_no_ = x; } + static counter_t incr_modify_change_no(); + static counter_t modify_change_no() { return modify_change_no_; } + static void set_modify_change_no(counter_t x) { modify_change_no_ = x; } /// Returns true if we are on the server side. /// Only in server side do we increment state/modify numbers @@ -80,8 +91,8 @@ class Ecf { static bool server_; static bool debug_equality_; static unsigned int debug_level_; - static unsigned int state_change_no_; - static unsigned int modify_change_no_; + static thread_local atomic_counter_t state_change_no_; + static thread_local atomic_counter_t modify_change_no_; }; /// Make sure the Ecf number don't change diff --git a/ACore/src/ecflow/core/EcfPortLock.hpp b/libs/core/src/ecflow/core/EcfPortLock.hpp similarity index 100% rename from ACore/src/ecflow/core/EcfPortLock.hpp rename to libs/core/src/ecflow/core/EcfPortLock.hpp diff --git a/ACore/src/ecflow/core/Enumerate.hpp b/libs/core/src/ecflow/core/Enumerate.hpp similarity index 100% rename from ACore/src/ecflow/core/Enumerate.hpp rename to libs/core/src/ecflow/core/Enumerate.hpp diff --git a/ACore/src/ecflow/core/Extract.cpp b/libs/core/src/ecflow/core/Extract.cpp similarity index 100% rename from ACore/src/ecflow/core/Extract.cpp rename to libs/core/src/ecflow/core/Extract.cpp diff --git a/ACore/src/ecflow/core/Extract.hpp b/libs/core/src/ecflow/core/Extract.hpp similarity index 100% rename from ACore/src/ecflow/core/Extract.hpp rename to libs/core/src/ecflow/core/Extract.hpp diff --git a/ACore/src/ecflow/core/File.cpp b/libs/core/src/ecflow/core/File.cpp similarity index 100% rename from ACore/src/ecflow/core/File.cpp rename to libs/core/src/ecflow/core/File.cpp diff --git a/ACore/src/ecflow/core/File.hpp b/libs/core/src/ecflow/core/File.hpp similarity index 100% rename from ACore/src/ecflow/core/File.hpp rename to libs/core/src/ecflow/core/File.hpp diff --git a/ACore/src/ecflow/core/File_r.cpp b/libs/core/src/ecflow/core/File_r.cpp similarity index 100% rename from ACore/src/ecflow/core/File_r.cpp rename to libs/core/src/ecflow/core/File_r.cpp diff --git a/ACore/src/ecflow/core/File_r.hpp b/libs/core/src/ecflow/core/File_r.hpp similarity index 100% rename from ACore/src/ecflow/core/File_r.hpp rename to libs/core/src/ecflow/core/File_r.hpp diff --git a/ACore/src/ecflow/core/Filesystem.cpp b/libs/core/src/ecflow/core/Filesystem.cpp similarity index 100% rename from ACore/src/ecflow/core/Filesystem.cpp rename to libs/core/src/ecflow/core/Filesystem.cpp diff --git a/ACore/src/ecflow/core/Filesystem.hpp b/libs/core/src/ecflow/core/Filesystem.hpp similarity index 100% rename from ACore/src/ecflow/core/Filesystem.hpp rename to libs/core/src/ecflow/core/Filesystem.hpp diff --git a/ACore/src/ecflow/core/Host.cpp b/libs/core/src/ecflow/core/Host.cpp similarity index 100% rename from ACore/src/ecflow/core/Host.cpp rename to libs/core/src/ecflow/core/Host.cpp diff --git a/ACore/src/ecflow/core/Host.hpp b/libs/core/src/ecflow/core/Host.hpp similarity index 100% rename from ACore/src/ecflow/core/Host.hpp rename to libs/core/src/ecflow/core/Host.hpp diff --git a/ACore/src/ecflow/core/Indentor.cpp b/libs/core/src/ecflow/core/Indentor.cpp similarity index 81% rename from ACore/src/ecflow/core/Indentor.cpp rename to libs/core/src/ecflow/core/Indentor.cpp index 37ba7d952..1b3e923f4 100644 --- a/ACore/src/ecflow/core/Indentor.cpp +++ b/libs/core/src/ecflow/core/Indentor.cpp @@ -17,11 +17,6 @@ namespace ecf { int Indentor::index_ = 0; bool Indentor::indent_ = true; -std::ostream& Indentor::indent(std::ostream& os, int char_spaces) { - os << (indent_ ? std::string(index_ * char_spaces, ' ') : ""); - return os; -} - void Indentor::indent(std::string& os, int char_spaces) { os += (indent_ ? std::string(index_ * char_spaces, ' ') : ""); } diff --git a/ACore/src/ecflow/core/Indentor.hpp b/libs/core/src/ecflow/core/Indentor.hpp similarity index 83% rename from ACore/src/ecflow/core/Indentor.hpp rename to libs/core/src/ecflow/core/Indentor.hpp index 95bb7784f..bdc9aa25c 100644 --- a/ACore/src/ecflow/core/Indentor.hpp +++ b/libs/core/src/ecflow/core/Indentor.hpp @@ -16,6 +16,7 @@ /// #include +#include namespace ecf { @@ -24,9 +25,14 @@ class Indentor { Indentor() { ++index_; } ~Indentor() { --index_; } - static std::ostream& indent(std::ostream& os, int char_spaces = 2); static void indent(std::string& os, int char_spaces = 2); + template + static Stream& indent(Stream& s, int char_spaces = 2) { + s << (indent_ ? std::string(index_ * char_spaces, ' ') : std::string("")); + return s; + } + private: static int index_; diff --git a/ACore/src/ecflow/core/Log.cpp b/libs/core/src/ecflow/core/Log.cpp similarity index 100% rename from ACore/src/ecflow/core/Log.cpp rename to libs/core/src/ecflow/core/Log.cpp diff --git a/ACore/src/ecflow/core/Log.hpp b/libs/core/src/ecflow/core/Log.hpp similarity index 100% rename from ACore/src/ecflow/core/Log.hpp rename to libs/core/src/ecflow/core/Log.hpp diff --git a/ACore/src/ecflow/core/LogVerification.cpp b/libs/core/src/ecflow/core/LogVerification.cpp similarity index 100% rename from ACore/src/ecflow/core/LogVerification.cpp rename to libs/core/src/ecflow/core/LogVerification.cpp diff --git a/ACore/src/ecflow/core/LogVerification.hpp b/libs/core/src/ecflow/core/LogVerification.hpp similarity index 100% rename from ACore/src/ecflow/core/LogVerification.hpp rename to libs/core/src/ecflow/core/LogVerification.hpp diff --git a/libs/core/src/ecflow/core/Message.hpp b/libs/core/src/ecflow/core/Message.hpp new file mode 100644 index 000000000..c8d79ae6c --- /dev/null +++ b/libs/core/src/ecflow/core/Message.hpp @@ -0,0 +1,46 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_core_Message_HPP +#define ecflow_core_Message_HPP + +#include +#include + +namespace ecf { + +/// +/// \brief Message is a utility class that easily creates a string-based Message from an arbitrary set of inputs +/// +/// The goal is to facilitate the construction/formatting of messages for error handling and logging. +/// A Message implicitly allows conversion to std::string, and provides the streaming operator<<. +/// +class Message { +public: + template + explicit Message(ARGS&&... args) { + ((buffer << std::forward(args)), ...); + } + + [[nodiscard]] std::string str() const { return buffer.str(); } + [[nodiscard]] operator std::string() const { return buffer.str(); } + +private: + std::ostringstream buffer; +}; + +inline std::ostream& operator<<(std::ostream& o, const Message& m) { + o << std::string(m); + return o; +} + +} // namespace ecf + +#endif /* ecflow_core_Message_HPP */ diff --git a/ACore/src/ecflow/core/NOrder.cpp b/libs/core/src/ecflow/core/NOrder.cpp similarity index 100% rename from ACore/src/ecflow/core/NOrder.cpp rename to libs/core/src/ecflow/core/NOrder.cpp diff --git a/ACore/src/ecflow/core/NOrder.hpp b/libs/core/src/ecflow/core/NOrder.hpp similarity index 100% rename from ACore/src/ecflow/core/NOrder.hpp rename to libs/core/src/ecflow/core/NOrder.hpp diff --git a/ACore/src/ecflow/core/NState.cpp b/libs/core/src/ecflow/core/NState.cpp similarity index 100% rename from ACore/src/ecflow/core/NState.cpp rename to libs/core/src/ecflow/core/NState.cpp diff --git a/ACore/src/ecflow/core/NState.hpp b/libs/core/src/ecflow/core/NState.hpp similarity index 100% rename from ACore/src/ecflow/core/NState.hpp rename to libs/core/src/ecflow/core/NState.hpp diff --git a/ACore/src/ecflow/core/NodePath.cpp b/libs/core/src/ecflow/core/NodePath.cpp similarity index 100% rename from ACore/src/ecflow/core/NodePath.cpp rename to libs/core/src/ecflow/core/NodePath.cpp diff --git a/ACore/src/ecflow/core/NodePath.hpp b/libs/core/src/ecflow/core/NodePath.hpp similarity index 100% rename from ACore/src/ecflow/core/NodePath.hpp rename to libs/core/src/ecflow/core/NodePath.hpp diff --git a/ACore/src/ecflow/core/Overload.hpp b/libs/core/src/ecflow/core/Overload.hpp similarity index 100% rename from ACore/src/ecflow/core/Overload.hpp rename to libs/core/src/ecflow/core/Overload.hpp diff --git a/ACore/src/ecflow/core/Passwd.cpp b/libs/core/src/ecflow/core/Passwd.cpp similarity index 100% rename from ACore/src/ecflow/core/Passwd.cpp rename to libs/core/src/ecflow/core/Passwd.cpp diff --git a/ACore/src/ecflow/core/Passwd.hpp b/libs/core/src/ecflow/core/Passwd.hpp similarity index 100% rename from ACore/src/ecflow/core/Passwd.hpp rename to libs/core/src/ecflow/core/Passwd.hpp diff --git a/ACore/src/ecflow/core/PasswdFile.cpp b/libs/core/src/ecflow/core/PasswdFile.cpp similarity index 100% rename from ACore/src/ecflow/core/PasswdFile.cpp rename to libs/core/src/ecflow/core/PasswdFile.cpp diff --git a/ACore/src/ecflow/core/PasswdFile.hpp b/libs/core/src/ecflow/core/PasswdFile.hpp similarity index 100% rename from ACore/src/ecflow/core/PasswdFile.hpp rename to libs/core/src/ecflow/core/PasswdFile.hpp diff --git a/ACore/src/ecflow/core/PasswordEncryption.hpp b/libs/core/src/ecflow/core/PasswordEncryption.hpp similarity index 100% rename from ACore/src/ecflow/core/PasswordEncryption.hpp rename to libs/core/src/ecflow/core/PasswordEncryption.hpp diff --git a/ACore/src/ecflow/core/Pid.cpp b/libs/core/src/ecflow/core/Pid.cpp similarity index 100% rename from ACore/src/ecflow/core/Pid.cpp rename to libs/core/src/ecflow/core/Pid.cpp diff --git a/ACore/src/ecflow/core/Pid.hpp b/libs/core/src/ecflow/core/Pid.hpp similarity index 100% rename from ACore/src/ecflow/core/Pid.hpp rename to libs/core/src/ecflow/core/Pid.hpp diff --git a/ACore/src/ecflow/core/PrintStyle.cpp b/libs/core/src/ecflow/core/PrintStyle.cpp similarity index 100% rename from ACore/src/ecflow/core/PrintStyle.cpp rename to libs/core/src/ecflow/core/PrintStyle.cpp diff --git a/ACore/src/ecflow/core/PrintStyle.hpp b/libs/core/src/ecflow/core/PrintStyle.hpp similarity index 100% rename from ACore/src/ecflow/core/PrintStyle.hpp rename to libs/core/src/ecflow/core/PrintStyle.hpp diff --git a/ACore/src/ecflow/core/SState.cpp b/libs/core/src/ecflow/core/SState.cpp similarity index 100% rename from ACore/src/ecflow/core/SState.cpp rename to libs/core/src/ecflow/core/SState.cpp diff --git a/ACore/src/ecflow/core/SState.hpp b/libs/core/src/ecflow/core/SState.hpp similarity index 100% rename from ACore/src/ecflow/core/SState.hpp rename to libs/core/src/ecflow/core/SState.hpp diff --git a/ACore/src/ecflow/core/Serialization.hpp b/libs/core/src/ecflow/core/Serialization.hpp similarity index 100% rename from ACore/src/ecflow/core/Serialization.hpp rename to libs/core/src/ecflow/core/Serialization.hpp diff --git a/ACore/src/ecflow/core/Stl.hpp b/libs/core/src/ecflow/core/Stl.hpp similarity index 62% rename from ACore/src/ecflow/core/Stl.hpp rename to libs/core/src/ecflow/core/Stl.hpp index 7fbd18b50..efbd46d51 100644 --- a/ACore/src/ecflow/core/Stl.hpp +++ b/libs/core/src/ecflow/core/Stl.hpp @@ -12,6 +12,7 @@ #define ecflow_core_Stl_HPP #include +#include namespace ecf { /// Helper struct that will aid the deletion of Pointer from a container @@ -57,6 +58,49 @@ void AssoDeletePtrs(Container& pContainer) { std::for_each(pContainer.begin(), pContainer.end(), TAsoDeletor()); pContainer.clear(); } + +namespace algorithm { + +namespace detail { + +template +struct is_shared_pointer : std::false_type +{ +}; + +template +struct is_shared_pointer> : std::true_type +{ +}; + +} // namespace detail + +template +constexpr bool is_shared_pointer_v = detail::is_shared_pointer::value; + +template +inline auto find_by(C& container, Predicate predicate) { + return std::find_if(std::begin(container), std::end(container), predicate); +} + +template +inline auto find_by_name(C& container, std::string_view name) { + // Important: special handling to seamlessly handle containers of std::shared_ptr. + if constexpr (is_shared_pointer_v) { + return find_by(container, [&](const auto& item) { return item->name() == name; }); + } + else { + return find_by(container, [&](const auto& item) { return item.name() == name; }); + } +} + +template +inline auto find_by_number(C& container, I number) { + return find_by(container, [&](const auto& item) { return item.number() == number; }); +} + +} // namespace algorithm + } // namespace ecf #endif /* ecflow_core_Stl_HPP */ diff --git a/ACore/src/ecflow/core/Str.cpp b/libs/core/src/ecflow/core/Str.cpp similarity index 94% rename from ACore/src/ecflow/core/Str.cpp rename to libs/core/src/ecflow/core/Str.cpp index e9626e549..593022c41 100644 --- a/ACore/src/ecflow/core/Str.cpp +++ b/libs/core/src/ecflow/core/Str.cpp @@ -355,6 +355,45 @@ void Str::split_using_string_view2(std::string_view strv, std::vector Str::tokenize_quotation(const std::string& s, std::string_view quotes) { + + std::vector tokens; + + std::string levels; + + const char* current = &s[0]; + const char* start = current; + while (*current != 0) { + if (*current == ' ' && levels.empty()) { + if (start != current) { + tokens.emplace_back(start, static_cast(current - start)); + } + start = current + 1; + } + else { + if (std::any_of( + std::begin(quotes), std::end(quotes), [¤t](char quote) { return *current == quote; })) { + if (!levels.empty() && (levels.back() == *current)) { + levels.pop_back(); + } + else { + if (levels.empty()) { + start = current; + } + levels.push_back(*current); + } + } + } + ++current; + } + + if (start != current) { + tokens.emplace_back(start, static_cast(current - start)); + } + + return tokens; +} + bool Str::get_token(std::string_view str, size_t pos, std::string& token, std::string_view delims) { // Time for StringSplitter::get_token 250000 times = 1.457s wall, (1.460s user + 0.000s system = 1.460s) CPU // (100.2%) Time for Str::get_token 250000 times = 0.566s wall, (0.560s user + 0.000s system = 0.560s) diff --git a/ACore/src/ecflow/core/Str.hpp b/libs/core/src/ecflow/core/Str.hpp similarity index 98% rename from ACore/src/ecflow/core/Str.hpp rename to libs/core/src/ecflow/core/Str.hpp index b516c255d..2de926364 100644 --- a/ACore/src/ecflow/core/Str.hpp +++ b/libs/core/src/ecflow/core/Str.hpp @@ -108,6 +108,8 @@ class Str { /// This function is used to choose the fastest implementation static void split(const std::string& line, std::vector& tokens, const std::string& delimiters = " \t"); + static std::vector tokenize_quotation(const std::string& s, std::string_view quotes); + static void split_orig(const std::string& line, std::vector& tokens, const std::string& delimiters = " \t"); diff --git a/ACore/src/ecflow/core/StringSplitter.cpp b/libs/core/src/ecflow/core/StringSplitter.cpp similarity index 100% rename from ACore/src/ecflow/core/StringSplitter.cpp rename to libs/core/src/ecflow/core/StringSplitter.cpp diff --git a/ACore/src/ecflow/core/StringSplitter.hpp b/libs/core/src/ecflow/core/StringSplitter.hpp similarity index 100% rename from ACore/src/ecflow/core/StringSplitter.hpp rename to libs/core/src/ecflow/core/StringSplitter.hpp diff --git a/ACore/src/ecflow/core/TimeSeries.cpp b/libs/core/src/ecflow/core/TimeSeries.cpp similarity index 100% rename from ACore/src/ecflow/core/TimeSeries.cpp rename to libs/core/src/ecflow/core/TimeSeries.cpp diff --git a/ACore/src/ecflow/core/TimeSeries.hpp b/libs/core/src/ecflow/core/TimeSeries.hpp similarity index 100% rename from ACore/src/ecflow/core/TimeSeries.hpp rename to libs/core/src/ecflow/core/TimeSeries.hpp diff --git a/ACore/src/ecflow/core/TimeSlot.cpp b/libs/core/src/ecflow/core/TimeSlot.cpp similarity index 100% rename from ACore/src/ecflow/core/TimeSlot.cpp rename to libs/core/src/ecflow/core/TimeSlot.cpp diff --git a/ACore/src/ecflow/core/TimeSlot.hpp b/libs/core/src/ecflow/core/TimeSlot.hpp similarity index 100% rename from ACore/src/ecflow/core/TimeSlot.hpp rename to libs/core/src/ecflow/core/TimeSlot.hpp diff --git a/ACore/src/ecflow/core/TimeStamp.cpp b/libs/core/src/ecflow/core/TimeStamp.cpp similarity index 100% rename from ACore/src/ecflow/core/TimeStamp.cpp rename to libs/core/src/ecflow/core/TimeStamp.cpp diff --git a/ACore/src/ecflow/core/TimeStamp.hpp b/libs/core/src/ecflow/core/TimeStamp.hpp similarity index 100% rename from ACore/src/ecflow/core/TimeStamp.hpp rename to libs/core/src/ecflow/core/TimeStamp.hpp diff --git a/ACore/src/ecflow/core/User.cpp b/libs/core/src/ecflow/core/User.cpp similarity index 100% rename from ACore/src/ecflow/core/User.cpp rename to libs/core/src/ecflow/core/User.cpp diff --git a/ACore/src/ecflow/core/User.hpp b/libs/core/src/ecflow/core/User.hpp similarity index 100% rename from ACore/src/ecflow/core/User.hpp rename to libs/core/src/ecflow/core/User.hpp diff --git a/ACore/src/ecflow/core/Version.cpp b/libs/core/src/ecflow/core/Version.cpp similarity index 100% rename from ACore/src/ecflow/core/Version.cpp rename to libs/core/src/ecflow/core/Version.cpp diff --git a/ACore/src/ecflow/core/Version.hpp b/libs/core/src/ecflow/core/Version.hpp similarity index 100% rename from ACore/src/ecflow/core/Version.hpp rename to libs/core/src/ecflow/core/Version.hpp diff --git a/ACore/src/ecflow/core/WhiteListFile.cpp b/libs/core/src/ecflow/core/WhiteListFile.cpp similarity index 100% rename from ACore/src/ecflow/core/WhiteListFile.cpp rename to libs/core/src/ecflow/core/WhiteListFile.cpp diff --git a/ACore/src/ecflow/core/WhiteListFile.hpp b/libs/core/src/ecflow/core/WhiteListFile.hpp similarity index 100% rename from ACore/src/ecflow/core/WhiteListFile.hpp rename to libs/core/src/ecflow/core/WhiteListFile.hpp diff --git a/ACore/src/ecflow/core/cereal_boost_time.hpp b/libs/core/src/ecflow/core/cereal_boost_time.hpp similarity index 100% rename from ACore/src/ecflow/core/cereal_boost_time.hpp rename to libs/core/src/ecflow/core/cereal_boost_time.hpp diff --git a/ACore/src/ecflow/core/cereal_optional_nvp.hpp b/libs/core/src/ecflow/core/cereal_optional_nvp.hpp similarity index 100% rename from ACore/src/ecflow/core/cereal_optional_nvp.hpp rename to libs/core/src/ecflow/core/cereal_optional_nvp.hpp diff --git a/ACore/src/ecflow/core/ecflow_source_build_dir.h.in b/libs/core/src/ecflow/core/ecflow_source_build_dir.h.in similarity index 100% rename from ACore/src/ecflow/core/ecflow_source_build_dir.h.in rename to libs/core/src/ecflow/core/ecflow_source_build_dir.h.in diff --git a/ACore/src/ecflow/core/ecflow_version.h.in b/libs/core/src/ecflow/core/ecflow_version.h.in similarity index 100% rename from ACore/src/ecflow/core/ecflow_version.h.in rename to libs/core/src/ecflow/core/ecflow_version.h.in diff --git a/libs/core/src/ecflow/core/exceptions/Exceptions.hpp b/libs/core/src/ecflow/core/exceptions/Exceptions.hpp new file mode 100644 index 000000000..5719ce0d3 --- /dev/null +++ b/libs/core/src/ecflow/core/exceptions/Exceptions.hpp @@ -0,0 +1,32 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_core_exceptions_Exceptions_HPP +#define ecflow_core_exceptions_Exceptions_HPP + +#include + +namespace ecf { + +struct Exception : public std::runtime_error +{ + explicit Exception(const char* what) : std::runtime_error(what) {} + explicit Exception(const std::string& what) : std::runtime_error(what) {} +}; + +struct InvalidArgument : public Exception +{ + explicit InvalidArgument(const char* what) : Exception(what) {} + explicit InvalidArgument(const std::string& what) : Exception(what) {} +}; + +} // namespace ecf + +#endif // ecflow_core_exceptions_Exceptions_HPP diff --git a/ACore/src/ecflow/core/perf_timer.hpp b/libs/core/src/ecflow/core/perf_timer.hpp similarity index 100% rename from ACore/src/ecflow/core/perf_timer.hpp rename to libs/core/src/ecflow/core/perf_timer.hpp diff --git a/ACore/test/TestCalendar.cpp b/libs/core/test/TestCalendar.cpp similarity index 100% rename from ACore/test/TestCalendar.cpp rename to libs/core/test/TestCalendar.cpp diff --git a/ACore/test/TestCereal.cpp b/libs/core/test/TestCereal.cpp similarity index 100% rename from ACore/test/TestCereal.cpp rename to libs/core/test/TestCereal.cpp diff --git a/ACore/test/TestCerealOptionalNVP.cpp b/libs/core/test/TestCerealOptionalNVP.cpp similarity index 100% rename from ACore/test/TestCerealOptionalNVP.cpp rename to libs/core/test/TestCerealOptionalNVP.cpp diff --git a/ACore/test/TestCerealWithHierarchy.cpp b/libs/core/test/TestCerealWithHierarchy.cpp similarity index 100% rename from ACore/test/TestCerealWithHierarchy.cpp rename to libs/core/test/TestCerealWithHierarchy.cpp diff --git a/ACore/test/TestChrono.cpp b/libs/core/test/TestChrono.cpp similarity index 100% rename from ACore/test/TestChrono.cpp rename to libs/core/test/TestChrono.cpp diff --git a/ACore/test/TestClassDataMemberInit.cpp b/libs/core/test/TestClassDataMemberInit.cpp similarity index 100% rename from ACore/test/TestClassDataMemberInit.cpp rename to libs/core/test/TestClassDataMemberInit.cpp diff --git a/ACore/test/TestCommandLine.cpp b/libs/core/test/TestCommandLine.cpp similarity index 100% rename from ACore/test/TestCommandLine.cpp rename to libs/core/test/TestCommandLine.cpp diff --git a/ACore/test/TestConverter.cpp b/libs/core/test/TestConverter.cpp similarity index 100% rename from ACore/test/TestConverter.cpp rename to libs/core/test/TestConverter.cpp diff --git a/ACore/test/TestCore_main.cpp b/libs/core/test/TestCore_main.cpp similarity index 100% rename from ACore/test/TestCore_main.cpp rename to libs/core/test/TestCore_main.cpp diff --git a/ACore/test/TestExtract.cpp b/libs/core/test/TestExtract.cpp similarity index 100% rename from ACore/test/TestExtract.cpp rename to libs/core/test/TestExtract.cpp diff --git a/ACore/test/TestFile.cpp b/libs/core/test/TestFile.cpp similarity index 95% rename from ACore/test/TestFile.cpp rename to libs/core/test/TestFile.cpp index d94237330..9c47c8d4e 100644 --- a/ACore/test/TestFile.cpp +++ b/libs/core/test/TestFile.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(test_splitFileIntoLines) { // This is sanity test for splitFileIntoLines used extensively cout << "ACore:: ...test_splitFileIntoLines\n"; - std::string path = File::test_data("ACore/test/data/test_splitFileIntoLines.txt", "ACore"); + std::string path = File::test_data("libs/core/test/data/test_splitFileIntoLines.txt", "libs/core"); std::string theText = "This is a test string"; { @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(test_splitFileIntoLines) { BOOST_AUTO_TEST_CASE(test_file_tokenizer) { cout << "ACore:: ...test_file_tokenizer\n"; - std::string path = File::test_data("ACore/test/data/test_file_tokenizer.txt", "ACore"); + std::string path = File::test_data("libs/core/test/data/test_file_tokenizer.txt", "libs/core"); size_t linesWithText = 100; std::string theText = "This is a test string"; @@ -178,8 +178,8 @@ BOOST_AUTO_TEST_CASE(test_file_backwardSearch) { cout << "ACore:: ...test_file_backwardSearch\n"; std::string nodePath = "dir0/dir1/dir2/dir3/dir4/dir5"; - std::string rootPath = File::test_data("ACore/test/data", "ACore"); - std::string expected = File::test_data("ACore/test/data/", "ACore") + nodePath; + std::string rootPath = File::test_data("libs/core/test/data", "libs/core"); + std::string expected = File::test_data("libs/core/test/data/", "libs/core") + nodePath; std::string path = rootPath; std::string dir = "dir"; @@ -250,8 +250,8 @@ BOOST_AUTO_TEST_CASE(test_file_forwardSearch) { std::string dir_path = "/dir0/dir1/dir2/dir3/dir4"; std::string nodePath = dir_path + "/task"; - std::string rootPath = File::test_data("ACore/test/data", "ACore"); - std::string expected = File::test_data("ACore/test/data", "ACore") + nodePath; + std::string rootPath = File::test_data("libs/core/test/data", "libs/core"); + std::string expected = File::test_data("libs/core/test/data", "libs/core") + nodePath; std::string path = rootPath; std::string dir = "dir"; @@ -336,8 +336,8 @@ BOOST_AUTO_TEST_CASE(test_create_missing_directories) { cout << "\n"; std::string nodePath = "dir0/dir1/dir2/dir3/dir4/dir5"; - std::string rootPath = File::test_data("ACore/test/data", "ACore"); - std::string expected = File::test_data("ACore/test/data/", "ACore") + nodePath; + std::string rootPath = File::test_data("libs/core/test/data", "libs/core"); + std::string expected = File::test_data("libs/core/test/data/", "libs/core") + nodePath; std::string dir_remove = rootPath + "/dir0"; { @@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE(test_create_missing_directories) { BOOST_AUTO_TEST_CASE(test_get_last_lines_of_a_file) { cout << "ACore:: ...test_get_last_lines_of_a_file\n"; - std::string path = File::test_data("ACore/test/data/test_get_last_lines_of_a_file.txt", "ACore"); + std::string path = File::test_data("libs/core/test/data/test_get_last_lines_of_a_file.txt", "libs/core"); std::string last_100_lines; size_t no_of_lines = 100; { // create file with 100 lines 0-99 @@ -536,14 +536,14 @@ BOOST_AUTO_TEST_CASE(test_directory_traversal) { BOOST_AUTO_TEST_CASE(test_get_all_files_by_extension) { cout << "ACore:: ...test_get_all_files_by_extension\n"; { - std::string rootPath = File::test_data("ACore/test/data/badPasswdFiles", "ACore"); + std::string rootPath = File::test_data("libs/core/test/data/badPasswdFiles", "libs/core"); std::vector vec; File::find_files_with_extn(rootPath, ".passwd", vec); // for(auto& file: vec) std::cout << file << "\n"; BOOST_REQUIRE_MESSAGE(vec.size() == 6, "Expected 6 files in directory " << rootPath); } { - std::string rootPath = File::test_data("ACore/test/data/badWhiteListFiles", "ACore"); + std::string rootPath = File::test_data("libs/core/test/data/badWhiteListFiles", "libs/core"); std::vector vec; File::find_files_with_extn(rootPath, ".lists", vec); // for(auto& file: vec) std::cout << file << "\n"; diff --git a/ACore/test/TestGetUserDetails.cpp b/libs/core/test/TestGetUserDetails.cpp similarity index 100% rename from ACore/test/TestGetUserDetails.cpp rename to libs/core/test/TestGetUserDetails.cpp diff --git a/ACore/test/TestLog.cpp b/libs/core/test/TestLog.cpp similarity index 98% rename from ACore/test/TestLog.cpp rename to libs/core/test/TestLog.cpp index e2ff0d538..28a54e016 100644 --- a/ACore/test/TestLog.cpp +++ b/libs/core/test/TestLog.cpp @@ -30,10 +30,10 @@ BOOST_AUTO_TEST_SUITE(T_Log) static std::string getLogPath() { // ECFLOW-712, generate unique name for log file, To allow parallel test - std::string log_file = "ACore/test/logfile"; + std::string log_file = "libs/core/test/logfile"; log_file += Pid::getpid(); // can throw log_file += ".txt"; - return File::test_data(log_file, "ACore"); + return File::test_data(log_file, "libs/core"); } BOOST_AUTO_TEST_CASE(test_log) { @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(test_log_new_path) { fs::remove(Log::instance()->path()); // Specify a new log path. Path could be a relative path like "test/logfile.log" - std::string relative_path = File::test_data("ACore/test/logfile.log", "ACore"); + std::string relative_path = File::test_data("libs/core/test/logfile.log", "libs/core"); BOOST_REQUIRE_NO_THROW(Log::instance()->new_path(relative_path)); BOOST_CHECK_MESSAGE(!fs::exists(Log::instance()->path()), diff --git a/libs/core/test/TestMessage.cpp b/libs/core/test/TestMessage.cpp new file mode 100644 index 000000000..80fda2d55 --- /dev/null +++ b/libs/core/test/TestMessage.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include + +#include + +#include "ecflow/core/Message.hpp" + +BOOST_AUTO_TEST_SUITE(U_Core) + +BOOST_AUTO_TEST_SUITE(T_Message) + +BOOST_AUTO_TEST_CASE(test_message_can_create_from_various_arguments) { + using namespace ecf; + using namespace std::string_literals; + + BOOST_CHECK_EQUAL(Message().str(), ""s); + BOOST_CHECK_EQUAL(Message("a", ' ', "1").str(), "a 1"s); + BOOST_CHECK_EQUAL(Message("a", ' ', "1.01").str(), "a 1.01"s); + BOOST_CHECK_EQUAL(Message("a", ' ', 1).str(), "a 1"s); + BOOST_CHECK_EQUAL(Message("a", ' ', 1.01).str(), "a 1.01"s); + BOOST_CHECK_EQUAL(Message("a", ' ', true).str(), "a 1"s); + BOOST_CHECK_EQUAL(Message("a", Message("b", 'c')).str(), "abc"s); +} + +BOOST_AUTO_TEST_CASE(test_message_can_convert_to_string) { + using namespace ecf; + using namespace std::string_literals; + + std::string s = Message("a", Message("b", 'c')); + BOOST_CHECK_EQUAL(s, "abc"s); +} + +BOOST_AUTO_TEST_CASE(test_message_can_stream) { + using namespace ecf; + using namespace std::string_literals; + + std::ostringstream oss; + oss << Message("a", Message("b", 'c')); + + BOOST_CHECK_EQUAL(oss.str(), "abc"s); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/ACore/test/TestMigration.cpp b/libs/core/test/TestMigration.cpp similarity index 96% rename from ACore/test/TestMigration.cpp rename to libs/core/test/TestMigration.cpp index 906f723b5..f6c8c8502 100644 --- a/ACore/test/TestMigration.cpp +++ b/libs/core/test/TestMigration.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_SUITE(T_Migration) BOOST_AUTO_TEST_CASE(test_migration_restore_cereal) { cout << "ACore:: ...test_migration_restore_cereal\n"; - std::string file_name = File::test_data("ACore/test/data/migration/", "ACore"); + std::string file_name = File::test_data("libs/core/test/data/migration/", "libs/core"); // Note: default calendar constructor will init with current time: Hence set for comparison Calendar calendar; diff --git a/ACore/test/TestNodePath.cpp b/libs/core/test/TestNodePath.cpp similarity index 100% rename from ACore/test/TestNodePath.cpp rename to libs/core/test/TestNodePath.cpp diff --git a/ACore/test/TestPasswdFile.cpp b/libs/core/test/TestPasswdFile.cpp similarity index 93% rename from ACore/test/TestPasswdFile.cpp rename to libs/core/test/TestPasswdFile.cpp index 85d825518..ee11603fe 100644 --- a/ACore/test/TestPasswdFile.cpp +++ b/libs/core/test/TestPasswdFile.cpp @@ -78,7 +78,7 @@ void test_passwd_files(const std::string& directory, bool pass) { BOOST_AUTO_TEST_CASE(test_parsing_for_good_passwd_files) { cout << "ACore:: ...test_parsing_for_good_passwd_files\n"; - std::string path = File::test_data("ACore/test/data/goodPasswdFiles", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodPasswdFiles", "libs/core"); // All the files in this directory are expected to pass test_passwd_files(path, true); @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_parsing_for_good_passwd_files) { BOOST_AUTO_TEST_CASE(test_parsing_for_bad_passwd_files) { cout << "ACore:: ...test_parsing_for_bad_passwd_files\n"; - std::string path = File::test_data("ACore/test/data/badPasswdFiles", "ACore"); + std::string path = File::test_data("libs/core/test/data/badPasswdFiles", "libs/core"); // All the files in this directory are expected to fail test_passwd_files(path, false); @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(test_parsing_for_bad_passwd_files) { BOOST_AUTO_TEST_CASE(test_passwd_empty_file) { cout << "ACore:: ...test_passwd_empty_file\n"; - std::string path = File::test_data("ACore/test/data/goodPasswdFiles/empty.passwd", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodPasswdFiles/empty.passwd", "libs/core"); PasswdFile theFile; std::string errorMsg; @@ -114,7 +114,7 @@ BOOST_AUTO_TEST_CASE(test_passwd_empty_file) { BOOST_AUTO_TEST_CASE(test_passwd) { cout << "ACore:: ...test_passwd\n"; - std::string path = File::test_data("ACore/test/data/goodPasswdFiles/ecf.passwd", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodPasswdFiles/ecf.passwd", "libs/core"); PasswdFile theFile; std::string errorMsg; diff --git a/ACore/test/TestPasswordEncryption.cpp b/libs/core/test/TestPasswordEncryption.cpp similarity index 100% rename from ACore/test/TestPasswordEncryption.cpp rename to libs/core/test/TestPasswordEncryption.cpp diff --git a/ACore/test/TestPerfTimer.cpp b/libs/core/test/TestPerfTimer.cpp similarity index 100% rename from ACore/test/TestPerfTimer.cpp rename to libs/core/test/TestPerfTimer.cpp diff --git a/ACore/test/TestRealCalendar.cpp b/libs/core/test/TestRealCalendar.cpp similarity index 100% rename from ACore/test/TestRealCalendar.cpp rename to libs/core/test/TestRealCalendar.cpp diff --git a/ACore/test/TestSanitizerAS.cpp b/libs/core/test/TestSanitizerAS.cpp similarity index 100% rename from ACore/test/TestSanitizerAS.cpp rename to libs/core/test/TestSanitizerAS.cpp diff --git a/ACore/test/TestSanitizerUB.cpp b/libs/core/test/TestSanitizerUB.cpp similarity index 100% rename from ACore/test/TestSanitizerUB.cpp rename to libs/core/test/TestSanitizerUB.cpp diff --git a/ACore/test/TestSerialisation.cpp b/libs/core/test/TestSerialisation.cpp similarity index 100% rename from ACore/test/TestSerialisation.cpp rename to libs/core/test/TestSerialisation.cpp diff --git a/ACore/test/TestSerialisation.hpp b/libs/core/test/TestSerialisation.hpp similarity index 100% rename from ACore/test/TestSerialisation.hpp rename to libs/core/test/TestSerialisation.hpp diff --git a/ACore/test/TestStr.cpp b/libs/core/test/TestStr.cpp similarity index 100% rename from ACore/test/TestStr.cpp rename to libs/core/test/TestStr.cpp diff --git a/ACore/test/TestStringSplitPerf.cpp b/libs/core/test/TestStringSplitPerf.cpp similarity index 100% rename from ACore/test/TestStringSplitPerf.cpp rename to libs/core/test/TestStringSplitPerf.cpp diff --git a/ACore/test/TestStringSplitter.cpp b/libs/core/test/TestStringSplitter.cpp similarity index 100% rename from ACore/test/TestStringSplitter.cpp rename to libs/core/test/TestStringSplitter.cpp diff --git a/ACore/test/TestTimeSeries.cpp b/libs/core/test/TestTimeSeries.cpp similarity index 100% rename from ACore/test/TestTimeSeries.cpp rename to libs/core/test/TestTimeSeries.cpp diff --git a/ACore/test/TestTimeSlot.cpp b/libs/core/test/TestTimeSlot.cpp similarity index 100% rename from ACore/test/TestTimeSlot.cpp rename to libs/core/test/TestTimeSlot.cpp diff --git a/ACore/test/TestVersion.cpp b/libs/core/test/TestVersion.cpp similarity index 100% rename from ACore/test/TestVersion.cpp rename to libs/core/test/TestVersion.cpp diff --git a/ACore/test/TestVersioning.cpp b/libs/core/test/TestVersioning.cpp similarity index 100% rename from ACore/test/TestVersioning.cpp rename to libs/core/test/TestVersioning.cpp diff --git a/ACore/test/TestVersioning.hpp b/libs/core/test/TestVersioning.hpp similarity index 100% rename from ACore/test/TestVersioning.hpp rename to libs/core/test/TestVersioning.hpp diff --git a/ACore/test/TestWhiteListFile.cpp b/libs/core/test/TestWhiteListFile.cpp similarity index 97% rename from ACore/test/TestWhiteListFile.cpp rename to libs/core/test/TestWhiteListFile.cpp index 78ef79cb0..a4f12a589 100644 --- a/ACore/test/TestWhiteListFile.cpp +++ b/libs/core/test/TestWhiteListFile.cpp @@ -76,7 +76,7 @@ void test_white_list_files(const std::string& directory, bool pass) { BOOST_AUTO_TEST_CASE(test_parsing_for_good_white_list_files) { cout << "ACore:: ...test_parsing_for_good_white_list_files\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles", "libs/core"); // All the files in this directory are expected to pass test_white_list_files(path, true); @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(test_parsing_for_good_white_list_files) { BOOST_AUTO_TEST_CASE(test_parsing_for_bad_white_list_files) { cout << "ACore:: ...test_parsing_for_bad_white_list_files\n"; - std::string path = File::test_data("ACore/test/data/badWhiteListFiles", "ACore"); + std::string path = File::test_data("libs/core/test/data/badWhiteListFiles", "libs/core"); // All the files in this directory are expected to fail test_white_list_files(path, false); @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(test_white_list_default) { BOOST_AUTO_TEST_CASE(test_white_list_empty_file) { cout << "ACore:: ...test_white_list_empty_file\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/empty.lists", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles/empty.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(test_white_list_empty_file) { BOOST_AUTO_TEST_CASE(test_white_list) { cout << "ACore:: ...test_white_list\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/good1.lists", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles/good1.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(test_white_list) { BOOST_AUTO_TEST_CASE(test_white_list_all_users_have_read_access) { cout << "ACore:: ...test_white_list_all_users_have_read_access\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/all_read_access.lists", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles/all_read_access.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(test_white_list_all_users_have_read_access) { BOOST_AUTO_TEST_CASE(test_white_list_all_users_have_write_access) { cout << "ACore:: ...test_white_list_all_users_have_write_access\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/all_write_access.lists", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles/all_write_access.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -378,7 +378,8 @@ BOOST_AUTO_TEST_CASE(test_white_list_all_users_have_write_access) { BOOST_AUTO_TEST_CASE(test_white_list_all_path_users_have_write_access) { cout << "ACore:: ...test_white_list_all_path_users_have_write_access\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/all_path_write_access.lists", "ACore"); + std::string path = + File::test_data("libs/core/test/data/goodWhiteListFiles/all_path_write_access.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -413,7 +414,8 @@ BOOST_AUTO_TEST_CASE(test_white_list_all_path_users_have_write_access) { BOOST_AUTO_TEST_CASE(test_white_list_all_path_users_have_read_access) { cout << "ACore:: ...test_white_list_all_path_users_have_read_access\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/all_path_read_access.lists", "ACore"); + std::string path = + File::test_data("libs/core/test/data/goodWhiteListFiles/all_path_read_access.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; @@ -448,7 +450,7 @@ BOOST_AUTO_TEST_CASE(test_white_list_all_path_users_have_read_access) { BOOST_AUTO_TEST_CASE(test_white_list_path_access_list) { cout << "ACore:: ...test_white_list_path_access_list\n"; - std::string path = File::test_data("ACore/test/data/goodWhiteListFiles/path_access.lists", "ACore"); + std::string path = File::test_data("libs/core/test/data/goodWhiteListFiles/path_access.lists", "libs/core"); WhiteListFile theFile; std::string errorMsg; diff --git a/ACore/test/data/badPasswdFiles/ecf.passwd b/libs/core/test/data/badPasswdFiles/ecf.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf.passwd rename to libs/core/test/data/badPasswdFiles/ecf.passwd diff --git a/ACore/test/data/badPasswdFiles/ecf1.passwd b/libs/core/test/data/badPasswdFiles/ecf1.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf1.passwd rename to libs/core/test/data/badPasswdFiles/ecf1.passwd diff --git a/ACore/test/data/badPasswdFiles/ecf2.passwd b/libs/core/test/data/badPasswdFiles/ecf2.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf2.passwd rename to libs/core/test/data/badPasswdFiles/ecf2.passwd diff --git a/ACore/test/data/badPasswdFiles/ecf3.passwd b/libs/core/test/data/badPasswdFiles/ecf3.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf3.passwd rename to libs/core/test/data/badPasswdFiles/ecf3.passwd diff --git a/ACore/test/data/badPasswdFiles/ecf4.passwd b/libs/core/test/data/badPasswdFiles/ecf4.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf4.passwd rename to libs/core/test/data/badPasswdFiles/ecf4.passwd diff --git a/ACore/test/data/badPasswdFiles/ecf5.passwd b/libs/core/test/data/badPasswdFiles/ecf5.passwd similarity index 100% rename from ACore/test/data/badPasswdFiles/ecf5.passwd rename to libs/core/test/data/badPasswdFiles/ecf5.passwd diff --git a/ACore/test/data/badWhiteListFiles/bad2.lists b/libs/core/test/data/badWhiteListFiles/bad2.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/bad2.lists rename to libs/core/test/data/badWhiteListFiles/bad2.lists diff --git a/ACore/test/data/badWhiteListFiles/bad3.lists b/libs/core/test/data/badWhiteListFiles/bad3.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/bad3.lists rename to libs/core/test/data/badWhiteListFiles/bad3.lists diff --git a/ACore/test/data/badWhiteListFiles/bad5.lists b/libs/core/test/data/badWhiteListFiles/bad5.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/bad5.lists rename to libs/core/test/data/badWhiteListFiles/bad5.lists diff --git a/ACore/test/data/badWhiteListFiles/bad_paths.lists b/libs/core/test/data/badWhiteListFiles/bad_paths.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/bad_paths.lists rename to libs/core/test/data/badWhiteListFiles/bad_paths.lists diff --git a/ACore/test/data/badWhiteListFiles/badsms.lists b/libs/core/test/data/badWhiteListFiles/badsms.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/badsms.lists rename to libs/core/test/data/badWhiteListFiles/badsms.lists diff --git a/ACore/test/data/badWhiteListFiles/multipleWriteUsers.lists b/libs/core/test/data/badWhiteListFiles/multipleWriteUsers.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/multipleWriteUsers.lists rename to libs/core/test/data/badWhiteListFiles/multipleWriteUsers.lists diff --git a/ACore/test/data/badWhiteListFiles/mutipleReadUser.lists b/libs/core/test/data/badWhiteListFiles/mutipleReadUser.lists similarity index 100% rename from ACore/test/data/badWhiteListFiles/mutipleReadUser.lists rename to libs/core/test/data/badWhiteListFiles/mutipleReadUser.lists diff --git a/ACore/test/data/goodPasswdFiles/ecf.passwd b/libs/core/test/data/goodPasswdFiles/ecf.passwd similarity index 100% rename from ACore/test/data/goodPasswdFiles/ecf.passwd rename to libs/core/test/data/goodPasswdFiles/ecf.passwd diff --git a/ACore/test/data/goodPasswdFiles/empty.passwd b/libs/core/test/data/goodPasswdFiles/empty.passwd similarity index 100% rename from ACore/test/data/goodPasswdFiles/empty.passwd rename to libs/core/test/data/goodPasswdFiles/empty.passwd diff --git a/ACore/test/data/goodWhiteListFiles/all_path_read_access.lists b/libs/core/test/data/goodWhiteListFiles/all_path_read_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/all_path_read_access.lists rename to libs/core/test/data/goodWhiteListFiles/all_path_read_access.lists diff --git a/ACore/test/data/goodWhiteListFiles/all_path_write_access.lists b/libs/core/test/data/goodWhiteListFiles/all_path_write_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/all_path_write_access.lists rename to libs/core/test/data/goodWhiteListFiles/all_path_write_access.lists diff --git a/ACore/test/data/goodWhiteListFiles/all_read_access.lists b/libs/core/test/data/goodWhiteListFiles/all_read_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/all_read_access.lists rename to libs/core/test/data/goodWhiteListFiles/all_read_access.lists diff --git a/ACore/test/data/goodWhiteListFiles/all_write_access.lists b/libs/core/test/data/goodWhiteListFiles/all_write_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/all_write_access.lists rename to libs/core/test/data/goodWhiteListFiles/all_write_access.lists diff --git a/ACore/test/data/goodWhiteListFiles/empty.lists b/libs/core/test/data/goodWhiteListFiles/empty.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/empty.lists rename to libs/core/test/data/goodWhiteListFiles/empty.lists diff --git a/ACore/test/data/goodWhiteListFiles/good1.lists b/libs/core/test/data/goodWhiteListFiles/good1.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/good1.lists rename to libs/core/test/data/goodWhiteListFiles/good1.lists diff --git a/ACore/test/data/goodWhiteListFiles/goodsms.lists b/libs/core/test/data/goodWhiteListFiles/goodsms.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/goodsms.lists rename to libs/core/test/data/goodWhiteListFiles/goodsms.lists diff --git a/ACore/test/data/goodWhiteListFiles/long_path_access.lists b/libs/core/test/data/goodWhiteListFiles/long_path_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/long_path_access.lists rename to libs/core/test/data/goodWhiteListFiles/long_path_access.lists diff --git a/ACore/test/data/goodWhiteListFiles/path_access.lists b/libs/core/test/data/goodWhiteListFiles/path_access.lists similarity index 100% rename from ACore/test/data/goodWhiteListFiles/path_access.lists rename to libs/core/test/data/goodWhiteListFiles/path_access.lists diff --git a/ACore/test/data/migration/calendar_1_2_2_ b/libs/core/test/data/migration/calendar_1_2_2_ similarity index 100% rename from ACore/test/data/migration/calendar_1_2_2_ rename to libs/core/test/data/migration/calendar_1_2_2_ diff --git a/ACore/test/data/migration/dstate_1_2_2_ b/libs/core/test/data/migration/dstate_1_2_2_ similarity index 100% rename from ACore/test/data/migration/dstate_1_2_2_ rename to libs/core/test/data/migration/dstate_1_2_2_ diff --git a/ACore/test/data/migration/nstate_1_2_2_ b/libs/core/test/data/migration/nstate_1_2_2_ similarity index 100% rename from ACore/test/data/migration/nstate_1_2_2_ rename to libs/core/test/data/migration/nstate_1_2_2_ diff --git a/ACore/test/data/migration/timeseries_1_2_2_1010 b/libs/core/test/data/migration/timeseries_1_2_2_1010 similarity index 100% rename from ACore/test/data/migration/timeseries_1_2_2_1010 rename to libs/core/test/data/migration/timeseries_1_2_2_1010 diff --git a/ACore/test/data/migration/timeseries_default_constructor_1_2_2_ b/libs/core/test/data/migration/timeseries_default_constructor_1_2_2_ similarity index 100% rename from ACore/test/data/migration/timeseries_default_constructor_1_2_2_ rename to libs/core/test/data/migration/timeseries_default_constructor_1_2_2_ diff --git a/ACore/test/data/migration/timeslot_1_2_2_11 b/libs/core/test/data/migration/timeslot_1_2_2_11 similarity index 100% rename from ACore/test/data/migration/timeslot_1_2_2_11 rename to libs/core/test/data/migration/timeslot_1_2_2_11 diff --git a/ACore/test/data/migration/timeslot_1_2_2_9959 b/libs/core/test/data/migration/timeslot_1_2_2_9959 similarity index 100% rename from ACore/test/data/migration/timeslot_1_2_2_9959 rename to libs/core/test/data/migration/timeslot_1_2_2_9959 diff --git a/ACore/test/data/migration/timeslot_default_constructor_1_2_2_ b/libs/core/test/data/migration/timeslot_default_constructor_1_2_2_ similarity index 100% rename from ACore/test/data/migration/timeslot_default_constructor_1_2_2_ rename to libs/core/test/data/migration/timeslot_default_constructor_1_2_2_ diff --git a/libs/node/CMakeLists.txt b/libs/node/CMakeLists.txt new file mode 100644 index 000000000..ccd2488d2 --- /dev/null +++ b/libs/node/CMakeLists.txt @@ -0,0 +1,224 @@ +# +# Copyright 2009- ECMWF. +# +# This software is licensed under the terms of the Apache Licence version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. +# + +set(test_srcs + # Headers + test/MyDefsFixture.hpp + # Sources + test/TestAdd.cpp + test/TestAlias.cpp + test/TestAssignmentOperator.cpp + test/TestChangeMgrSingleton.cpp + test/TestClientSuiteMgr.cpp + test/TestCopyConstructor.cpp + test/TestDefStatus.cpp + test/TestDefs.cpp + test/TestEcfFile.cpp + test/TestEcfFileLocator.cpp + test/TestEnviromentSubstitution.cpp + test/TestExprParser.cpp + test/TestExprRepeatDateArithmetic.cpp + test/TestExprRepeatDateListArithmetic.cpp + test/TestFindAbsNodePath.cpp + test/TestFlag.cpp + test/TestHistoryParser.cpp + test/TestInLimit.cpp + test/TestJobCreator.cpp + test/TestJobProfiler.cpp + test/TestLimit.cpp + test/TestMigration.cpp + test/TestMissNextTimeSlot.cpp + test/TestMovePeer.cpp + test/TestNodeBeginRequeue.cpp + test/TestNodeState.cpp + test/TestNode_main.cpp # test entry point + test/TestOrder.cpp + test/TestPersistence.cpp + test/TestPreProcessing.cpp + test/TestRepeatWithTimeDependencies.cpp + test/TestReplace.cpp + test/TestSetState.cpp + test/TestSpecificIssues.cpp + test/TestSystem.cpp + test/TestTaskScriptGenerator.cpp + test/TestTimeDependencies.cpp + test/TestVariableGeneration.cpp + test/TestVariableInheritance.cpp + test/TestVariableSubstitution.cpp + test/TestVariableSubstitutionDefs.cpp + test/TestZombies.cpp +) + +ecbuild_add_test( + TARGET + u_node + LABELS + unit + nightly + SOURCES + ${test_srcs} + LIBS + test_support + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + TEST_DEPENDS + u_attributes +) +target_clangformat(u_node + CONDITION ENABLE_TESTS) + + +set(test_srcs + # Headers + test/parser/PersistHelper.hpp + test/parser/TemporaryFile.hpp + # Sources + test/parser/PersistHelper.cpp + test/parser/TemporaryFile.cpp + test/parser/TestAutoAddExterns.cpp + test/parser/TestAvisoAttr.cpp + test/parser/TestDefsStructurePersistAndReload.cpp + test/parser/TestMementoPersistAndReload.cpp + test/parser/TestMigration.cpp + test/parser/TestMirrorAttr.cpp + test/parser/TestParser.cpp + test/parser/TestParser_main.cpp # test entry point + test/parser/TestVariableParsing.cpp +) +ecbuild_add_test( + TARGET + u_parser + LABELS + unit + nightly + SOURCES + ${test_srcs} + INCLUDES + test + test/parser + LIBS + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + TEST_DEPENDS + u_node +) +target_clangformat(u_parser + CONDITION ENABLE_TESTS +) + +if (ENABLE_ALL_TESTS) + set(test_srcs + test/TestSingleExprParse.cpp + test/TestSingleExprParse_main.cpp # test entry point + ) + + ecbuild_add_test( + TARGET + u_node_single + LABELS + unit + nightly + SOURCES + ${test_srcs} + LIBS + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + TEST_DEPENDS + u_anattr + ) + target_clangformat(u_node_single + CONDITION ENABLE_TESTS + ) + + + set(test_srcs + # Headers + test/parser/PersistHelper.hpp + test/parser/TemporaryFile.hpp + # Sources + test/parser/PersistHelper.cpp + test/parser/TemporaryFile.cpp + test/parser/TestParserPerformance_main.cpp # test entry point + test/parser/TestSingleDefsFile.cpp + ) + + ecbuild_add_test( + TARGET + p_parser + LABELS + performance + nightly + SOURCES + ${test_srcs} + LIBS + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + Boost::timer + ) + target_clangformat(p_parser + CONDITION ENABLE_TESTS + ) + + + set(test_srcs + # Headers + test/parser/PersistHelper.hpp + test/parser/TemporaryFile.hpp + # Sources + test/parser/ParseTimer.cpp + test/parser/PersistHelper.cpp + test/parser/TemporaryFile.cpp + ) + + # The following is not technically a test (as it makes no checks), + # but a tool to measure the time it takes to parse 'mega.def' file + ecbuild_add_test( + TARGET + p_parser_timer + LABELS + performance + nightly + ARGS + ${CMAKE_CURRENT_SOURCE_DIR}/test/parser/data/single_defs/mega.def + SOURCES + ${test_srcs} + LIBS + ecflow_all + Boost::boost # Boost header-only libraries must be available + Boost::timer + ) + target_clangformat(p_parser_timer + CONDITION ENABLE_TESTS + ) + + # The following is not technically a test (as it makes no checks), + # but a tool to parse 'mega.def' file + set(test_srcs + test/parser/ParseOnly.cpp + ) + ecbuild_add_test( + TARGET + p_parser_only + LABELS + performance + nightly + ARGS + ${CMAKE_CURRENT_SOURCE_DIR}/test/parser/data/single_defs/mega.def + SOURCES + ${test_srcs} + LIBS + ecflow_all + Boost::boost # Boost header-only libraries must be available (namely unit_test_framework) + ) + target_clangformat(p_parser_only + CONDITION ENABLE_TESTS + ) + +endif() diff --git a/ANode/src/ecflow/node/AbstractObserver.hpp b/libs/node/src/ecflow/node/AbstractObserver.hpp similarity index 100% rename from ANode/src/ecflow/node/AbstractObserver.hpp rename to libs/node/src/ecflow/node/AbstractObserver.hpp diff --git a/ANode/src/ecflow/node/Alias.cpp b/libs/node/src/ecflow/node/Alias.cpp similarity index 100% rename from ANode/src/ecflow/node/Alias.cpp rename to libs/node/src/ecflow/node/Alias.cpp diff --git a/ANode/src/ecflow/node/Alias.hpp b/libs/node/src/ecflow/node/Alias.hpp similarity index 100% rename from ANode/src/ecflow/node/Alias.hpp rename to libs/node/src/ecflow/node/Alias.hpp diff --git a/ANode/src/ecflow/node/Aspect.hpp b/libs/node/src/ecflow/node/Aspect.hpp similarity index 97% rename from ANode/src/ecflow/node/Aspect.hpp rename to libs/node/src/ecflow/node/Aspect.hpp index 7a1e64f70..ffcbd7f91 100644 --- a/ANode/src/ecflow/node/Aspect.hpp +++ b/libs/node/src/ecflow/node/Aspect.hpp @@ -53,7 +53,9 @@ class Aspect { ALIAS_NUMBER, QUEUE, QUEUE_INDEX, - GENERIC + GENERIC, + AVISO, + MIRROR }; // Disable default construction diff --git a/ANode/src/ecflow/node/Attr.cpp b/libs/node/src/ecflow/node/Attr.cpp similarity index 100% rename from ANode/src/ecflow/node/Attr.cpp rename to libs/node/src/ecflow/node/Attr.cpp diff --git a/ANode/src/ecflow/node/Attr.hpp b/libs/node/src/ecflow/node/Attr.hpp similarity index 100% rename from ANode/src/ecflow/node/Attr.hpp rename to libs/node/src/ecflow/node/Attr.hpp diff --git a/ANode/src/ecflow/node/AutoRestoreAttr.cpp b/libs/node/src/ecflow/node/AutoRestoreAttr.cpp similarity index 100% rename from ANode/src/ecflow/node/AutoRestoreAttr.cpp rename to libs/node/src/ecflow/node/AutoRestoreAttr.cpp diff --git a/ANode/src/ecflow/node/AutoRestoreAttr.hpp b/libs/node/src/ecflow/node/AutoRestoreAttr.hpp similarity index 100% rename from ANode/src/ecflow/node/AutoRestoreAttr.hpp rename to libs/node/src/ecflow/node/AutoRestoreAttr.hpp diff --git a/libs/node/src/ecflow/node/AvisoAttr.cpp b/libs/node/src/ecflow/node/AvisoAttr.cpp new file mode 100644 index 000000000..677d732bc --- /dev/null +++ b/libs/node/src/ecflow/node/AvisoAttr.cpp @@ -0,0 +1,249 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "ecflow/node/AvisoAttr.hpp" + +#include + +#include "ecflow/core/Ecf.hpp" +#include "ecflow/core/Message.hpp" +#include "ecflow/core/Overload.hpp" +#include "ecflow/core/exceptions/Exceptions.hpp" +#include "ecflow/node/Node.hpp" +#include "ecflow/node/Operations.hpp" + +namespace ecf { + +bool AvisoAttr::is_valid_name(const std::string& name) { + return ecf::Str::valid_name(name); +} + +AvisoAttr::AvisoAttr(Node* parent, + name_t name, + listener_t listener, + url_t url, + schema_t schema, + polling_t polling, + revision_t revision, + auth_t auth, + reason_t reason) + : parent_{parent}, + parent_path_{parent ? parent->absNodePath() : ""}, + name_{std::move(name)}, + listener_{std::move(listener)}, + url_{std::move(url)}, + schema_{std::move(schema)}, + polling_{std::move(polling)}, + auth_{std::move(auth)}, + reason_{std::move(reason)}, + revision_{revision}, + controller_{nullptr} { + if (!ecf::Str::valid_name(name_)) { + throw ecf::InvalidArgument(ecf::Message("Invalid AvisoAttr name :", name_)); + } +} + +AvisoAttr AvisoAttr::make_detached() const { + AvisoAttr detached = *this; + detached.parent_ = nullptr; + detached.controller_ = nullptr; + return detached; +} + +void AvisoAttr::set_listener(std::string_view listener) { + state_change_no_ = Ecf::incr_state_change_no(); + + listener_ = listener; +} + +void AvisoAttr::set_revision(revision_t revision) { + state_change_no_ = Ecf::incr_state_change_no(); + + revision_ = revision; +} + +std::string AvisoAttr::path() const { + std::string path = parent_path_; + path += ':'; + path += name_; + return path; +} + +bool AvisoAttr::why(std::string& theReasonWhy) const { + if (isFree()) { + return false; + } + + theReasonWhy += ecf::Message(" is Aviso dependent (", listener_, "), but no notification received"); + return true; +} + +void AvisoAttr::reset() { + state_change_no_ = Ecf::incr_state_change_no(); + + if (parent_->state() == NState::QUEUED) { + start(); + } +} + +bool AvisoAttr::isFree() const { + SLOG(D, "AvisoAttr: check Aviso attribute (name: " << name_ << ", listener: " << listener_ << ") is free"); + + if (controller_ == nullptr) { + return false; + } + + // Task associated with Attribute is free when any notification is found + auto notifications = controller_->get_notifications(this->path()); + + if (notifications.empty()) { + // No notifications, nothing to do -- task continues to wait + return false; + } + + // Notifications found -- task can continue + + // (a) get the latest revision + auto& back = notifications.back(); + + state_change_no_ = Ecf::incr_state_change_no(); + + // (b) update the revision, in the listener configuration + auto is_free = std::visit( + ecf::overload{ + [this](const ecf::service::aviso::NotificationPackage& response) { + SLOG(D, "AvisoAttr::isFree: " << this->path() << " updated revision to " << this->revision_); + this->revision_ = response.configuration.revision(); + parent_->flag().clear(Flag::REMOTE_ERROR); + parent_->flag().set_state_change_no(state_change_no_); + reason_ = ""; + return true; + }, + [this](const ecf::service::aviso::AvisoNoMatch& response) { + parent_->flag().clear(Flag::REMOTE_ERROR); + parent_->flag().set_state_change_no(state_change_no_); + reason_ = ""; + return false; + }, + [this](const ecf::service::aviso::AvisoError& response) { + parent_->flag().set(Flag::REMOTE_ERROR); + parent_->flag().set_state_change_no(state_change_no_); + reason_ = response.reason(); + return false; + }}, + back); + + ecf::visit_parents(*parent_, [n = this->state_change_no_](Node& node) { node.set_state_change_no(n); }); + + return is_free; +} + +void AvisoAttr::start() const { + LOG(Log::DBG, Message("AvisoAttr: subscribe Aviso attribute (name: ", name_, ", listener: ", listener_, ")")); + + // Path -- the unique identifier of the Aviso listener + std::string aviso_path = path(); + + // Listener -- the configuration for the Aviso listener + auto aviso_listener = listener_; + aviso_listener = aviso_listener.substr(1, aviso_listener.size() - 2); + + // URL -- the URL for the Aviso server + std::string aviso_url = url_; + parent_->variableSubstitution(aviso_url); + if (aviso_url.empty()) { + throw std::runtime_error("AvisoAttr: invalid Aviso URL detected for " + aviso_path); + } + + // Schema -- the path to the Schema used to interpret the Aviso notifications + std::string aviso_schema = schema_; + parent_->variableSubstitution(aviso_schema); + + std::string aviso_polling = polling_; + parent_->variableSubstitution(aviso_polling); + if (aviso_polling.empty()) { + throw std::runtime_error("AvisoAttr: invalid Aviso polling interval detected for " + aviso_path); + } + auto polling = boost::lexical_cast(aviso_polling); + + std::string aviso_auth = auth_; + parent_->variableSubstitution(aviso_auth); + + start_controller(aviso_path, aviso_listener, aviso_url, aviso_schema, polling, aviso_auth); +} + +void AvisoAttr::start_controller(const std::string& aviso_path, + const std::string& aviso_listener, + const std::string& aviso_url, + const std::string& aviso_schema, + std::uint32_t polling, + const std::string& aviso_auth) const { + + if (!controller_) { + // Controller -- start up the Aviso controller, and subscribe the Aviso listener + controller_ = std::make_shared(); + controller_->subscribe(ecf::service::aviso::AvisoSubscribe{ + aviso_path, aviso_listener, aviso_url, aviso_schema, polling, revision_, aviso_auth}); + // Controller -- effectively start the Aviso listener + // n.b. this must be done after subscribing in the controller, so that the polling interval is set + controller_->start(); + } +} + +void AvisoAttr::stop_controller(const std::string& aviso_path) const { + if (controller_ != nullptr) { + SLOG(D, "AvisoAttr: finishing polling for Aviso attribute (" << parent_path_ << ":" << name_ << ")"); + + controller_->subscribe(ecf::service::aviso::AvisoUnsubscribe{aviso_path}); + + // Controller -- shutdown up the Aviso controller + controller_->stop(); + controller_ = nullptr; + } +} + +void AvisoAttr::finish() const { + using namespace ecf; + + std::string aviso_path = path(); + stop_controller(aviso_path); +} + +bool operator==(const AvisoAttr& lhs, const AvisoAttr& rhs) { + return lhs.name() == rhs.name() && lhs.listener() == rhs.listener() && lhs.url() == rhs.url() && + lhs.schema() == rhs.schema() && lhs.polling() == rhs.polling() && lhs.revision() == rhs.revision() && + lhs.auth() == rhs.auth() && lhs.reason() == rhs.reason(); +} + +std::string to_python_string(const AvisoAttr& aviso) { + std::string s; + s += "AvisoAttr("; + s += "name="; + s += aviso.name(); + s += ", listener="; + s += aviso.listener(); + s += ", url="; + s += aviso.url(); + s += ", schema="; + s += aviso.schema(); + s += ", polling="; + s += aviso.polling(); + s += ", revision="; + s += aviso.revision(); + s += ", auth="; + s += aviso.auth(); + s += ", reason="; + s += aviso.reason(); + s += ")"; + return s; +} + +} // namespace ecf diff --git a/libs/node/src/ecflow/node/AvisoAttr.hpp b/libs/node/src/ecflow/node/AvisoAttr.hpp new file mode 100644 index 000000000..4c8e33245 --- /dev/null +++ b/libs/node/src/ecflow/node/AvisoAttr.hpp @@ -0,0 +1,159 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_node_AvisoAttr_HPP +#define ecflow_node_AvisoAttr_HPP + +#include +#include +#include + +#include "ecflow/core/Log.hpp" +#include "ecflow/core/Str.hpp" +#include "ecflow/service/aviso/AvisoService.hpp" + +namespace cereal { +class access; +} + +class Node; + +namespace ecf { + +/// +/// \brief AvisoAttr represents an attribute, attached to a \ref Node. +/// +/// The Aviso attribute effectively acts as a trigger for the Node, granting +/// the Node to be (re)queued as soon as a related notification is received. +/// +/// \see https://github.com/ecmwf/aviso +/// + +class AvisoAttr { +public: + using path_t = std::string; + using name_t = std::string; + using listener_t = std::string; + using url_t = std::string; + using schema_t = std::string; + using polling_t = std::string; + using revision_t = std::uint64_t; + using auth_t = std::string; + using reason_t = std::string; + + using controller_t = ecf::service::aviso::AvisoController; + using controller_ptr_t = std::shared_ptr; + + static constexpr const char* default_url = "%ECF_AVISO_URL%"; + static constexpr const char* default_schema = "%ECF_AVISO_SCHEMA%"; + static constexpr const char* default_polling = "%ECF_AVISO_POLLING%"; + static constexpr const char* default_auth = "%ECF_AVISO_AUTH%"; + + static bool is_valid_name(const std::string& name); + + /** + * Creates a(n invalid) Aviso + * + * Note: this is required by Cereal serialization + * Cereal invokes the default ctor to create the object and only then proceeds to member-wise serialization. + */ + AvisoAttr() = default; + AvisoAttr(Node* parent, + name_t name, + listener_t handle, + url_t url, + schema_t schema, + polling_t polling, + revision_t revision, + auth_t auth, + reason_t reason); + AvisoAttr(const AvisoAttr& rhs) = default; + + AvisoAttr& operator=(const AvisoAttr& rhs) = default; + + [[nodiscard]] AvisoAttr make_detached() const; + + [[nodiscard]] inline Node* parent() const { return parent_; } + [[nodiscard]] inline const std::string& name() const { return name_; } + [[nodiscard]] inline const std::string& listener() const { return listener_; } + [[nodiscard]] inline const std::string& url() const { return url_; } + [[nodiscard]] inline const std::string& schema() const { return schema_; } + [[nodiscard]] inline polling_t polling() const { return polling_; } + [[nodiscard]] inline revision_t revision() const { return revision_; } + [[nodiscard]] inline const std::string& auth() const { return auth_; } + [[nodiscard]] inline const std::string& reason() const { return reason_; } + [[nodiscard]] path_t path() const; + + void set_listener(std::string_view listener); + void set_revision(revision_t revision); + + unsigned int state_change_no() const { return state_change_no_; } + + bool why(std::string& theReasonWhy) const; + + void reset(); + + [[nodiscard]] bool isFree() const; + + void start() const; + void finish() const; + + template + friend void serialize(Archive& ar, AvisoAttr& aviso, std::uint32_t version); + +private: + void start_controller(const std::string& aviso_path, + const std::string& aviso_listener, + const std::string& aviso_url, + const std::string& aviso_schema, + std::uint32_t polling, + const std::string& aviso_auth) const; + void stop_controller(const std::string& aviso_path) const; + + Node* parent_{nullptr}; // only ever used on the server side, to access parent Node variables + path_t parent_path_; + name_t name_; + listener_t listener_; + url_t url_; + schema_t schema_; + polling_t polling_; + + auth_t auth_; + mutable reason_t reason_{}; + + // The following are mutable as they are modified by the const method isFree() + mutable revision_t revision_; + mutable unsigned int state_change_no_{0}; // *not* persisted, only used on server side + + // The controller is only instanciated between start() and finish() calls + // This allows the AvisoAttr have a copy-ctor and assignment operator + mutable controller_ptr_t controller_; +}; + +bool operator==(const AvisoAttr& lhs, const AvisoAttr& rhs); + +std::string to_python_string(const AvisoAttr& aviso); + +template +void serialize(Archive& ar, AvisoAttr& aviso, [[maybe_unused]] std::uint32_t version) { + ar & aviso.parent_path_; + ar & aviso.name_; + ar & aviso.listener_; + ar & aviso.url_; + ar & aviso.schema_; + ar & aviso.polling_; + ar & aviso.auth_; + ar & aviso.reason_; + ar & aviso.revision_; +} + +} // namespace ecf + +#endif /* ecflow_node_AvisoAttr_HPP */ diff --git a/ANode/src/ecflow/node/ClientSuiteMgr.cpp b/libs/node/src/ecflow/node/ClientSuiteMgr.cpp similarity index 100% rename from ANode/src/ecflow/node/ClientSuiteMgr.cpp rename to libs/node/src/ecflow/node/ClientSuiteMgr.cpp diff --git a/ANode/src/ecflow/node/ClientSuiteMgr.hpp b/libs/node/src/ecflow/node/ClientSuiteMgr.hpp similarity index 100% rename from ANode/src/ecflow/node/ClientSuiteMgr.hpp rename to libs/node/src/ecflow/node/ClientSuiteMgr.hpp diff --git a/ANode/src/ecflow/node/ClientSuites.cpp b/libs/node/src/ecflow/node/ClientSuites.cpp similarity index 100% rename from ANode/src/ecflow/node/ClientSuites.cpp rename to libs/node/src/ecflow/node/ClientSuites.cpp diff --git a/ANode/src/ecflow/node/ClientSuites.hpp b/libs/node/src/ecflow/node/ClientSuites.hpp similarity index 100% rename from ANode/src/ecflow/node/ClientSuites.hpp rename to libs/node/src/ecflow/node/ClientSuites.hpp diff --git a/ANode/src/ecflow/node/CmdContext.cpp b/libs/node/src/ecflow/node/CmdContext.cpp similarity index 100% rename from ANode/src/ecflow/node/CmdContext.cpp rename to libs/node/src/ecflow/node/CmdContext.cpp diff --git a/ANode/src/ecflow/node/CmdContext.hpp b/libs/node/src/ecflow/node/CmdContext.hpp similarity index 100% rename from ANode/src/ecflow/node/CmdContext.hpp rename to libs/node/src/ecflow/node/CmdContext.hpp diff --git a/ANode/src/ecflow/node/Defs.cpp b/libs/node/src/ecflow/node/Defs.cpp similarity index 99% rename from ANode/src/ecflow/node/Defs.cpp rename to libs/node/src/ecflow/node/Defs.cpp index 399f4a7d5..00bdfcb64 100644 --- a/ANode/src/ecflow/node/Defs.cpp +++ b/libs/node/src/ecflow/node/Defs.cpp @@ -406,7 +406,7 @@ bool Defs::verification(std::string& errorMsg) const { suite_ptr Defs::add_suite(const std::string& name) { if (findSuite(name).get()) { std::stringstream ss; - ss << "Add Suite failed: A Suite of name '" << name << "' already exist"; + ss << "Add Suite failed: A Suite of name '" << name << "' already exists"; throw std::runtime_error(ss.str()); } suite_ptr the_suite = Suite::create(name); @@ -417,7 +417,7 @@ suite_ptr Defs::add_suite(const std::string& name) { void Defs::addSuite(const suite_ptr& s, size_t position) { if (findSuite(s->name()).get()) { std::stringstream ss; - ss << "Add Suite failed: A Suite of name '" << s->name() << "' already exist"; + ss << "Add Suite failed: A Suite of name '" << s->name() << "' already exists"; throw std::runtime_error(ss.str()); } add_suite_only(s, position); @@ -1511,7 +1511,7 @@ void Defs::restore_from_string(const std::string& str) { std::string errorMsg, warningMsg; if (!restore_from_string(str, errorMsg, warningMsg)) { std::stringstream e; - e << "Defs::defs_restore_from_string: " << errorMsg; + e << "Defs::restore_from_string: " << errorMsg; throw std::runtime_error(e.str()); } } diff --git a/ANode/src/ecflow/node/Defs.hpp b/libs/node/src/ecflow/node/Defs.hpp similarity index 99% rename from ANode/src/ecflow/node/Defs.hpp rename to libs/node/src/ecflow/node/Defs.hpp index 100925d0a..588a1ca16 100644 --- a/ANode/src/ecflow/node/Defs.hpp +++ b/libs/node/src/ecflow/node/Defs.hpp @@ -36,6 +36,7 @@ #include "ecflow/node/Flag.hpp" #include "ecflow/node/NodeFwd.hpp" #include "ecflow/node/ServerState.hpp" +#include "ecflow/node/Suite.hpp" namespace cereal { class access; diff --git a/ANode/src/ecflow/node/DefsDelta.cpp b/libs/node/src/ecflow/node/DefsDelta.cpp similarity index 100% rename from ANode/src/ecflow/node/DefsDelta.cpp rename to libs/node/src/ecflow/node/DefsDelta.cpp diff --git a/ANode/src/ecflow/node/DefsDelta.hpp b/libs/node/src/ecflow/node/DefsDelta.hpp similarity index 100% rename from ANode/src/ecflow/node/DefsDelta.hpp rename to libs/node/src/ecflow/node/DefsDelta.hpp diff --git a/ANode/src/ecflow/node/DefsTreeVisitor.hpp b/libs/node/src/ecflow/node/DefsTreeVisitor.hpp similarity index 100% rename from ANode/src/ecflow/node/DefsTreeVisitor.hpp rename to libs/node/src/ecflow/node/DefsTreeVisitor.hpp diff --git a/ANode/src/ecflow/node/EcfFile.cpp b/libs/node/src/ecflow/node/EcfFile.cpp similarity index 100% rename from ANode/src/ecflow/node/EcfFile.cpp rename to libs/node/src/ecflow/node/EcfFile.cpp diff --git a/ANode/src/ecflow/node/EcfFile.hpp b/libs/node/src/ecflow/node/EcfFile.hpp similarity index 100% rename from ANode/src/ecflow/node/EcfFile.hpp rename to libs/node/src/ecflow/node/EcfFile.hpp diff --git a/ANode/src/ecflow/node/ExprAst.cpp b/libs/node/src/ecflow/node/ExprAst.cpp similarity index 100% rename from ANode/src/ecflow/node/ExprAst.cpp rename to libs/node/src/ecflow/node/ExprAst.cpp diff --git a/ANode/src/ecflow/node/ExprAst.hpp b/libs/node/src/ecflow/node/ExprAst.hpp similarity index 100% rename from ANode/src/ecflow/node/ExprAst.hpp rename to libs/node/src/ecflow/node/ExprAst.hpp diff --git a/ANode/src/ecflow/node/ExprAstVisitor.cpp b/libs/node/src/ecflow/node/ExprAstVisitor.cpp similarity index 100% rename from ANode/src/ecflow/node/ExprAstVisitor.cpp rename to libs/node/src/ecflow/node/ExprAstVisitor.cpp diff --git a/ANode/src/ecflow/node/ExprAstVisitor.hpp b/libs/node/src/ecflow/node/ExprAstVisitor.hpp similarity index 100% rename from ANode/src/ecflow/node/ExprAstVisitor.hpp rename to libs/node/src/ecflow/node/ExprAstVisitor.hpp diff --git a/ANode/src/ecflow/node/ExprDuplicate.cpp b/libs/node/src/ecflow/node/ExprDuplicate.cpp similarity index 100% rename from ANode/src/ecflow/node/ExprDuplicate.cpp rename to libs/node/src/ecflow/node/ExprDuplicate.cpp diff --git a/ANode/src/ecflow/node/ExprDuplicate.hpp b/libs/node/src/ecflow/node/ExprDuplicate.hpp similarity index 100% rename from ANode/src/ecflow/node/ExprDuplicate.hpp rename to libs/node/src/ecflow/node/ExprDuplicate.hpp diff --git a/ANode/src/ecflow/node/ExprParser.cpp b/libs/node/src/ecflow/node/ExprParser.cpp similarity index 100% rename from ANode/src/ecflow/node/ExprParser.cpp rename to libs/node/src/ecflow/node/ExprParser.cpp diff --git a/ANode/src/ecflow/node/ExprParser.hpp b/libs/node/src/ecflow/node/ExprParser.hpp similarity index 100% rename from ANode/src/ecflow/node/ExprParser.hpp rename to libs/node/src/ecflow/node/ExprParser.hpp diff --git a/ANode/src/ecflow/node/Expression.cpp b/libs/node/src/ecflow/node/Expression.cpp similarity index 100% rename from ANode/src/ecflow/node/Expression.cpp rename to libs/node/src/ecflow/node/Expression.cpp diff --git a/ANode/src/ecflow/node/Expression.hpp b/libs/node/src/ecflow/node/Expression.hpp similarity index 100% rename from ANode/src/ecflow/node/Expression.hpp rename to libs/node/src/ecflow/node/Expression.hpp diff --git a/ANode/src/ecflow/node/Family.cpp b/libs/node/src/ecflow/node/Family.cpp similarity index 100% rename from ANode/src/ecflow/node/Family.cpp rename to libs/node/src/ecflow/node/Family.cpp diff --git a/ANode/src/ecflow/node/Family.hpp b/libs/node/src/ecflow/node/Family.hpp similarity index 100% rename from ANode/src/ecflow/node/Family.hpp rename to libs/node/src/ecflow/node/Family.hpp diff --git a/ANode/src/ecflow/node/Flag.cpp b/libs/node/src/ecflow/node/Flag.cpp similarity index 87% rename from ANode/src/ecflow/node/Flag.cpp rename to libs/node/src/ecflow/node/Flag.cpp index 03cebb1cb..baf5777a0 100644 --- a/ANode/src/ecflow/node/Flag.cpp +++ b/libs/node/src/ecflow/node/Flag.cpp @@ -19,16 +19,14 @@ namespace ecf { void Flag::set(Flag::Type flag) { - if (!is_set(flag)) { - // minimize changes to state_change_no_ + if (!is_set(flag)) { // minimize changes to state_change_no_ flag_ |= (1 << flag); state_change_no_ = Ecf::incr_state_change_no(); } } void Flag::clear(Flag::Type flag) { - if (is_set(flag)) { - // minimize changes to state_change_no_ + if (is_set(flag)) { // minimize changes to state_change_no_ flag_ &= ~(1 << flag); state_change_no_ = Ecf::incr_state_change_no(); } @@ -41,7 +39,7 @@ void Flag::reset() { std::vector Flag::list() { std::vector ret; - ret.reserve(24); + ret.reserve(25); ret.push_back(Flag::FORCE_ABORT); ret.push_back(Flag::USER_EDIT); ret.push_back(Flag::TASK_ABORTED); @@ -66,18 +64,20 @@ std::vector Flag::list() { ret.push_back(Flag::ECF_SIGTERM); ret.push_back(Flag::LOG_ERROR); ret.push_back(Flag::CHECKPT_ERROR); + ret.push_back(Flag::REMOTE_ERROR); return ret; } -constexpr std::array Flag::array() { - return std::array{Flag::FORCE_ABORT, Flag::USER_EDIT, Flag::TASK_ABORTED, - Flag::EDIT_FAILED, Flag::JOBCMD_FAILED, Flag::KILLCMD_FAILED, - Flag::STATUSCMD_FAILED, Flag::NO_SCRIPT, Flag::KILLED, - Flag::STATUS, Flag::LATE, Flag::MESSAGE, - Flag::BYRULE, Flag::QUEUELIMIT, Flag::WAIT, - Flag::LOCKED, Flag::ZOMBIE, Flag::NO_REQUE_IF_SINGLE_TIME_DEP, - Flag::ARCHIVED, Flag::RESTORED, Flag::THRESHOLD, - Flag::ECF_SIGTERM, Flag::LOG_ERROR, Flag::CHECKPT_ERROR}; +constexpr std::array Flag::array() { + return std::array{Flag::FORCE_ABORT, Flag::USER_EDIT, Flag::TASK_ABORTED, + Flag::EDIT_FAILED, Flag::JOBCMD_FAILED, Flag::KILLCMD_FAILED, + Flag::STATUSCMD_FAILED, Flag::NO_SCRIPT, Flag::KILLED, + Flag::STATUS, Flag::LATE, Flag::MESSAGE, + Flag::BYRULE, Flag::QUEUELIMIT, Flag::WAIT, + Flag::LOCKED, Flag::ZOMBIE, Flag::NO_REQUE_IF_SINGLE_TIME_DEP, + Flag::ARCHIVED, Flag::RESTORED, Flag::THRESHOLD, + Flag::ECF_SIGTERM, Flag::LOG_ERROR, Flag::CHECKPT_ERROR, + Flag::REMOTE_ERROR}; } std::string Flag::enum_to_string(Flag::Type flag) { @@ -155,6 +155,9 @@ std::string Flag::enum_to_string(Flag::Type flag) { case Flag::STATUS: return "status"; break; + case Flag::REMOTE_ERROR: + return "remote_error"; + break; case Flag::NOT_SET: return "not_set"; break; @@ -238,6 +241,9 @@ const char* Flag::enum_to_char_star(Flag::Type flag) { case Flag::CHECKPT_ERROR: return "checkpt_error"; break; + case Flag::REMOTE_ERROR: + return "remote_error"; + break; case Flag::NOT_SET: return "not_set"; break; @@ -297,11 +303,13 @@ Flag::Type Flag::string_to_flag_type(const std::string& s) { return Flag::LOG_ERROR; if (s == "checkpt_error") return Flag::CHECKPT_ERROR; + if (s == "remote_error") + return Flag::REMOTE_ERROR; return Flag::NOT_SET; } void Flag::valid_flag_type(std::vector& vec) { - vec.reserve(24); + vec.reserve(25); vec.emplace_back("force_aborted"); vec.emplace_back("user_edit"); vec.emplace_back("task_aborted"); @@ -326,6 +334,7 @@ void Flag::valid_flag_type(std::vector& vec) { vec.emplace_back("sigterm"); vec.emplace_back("log_error"); vec.emplace_back("checkpt_error"); + vec.emplace_back("remote_error"); } std::string Flag::to_string() const { @@ -335,8 +344,8 @@ std::string Flag::to_string() const { } void Flag::write(std::string& ret) const { - bool added = false; - std::array flag_list = Flag::array(); + bool added = false; + auto flag_list = Flag::array(); for (auto& i : flag_list) { if (is_set(i)) { if (added) diff --git a/ANode/src/ecflow/node/Flag.hpp b/libs/node/src/ecflow/node/Flag.hpp similarity index 60% rename from ANode/src/ecflow/node/Flag.hpp rename to libs/node/src/ecflow/node/Flag.hpp index 7561e3d77..8e0d6adde 100644 --- a/ANode/src/ecflow/node/Flag.hpp +++ b/libs/node/src/ecflow/node/Flag.hpp @@ -43,36 +43,92 @@ namespace ecf { class Flag { public: + using underlying_type_t = int; + static_assert(sizeof(underlying_type_t) >= 4, "Flag's underlying type must have at least 4 bytes"); + Flag() = default; /// The BYRULE is used to distinguish between tasks that have RUN and completed /// and those that have completed by complete expression. enum Type { - FORCE_ABORT = 0, // Node* do not run when try_no > ECF_TRIES, and task aborted by user - USER_EDIT = 1, // task - TASK_ABORTED = 2, // task* - EDIT_FAILED = 3, // task* - JOBCMD_FAILED = 4, // task* - NO_SCRIPT = 5, // task* - KILLED = 6, // task* do not run when try_no > ECF_TRIES, and task killed by user - LATE = 7, // Node attribute, - MESSAGE = 8, // Node - BYRULE = 9, // Node*, set if node is set to complete by complete trigger expression - QUEUELIMIT = 10, // Node ( NOT USED currently) - WAIT = 11, // task* set when waiting for trigger expression in client command - LOCKED = 12, // Server ( NOT USED currently) - ZOMBIE = 13, // task* Set/cleared but never queried by GUI - NO_REQUE_IF_SINGLE_TIME_DEP = 14, // - ARCHIVED = 15, // Container* - RESTORED = 16, // Container*, Avoid re-archiving node that is restored, until it is re-queued again - THRESHOLD = 17, // Job threshold exceeded.(slow disk,large includes/huge scripts,overloaded machine,server) - ECF_SIGTERM = 18, // Record on defs that server received SIGTERM signal, main used in test - NOT_SET = 19, - LOG_ERROR = 20, // Error in opening or writing to the log file - CHECKPT_ERROR = 21, // Error in saving checkpoint file - KILLCMD_FAILED = 22, // task* - STATUSCMD_FAILED = 23, // task* - STATUS = 24 // task* + + // Node* do not run when try_no > ECF_TRIES, and task aborted by user + FORCE_ABORT = 0, + + // task + USER_EDIT = 1, + + // task* + TASK_ABORTED = 2, + + // task* + EDIT_FAILED = 3, + + // task* + JOBCMD_FAILED = 4, + + // task* + NO_SCRIPT = 5, + + // task* do not run when try_no > ECF_TRIES, and task killed by user + KILLED = 6, + + // Node attribute, + LATE = 7, + + // Node + MESSAGE = 8, + + // Node*, set if node is set to complete by complete trigger expression + BYRULE = 9, + + // Node ( NOT USED currently) + QUEUELIMIT = 10, + + // task* set when waiting for trigger expression in client command + WAIT = 11, + + // Server ( NOT USED currently) + LOCKED = 12, + + // task* Set/cleared but never queried by GUI + ZOMBIE = 13, + + // + NO_REQUE_IF_SINGLE_TIME_DEP = 14, + + // Container + ARCHIVED = 15, + + // Container, Avoid re-archiving node that is restored, until re-queued again + RESTORED = 16, + + // Job threshold exceeded, slow disk, large includes/huge scripts,overloaded machine,server) + THRESHOLD = 17, + + // Record on defs that server received SIGTERM signal, main used in test + ECF_SIGTERM = 18, + + // + NOT_SET = 19, + + // Error in opening or writing to the log file + LOG_ERROR = 20, + + // Error in saving checkpoint file + CHECKPT_ERROR = 21, + + // task* + KILLCMD_FAILED = 22, + + // task* + STATUSCMD_FAILED = 23, + + // task* + STATUS = 24, + + // Error connecting to remote source + REMOTE_ERROR = 25 }; bool operator==(const Flag& rhs) const { return flag_ == rhs.flag_; } @@ -85,7 +141,7 @@ class Flag { void reset(); int flag() const { return flag_; } - void set_flag(int f) { flag_ = f; } + void set_flag(underlying_type_t f) { flag_ = f; } void set_flag(const std::string& flags); // these are comma separated /// returns a comma separated list of all flags set @@ -97,11 +153,12 @@ class Flag { static const char* enum_to_char_star(Flag::Type flag); /// Used to determine change in state relative to client + void set_state_change_no(unsigned int n) { state_change_no_ = n; } unsigned int state_change_no() const { return state_change_no_; } /// returns the list of all flag types static std::vector list(); - static constexpr std::array array(); + static constexpr std::array array(); /// Converts from string to flag types. static Flag::Type string_to_flag_type(const std::string& s); @@ -110,7 +167,7 @@ class Flag { static void valid_flag_type(std::vector& vec); private: - int flag_{0}; + underlying_type_t flag_{0}; unsigned int state_change_no_{0}; // *not* persisted, only used on server side friend class cereal::access; diff --git a/ANode/src/ecflow/node/InLimit.cpp b/libs/node/src/ecflow/node/InLimit.cpp similarity index 100% rename from ANode/src/ecflow/node/InLimit.cpp rename to libs/node/src/ecflow/node/InLimit.cpp diff --git a/ANode/src/ecflow/node/InLimit.hpp b/libs/node/src/ecflow/node/InLimit.hpp similarity index 100% rename from ANode/src/ecflow/node/InLimit.hpp rename to libs/node/src/ecflow/node/InLimit.hpp diff --git a/ANode/src/ecflow/node/InLimitMgr.cpp b/libs/node/src/ecflow/node/InLimitMgr.cpp similarity index 100% rename from ANode/src/ecflow/node/InLimitMgr.cpp rename to libs/node/src/ecflow/node/InLimitMgr.cpp diff --git a/ANode/src/ecflow/node/InLimitMgr.hpp b/libs/node/src/ecflow/node/InLimitMgr.hpp similarity index 100% rename from ANode/src/ecflow/node/InLimitMgr.hpp rename to libs/node/src/ecflow/node/InLimitMgr.hpp diff --git a/ANode/src/ecflow/node/JobCreationCtrl.cpp b/libs/node/src/ecflow/node/JobCreationCtrl.cpp similarity index 100% rename from ANode/src/ecflow/node/JobCreationCtrl.cpp rename to libs/node/src/ecflow/node/JobCreationCtrl.cpp diff --git a/ANode/src/ecflow/node/JobCreationCtrl.hpp b/libs/node/src/ecflow/node/JobCreationCtrl.hpp similarity index 100% rename from ANode/src/ecflow/node/JobCreationCtrl.hpp rename to libs/node/src/ecflow/node/JobCreationCtrl.hpp diff --git a/ANode/src/ecflow/node/JobProfiler.cpp b/libs/node/src/ecflow/node/JobProfiler.cpp similarity index 100% rename from ANode/src/ecflow/node/JobProfiler.cpp rename to libs/node/src/ecflow/node/JobProfiler.cpp diff --git a/ANode/src/ecflow/node/JobProfiler.hpp b/libs/node/src/ecflow/node/JobProfiler.hpp similarity index 100% rename from ANode/src/ecflow/node/JobProfiler.hpp rename to libs/node/src/ecflow/node/JobProfiler.hpp diff --git a/ANode/src/ecflow/node/Jobs.cpp b/libs/node/src/ecflow/node/Jobs.cpp similarity index 90% rename from ANode/src/ecflow/node/Jobs.cpp rename to libs/node/src/ecflow/node/Jobs.cpp index dd123ca66..3f79dcb7e 100644 --- a/ANode/src/ecflow/node/Jobs.cpp +++ b/libs/node/src/ecflow/node/Jobs.cpp @@ -14,6 +14,7 @@ #include "ecflow/core/Log.hpp" #include "ecflow/node/Defs.hpp" #include "ecflow/node/JobsParam.hpp" +#include "ecflow/node/Operations.hpp" #include "ecflow/node/Signal.hpp" #include "ecflow/node/Suite.hpp" #include "ecflow/node/SuiteChanged.hpp" @@ -54,12 +55,12 @@ bool Jobs::generate(JobsParam& jobsParam) const { if (defs_) { if (defs_->server().get_state() == SState::RUNNING) { - const std::vector& suiteVec = defs_->suiteVec(); - size_t theSize = suiteVec.size(); - for (size_t i = 0; i < theSize; i++) { - // SuiteChanged moved internal to Suite::resolveDependencies. i.e on fast path - // and when suites not begun we save a constructor/destructor calls - (void)suiteVec[i]->resolveDependencies(jobsParam); + const std::vector& suites = defs_->suiteVec(); + for (const suite_ptr& suite : suites) { + // SuiteChanged moved into Suite::resolveDependencies. + // This ensures the fast path and when suite are not begun we save a ctor/dtor call + ecf::visit_all(*suite, ActivateAll{}); + (void)suite->resolveDependencies(jobsParam); } } } diff --git a/ANode/src/ecflow/node/Jobs.hpp b/libs/node/src/ecflow/node/Jobs.hpp similarity index 100% rename from ANode/src/ecflow/node/Jobs.hpp rename to libs/node/src/ecflow/node/Jobs.hpp diff --git a/ANode/src/ecflow/node/JobsParam.cpp b/libs/node/src/ecflow/node/JobsParam.cpp similarity index 100% rename from ANode/src/ecflow/node/JobsParam.cpp rename to libs/node/src/ecflow/node/JobsParam.cpp diff --git a/ANode/src/ecflow/node/JobsParam.hpp b/libs/node/src/ecflow/node/JobsParam.hpp similarity index 100% rename from ANode/src/ecflow/node/JobsParam.hpp rename to libs/node/src/ecflow/node/JobsParam.hpp diff --git a/ANode/src/ecflow/node/Limit.cpp b/libs/node/src/ecflow/node/Limit.cpp similarity index 100% rename from ANode/src/ecflow/node/Limit.cpp rename to libs/node/src/ecflow/node/Limit.cpp diff --git a/ANode/src/ecflow/node/Limit.hpp b/libs/node/src/ecflow/node/Limit.hpp similarity index 100% rename from ANode/src/ecflow/node/Limit.hpp rename to libs/node/src/ecflow/node/Limit.hpp diff --git a/ANode/src/ecflow/node/LimitFwd.hpp b/libs/node/src/ecflow/node/LimitFwd.hpp similarity index 100% rename from ANode/src/ecflow/node/LimitFwd.hpp rename to libs/node/src/ecflow/node/LimitFwd.hpp diff --git a/ANode/src/ecflow/node/Memento.cpp b/libs/node/src/ecflow/node/Memento.cpp similarity index 96% rename from ANode/src/ecflow/node/Memento.cpp rename to libs/node/src/ecflow/node/Memento.cpp index 9b771ba8e..eef632501 100644 --- a/ANode/src/ecflow/node/Memento.cpp +++ b/libs/node/src/ecflow/node/Memento.cpp @@ -208,6 +208,16 @@ void NodeLabelMemento::serialize(Archive& ar, std::uint32_t const version) { ar(cereal::base_class(this), CEREAL_NVP(label_)); } +template +void NodeAvisoMemento::serialize(Archive& ar, std::uint32_t const version) { + ar(cereal::base_class(this), CEREAL_NVP(aviso_)); +} + +template +void NodeMirrorMemento::serialize(Archive& ar, std::uint32_t const version) { + ar(cereal::base_class(this), CEREAL_NVP(mirror_)); +} + template void NodeQueueMemento::serialize(Archive& ar, std::uint32_t const version) { ar(cereal::base_class(this), CEREAL_NVP(queue_)); @@ -335,6 +345,8 @@ CEREAL_TEMPLATE_SPECIALIZE_V(ServerVariableMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeEventMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeMeterMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeLabelMemento); +CEREAL_TEMPLATE_SPECIALIZE_V(NodeAvisoMemento); +CEREAL_TEMPLATE_SPECIALIZE_V(NodeMirrorMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeQueueMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeGenericMemento); CEREAL_TEMPLATE_SPECIALIZE_V(NodeQueueIndexMemento); @@ -372,6 +384,8 @@ CEREAL_REGISTER_TYPE(ServerVariableMemento) CEREAL_REGISTER_TYPE(NodeEventMemento) CEREAL_REGISTER_TYPE(NodeMeterMemento) CEREAL_REGISTER_TYPE(NodeLabelMemento) +CEREAL_REGISTER_TYPE(NodeAvisoMemento) +CEREAL_REGISTER_TYPE(NodeMirrorMemento) CEREAL_REGISTER_TYPE(NodeQueueMemento) CEREAL_REGISTER_TYPE(NodeGenericMemento) CEREAL_REGISTER_TYPE(NodeQueueIndexMemento) diff --git a/ANode/src/ecflow/node/Memento.hpp b/libs/node/src/ecflow/node/Memento.hpp similarity index 95% rename from ANode/src/ecflow/node/Memento.hpp rename to libs/node/src/ecflow/node/Memento.hpp index 3e60d72da..ff97e692e 100644 --- a/ANode/src/ecflow/node/Memento.hpp +++ b/libs/node/src/ecflow/node/Memento.hpp @@ -43,10 +43,12 @@ #include "ecflow/attribute/VerifyAttr.hpp" #include "ecflow/attribute/ZombieAttr.hpp" #include "ecflow/node/Alias.hpp" +#include "ecflow/node/AvisoAttr.hpp" #include "ecflow/node/Defs.hpp" #include "ecflow/node/Expression.hpp" #include "ecflow/node/Family.hpp" #include "ecflow/node/Limit.hpp" +#include "ecflow/node/MirrorAttr.hpp" #include "ecflow/node/Suite.hpp" #include "ecflow/node/Task.hpp" @@ -651,6 +653,42 @@ class NodeCronMemento : public Memento { void serialize(Archive& ar, std::uint32_t const version); }; +class NodeAvisoMemento : public Memento { +public: + NodeAvisoMemento() = default; + explicit NodeAvisoMemento(const ecf::AvisoAttr& a) : aviso_(a.make_detached()) {} + +private: + void do_incremental_node_sync(Node* n, std::vector& aspects, bool f) const override { + n->set_memento(this, aspects, f); + } + + ecf::AvisoAttr aviso_; + friend class Node; + + friend class cereal::access; + template + void serialize(Archive& ar, std::uint32_t const version); +}; + +class NodeMirrorMemento : public Memento { +public: + NodeMirrorMemento() = default; + explicit NodeMirrorMemento(const ecf::MirrorAttr& a) : mirror_(a.make_detached()) {} + +private: + void do_incremental_node_sync(Node* n, std::vector& aspects, bool f) const override { + n->set_memento(this, aspects, f); + } + + ecf::MirrorAttr mirror_; + friend class Node; + + friend class cereal::access; + template + void serialize(Archive& ar, std::uint32_t const version); +}; + class NodeDateMemento : public Memento { public: explicit NodeDateMemento(const DateAttr& attr) : attr_(attr) {} diff --git a/libs/node/src/ecflow/node/MirrorAttr.cpp b/libs/node/src/ecflow/node/MirrorAttr.cpp new file mode 100644 index 000000000..25a621e20 --- /dev/null +++ b/libs/node/src/ecflow/node/MirrorAttr.cpp @@ -0,0 +1,184 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "ecflow/node/MirrorAttr.hpp" + +#include + +#include "ecflow/core/Ecf.hpp" +#include "ecflow/core/Message.hpp" +#include "ecflow/core/Overload.hpp" +#include "ecflow/core/exceptions/Exceptions.hpp" +#include "ecflow/node/Node.hpp" +#include "ecflow/node/Operations.hpp" + +namespace ecf { + +bool MirrorAttr::is_valid_name(const std::string& name) { + return ecf::Str::valid_name(name); +} + +MirrorAttr::MirrorAttr(Node* parent, + name_t name, + remote_path_t remote_path, + remote_host_t remote_host, + remote_port_t remote_port, + polling_t polling, + flag_t ssl, + auth_t auth, + reason_t reason) + : parent_{parent}, + name_{std::move(name)}, + remote_path_{std::move(remote_path)}, + remote_host_{std::move(remote_host)}, + remote_port_{std::move(remote_port)}, + polling_{std::move(polling)}, + ssl_{ssl}, + auth_{std::move(auth)}, + reason_{std::move(reason)}, + controller_{nullptr} { + if (!is_valid_name(name_)) { + throw ecf::InvalidArgument(ecf::Message("Invalid MirrorAttr name :", name_)); + } +} + +MirrorAttr::~MirrorAttr() { + stop_controller(); +} + +[[nodiscard]] MirrorAttr MirrorAttr::make_detached() const { + MirrorAttr clone{*this}; + clone.parent_ = nullptr; + clone.controller_ = nullptr; + return clone; +} + +std::string MirrorAttr::absolute_name() const { + return parent_->absNodePath() + ':' + name_; +} + +bool MirrorAttr::why(std::string& theReasonWhy) const { + theReasonWhy += ecf::Message(" is a Mirror of ", remote_path(), " at '", remote_host(), ":", remote_port(), "'"); + return true; +} + +void MirrorAttr::reset() { + state_change_no_ = Ecf::incr_state_change_no(); + start_controller(); +} + +void MirrorAttr::finish() { + stop_controller(); +} + +void MirrorAttr::mirror() { + SLOG(D, "MirrorAttr: poll Mirror attribute '" << absolute_name() << "'"); + + start_controller(); + + // Task associated with Attribute is free when any notification is found + if (auto notifications = controller_->get_notifications(remote_path_); !notifications.empty()) { + + // Update the 'local' state change number + state_change_no_ = Ecf::incr_state_change_no(); + + // Notifications found -- Node state to be updated or error to be reported + std::visit(ecf::overload{[this](const service::mirror::MirrorNotification& notification) { + SLOG(D, + "MirrorAttr: Updating Mirror attribute (name: " << name_ << ") to state " + << notification.status()); + auto latest_state = static_cast(notification.status()); + reason_ = ""; + parent_->flag().clear(Flag::REMOTE_ERROR); + parent_->flag().set_state_change_no(state_change_no_); + parent_->setStateOnly(latest_state, true); + }, + [this](const service::mirror::MirrorError& error) { + SLOG(D, + "MirrorAttr: Failure detected on Mirror attribute (name: " + << name_ << ") due to " << error.reason()); + reason_ = error.reason(); + parent_->flag().set(Flag::REMOTE_ERROR); + parent_->flag().set_state_change_no(state_change_no_); + parent_->setStateOnly(NState::UNKNOWN, true); + }}, + notifications.back()); + + // Propagate the 'local' state change number to all parents + ecf::visit_parents(*parent_, [n = this->state_change_no_](Node& node) { node.set_state_change_no(n); }); + + // Propagate the 'local' state change number to the top level suite + auto find_suite = [](Node* node) -> Suite* { + Node* top = node; + while (top->parent() != nullptr) { + top = top->parent(); + } + if (top->isSuite()) { + return static_cast(top); + } + return nullptr; + }; + if (Suite* suite = find_suite(parent_); suite) { + suite->Suite::set_state_change_no(state_change_no_); + } + } + else { + SLOG(D, "MirrorAttr: No notifications found for Mirror attribute (name: " << name_ << ")"); + } + + // No notifications, nothing to do... +} + +void MirrorAttr::start_controller() const { + if (controller_ == nullptr) { + // Substitute variables in Mirror configuration + std::string remote_host = remote_host_; + parent_->variableSubstitution(remote_host); + std::string remote_port = remote_port_; + parent_->variableSubstitution(remote_port); + std::string polling = polling_; + parent_->variableSubstitution(polling); + std::string auth = auth_; + parent_->variableSubstitution(auth); + + SLOG(D, + "MirrorAttr: start polling Mirror attribute '" << absolute_name() << "', from " << remote_path_ << " @ " + << remote_host << ':' << remote_port << ")"); + + // Controller -- start up the Mirror controller, and configure the Mirror request + controller_ = std::make_shared(); + controller_->subscribe(ecf::service::mirror::MirrorRequest{ + remote_path_, remote_host, remote_port, boost::lexical_cast(polling), ssl_, auth}); + // Controller -- effectively start the Mirror process + // n.b. this must be done after subscribing in the controller, so that the polling interval is set + controller_->start(); + } +} + +void MirrorAttr::stop_controller() const { + if (controller_ != nullptr) { + SLOG(D, + "MirrorAttr: finishing polling for Mirror attribute \"" << parent_->absNodePath() << ":" << name_ + << "\", from host: " << remote_host_ + << ", port: " << remote_port_ << ")"); + + controller_->stop(); + controller_.reset(); + } +} + +bool operator==(const MirrorAttr& lhs, const MirrorAttr& rhs) { + return lhs.name() == rhs.name() && lhs.remote_path() == rhs.remote_path() && + lhs.remote_host() == rhs.remote_host() && lhs.remote_port() == rhs.remote_port() && + lhs.polling() == rhs.polling() && lhs.ssl() == rhs.ssl() && lhs.auth() == rhs.auth() && + lhs.reason() == rhs.reason(); +} + +} // namespace ecf diff --git a/libs/node/src/ecflow/node/MirrorAttr.hpp b/libs/node/src/ecflow/node/MirrorAttr.hpp new file mode 100644 index 000000000..fe1d58a29 --- /dev/null +++ b/libs/node/src/ecflow/node/MirrorAttr.hpp @@ -0,0 +1,150 @@ +/* + * Copyright 2009- ECMWF. + * + * This software is licensed under the terms of the Apache Licence version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#ifndef ecflow_node_MirrorAttr_HPP +#define ecflow_node_MirrorAttr_HPP + +#include +#include +#include + +#include "ecflow/core/Log.hpp" +#include "ecflow/core/Str.hpp" +#include "ecflow/service/mirror/MirrorService.hpp" + +namespace cereal { +class access; +} + +class Node; + +namespace ecf { + +/// +/// \brief MirrorAttr represents an attribute, attached to a \ref Node. +/// +/// The Mirror attribute effectively mirrors the status of a remote Node, allowing other Nodes to be triggered. +/// + +class MirrorAttr { +public: + using name_t = std::string; + using remote_path_t = std::string; + using remote_host_t = std::string; + using remote_port_t = std::string; + using polling_t = std::string; + using flag_t = bool; + using auth_t = std::string; + using reason_t = std::string; + + using controller_t = ecf::service::mirror::MirrorController; + using controller_ptr_t = std::shared_ptr; + + static constexpr const char* default_remote_host = "%ECF_MIRROR_REMOTE_HOST%"; + static constexpr const char* default_remote_port = "%ECF_MIRROR_REMOTE_PORT%"; + static constexpr const char* default_polling = "%ECF_MIRROR_REMOTE_POLLING%"; + static constexpr const char* default_remote_auth = "%ECF_MIRROR_REMOTE_AUTH%"; + + static bool is_valid_name(const std::string& name); + + /** + * Creates a(n invalid) Mirror + * + * Note: this is required by Cereal serialization + * Cereal invokes the default ctor to create the object and only then proceeds to member-wise serialization. + */ + MirrorAttr() = default; + MirrorAttr(Node* parent, + name_t name, + remote_path_t remote_path, + remote_host_t remote_host, + remote_port_t remote_port, + polling_t polling, + flag_t ssl, + auth_t auth, + reason_t reason); + + MirrorAttr(const MirrorAttr& rhs) = default; + ~MirrorAttr(); + + MirrorAttr& operator=(const MirrorAttr& rhs) = default; + + [[nodiscard]] MirrorAttr make_detached() const; + + [[nodiscard]] inline const std::string& name() const { return name_; } + [[nodiscard]] std::string absolute_name() const; + + [[nodiscard]] inline const std::string& remote_path() const { return remote_path_; } + [[nodiscard]] inline const std::string& remote_host() const { return remote_host_; } + [[nodiscard]] inline const std::string& remote_port() const { return remote_port_; } + [[nodiscard]] inline polling_t polling() const { return polling_; } + [[nodiscard]] inline flag_t ssl() const { return ssl_; } + [[nodiscard]] inline const std::string& auth() const { return auth_; } + [[nodiscard]] inline const std::string& reason() const { return reason_; } + + void set_parent(Node* parent) { parent_ = parent; } + + unsigned int state_change_no() const { return state_change_no_; } + + bool why(std::string& theReasonWhy) const; + + /** + * Initialises the Mirror procedure, which effectively starts the background polling mechanism. + */ + void reset(); + void finish(); + + /** + * Check if state changes were detected by the background polling mechanism, and if so, reflect it on the Node. + */ + void mirror(); + + template + friend void serialize(Archive& ar, MirrorAttr& aviso, std::uint32_t version); + +private: + void start_controller() const; + void stop_controller() const; + + Node* parent_{nullptr}; // only ever used on the server side, to update parent Node state + name_t name_; + remote_path_t remote_path_; + remote_host_t remote_host_; + remote_port_t remote_port_; + polling_t polling_; + flag_t ssl_; + auth_t auth_; + reason_t reason_; + + // The following are mutable as they are modified by the const method isFree() + mutable unsigned int state_change_no_{0}; // *not* persisted, only used on server side + + // The controller is only instanciated when the Mirror is reset() + // This allows the MirrorAttr have a copy-ctor and assignment operator + mutable controller_ptr_t controller_; +}; + +bool operator==(const MirrorAttr& lhs, const MirrorAttr& rhs); + +template +void serialize(Archive& ar, MirrorAttr& aviso, [[maybe_unused]] std::uint32_t version) { + ar & aviso.name_; + ar & aviso.remote_path_; + ar & aviso.remote_host_; + ar & aviso.remote_port_; + ar & aviso.polling_; + ar & aviso.ssl_; + ar & aviso.auth_; + ar & aviso.reason_; +} + +} // namespace ecf + +#endif /* ecflow_node_MirrorAttr_HPP */ diff --git a/ANode/src/ecflow/node/MiscAttrs.cpp b/libs/node/src/ecflow/node/MiscAttrs.cpp similarity index 100% rename from ANode/src/ecflow/node/MiscAttrs.cpp rename to libs/node/src/ecflow/node/MiscAttrs.cpp diff --git a/ANode/src/ecflow/node/MiscAttrs.hpp b/libs/node/src/ecflow/node/MiscAttrs.hpp similarity index 100% rename from ANode/src/ecflow/node/MiscAttrs.hpp rename to libs/node/src/ecflow/node/MiscAttrs.hpp diff --git a/ANode/src/ecflow/node/Node.cpp b/libs/node/src/ecflow/node/Node.cpp similarity index 97% rename from ANode/src/ecflow/node/Node.cpp rename to libs/node/src/ecflow/node/Node.cpp index 6d6276adc..fe4365e24 100644 --- a/ANode/src/ecflow/node/Node.cpp +++ b/libs/node/src/ecflow/node/Node.cpp @@ -20,21 +20,25 @@ #include "ecflow/core/Log.hpp" #include "ecflow/core/PrintStyle.hpp" #include "ecflow/core/Serialization.hpp" +#include "ecflow/core/Stl.hpp" #include "ecflow/core/Str.hpp" #include "ecflow/core/cereal_boost_time.hpp" #include "ecflow/node/AbstractObserver.hpp" #include "ecflow/node/AutoRestoreAttr.hpp" +#include "ecflow/node/AvisoAttr.hpp" #include "ecflow/node/CmdContext.hpp" #include "ecflow/node/Defs.hpp" #include "ecflow/node/ExprAst.hpp" #include "ecflow/node/ExprAstVisitor.hpp" #include "ecflow/node/Expression.hpp" #include "ecflow/node/Limit.hpp" +#include "ecflow/node/MirrorAttr.hpp" #include "ecflow/node/MiscAttrs.hpp" #include "ecflow/node/NodeStats.hpp" #include "ecflow/node/Suite.hpp" #include "ecflow/node/SuiteChanged.hpp" #include "ecflow/node/Task.hpp" +#include "ecflow/node/formatter/Format.hpp" #include "ecflow/node/parser/DefsStructureParser.hpp" using namespace ecf; @@ -237,6 +241,11 @@ void Node::begin() { // Set the state without causing any side effects initState(0); + if (!mirrors_.empty()) { + // In case mirror attributes are available, the node state becomes UNKNOWN + setStateOnly(NState::State::UNKNOWN, true /*force*/, Str::EMPTY() /* additional info to log */, false); + } + clearTrigger(); clearComplete(); @@ -279,6 +288,14 @@ void Node::begin() { date.reset(); } markHybridTimeDependentsAsComplete(); + + for (auto& aviso : avisos_) { + aviso.reset(); + } + } + + for (auto& mirror : mirrors_) { + mirror.reset(); } inLimitMgr_.reset(); // new to 5.0.0 clear inlimit.incremented() flag @@ -294,7 +311,12 @@ void Node::requeue(Requeue_args& args) { #ifdef DEBUG_REQUEUE LOG(Log::DBG, " Node::requeue() " << absNodePath() << " resetRepeats = " << args.resetRepeats_); #endif - /// Note: we don't reset verify attributes as they record state stat's + // Note: we don't reset verify attributes as they record state stat's + + if (!mirrors_.empty()) { + // In case mirror attributes are available, the node state becomes UNKNOWN + setStateOnly(NState::State::UNKNOWN, true /*force*/, Str::EMPTY() /* additional info to log */, false); + } // Set the state without causing any side effects initState(args.clear_suspended_in_child_nodes_, args.log_state_changes_); @@ -390,6 +412,11 @@ void Node::reset() { // Set the state without causing any side effects initState(1); + if (!mirrors_.empty()) { + // In case of mirror attributes, the node state becomes UNKNOWN + setStateOnly(NState::State::UNKNOWN, true /*force*/, Str::EMPTY() /* additional info to log */, false); + } + clearTrigger(); clearComplete(); @@ -725,6 +752,11 @@ bool Node::resolveDependencies(JobsParam& jobsParam) { return false; } + if (!mirrors_.empty()) { + // In case mirror attributes are configured, the node is never free (i.e. will not be run) + return false; + } + if (!timeDependenciesFree()) { #ifdef DEBUG_DEPENDENCIES const Calendar& calendar = suite()->calendar(); @@ -1045,11 +1077,9 @@ void Node::setStateOnly(NState::State newState, // Record state changes for verification if (misc_attrs_) { - size_t theSize = misc_attrs_->verifys_.size(); - for (size_t i = 0; i < theSize; i++) { - if (misc_attrs_->verifys_[i].state() == newState) { - // cout << "Verify: calendar " << to_simple_string(calendar.date()) << "\n"; - misc_attrs_->verifys_[i].incrementActual(); + for (auto& verify : misc_attrs_->verifys_) { + if (verify.state() == newState) { + verify.incrementActual(); } } } @@ -1092,22 +1122,27 @@ DState::State Node::dstate() const { } bool Node::set_event(const std::string& event_name_or_number) { - for (Event& e : events_) { - if (e.name_or_number() == event_name_or_number) { - e.set_value(true); - return true; - } + auto found = ecf::algorithm::find_by( + events_, [&](const auto& item) { return item.name_or_number() == event_name_or_number; }); + + if (found == std::end(events_)) { + return false; } - return false; + + found->set_value(true); + return true; } + bool Node::clear_event(const std::string& event_name_or_number) { - for (Event& e : events_) { - if (e.name_or_number() == event_name_or_number) { - e.set_value(false); - return true; - } + auto found = ecf::algorithm::find_by( + events_, [&](const auto& item) { return item.name_or_number() == event_name_or_number; }); + + if (found == std::end(events_)) { + return false; } - return false; + + found->set_value(false); + return true; } void Node::setRepeatToLastValue() { @@ -1773,6 +1808,12 @@ void Node::print(std::string& os) const { for (const CronAttr& cron : crons_) { cron.print(os); } + for (const AvisoAttr& a : avisos_) { + ecf::format_as_defs(a, os); + } + for (const MirrorAttr& m : mirrors_) { + ecf::format_as_defs(m, os); + } if (auto_cancel_) auto_cancel_->print(os); @@ -2341,6 +2382,20 @@ bool Node::why(std::vector& vec, bool html) const { why_found = true; } } + for (const auto& aviso : avisos_) { + postFix.clear(); + if (aviso.why(postFix)) { + vec.push_back(prefix + postFix); + why_found = true; + } + } + for (const auto& mirror : mirrors_) { + postFix.clear(); + if (mirror.why(postFix)) { + vec.push_back(prefix + postFix); + why_found = true; + } + } } // ************************************************************************************** @@ -2878,9 +2933,11 @@ void Node::serialize(Archive& ar, std::uint32_t const version) { CEREAL_OPTIONAL_NVP(ar, c_expr_, [this]() { return c_expr_.get(); }); // conditionally save CEREAL_OPTIONAL_NVP(ar, t_expr_, [this]() { return t_expr_.get(); }); // conditionally save - CEREAL_OPTIONAL_NVP(ar, meters_, [this]() { return !meters_.empty(); }); // conditionally save - CEREAL_OPTIONAL_NVP(ar, events_, [this]() { return !events_.empty(); }); // conditionally save - CEREAL_OPTIONAL_NVP(ar, labels_, [this]() { return !labels_.empty(); }); // conditionally save + CEREAL_OPTIONAL_NVP(ar, meters_, [this]() { return !meters_.empty(); }); // conditionally save + CEREAL_OPTIONAL_NVP(ar, events_, [this]() { return !events_.empty(); }); // conditionally save + CEREAL_OPTIONAL_NVP(ar, labels_, [this]() { return !labels_.empty(); }); // conditionally save + CEREAL_OPTIONAL_NVP(ar, avisos_, [this]() { return !avisos_.empty(); }); // conditionally save + CEREAL_OPTIONAL_NVP(ar, mirrors_, [this]() { return !mirrors_.empty(); }); // conditionally save CEREAL_OPTIONAL_NVP(ar, times_, [this]() { return !times_.empty(); }); // conditionally save CEREAL_OPTIONAL_NVP(ar, todays_, [this]() { return !todays_.empty(); }); // conditionally save diff --git a/ANode/src/ecflow/node/Node.hpp b/libs/node/src/ecflow/node/Node.hpp similarity index 96% rename from ANode/src/ecflow/node/Node.hpp rename to libs/node/src/ecflow/node/Node.hpp index 4de1ab325..7028fd693 100644 --- a/ANode/src/ecflow/node/Node.hpp +++ b/libs/node/src/ecflow/node/Node.hpp @@ -57,6 +57,8 @@ namespace ecf { class Calendar; class NodeTreeVisitor; class LateAttr; +class AvisoAttr; +class MirrorAttr; } // namespace ecf class Node : public std::enable_shared_from_this { @@ -70,6 +72,7 @@ class Node : public std::enable_shared_from_this { Node(const Node& rhs); virtual ~Node(); + virtual bool check_defaults() const; // parse string and create suite || family || task || alias. Can return a NULL node_ptr() for errors @@ -393,6 +396,12 @@ class Node : public std::enable_shared_from_this { const std::vector& days() const { return days_; } const std::vector& crons() const { return crons_; } + std::vector& avisos() { return avisos_; } + const std::vector& avisos() const { return avisos_; } + + std::vector& mirrors() { return mirrors_; } + const std::vector& mirrors() const { return mirrors_; } + const std::vector& verifys() const; const std::vector& zombies() const; const std::vector& queues() const; @@ -456,6 +465,8 @@ class Node : public std::enable_shared_from_this { void addDate(const DateAttr&); void addDay(const DayAttr&); void addCron(const ecf::CronAttr&); + void addAviso(const ecf::AvisoAttr&); + void addMirror(const ecf::MirrorAttr&); void addLimit(const Limit&, bool check = true); // will throw std::runtime_error if duplicate void addInLimit(const InLimit& l, bool check = true); // will throw std::runtime_error if duplicate @@ -507,6 +518,8 @@ class Node : public std::enable_shared_from_this { void deleteEvent(const std::string& name); void deleteMeter(const std::string& name); void deleteLabel(const std::string& name); + void deleteAviso(const std::string& name); + void deleteMirror(const std::string& name); void delete_queue(const std::string& name); void delete_generic(const std::string& name); void deleteTrigger(); @@ -529,6 +542,9 @@ class Node : public std::enable_shared_from_this { void changeMeter(const std::string& name, const std::string& value); void changeMeter(const std::string& name, int value); void changeLabel(const std::string& name, const std::string& value); + void changeAviso(const std::string& name, const std::string& value); + void changeAviso(const std::string& name, const std::string& value, uint64_t revision); + void changeMirror(const std::string& name, const std::string& value); void changeTrigger(const std::string& expression); void changeComplete(const std::string& expression); void changeRepeat(const std::string& value); @@ -557,6 +573,8 @@ class Node : public std::enable_shared_from_this { void set_memento(const NodeEventMemento*, std::vector& aspects, bool f); void set_memento(const NodeMeterMemento*, std::vector& aspects, bool f); void set_memento(const NodeLabelMemento*, std::vector& aspects, bool f); + void set_memento(const NodeAvisoMemento*, std::vector& aspects, bool f); + void set_memento(const NodeMirrorMemento*, std::vector& aspects, bool f); void set_memento(const NodeQueueMemento*, std::vector& aspects, bool f); void set_memento(const NodeGenericMemento*, std::vector& aspects, bool f); void set_memento(const NodeQueueIndexMemento*, std::vector& aspects, bool f); @@ -626,6 +644,8 @@ class Node : public std::enable_shared_from_this { bool findLimit(const Limit&) const; bool findLabel(const std::string& name) const; const Label& find_label(const std::string& name) const; + bool findAviso(const std::string& name) const; + bool findMirror(const std::string& name) const; const QueueAttr& find_queue(const std::string& name) const; QueueAttr& findQueue(const std::string& name); const GenericAttr& find_generic(const std::string& name) const; @@ -682,7 +702,7 @@ class Node : public std::enable_shared_from_this { virtual void handleStateChange() = 0; // can end up changing state /// update change numbers to force sync - virtual void force_sync(){}; + virtual void force_sync() {}; /// check trigger expression have nodes and events,meter,repeat that resolve bool check_expressions(Ast*, const std::string& expr, bool trigger, std::string& errorMsg) const; @@ -693,6 +713,9 @@ class Node : public std::enable_shared_from_this { virtual boost::posix_time::time_duration sum_runtime() { return sc_rt_; } + void set_state_change_no(unsigned int x) { state_change_no_ = x; } + unsigned int state_change_no() const { return state_change_no_; } + protected: void set_runtime(const boost::posix_time::time_duration& rt) { sc_rt_ = rt; } @@ -837,6 +860,10 @@ class Node : public std::enable_shared_from_this { std::vector::const_iterator event_end() const { return events_.end(); } std::vector