ChimeraTK-DeviceAccess-TangoBackend 00.01.02
Loading...
Searching...
No Matches
TangoServerLauncher.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
5
6#include <chrono>
7#include <filesystem>
8#include <memory>
9#include <random>
10#include <thread>
11
12TangoServerLauncher::TangoServerLauncher(std::string setTestName, bool setVerbose)
13: testName(std::move(setTestName)), verbose(setVerbose) {
14 self = this;
15 start();
16}
17
18/**********************************************************************************************************************/
19
21 if(tangoServerProcess.joinable()) {
22 stop();
23 }
24
25 remoteProxy.reset();
26
28 try {
29 std::filesystem::remove(offlineDatabase);
30 }
31 catch(std::runtime_error&) {
32 // ignore
33 }
34 }
35}
36
37/**********************************************************************************************************************/
38
40 if(tangoServerProcess.running()) {
41 return;
42 }
43
44 argv.clear();
45 // argv.emplace_back(testName + "_ds");
46 argv.emplace_back("Test" + testName);
47 if(verbose || std::getenv("TANGO_TESTS_VERBOSE") != nullptr) {
48 argv.emplace_back("-v5");
49 }
50 deviceString = std::string("tango/test/tg_test01") + testName;
51
52 if(offlineDatabase.empty()) {
53 argv.emplace_back("-nodb");
54 argv.emplace_back("-dlist");
55 }
56 else {
57 argv.emplace_back("-file=" + offlineDatabase);
58 }
59 argv.emplace_back(deviceString);
60 argv.emplace_back("-ORBendPoint");
61 argv.emplace_back("giop:tcp:127.0.0.1:" + port());
62
63 try {
64 tangoServerProcess = boost::process::child("./tangoTestServer", boost::process::args(argv));
65 }
66 catch(...) {
67 abort();
68 }
69
70 auto url = getClientUrl();
71 url.replace(url.find("%23"), 3, "#");
72 auto start = std::chrono::steady_clock::now();
73 while(true) {
74 try {
75 std::this_thread::sleep_for(std::chrono::milliseconds(500));
76 remoteProxy = std::make_shared<Tango::DeviceProxy>(url);
77 remoteProxy->read_attribute("State");
78 break;
79 }
80 catch(CORBA::Exception& ex) {
81 if(auto now = std::chrono::steady_clock::now(); now > start + std::chrono::seconds(10)) {
82 Tango::Except::print_exception(ex);
83 assert(false);
84 }
85 }
86 }
87}
88
89/**********************************************************************************************************************/
90
92 remoteProxy.reset();
93
94 auto remotePid = tangoServerProcess.id();
95 kill(remotePid, SIGINT);
96 tangoServerProcess.wait();
97}
98
99/**********************************************************************************************************************/
100
102 static std::string corbaPort;
103 if(corbaPort.empty()) {
104 std::random_device rd;
105 std::uniform_int_distribution<int> dist(10000, 50000);
106 corbaPort = std::to_string(dist(rd));
107 }
108
109 return corbaPort;
110}
111
112/**********************************************************************************************************************/
113
115 return "tango://localhost:" + port() + "/" + device() + "%23dbase=no";
116}
117
118/**********************************************************************************************************************/
119
120const std::string& TangoServerLauncher::device() const {
121 return deviceString;
122}
123
124/**********************************************************************************************************************/
125
127 createOfflineDatabase = create;
128
129 return *this;
130}
131
132/**********************************************************************************************************************/
133
139
140/**********************************************************************************************************************/
141
143 offlineDatabase = basePath + ".db";
145 auto sourceTemplate = basePath + "_template.db";
146 try {
147 std::filesystem::copy_file(sourceTemplate, offlineDatabase, std::filesystem::copy_options::overwrite_existing);
148 }
149 catch(std::runtime_error& err) {
150 std::cerr << err.what() << std::endl;
151 throw;
152 }
153 }
154
155 return *this;
156}
157
158/**********************************************************************************************************************/
159
161 testName = newNames;
162
163 return *this;
164}
165
166/**********************************************************************************************************************/
167
boost::process::child tangoServerProcess
TangoServerLauncher(std::string setTestName="Unified", bool setVerbose=false)
std::vector< std::string > argv
std::string getClientUrl() const
An URL that can be used by the Tango::DeviceProxy to connect to this server.
const std::string & device() const
The Tango device name.
TangoServerLauncher & setCreateOfflineDatabase(bool create)
TangoServerLauncher & overrideNames(const std::string &newNames)
void stop()
Shut down the Tango server.
static TangoServerLauncher * self
TangoServerLauncher & setKeepOfflineDatabase(bool keep)
std::shared_ptr< Tango::DeviceProxy > remoteProxy
static std::string port()
Get the port used for CORBA commuication.
TangoServerLauncher & setOfflineDatabase(const std::string &basePath)
Configure the Tango server to run against an offline database.