Line data Source code
1 : #include "test/common.h"
2 :
3 : #include "artdaq-database/BasicTypes/basictypes.h"
4 : #include "artdaq-database/ConfigurationDB/configuration_common.h"
5 : #include "artdaq-database/ConfigurationDB/dispatch_common.h"
6 : #include "artdaq-database/ConfigurationDB/options_operations.h"
7 :
8 : #include "artdaq-database/JsonDocument/JSONDocument.h"
9 : #include "artdaq-database/JsonDocument/JSONDocumentBuilder.h"
10 : #include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb.h"
11 : #include "artdaq-database/StorageProviders/MongoDB/provider_mongodb.h"
12 :
13 : #include "artdaq-database/DataFormats/Json/json_reader.h"
14 : #include "artdaq-database/DataFormats/Json/presort_json.h"
15 :
16 : namespace db = artdaq::database;
17 : namespace cf = db::configuration;
18 : namespace cfo = cf::options;
19 :
20 : namespace bpo = boost::program_options;
21 :
22 : using Options = cf::BulkOperations;
23 :
24 2 : int main(int argc, char* argv[]) try {
25 2 : artdaq::database::filesystem::debug::enable();
26 2 : artdaq::database::mongo::debug::enable();
27 : // artdaq::database::docrecord::debug::JSONDocument();
28 2 : artdaq::database::docrecord::debug::JSONDocumentBuilder();
29 :
30 2 : artdaq::database::configuration::debug::ManageConfigs();
31 2 : artdaq::database::configuration::debug::ManageAliases();
32 2 : artdaq::database::configuration::debug::ManageDocuments();
33 :
34 2 : artdaq::database::configuration::debug::options::OperationBase();
35 2 : artdaq::database::configuration::debug::options::ManageDocuments();
36 2 : artdaq::database::configuration::debug::options::ManageConfigs();
37 2 : artdaq::database::configuration::debug::options::ManageAliases();
38 :
39 2 : artdaq::database::configuration::debug::detail::ManageConfigs();
40 2 : artdaq::database::configuration::debug::detail::ManageAliases();
41 2 : artdaq::database::configuration::debug::detail::ManageDocuments();
42 :
43 2 : artdaq::database::configuration::debug::MongoDB();
44 2 : artdaq::database::configuration::debug::UconDB();
45 :
46 2 : debug::registerUngracefullExitHandlers();
47 2 : artdaq::database::useFakeTime(true);
48 :
49 2 : auto options = Options{argv[0]};
50 2 : auto desc = options.makeProgramOptions();
51 :
52 2 : bpo::variables_map vm;
53 :
54 : try {
55 2 : bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
56 2 : bpo::notify(vm);
57 0 : } catch (bpo::error const& e) {
58 0 : std::cerr << "Exception from command line processing in " << argv[0] << ": " << e.what() << "\n";
59 0 : return process_exit_code::INVALID_ARGUMENT;
60 0 : }
61 :
62 4 : if (vm.count("help") != 0u) {
63 0 : std::cerr << desc << std::endl;
64 0 : return process_exit_code::HELP;
65 : }
66 :
67 2 : auto exit_code = options.readProgramOptions(vm);
68 2 : if (exit_code != process_exit_code::SUCCESS) {
69 0 : std::cerr << desc << std::endl;
70 0 : return exit_code;
71 : }
72 :
73 4 : if (vm.count(apiliteral::option::result) == 0u) {
74 : std::cerr << "Exception from command line processing in " << argv[0] << ": no result file name given.\n"
75 : << "For usage and an options list, please do '" << argv[0] << " --help"
76 0 : << "'.\n";
77 :
78 0 : return process_exit_code::INVALID_ARGUMENT | 1;
79 : }
80 :
81 2 : auto file_res_name = vm[apiliteral::option::result].as<std::string>();
82 :
83 2 : auto options_string = options.to_string();
84 2 : auto operation_name = std::string{"newconfig"};
85 :
86 2 : std::cout << "Parsed options:\n" << options_string << "\n";
87 :
88 : using namespace artdaq::database::configuration::json;
89 :
90 2 : cf::registerOperation<cf::opsig_str_t, cf::opsig_str_t::FP, std::string const&>(operation_name, create_configuration, options_string);
91 :
92 2 : std::cout << "Running test:<" << operation_name << ">\n";
93 :
94 2 : auto result = cf::getOperations().at(operation_name)->invoke();
95 :
96 2 : if (!result.first) {
97 0 : std::cout << "Test failed; error message: " << result.second << "\n";
98 0 : std::cout << ::debug::current_exception_diagnostic_information();
99 0 : return process_exit_code::FAILURE;
100 : }
101 :
102 2 : if (result.second.empty()) {
103 : std::cout << "Test failed; error message: result is empty."
104 0 : << "\n";
105 0 : return process_exit_code::FAILURE;
106 : }
107 :
108 2 : auto returned = std::string{result.second};
109 :
110 2 : auto expected = std::string{};
111 2 : db::read_buffer_from_file(expected, file_res_name);
112 :
113 : using cfo::data_format_t;
114 :
115 2 : if (options.format() == data_format_t::gui) {
116 : // Presort GUI JSON documents by "name" field before comparison
117 2 : auto sorted_returned = artdaq::database::json::presort_gui_json_by_name(returned);
118 2 : auto sorted_expected = artdaq::database::json::presort_gui_json_by_name(expected);
119 :
120 2 : auto compare_result = artdaq::database::json::compare_json_objects(sorted_returned, sorted_expected);
121 2 : if (compare_result.first) {
122 2 : std::cout << "returned:\n" << returned << "\n";
123 :
124 2 : return process_exit_code::SUCCESS;
125 : }
126 0 : std::cout << "Test failed (expected!=returned); error message: " << compare_result.second << "\n";
127 6 : } else if (options.format() == data_format_t::db || options.format() == data_format_t::json) {
128 0 : auto compare_result = artdaq::database::json::compare_json_objects(returned, expected);
129 0 : if (compare_result.first) {
130 0 : std::cout << "returned:\n" << returned << "\n";
131 :
132 0 : return process_exit_code::SUCCESS;
133 : }
134 0 : std::cout << "Test failed (expected!=returned); error message: " << compare_result.second << "\n";
135 0 : } else if (expected == returned) {
136 0 : std::cout << "returned:\n" << returned << "\n";
137 :
138 0 : return process_exit_code::SUCCESS;
139 0 : } else if (expected.pop_back(), expected == returned) {
140 0 : std::cout << "returned:\n" << returned << "\n";
141 :
142 0 : return process_exit_code::SUCCESS;
143 : }
144 :
145 0 : std::cout << "Test failed (expected!=returned)\n";
146 :
147 0 : std::cout << "returned:\n" << returned << "\n";
148 0 : std::cout << "expected:\n" << expected << "\n";
149 :
150 0 : auto mismatch = std::mismatch(expected.begin(), expected.end(), returned.begin());
151 0 : std::cout << "File sizes (exp,ret)=(" << std::distance(expected.begin(), expected.end()) << "," << std::distance(returned.begin(), returned.end())
152 0 : << ")\n";
153 :
154 0 : std::cout << "First mismatch at position " << std::distance(expected.begin(), mismatch.first) << ", (exp,ret)=(0x" << std::hex
155 0 : << static_cast<unsigned int>(*mismatch.first) << ",0x" << static_cast<unsigned int>(*mismatch.second) << ")\n";
156 :
157 0 : auto file_out_name = std::string(db::filesystem::mkdir(tmpdir))
158 0 : .append("/")
159 0 : .append(argv[0])
160 0 : .append("-")
161 0 : .append(operation_name)
162 0 : .append("-")
163 0 : .append(basename(const_cast<char*>(file_res_name.c_str())))
164 0 : .append(".txt");
165 :
166 0 : db::write_buffer_to_file(returned, file_out_name);
167 :
168 0 : std::cout << "Wrote file:" << file_out_name << "\n";
169 :
170 0 : return process_exit_code::FAILURE;
171 2 : } catch (...) {
172 0 : std::cout << "Process exited with error: " << ::debug::current_exception_diagnostic_information();
173 0 : return process_exit_code::UNCAUGHT_EXCEPTION;
174 0 : }
|