Line data Source code
1 : /**
2 : * @file config_client_test.cxx
3 : *
4 : * Tests the connection to the connectivity service, and whether publishes
5 : * and lookups work as expected.
6 : *
7 : * Run "config_client_test --help" to see options
8 : *
9 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
10 : * Licensing/copyright details are in the COPYING file that you should have
11 : * received with this code.
12 : */
13 :
14 : #include "iomanager/network/ConfigClient.hpp"
15 : #include "iomanager/network/NetworkIssues.hpp"
16 : #include "logging/Logging.hpp"
17 :
18 : #include "confmodel/NetworkConnection.hpp"
19 :
20 : #include "boost/program_options.hpp"
21 : #include "nlohmann/json.hpp"
22 :
23 : #include <chrono>
24 : #include <cstdlib>
25 : #include <fstream>
26 : #include <iostream>
27 : #include <string>
28 : #include <vector>
29 :
30 : using namespace dunedaq::iomanager;
31 : using nlohmann::json;
32 : using namespace std::chrono;
33 :
34 : int
35 0 : main(int argc, char* argv[])
36 : {
37 :
38 0 : std::string name("ccTest");
39 0 : std::string server("localhost");
40 0 : std::string port("5000");
41 0 : std::string file;
42 0 : int connection_count = 10;
43 0 : int pause = 0;
44 0 : bool use_multi = false;
45 0 : bool verbose = false;
46 0 : namespace po = boost::program_options;
47 0 : po::options_description desc("Simple test program for ConfigClient class");
48 0 : desc.add_options()(
49 : //"file,f", po::value<std::string>(&file), "file to publish as our configuration")(
50 : "name,n",
51 0 : po::value<std::string>(&name),
52 0 : "name of session to publish our config under")(
53 0 : "count,c", po::value<int>(&connection_count), "number of connections to publish")(
54 0 : "port,p", po::value<std::string>(&port), "port to connect to on configuration server")(
55 0 : "server,s", po::value<std::string>(&server), "Configuration server to connect to")(
56 0 : "pause,P", po::value<int>(&pause), "Pause (in seconds) between publish an lookups")(
57 0 : ",m", po::bool_switch(&use_multi), "publish using vectors of ids and uris")(
58 0 : "verbose,v", po::bool_switch(&verbose), "print more verbose output");
59 :
60 0 : try {
61 0 : po::variables_map vm;
62 0 : po::store(po::parse_command_line(argc, argv, desc), vm);
63 0 : po::notify(vm);
64 0 : } catch (std::exception& ex) {
65 0 : std::cerr << "Error parsing command line " << ex.what() << std::endl; // NOLINT
66 0 : std::cerr << desc << std::endl; // NOLINT
67 0 : return 0;
68 0 : }
69 :
70 0 : dunedaq::logging::Logging::setup(name, "config_client_test");
71 :
72 0 : ConfigClient client(server, port, name, 1000ms);
73 :
74 0 : std::vector<ConnectionRegistration> connections;
75 0 : std::ostringstream num_str;
76 0 : for (int con = 0; con < connection_count; con++) {
77 0 : num_str.str("");
78 0 : num_str << std::setfill('0') << std::setw(3) << con;
79 0 : std::string conn_id = "DRO-" + num_str.str() + "-tp_to_trigger";
80 0 : num_str.str("");
81 0 : num_str << 1234 + con;
82 0 : std::string uri = "tcp://192.168.1.100:" + num_str.str();
83 0 : ConnectionRegistration conn_reg;
84 0 : conn_reg.uid = conn_id;
85 0 : conn_reg.data_type = "TPSet";
86 0 : conn_reg.uri = uri;
87 0 : conn_reg.connection_type = dunedaq::iomanager::ConnectionType::kSendRecv;
88 0 : connections.push_back(conn_reg);
89 0 : }
90 :
91 0 : std::cout << "Publishing my connections\n"; // NOLINT
92 0 : auto start = system_clock::now();
93 0 : if (use_multi) {
94 0 : client.publish(connections);
95 : } else {
96 0 : for (int con = 0; con < connection_count; con++) {
97 0 : client.publish(connections[con]);
98 : }
99 : }
100 0 : auto end_publish = system_clock::now();
101 :
102 0 : if (pause > 0) {
103 0 : std::cout << " Pausing to allow initial entries to time out"; // NOLINT
104 0 : std::cout.flush(); // NOLINT
105 0 : for (int s = 0; s < pause; s++) {
106 0 : std::this_thread::sleep_for(1s);
107 0 : std::cout << "."; // NOLINT
108 0 : std::cout.flush(); // NOLINT
109 : }
110 0 : std::cout << std::endl; // NOLINT
111 : }
112 :
113 0 : auto start_lookups = system_clock::now();
114 0 : std::cout << "Looking up connections[1]: "; // NOLINT
115 0 : std::cout.flush(); // NOLINT
116 0 : ConnectionRequest req;
117 0 : req.data_type = connections[0].data_type;
118 0 : req.uid_regex = connections[0].uid;
119 0 : auto result = client.resolve_connection(req);
120 0 : if (result.connections.size() == 1) {
121 0 : std::cout << "resolved to [" << result.connections[0].uid << "]\n"; // NOLINT
122 : } else {
123 0 : std::cout << "Unexpected number of uris (" << result.connections.size() << ")in response\n"; // NOLINT
124 : }
125 0 : for (std::string dt : { "2", "DRO-.*-", "DRO-00[1-4]-tp_to_trigger", "tp_to_trigger" }) {
126 0 : std::cout << "Looking up connections matching '" << dt << "'"; // NOLINT
127 0 : req.uid_regex = dt;
128 0 : result = client.resolve_connection(req);
129 0 : std::cout << ". Resolved to " << result.connections.size() << " uris:"; // NOLINT
130 0 : if (verbose) {
131 0 : std::cout << " ["; // NOLINT
132 0 : for (unsigned int i = 0; i < result.connections.size(); i++) {
133 0 : std::cout << result.connections[i].uri; // NOLINT
134 0 : if (i < result.connections.size() - 1)
135 0 : std::cout << ","; // NOLINT
136 : }
137 0 : std::cout << "]"; // NOLINT
138 : }
139 0 : std::cout << std::endl; // NOLINT
140 0 : }
141 0 : auto end_lookups = std::chrono::system_clock::now();
142 :
143 0 : std::cout << "Retracting connections\n"; // NOLINT
144 0 : if (use_multi) {
145 0 : client.retract();
146 : } else {
147 0 : for (auto const& con : connections) {
148 0 : ConnectionId id;
149 0 : id.uid = con.uid;
150 0 : id.data_type = con.data_type;
151 0 : client.retract(id);
152 0 : }
153 : }
154 :
155 0 : auto end_retract = system_clock::now();
156 0 : double retract_time = static_cast<double>(duration_cast<microseconds>(end_retract - end_lookups).count());
157 0 : double publish_time = static_cast<double>(duration_cast<microseconds>(end_publish - start).count());
158 0 : double lookup_time = static_cast<double>(duration_cast<microseconds>(end_lookups - start_lookups).count());
159 0 : std::cout << "Timing: publish " << publish_time / 1e6 << ", lookup " << lookup_time / 1e6 << ", retract " // NOLINT
160 0 : << retract_time / 1e6 << " seconds" << std::endl;
161 :
162 0 : return 0;
163 0 : } // NOLINT
|