2 #include <logging/logging.h>
3 #include <boost/program_options.hpp>
14 namespace bpo = boost::program_options;
16 void checkForUpdatesCmd(
const std::vector<std::string> &opts) {
17 namespace fs = boost::filesystem;
18 unsigned int devicesPerSec;
20 unsigned int parallelism;
22 bpo::options_description description(
"Check for update options");
24 description.add_options()
25 (
"inputdir,i", bpo::value<std::string>(&inputDir)->required(),
"path to the input data")
26 (
"rate,r", bpo::value<unsigned int>(&devicesPerSec)->default_value(5),
"devices/sec")
27 (
"number,n", bpo::value<unsigned int>(&opsNr)->default_value(100),
"number of operation to execute")
28 (
"threads,t", bpo::value<unsigned int>(¶llelism)->default_value(std::thread::hardware_concurrency()),
"number of worker threads");
31 bpo::variables_map vm;
32 bpo::store(bpo::command_line_parser(opts).options(description).run(), vm);
35 const fs::path inputPath(inputDir);
36 LOG_INFO <<
"Checking for updates...";
37 checkForUpdates(inputPath, devicesPerSec, opsNr, parallelism);
41 void fetchRemoteCmd(
const std::vector<std::string> &opts) {
44 std::string branchName;
45 std::string remoteUrl;
46 unsigned int opsPerSec;
48 unsigned int parallelism;
49 bpo::options_description description(
"Fetch from ostree");
51 description.add_options()
52 (
"inputdir,i", bpo::value<std::string>(&inputDir)->required(),
"Directory containig provisioned devices.")
53 (
"outputdir,o", bpo::value<std::string>(&outDir)->required(),
"Directory where repos will be created")
54 (
"branch,b", bpo::value<std::string>(&branchName)->required(),
"Name of a branch to pull")
55 (
"url,u", bpo::value<std::string>(&remoteUrl)->required(),
"Url of the repository")
56 (
"number,n", bpo::value<unsigned int>(&opsNr)->default_value(100),
"number of operation to execute")
57 (
"threads,t", bpo::value<unsigned int>(¶llelism)->default_value(std::thread::hardware_concurrency()),
"number of worker threads")
58 (
"rate,r", bpo::value<unsigned int>(&opsPerSec)->default_value(50),
"repo pulls per second");
61 bpo::variables_map vm;
62 bpo::store(bpo::command_line_parser(opts).options(description).run(), vm);
65 const boost::filesystem::path outputPath(outDir);
66 fetchFromOstree(inputDir, outputPath, branchName, remoteUrl, opsPerSec, opsNr, parallelism);
69 void checkAndFetchCmd(
const std::vector<std::string> &opts) {
70 namespace fs = boost::filesystem;
71 unsigned int checkPerSec;
73 unsigned int checkParallelism;
74 std::string branchName;
75 std::string remoteUrl;
76 unsigned int fetchesPerSec;
77 unsigned int fetchesNr;
78 unsigned int fetchesParallelism;
81 bpo::options_description description(
"Check for update options");
83 description.add_options()
84 (
"inputdir,i", bpo::value<std::string>(&inputDir)->required(),
"path to the input data")
85 (
"outputdir,o", bpo::value<std::string>(&outDir)->required(),
"Directory where repos will be created")
86 (
"branch,b", bpo::value<std::string>(&branchName)->required(),
"Name of a branch to pull")
87 (
"url,u", bpo::value<std::string>(&remoteUrl)->required(),
"Url of the repository")
88 (
"fn", bpo::value<unsigned int>(&fetchesNr)->default_value(100),
"number of fetches from treehub")
89 (
"ft", bpo::value<unsigned int>(&fetchesParallelism)->default_value(std::thread::hardware_concurrency()),
"number of fetch worker threads")
90 (
"fr", bpo::value<unsigned int>(&fetchesPerSec)->default_value(50),
"fetches per second")
91 (
"cr", bpo::value<unsigned int>(&checkPerSec)->default_value(5),
"check for update/sec")
92 (
"cn", bpo::value<unsigned int>(&checkNr)->default_value(100),
"number of checks to execute")
93 (
"ct", bpo::value<unsigned int>(&checkParallelism)->default_value(std::thread::hardware_concurrency()),
"number of check worker threads");
96 bpo::variables_map vm;
97 bpo::store(bpo::command_line_parser(opts).options(description).run(), vm);
100 const fs::path inputPath(inputDir);
101 const fs::path outputPath(outDir);
102 std::thread checkThread{checkForUpdates, std::ref(inputPath), checkPerSec, checkNr, checkParallelism};
103 std::thread fetchThread{
104 fetchFromOstree, std::ref(inputPath), std::ref(outputPath), std::ref(branchName), std::ref(remoteUrl),
105 fetchesPerSec, fetchesNr, fetchesParallelism};
111 void provisionDevicesCmd(
const std::vector<std::string> &opts) {
112 using namespace boost::filesystem;
113 unsigned int devicesNr;
117 std::string pathToCredentials;
119 bpo::options_description description(
"Register devices");
122 description.add_options()
123 (
"outputdir,o", bpo::value<std::string>(&outDir)->required(),
"output directory")
124 (
"gateway,g", bpo::value<std::string>(&gwUrl)->required(),
"url of the device gateway")
125 (
"credentials,c", bpo::value<std::string>(&pathToCredentials),
"path to a provisioning credentials")
126 (
"dev-number,n", bpo::value<unsigned int>(&devicesNr)->default_value(100),
"number of devices")
127 (
"rate,r", bpo::value<uint>(&devicesPerSec)->default_value(2),
"devices/sec")
128 (
"threads,t", bpo::value<size_t>(¶llelism)->default_value(std::thread::hardware_concurrency()),
"number of worker threads");
131 bpo::variables_map vm;
132 bpo::store(bpo::command_line_parser(opts).options(description).run(), vm);
135 const path devicesDir(outDir);
137 const path credentialsFile(pathToCredentials);
138 mkDevices(devicesDir, credentialsFile, gwUrl, parallelism, devicesNr, devicesPerSec);
141 void setLogLevel(
const bpo::variables_map &vm) {
143 boost::log::trivial::severity_level severity =
144 static_cast<boost::log::trivial::severity_level>(vm[
"loglevel"].as<int>());
145 if (severity < boost::log::trivial::trace) {
146 LOG_DEBUG <<
"Invalid log level";
147 severity = boost::log::trivial::trace;
149 if (boost::log::trivial::fatal < severity) {
150 LOG_WARNING <<
"Invalid log level";
151 severity = boost::log::trivial::fatal;
154 loggerConfig.loglevel = severity;
155 logger_set_threshold(loggerConfig);
158 int main(
int argc,
char *argv[]) {
159 std::srand(static_cast<unsigned int>(std::time(0)));
161 std::map<std::string, std::function<void(std::vector<std::string>)>> commands{{
"provision", provisionDevicesCmd},
162 {
"check", checkForUpdatesCmd}
165 {
"checkfetch", checkAndFetchCmd},
166 {
"fetch", fetchRemoteCmd}
170 std::stringstream acc;
172 acc <<
"Supported tests: ";
173 for (
auto const &elem : commands) {
181 std::string supportedTests = acc.str();
183 bpo::options_description description(
"OTA load tests");
184 description.add_options()(
"help,h",
"Show help message")(
"loglevel", bpo::value<int>()->default_value(3),
185 "set log level 0-4 (trace, debug, warning, info, error)")(
186 "test", bpo::value<std::string>(&cmd), supportedTests.c_str());
188 bpo::variables_map vm;
189 bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(description).allow_unregistered().run();
190 bpo::store(parsed, vm);
193 if (vm.count(
"help")) {
194 std::cout << description << std::endl;
201 if (vm.count(
"test")) {
202 auto fn = commands.find(cmd);
203 if (fn != commands.end()) {
204 openssl_callbacks_setup();
205 std::vector<std::string> unprocessedOptions = bpo::collect_unrecognized(parsed.options, bpo::include_positional);
206 fn->second(unprocessedOptions);
207 openssl_callbacks_cleanup();
209 LOG_ERROR << supportedTests;