fda0cd403149c4b1f3dda9d556b724e9eae4bab7
[ric-plt/sdl.git] / src / cli / testgetsetcommand.cpp
1 #include <ostream>
2 #include <cstdlib>
3 #include <fstream>
4 #include <string>
5 #include <iostream>
6 #include <boost/property_tree/ptree.hpp>
7 #include <boost/property_tree/json_parser.hpp>
8 #include <chrono>
9 #include <thread>
10 #include "private/cli/commandmap.hpp"
11 #include "private/configurationpaths.hpp"
12 #include <sdl/syncstorage.hpp>
13
14 using namespace shareddatalayer;
15 using namespace shareddatalayer::cli;
16
17 namespace
18 {
19     std::shared_ptr<shareddatalayer::SyncStorage> createSyncStorage(const std::string& nsStr, std::ostream& out)
20     {
21         try
22         {
23             auto sdl(shareddatalayer::SyncStorage::create());
24             sdl->waitReady(nsStr, std::chrono::minutes(1));
25             sdl->setOperationTimeout(std::chrono::seconds(5));
26             return sdl;
27         }
28         catch (const shareddatalayer::Exception& error)
29         {
30             out << "SyncStorage create failed: " << error.what() << std::endl;
31         }
32
33         out << "Test suspended!" << std::endl;
34         return nullptr;
35     }
36
37     void execRemoveAll(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, std::ostream& out)
38     {
39         try
40         {
41             sdl.removeAll(nsStr);
42         }
43         catch (const shareddatalayer::Exception& error)
44         {
45             out << "removeAll failed: " << error.what() << std::endl;
46         }
47     }
48
49     void execSet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
50     {
51         try
52         {
53             sdl.set(nsStr, { { key, val } });
54         }
55         catch (const shareddatalayer::Exception& error)
56         {
57             out << "Set " << key << " failed: " << error.what() << std::endl;
58         }
59     }
60
61     void execGet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
62     {
63         try
64         {
65             auto map(sdl.get(nsStr, { key }));
66             auto i(map.find(key));
67             if (i == map.end())
68                 out << "Get " << key << ": Not found!" << std::endl;
69             else if (i->second != val)
70                 out << "Get " << key << ": Wrong value!" << std::endl;
71         }
72         catch (const shareddatalayer::Exception& error)
73         {
74             out << "Get " << key << " failed: " << error.what() << std::endl;
75         }
76     }
77
78     void timeoutThread(const int& timeout)
79     {
80         std::this_thread::sleep_for(std::chrono::seconds(timeout));
81         std::cerr << "SyncStorage create timeout, aborting after " << timeout << " seconds"<< std::endl;
82         std::exit(EXIT_FAILURE);
83     }
84
85     void setTimeout(const int& timeout)
86     {
87         if (timeout)
88         {
89             std::thread t(timeoutThread, timeout);
90             t.detach();
91         }
92     }
93
94     int TestGetSetCommand(std::ostream& out, const boost::program_options::variables_map& map)
95     {
96         auto keyCount(map["key-count"].as<int>());
97         const auto timeout(map["timeout"].as<int>());
98         auto ns(map["ns"].as<std::string>());
99         setTimeout(timeout);
100         auto sdl(createSyncStorage(ns, out));
101         if (sdl == nullptr)
102             return EXIT_FAILURE;
103
104         out << "namespace\t"
105             << "key\t"
106             << "value\t"
107             << "Write\tRead" << std::endl;
108
109         for (uint8_t val(0); 0 < keyCount--; ++val)
110         {
111             auto key("key_" + std::to_string(val));
112
113             auto wStart(std::chrono::high_resolution_clock::now());
114             execSet(std::ref(*sdl), ns, key, {val}, out);
115             auto wEnd(std::chrono::high_resolution_clock::now());
116             auto writeLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(wEnd - wStart);
117
118             auto rStart(std::chrono::high_resolution_clock::now());
119             execGet(std::ref(*sdl), ns, key, {val}, out);
120             auto rEnd(std::chrono::high_resolution_clock::now());
121             auto readLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(rEnd - rStart);
122
123             out << ns << '\t'
124                 << key << '\t'
125                 << std::dec << static_cast<int>(val) << "\t"
126                 << std::dec << writeLatency_us.count() << "\t"
127                 << std::dec << readLatency_us.count() << std::endl;
128         }
129
130         auto start(std::chrono::high_resolution_clock::now());
131         execRemoveAll(std::ref(*sdl), ns, out);
132         auto end(std::chrono::high_resolution_clock::now());
133         auto used_us = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
134         out << "All test keys removed in " << used_us.count() << " microseconds" << std::endl;
135
136         return EXIT_SUCCESS;
137     }
138 }
139
140 AUTO_REGISTER_COMMAND(std::bind(TestGetSetCommand, std::placeholders::_1, std::placeholders::_3),
141                       "test-get-set",
142                       "Write and read to DB and check latency",
143                       "Check that basic SDL api commands (set/get) works normally and measure latency.",
144                       CommandMap::Category::UTIL, 30010,
145                       ("key-count", boost::program_options::value<int>()->default_value(10), "Number of write/read keys")
146                       ("timeout", boost::program_options::value<int>()->default_value(0), "Timeout (in seconds), Default is no timeout")
147                       ("ns", boost::program_options::value<std::string>()->default_value("sdltoolns"), "namespace to use"));