Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-20 08:45:51

0001 #include <cassert>
0002 #include <cstdlib>
0003 #include <filesystem>
0004 #include <fstream>
0005 #include <stdexcept>
0006 #include <string>
0007 #include <unistd.h>
0008 
0009 #include "EventTiming.hh"
0010 #include "SEventConfig.hh"
0011 #include "config.h"
0012 
0013 namespace
0014 {
0015 namespace fs = std::filesystem;
0016 
0017 void WriteText(const fs::path& path, const std::string& text)
0018 {
0019     std::ofstream output(path, std::ios::binary | std::ios::trunc);
0020     assert(output);
0021     output << text;
0022     output.close();
0023     assert(output);
0024 }
0025 
0026 void Require(bool condition, const char* message)
0027 {
0028     if (!condition)
0029         throw std::runtime_error(message);
0030 }
0031 } // namespace
0032 
0033 int main()
0034 {
0035     const fs::path directory = fs::temp_directory_path() /
0036                                ("ConfigTest-" + std::to_string(static_cast<long long>(::getpid())));
0037     const fs::path output_dir = directory / "output";
0038     fs::remove_all(directory);
0039     fs::create_directories(directory);
0040 
0041     WriteText(
0042         directory / "timing.json",
0043         "{\n"
0044         "  \"event\": {\"output_dir\": \"" +
0045             output_dir.string() + "\"},\n"
0046                                   "  \"event_timing\": {\n"
0047                                   "    \"output\": \"events.csv\",\n"
0048                                   "    \"profile\": {\n"
0049                                   "      \"enabled\": true,\n"
0050                                   "      \"output\": \"event_timing_profile_%03d.csv\",\n"
0051                                   "      \"path_index\": 7\n"
0052                                   "    }\n"
0053                                   "  }\n"
0054                                   "}\n");
0055 
0056     setenv("SIMPHONY_CONFIG_DIR", directory.c_str(), 1);
0057     EventTimingProfile::Clear();
0058     const simphony::Config config("timing");
0059 
0060     assert(config.event_timing_output == output_dir / "events.csv");
0061     assert(config.event_timing_profile_enabled);
0062     assert(config.event_timing_profile_output == output_dir / "event_timing_profile_%03d.csv");
0063     assert(config.event_timing_profile_path_index == 7);
0064     assert(EventTimingProfile::Enabled());
0065     assert(EventTimingProfile::Path() == output_dir / "event_timing_profile_007.csv");
0066     assert(EventTimingRecorder(config.event_timing_output).enabled());
0067     const std::vector<EventTimingProfileRecord> records = EventTimingProfile::Records();
0068     assert(records.size() == 1u);
0069     assert(records.front().name == "EventTimingProfile__Configure");
0070     assert(records.front().sample.has(EventTimingCapture::Monotonic));
0071 
0072     WriteText(directory / "omitted.json", "{}\n");
0073     const simphony::Config omitted("omitted");
0074     assert(omitted.event_timing_output.empty());
0075     assert(!EventTimingRecorder(omitted.event_timing_output).enabled());
0076     assert(!EventTimingProfile::Enabled());
0077 
0078     WriteText(
0079         directory / "empty.json",
0080         "{\"event_timing\": {\"output\": \"\", \"profile\": {\"enabled\": false}}}\n");
0081     const simphony::Config empty("empty");
0082     assert(empty.event_timing_output.empty());
0083     assert(!EventTimingRecorder(empty.event_timing_output).enabled());
0084     assert(!EventTimingProfile::Enabled());
0085 
0086     WriteText(
0087         directory / "bad-timing.json",
0088         "{\"event_timing\": {\"profile\": {\"path_index\": \"seven\"}}}\n");
0089     bool rejected_bad_index = false;
0090     try
0091     {
0092         (void)simphony::Config("bad-timing");
0093     }
0094     catch (const std::runtime_error&)
0095     {
0096         rejected_bad_index = true;
0097     }
0098     assert(rejected_bad_index);
0099 
0100     WriteText(directory / "ser-none.json", "{\"ser\": {\"interval\": 8, \"hint\": \"none\"}}\n");
0101     const simphony::Config ser_none("ser-none");
0102     Require(ser_none.ser_hint == simphony::SerHint::None, "ser.hint none was not parsed");
0103     Require(SEventConfig::_SerHint == 0, "ser.hint none was not applied");
0104 
0105     WriteText(directory / "ser-bounce.json", "{\"ser\": {\"interval\": 8, \"hint\": \"bounce\"}}\n");
0106     const simphony::Config ser_bounce("ser-bounce");
0107     Require(ser_bounce.ser_hint == simphony::SerHint::Bounce, "ser.hint bounce was not parsed");
0108     Require(SEventConfig::_SerHint == 1, "ser.hint bounce was not applied");
0109 
0110     for (const auto& [name, value] : std::vector<std::pair<std::string, std::string>>{
0111              {"bad-ser-number", "2"},
0112              {"bad-ser-name", "\"boundary-wavelength\""},
0113          })
0114     {
0115         WriteText(directory / (name + ".json"), "{\"ser\": {\"hint\": " + value + "}}\n");
0116         bool rejected_bad_hint = false;
0117         try
0118         {
0119             (void)simphony::Config(name);
0120         }
0121         catch (const std::runtime_error&)
0122         {
0123             rejected_bad_hint = true;
0124         }
0125         Require(rejected_bad_hint, "invalid ser.hint was accepted");
0126     }
0127 
0128     EventTimingProfile::Configure(false);
0129     unsetenv("SIMPHONY_CONFIG_DIR");
0130     fs::remove_all(directory);
0131     return 0;
0132 }