From 54015e89f1bf959f286468dc8589a77fcf123a9e Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 5 May 2026 14:43:38 +0200 Subject: [PATCH 1/2] Added support for Device in adapter stream to the agent with MTConnectDevices complete document. Added tests and fixed all test names that were not descriptive --- src/mtconnect/agent.cpp | 9 +- src/mtconnect/configuration/agent_config.cpp | 3 +- src/mtconnect/parser/xml_parser.cpp | 80 ++++++++++++++--- src/mtconnect/sink/rest_sink/request.hpp | 1 + src/mtconnect/sink/rest_sink/server.hpp | 1 + src/mtconnect/sink/rest_sink/session_impl.cpp | 10 ++- test_package/agent_asset_test.cpp | 10 +-- test_package/agent_test.cpp | 12 +-- test_package/asset_buffer_test.cpp | 8 +- test_package/asset_test.cpp | 2 +- test_package/change_observer_test.cpp | 10 +-- test_package/checkpoint_test.cpp | 14 +-- test_package/component_test.cpp | 10 +-- test_package/composition_test.cpp | 6 +- test_package/config_test.cpp | 32 +++---- test_package/connector_test.cpp | 20 ++--- test_package/coordinate_system_test.cpp | 6 +- test_package/cutting_tool_test.cpp | 27 +++--- test_package/data_item_test.cpp | 16 ++-- test_package/data_set_test.cpp | 32 +++---- test_package/device_test.cpp | 10 +-- test_package/entity_parser_test.cpp | 10 +-- test_package/entity_printer_test.cpp | 10 +-- test_package/entity_test.cpp | 26 +++--- test_package/file_asset_test.cpp | 4 +- test_package/file_cache_test.cpp | 4 +- test_package/json_mapping_test.cpp | 4 +- test_package/json_printer_asset_test.cpp | 12 +-- test_package/json_printer_probe_test.cpp | 22 ++--- test_package/json_printer_stream_test.cpp | 28 +++--- test_package/json_printer_test.cpp | 10 +-- test_package/kinematics_test.cpp | 12 +-- test_package/mqtt_isolated_test.cpp | 4 +- test_package/mqtt_sink_test.cpp | 10 +-- test_package/observation_test.cpp | 12 +-- test_package/pipeline_deliver_test.cpp | 6 +- test_package/qif_document_test.cpp | 2 +- test_package/references_test.cpp | 2 +- test_package/relationship_test.cpp | 6 +- test_package/routing_test.cpp | 12 +-- test_package/sensor_configuration_test.cpp | 2 +- test_package/solid_model_test.cpp | 12 +-- test_package/specification_test.cpp | 18 ++-- test_package/table_test.cpp | 22 ++--- test_package/timestamp_extractor_test.cpp | 8 +- test_package/utilities_test.cpp | 18 ++-- test_package/xml_parser_test.cpp | 88 +++++++++++++++---- 47 files changed, 406 insertions(+), 277 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 1f21e2ec3..0774a86f7 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -461,7 +461,14 @@ namespace mtconnect { { auto printer = dynamic_cast(m_printers["xml"].get()); auto device = m_xmlParser->parseDevice(deviceXml, printer); - loadDevices({device}, source); + if (device == nullptr) + { + LOG(error) << "Error loading device: " << deviceXml; + } + else + { + loadDevices({device}, source); + } } catch (runtime_error &e) { diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 0b5a38e81..e0f1e5f5a 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -522,7 +522,8 @@ namespace mtconnect::configuration { } ptree empty; - auto logger = config.get_child_optional("logger_config").value_or(empty); + auto logger = config.get_child_optional("logger_config") + .value_or(config.get_child_optional("logging").value_or(empty)); const string defaultFileName = channelName + ".log"; const string defaultArchivePattern = channelName + "_%Y-%m-%d_%H-%M-%S_%N.log"; diff --git a/src/mtconnect/parser/xml_parser.cpp b/src/mtconnect/parser/xml_parser.cpp index 5617e3da2..5764fafda 100644 --- a/src/mtconnect/parser/xml_parser.cpp +++ b/src/mtconnect/parser/xml_parser.cpp @@ -258,33 +258,87 @@ namespace mtconnect::parser { DevicePtr XmlParser::parseDevice(const std::string &deviceXml, printer::XmlPrinter *aPrinter) { DevicePtr device; - - using namespace boost::adaptors; - using namespace boost::range; - std::unique_lock lock(m_mutex); + // Parse the device XML unti an in memory doc and then see if we have a root MTConnectDevices + // node or a Device node. If devices, then we need to find the first device and then use the + // entity parser to parse the device. We then log any errors. + + xmlDocPtr doc = nullptr; try { - entity::ErrorList errors; - auto entity = entity::XmlParser::parse(Device::getRoot(), deviceXml, errors); - if (errors.size() > 0) + xmlInitParser(); + xmlSetGenericErrorFunc(nullptr, agentXMLErrorFunc); + + doc = xmlReadMemory(deviceXml.c_str(), int32_t(deviceXml.length()), "DeviceStream.xml", + nullptr, XML_PARSE_NOBLANKS); + if (!doc) + throw runtime_error("Failed to parse device XML"); + + auto root = xmlDocGetRootElement(doc); + if (!root) + throw runtime_error("Device XML has no root element"); + + xmlNodePtr deviceNode = nullptr; + if (xmlStrcmp(root->name, BAD_CAST "MTConnectDevices") == 0) { - LOG(warning) << "Errors parsing Device: " << deviceXml; - for (auto &e : errors) + for (auto child = root->children; child; child = child->next) { - LOG(warning) << " " << e->what(); + if (xmlStrcmp(child->name, BAD_CAST "Devices") == 0) + { + deviceNode = child->children; + break; + } } } + else if (xmlStrcmp(root->name, BAD_CAST "Device") == 0) + { + deviceNode = root; + } else { - device = dynamic_pointer_cast(entity); + throw runtime_error("Root element of device XML must be either MTConnectDevices or Device"); } + + if (!deviceNode) + throw runtime_error("No Device node found in device XML"); + + entity::ErrorList errors; + auto entity = entity::XmlParser::parseXmlNode(Device::getRoot(), deviceNode, errors); + + for (auto &e : errors) + { + if (entity) + LOG(warning) << "When parsing device, a problem was skipped: " << e->what(); + else + LOG(error) << "Failed to parse device: " << e->what(); + } + + if (entity) + device = dynamic_pointer_cast(entity); + else + LOG(error) << "Failed to parse device, skipping"; + + xmlFreeDoc(doc); + doc = nullptr; + } + catch (const runtime_error &e) + { + if (doc) + xmlFreeDoc(doc); + LOG(error) << "Cannot parse device XML: " << e.what(); } catch (const string &e) { - LOG(fatal) << "Cannot parse XML document: " << e; - throw FatalException(); + if (doc) + xmlFreeDoc(doc); + LOG(error) << "Cannot parse XML document: " << e; + } + catch (...) + { + if (doc) + xmlFreeDoc(doc); + LOG(error) << "Cannot parse XML document: unknown exception"; } return device; diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index b96207faf..01f76b8ea 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -45,6 +45,7 @@ namespace mtconnect::sink::rest_sink { std::string m_contentType; ///< The content type for the body std::string m_path; ///< The URI for the request std::string m_foreignIp; ///< The requestors IP Address + std::string m_foreignHost; ///< The requestors IP Address uint16_t m_foreignPort; ///< The requestors Port QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 73377b428..450233a96 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -201,6 +201,7 @@ namespace mtconnect::sink::rest_sink { RestError re(error, request->m_accepts, status::not_found, std::nullopt, request->m_requestId); re.setUri(request->getUri()); + LOG(warning) << "[" << request->m_foreignHost << "]: " << txt.str(); m_errorFunction(session, re); } } diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index d9721763d..233dba92c 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -239,11 +239,17 @@ namespace mtconnect::sink::rest_sink { } m_request->m_foreignIp = remote.address().to_string(); + if (auto a = msg.find(http::field::forwarded); a != msg.end()) + m_request->m_foreignHost = string(a->value()); + else if (auto a = msg.find(http::field::host); a != msg.end()) + m_request->m_foreignHost = string(a->value()); + else + m_request->m_foreignHost = m_request->m_foreignIp; m_request->m_foreignPort = remote.port(); if (auto a = msg.find(http::field::connection); a != msg.end()) m_close = a->value() == "close"; - LOG(info) << "ReST Request: From [" << m_request->m_foreignIp << ':' << remote.port() + LOG(info) << "ReST Request: From [" << m_request->m_foreignHost << ':' << remote.port() << "]: " << msg.method() << " " << msg.target(); // Check if this is a websocket upgrade request. If so, begin a websocket session. @@ -302,7 +308,7 @@ namespace mtconnect::sink::rest_sink { m_complete = complete; m_mimeType = mimeType; m_streaming = true; - + auto now = std::chrono::floor(std::chrono::system_clock::now()); std::string date = std::format("{:%a, %d %b %Y %T} GMT", now); diff --git a/test_package/agent_asset_test.cpp b/test_package/agent_asset_test.cpp index 36b8d9843..b9ce099bc 100644 --- a/test_package/agent_asset_test.cpp +++ b/test_package/agent_asset_test.cpp @@ -643,7 +643,7 @@ TEST_F(AgentAssetTest, should_add_asset_changed_and_asset_added_with_discrete_in } } -TEST_F(AgentAssetTest, AssetPrependId) +TEST_F(AgentAssetTest, asset_id_is_zero_padded_when_prepend_id_prefix_is_used) { addAdapter(); auto agent = m_agentTestHelper->getAgent(); @@ -957,7 +957,7 @@ TEST_F(AgentAssetTest, should_respond_to_http_push_with_list_of_errors) } } -TEST_F(AgentAssetTest, update_asset_count_data_item_v2_0) +TEST_F(AgentAssetTest, asset_count_data_set_is_updated_when_assets_are_added_or_removed) { m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 10, "2.0", 4, true); addAdapter(); @@ -1031,7 +1031,7 @@ TEST_F(AgentAssetTest, update_asset_count_data_item_v2_0) } } -TEST_F(AgentAssetTest, asset_count_should_not_occur_in_header_post_20) +TEST_F(AgentAssetTest, asset_count_is_absent_from_probe_header_in_schema_2_0) { auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 4, true); @@ -1057,7 +1057,7 @@ TEST_F(AgentAssetTest, asset_count_should_not_occur_in_header_post_20) } } -TEST_F(AgentAssetTest, asset_count_should_track_asset_additions_by_type) +TEST_F(AgentAssetTest, asset_count_tracks_additions_and_removals_per_type) { auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 4, true); @@ -1115,7 +1115,7 @@ TEST_F(AgentAssetTest, asset_count_should_track_asset_additions_by_type) } } -TEST_F(AgentAssetTest, asset_should_also_work_using_post_with_assets) +TEST_F(AgentAssetTest, assets_endpoint_accepts_post_requests_for_asset_storage) { auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 4, true); diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 72315732b..71efaedf7 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -88,7 +88,7 @@ class AgentTest : public testing::Test std::chrono::milliseconds m_delay {}; }; -TEST_F(AgentTest, Constructor) +TEST_F(AgentTest, agent_throws_fatal_exception_for_bad_path_and_initializes_with_valid_path) { using namespace configuration; ConfigOptions options {{BufferSize, 17}, {MaxAssets, 8}, {SchemaVersion, "1.7"s}}; @@ -109,7 +109,7 @@ TEST_F(AgentTest, Constructor) ASSERT_NO_THROW(agent->initialize(context)); } -TEST_F(AgentTest, Probe) +TEST_F(AgentTest, probe_endpoint_returns_device_name_for_multiple_paths) { { PARSE_XML_RESPONSE("/probe"); @@ -132,7 +132,7 @@ TEST_F(AgentTest, Probe) } } -TEST_F(AgentTest, FailWithDuplicateDeviceUUID) +TEST_F(AgentTest, agent_throws_fatal_exception_when_devices_have_duplicate_uuid) { using namespace configuration; ConfigOptions options {{BufferSize, 17}, {MaxAssets, 8}, {SchemaVersion, "1.5"s}}; @@ -519,7 +519,7 @@ TEST_F(AgentTest, should_report_2_6_out_of_range_for_current_at) } } -TEST_F(AgentTest, AddAdapter) { addAdapter(); } +TEST_F(AgentTest, adapter_can_be_added_to_agent) { addAdapter(); } TEST_F(AgentTest, should_download_file) { @@ -1271,7 +1271,7 @@ TEST_F(AgentTest, should_ignore_timestamps_if_configured_to_do_so) } } -TEST_F(AgentTest, InitialTimeSeriesValues) +TEST_F(AgentTest, time_series_data_item_reports_unavailable_initially) { addAdapter(); @@ -2401,7 +2401,7 @@ TEST_F(AgentTest, put_condition_should_parse_condition_data) } } -TEST_F(AgentTest, shound_add_asset_count_when_20) +TEST_F(AgentTest, asset_count_data_item_is_added_to_probe_in_schema_2_0) { m_agentTestHelper->createAgent("/samples/min_config.xml", 8, 4, "2.0", 25); diff --git a/test_package/asset_buffer_test.cpp b/test_package/asset_buffer_test.cpp index 558c041a7..6cb3de285 100644 --- a/test_package/asset_buffer_test.cpp +++ b/test_package/asset_buffer_test.cpp @@ -116,7 +116,7 @@ class AssetBufferTest : public testing::Test std::unique_ptr m_assetBuffer; }; -TEST_F(AssetBufferTest, AddAsset) +TEST_F(AssetBufferTest, asset_is_added_to_buffer) { ErrorList errors; auto asset = makeAsset("Asset", "A1", "D1", "2020-12-01T12:00:00Z", errors); @@ -128,7 +128,7 @@ TEST_F(AssetBufferTest, AddAsset) ASSERT_EQ(1, m_assetBuffer->getCountForDevice("D1")); } -TEST_F(AssetBufferTest, ReplaceAsset) +TEST_F(AssetBufferTest, existing_asset_is_replaced_in_buffer) { ErrorList errors; auto asset1 = makeAsset("Asset", "A1", "D1", "2020-12-01T12:00:00Z", errors); @@ -147,7 +147,7 @@ TEST_F(AssetBufferTest, ReplaceAsset) ASSERT_EQ(1, m_assetBuffer->getCountForDevice("D2")); } -TEST_F(AssetBufferTest, TestOverflow) +TEST_F(AssetBufferTest, oldest_asset_is_evicted_when_buffer_overflows) { ErrorList errors; for (int i = 0; i < 10; i++) @@ -175,7 +175,7 @@ TEST_F(AssetBufferTest, TestOverflow) ASSERT_EQ(1, m_assetBuffer->getCountForDevice("D3")); } -TEST_F(AssetBufferTest, RemovedAsset) +TEST_F(AssetBufferTest, removed_asset_decrements_count_and_is_evicted_on_overflow) { ErrorList errors; for (int i = 0; i < 10; i++) diff --git a/test_package/asset_test.cpp b/test_package/asset_test.cpp index 6794d6676..ffa369f0f 100644 --- a/test_package/asset_test.cpp +++ b/test_package/asset_test.cpp @@ -60,7 +60,7 @@ class AssetTest : public testing::Test std::unique_ptr m_writer; }; -TEST_F(AssetTest, TestExtendedAsset) +TEST_F(AssetTest, extended_asset_with_arbitrary_content_is_parsed_and_printed) { auto doc = R"DOC( diff --git a/test_package/change_observer_test.cpp b/test_package/change_observer_test.cpp index 26d91807e..6906db1ba 100644 --- a/test_package/change_observer_test.cpp +++ b/test_package/change_observer_test.cpp @@ -72,7 +72,7 @@ namespace mtconnect { std::optional m_guard; }; - TEST_F(ChangeObserverTest, AddObserver) + TEST_F(ChangeObserverTest, observer_is_registered_with_signaler_after_add) { mtconnect::ChangeObserver changeObserver(*m_strand); @@ -81,7 +81,7 @@ namespace mtconnect { ASSERT_TRUE(m_signaler->hasObserver(&changeObserver)); } - TEST_F(ChangeObserverTest, SignalObserver) + TEST_F(ChangeObserverTest, observer_receives_signal_with_correct_sequence_number) { mtconnect::ChangeObserver changeObserver(*m_strand); @@ -139,7 +139,7 @@ namespace mtconnect { ASSERT_FALSE(changeObserver.wasSignaled()); } - TEST_F(ChangeObserverTest, Cleanup) + TEST_F(ChangeObserverTest, observer_is_removed_from_signaler_when_destroyed) { mtconnect::ChangeObserver *changeObserver = nullptr; @@ -153,7 +153,7 @@ namespace mtconnect { ASSERT_FALSE(m_signaler->hasObserver(changeObserver)); } - TEST_F(ChangeObserverTest, ChangeSequence) + TEST_F(ChangeObserverTest, observer_captures_lowest_sequence_when_signaled_multiple_times) { mtconnect::ChangeObserver changeObserver(*m_strand); @@ -183,7 +183,7 @@ namespace mtconnect { ASSERT_EQ(uint64_t {100}, changeObserver.getSequence()); } - TEST_F(ChangeObserverTest, ChangeSequence2) + TEST_F(ChangeObserverTest, observer_tracks_minimum_sequence_across_out_of_order_signals) { using namespace std::chrono_literals; mtconnect::ChangeObserver changeObserver(*m_strand); diff --git a/test_package/checkpoint_test.cpp b/test_package/checkpoint_test.cpp index 8e09c0a60..599f93954 100644 --- a/test_package/checkpoint_test.cpp +++ b/test_package/checkpoint_test.cpp @@ -84,7 +84,7 @@ class CheckpointTest : public testing::Test DevicePtr m_device; }; -TEST_F(CheckpointTest, AddObservations) +TEST_F(CheckpointTest, adding_observations_updates_refcounts_and_condition_chains) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -151,7 +151,7 @@ TEST_F(CheckpointTest, AddObservations) EXPECT_EQ(1, p5.use_count()); } -TEST_F(CheckpointTest, Copy) +TEST_F(CheckpointTest, copying_checkpoint_increments_observation_refcounts) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -184,7 +184,7 @@ TEST_F(CheckpointTest, Copy) ASSERT_EQ(2, p2.use_count()); } -TEST_F(CheckpointTest, GetObservations) +TEST_F(CheckpointTest, get_observations_returns_filtered_subset_by_data_item_id) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -241,7 +241,7 @@ TEST_F(CheckpointTest, GetObservations) ASSERT_EQ(2, list2.size()); } -TEST_F(CheckpointTest, Filter) +TEST_F(CheckpointTest, filter_removes_observations_not_matching_data_item_ids) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -294,7 +294,7 @@ TEST_F(CheckpointTest, Filter) d1.reset(); } -TEST_F(CheckpointTest, CopyAndFilter) +TEST_F(CheckpointTest, copy_with_filter_retains_only_matching_observations) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -364,7 +364,7 @@ TEST_F(CheckpointTest, CopyAndFilter) ASSERT_EQ(3, list.size()); } -TEST_F(CheckpointTest, ConditionChaining) +TEST_F(CheckpointTest, condition_observations_are_chained_and_cleared_correctly) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -487,7 +487,7 @@ TEST_F(CheckpointTest, ConditionChaining) ASSERT_EQ(1, (int)list.size()); } -TEST_F(CheckpointTest, LastConditionNormal) +TEST_F(CheckpointTest, last_condition_returns_normal_with_empty_code_when_cleared) { entity::ErrorList errors; Timestamp time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; diff --git a/test_package/component_test.cpp b/test_package/component_test.cpp index a48b9bd71..7ebff4ec2 100644 --- a/test_package/component_test.cpp +++ b/test_package/component_test.cpp @@ -67,7 +67,7 @@ class ComponentTest : public testing::Test ComponentPtr m_compB; }; -TEST_F(ComponentTest, Getters) +TEST_F(ComponentTest, component_getters_return_correct_id_name_uuid_and_native_name) { ASSERT_EQ((string) "Axes", string(m_compA->getName())); ASSERT_EQ((string) "1", m_compA->getId()); @@ -83,7 +83,7 @@ TEST_F(ComponentTest, Getters) } // Workning our way through -TEST_F(ComponentTest, Description) +TEST_F(ComponentTest, component_description_stores_manufacturer_serial_number_and_value) { map attributes; attributes["manufacturer"] = "MANUFACTURER"; @@ -111,7 +111,7 @@ TEST_F(ComponentTest, Description) ASSERT_FALSE(d2->hasValue()); } -TEST_F(ComponentTest, Relationships) +TEST_F(ComponentTest, component_parent_and_device_relationships_are_set_correctly) { // Test get/set parents ErrorList errors; @@ -142,7 +142,7 @@ TEST_F(ComponentTest, Relationships) ASSERT_EQ(2, m_compA.use_count()); } -TEST_F(ComponentTest, DataItems) +TEST_F(ComponentTest, data_items_are_added_and_retrieved_from_component) { ASSERT_FALSE(m_compA->getDataItems()); @@ -166,7 +166,7 @@ TEST_F(ComponentTest, DataItems) // Not relevant right now. Tested as references in other places #if 0 -TEST_F(ComponentTest, References) +TEST_F(ComponentTest, component_references_are_stored_with_name_and_id) { diff --git a/test_package/composition_test.cpp b/test_package/composition_test.cpp index baa2d34c1..8ef03320a 100644 --- a/test_package/composition_test.cpp +++ b/test_package/composition_test.cpp @@ -65,7 +65,7 @@ class CompositionTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(CompositionTest, ParseDeviceAndComponentRelationships) +TEST_F(CompositionTest, composition_attributes_description_and_specifications_are_parsed) { using namespace mtconnect::entity; ASSERT_NE(nullptr, m_component); @@ -114,7 +114,7 @@ TEST_F(CompositionTest, ParseDeviceAndComponentRelationships) #define CONFIGURATION_PATH COMPOSITION_PATH "/m:Configuration" #define SPECIFICATIONS_PATH CONFIGURATION_PATH "/m:Specifications" -TEST_F(CompositionTest, XmlPrinting) +TEST_F(CompositionTest, composition_with_specifications_is_printed_in_xml) { { PARSE_XML_RESPONSE("/probe"); @@ -135,7 +135,7 @@ TEST_F(CompositionTest, XmlPrinting) } } -TEST_F(CompositionTest, JsonPrinting) +TEST_F(CompositionTest, composition_with_specifications_is_printed_in_json) { { PARSE_JSON_RESPONSE("/probe"); diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index a7322a1fa..816276bff 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -130,7 +130,7 @@ namespace { std::filesystem::path m_cwd; }; - TEST_F(ConfigTest, BlankConfig) + TEST_F(ConfigTest, blank_config_loads_default_agent_with_one_device) { m_config->loadConfig(""); @@ -140,7 +140,7 @@ namespace { ASSERT_EQ("1.1", *agent->getSchemaVersion()); } - TEST_F(ConfigTest, BufferSize) + TEST_F(ConfigTest, buffer_size_is_rounded_up_to_next_power_of_two) { m_config->loadConfig("BufferSize = 4\n"); @@ -151,7 +151,7 @@ namespace { ASSERT_EQ(16U, circ.getBufferSize()); } - TEST_F(ConfigTest, Device) + TEST_F(ConfigTest, device_is_created_from_config_with_adapter_options) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n"); m_config->loadConfig(str); @@ -173,7 +173,7 @@ namespace { ASSERT_TRUE(device->preserveUuid()); } - TEST_F(ConfigTest, Adapter) + TEST_F(ConfigTest, adapter_config_sets_host_port_and_options) { using namespace std::chrono_literals; @@ -207,7 +207,7 @@ namespace { // ASSERT_TRUE(device->m_preserveUuid); } - TEST_F(ConfigTest, DefaultPreserveUUID) + TEST_F(ConfigTest, default_preserve_uuid_is_applied_to_all_devices) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -221,7 +221,7 @@ namespace { ASSERT_TRUE(device->preserveUuid()); } - TEST_F(ConfigTest, DefaultPreserveOverride) + TEST_F(ConfigTest, adapter_preserve_uuid_overrides_global_default) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -238,7 +238,7 @@ namespace { ASSERT_FALSE(device->preserveUuid()); } - TEST_F(ConfigTest, DisablePut) + TEST_F(ConfigTest, allow_put_enables_put_requests_on_rest_service) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -254,7 +254,7 @@ namespace { ASSERT_TRUE(rest->getServer()->arePutsAllowed()); } - TEST_F(ConfigTest, LimitPut) + TEST_F(ConfigTest, allow_put_from_localhost_restricts_puts_to_loopback_address) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -272,7 +272,7 @@ namespace { ASSERT_TRUE(rest->getServer()->allowPutFrom(std::string("127.0.0.1"))); } - TEST_F(ConfigTest, LimitPutFromHosts) + TEST_F(ConfigTest, allow_put_from_multiple_hosts_permits_puts_from_each) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -291,7 +291,7 @@ namespace { ASSERT_TRUE(rest->getServer()->allowPutFrom(std::string("192.168.0.1"))); } - TEST_F(ConfigTest, Namespaces) + TEST_F(ConfigTest, custom_namespaces_are_registered_for_streams_devices_assets_and_errors) { string streams( "StreamsNamespaces {\n" @@ -363,7 +363,7 @@ namespace { ASSERT_EQ(std::string("urn:example.com:ExampleErrors:1.2"), path); } - TEST_F(ConfigTest, LegacyTimeout) + TEST_F(ConfigTest, legacy_timeout_is_applied_to_adapter_from_global_config) { using namespace std::chrono_literals; @@ -379,7 +379,7 @@ namespace { ASSERT_EQ(2000s, adapter->getLegacyTimeout()); } - TEST_F(ConfigTest, IgnoreTimestamps) + TEST_F(ConfigTest, ignore_timestamps_option_is_propagated_to_adapter) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -393,7 +393,7 @@ namespace { ASSERT_TRUE(IsOptionSet(adapter->getOptions(), configuration::IgnoreTimestamps)); } - TEST_F(ConfigTest, IgnoreTimestampsOverride) + TEST_F(ConfigTest, adapter_ignore_timestamps_overrides_global_setting) { string str("Devices = " TEST_RESOURCE_DIR "/samples/test_config.xml\n" @@ -411,7 +411,7 @@ namespace { ASSERT_FALSE(IsOptionSet(adapter->getOptions(), configuration::IgnoreTimestamps)); } - TEST_F(ConfigTest, SpecifyMTCNamespace) + TEST_F(ConfigTest, mtc_namespace_location_is_set_without_urn_when_using_m_prefix) { string streams( "StreamsNamespaces {\n" @@ -435,7 +435,7 @@ namespace { printer->clearStreamsNamespaces(); } - TEST_F(ConfigTest, SetSchemaVersion) + TEST_F(ConfigTest, schema_version_is_set_on_xml_printer_from_config) { string streams("SchemaVersion = 1.4\n"); @@ -451,7 +451,7 @@ namespace { printer->setSchemaVersion("1.3"); } - TEST_F(ConfigTest, SchemaDirectory) + TEST_F(ConfigTest, schema_directory_registers_all_namespace_urns_and_locations) { string schemas( "SchemaVersion = 1.3\n" diff --git a/test_package/connector_test.cpp b/test_package/connector_test.cpp index 1da1fac85..0b9656d6c 100644 --- a/test_package/connector_test.cpp +++ b/test_package/connector_test.cpp @@ -283,7 +283,7 @@ TEST_F(ConnectorTest, should_process_a_protocol_command) ASSERT_EQ("* Hello Connector", m_connector->m_command); } -TEST_F(ConnectorTest, Heartbeat) +TEST_F(ConnectorTest, heartbeat_is_enabled_after_valid_pong_received) { // Start the accept thread startServer(); @@ -303,7 +303,7 @@ TEST_F(ConnectorTest, Heartbeat) ASSERT_EQ(std::chrono::milliseconds {1000}, m_connector->heartbeatFrequency()); } -TEST_F(ConnectorTest, HeartbeatPong) +TEST_F(ConnectorTest, heartbeat_pong_response_keeps_connection_alive) { // TODO Copy&Paste from Heartbeat // Start the accept thread @@ -339,7 +339,7 @@ TEST_F(ConnectorTest, HeartbeatPong) } } -TEST_F(ConnectorTest, HeartbeatDataKeepAlive) +TEST_F(ConnectorTest, data_response_keeps_connection_alive_during_heartbeat) { startServer(); @@ -373,7 +373,7 @@ TEST_F(ConnectorTest, HeartbeatDataKeepAlive) } } -TEST_F(ConnectorTest, HeartbeatTimeout) +TEST_F(ConnectorTest, connection_is_disconnected_when_heartbeat_times_out) { startServer(); @@ -396,7 +396,7 @@ TEST_F(ConnectorTest, HeartbeatTimeout) ASSERT_TRUE(m_connector->m_disconnected); } -TEST_F(ConnectorTest, LegacyTimeout) +TEST_F(ConnectorTest, connection_is_disconnected_when_legacy_timeout_expires) { startServer(); @@ -416,7 +416,7 @@ TEST_F(ConnectorTest, LegacyTimeout) ASSERT_TRUE(m_connector->m_disconnected); } -TEST_F(ConnectorTest, ParseBuffer) +TEST_F(ConnectorTest, fragmented_data_is_assembled_into_complete_lines) { startServer(); @@ -447,7 +447,7 @@ TEST_F(ConnectorTest, ParseBuffer) ASSERT_EQ((string) "And Again", m_connector->m_data); } -TEST_F(ConnectorTest, ParseBufferFraming) +TEST_F(ConnectorTest, multiple_lines_are_correctly_framed_from_stream) { startServer(); @@ -466,7 +466,7 @@ TEST_F(ConnectorTest, ParseBufferFraming) ASSERT_EQ((string) "fourth", m_connector->m_list[3]); } -TEST_F(ConnectorTest, SendCommand) +TEST_F(ConnectorTest, command_is_sent_with_star_prefix_to_server) { startServer(); @@ -483,7 +483,7 @@ TEST_F(ConnectorTest, SendCommand) ASSERT_EQ("* Hello There;", line); } -TEST_F(ConnectorTest, IPV6Connection) +TEST_F(ConnectorTest, connector_connects_via_ipv6_address) { // TODO: Need to port to Windows > VISTA #if !defined(WIN32) && !defined(AGENT_WITHOUT_IPV6) @@ -545,7 +545,7 @@ TEST_F(ConnectorTest, should_start_heartbeats_when_a_valid_pong_is_received) ASSERT_EQ(std::chrono::milliseconds {323}, m_connector->heartbeatFrequency()); } -TEST_F(ConnectorTest, test_trimming_trailing_white_space) +TEST_F(ConnectorTest, trailing_whitespace_is_trimmed_from_received_lines) { startServer(); diff --git a/test_package/coordinate_system_test.cpp b/test_package/coordinate_system_test.cpp index 3b362d05f..25cc7d13d 100644 --- a/test_package/coordinate_system_test.cpp +++ b/test_package/coordinate_system_test.cpp @@ -63,7 +63,7 @@ class CoordinateSystemTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(CoordinateSystemTest, ParseDeviceAndComponentRelationships) +TEST_F(CoordinateSystemTest, coordinate_systems_with_origin_and_transformation_are_parsed) { ASSERT_NE(nullptr, m_device); @@ -111,7 +111,7 @@ TEST_F(CoordinateSystemTest, ParseDeviceAndComponentRelationships) #define CONFIGURATION_PATH "//m:Device/m:Configuration" #define COORDINATE_SYSTEMS_PATH CONFIGURATION_PATH "/m:CoordinateSystems" -TEST_F(CoordinateSystemTest, XmlPrinting) +TEST_F(CoordinateSystemTest, coordinate_systems_are_printed_with_correct_attributes_in_xml) { { PARSE_XML_RESPONSE("/probe"); @@ -149,7 +149,7 @@ TEST_F(CoordinateSystemTest, XmlPrinting) } } -TEST_F(CoordinateSystemTest, JsonPrinting) +TEST_F(CoordinateSystemTest, coordinate_systems_are_printed_with_correct_fields_in_json) { { PARSE_JSON_RESPONSE("/probe"); diff --git a/test_package/cutting_tool_test.cpp b/test_package/cutting_tool_test.cpp index b48816786..93b3fde6d 100644 --- a/test_package/cutting_tool_test.cpp +++ b/test_package/cutting_tool_test.cpp @@ -85,7 +85,7 @@ class CuttingToolTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(CuttingToolTest, TestMinmalArchetype) +TEST_F(CuttingToolTest, minimal_cutting_tool_archetype_is_parsed) { const auto doc = R"DOC( @@ -144,7 +144,7 @@ TEST_F(CuttingToolTest, TestMinmalArchetype) ASSERT_EQ(content, doc); } -TEST_F(CuttingToolTest, TestMeasurements) +TEST_F(CuttingToolTest, cutting_tool_archetype_measurements_are_parsed) { const auto doc = R"DOC( @@ -203,7 +203,7 @@ TEST_F(CuttingToolTest, TestMeasurements) ASSERT_EQ(content, doc); } -TEST_F(CuttingToolTest, TestItems) +TEST_F(CuttingToolTest, cutting_tool_archetype_cutting_items_are_parsed) { const auto doc = R"DOC( @@ -336,7 +336,7 @@ TEST_F(CuttingToolTest, TestItems) ASSERT_EQ(content, doc); } -TEST_F(CuttingToolTest, TestMinmalTool) +TEST_F(CuttingToolTest, minimal_cutting_tool_is_parsed) { const auto doc = R"DOC( @@ -395,7 +395,7 @@ TEST_F(CuttingToolTest, TestMinmalTool) ASSERT_EQ(content, doc); } -TEST_F(CuttingToolTest, TestMinmalToolError) +TEST_F(CuttingToolTest, cutting_tool_without_cutter_status_fails_validation) { const auto doc = R"DOC( @@ -418,7 +418,7 @@ TEST_F(CuttingToolTest, TestMinmalToolError) ASSERT_EQ("CuttingTool: Invalid element 'CuttingToolLifeCycle'", string(errors.back()->what())); } -TEST_F(CuttingToolTest, TestMeasurementsError) +TEST_F(CuttingToolTest, cutting_tool_measurements_without_value_fails_validation) { const auto doc = R"DOC( @@ -458,7 +458,7 @@ TEST_F(CuttingToolTest, TestMeasurementsError) EXPECT_EQ("CuttingToolLifeCycle: Invalid element 'Measurements'", string((*it)->what())); } -TEST_F(CuttingToolTest, AssetWithSimpleCuttingItems) +TEST_F(CuttingToolTest, cutting_tool_with_simple_cutting_items_is_loaded_via_adapter) { auto printer = dynamic_cast(m_agentTestHelper->m_agent->getPrinter("xml")); ASSERT_TRUE(printer != nullptr); @@ -659,19 +659,19 @@ TEST_F(CuttingToolTest, test_extended_cutting_tool_with_json_v2) )DOC"; - + ErrorList errors; entity::XmlParser parser; - + auto entity = parser.parse(Asset::getRoot(), doc, errors); ASSERT_EQ(0, errors.size()); - + auto asset = dynamic_cast(entity.get()); ASSERT_NE(nullptr, asset); - + entity::JsonEntityPrinter jprinter(2, true); auto jdoc = jprinter.print(entity); - + EXPECT_EQ(R"({ "CuttingTool": { "CuttingToolLifeCycle": { @@ -733,7 +733,8 @@ TEST_F(CuttingToolTest, test_extended_cutting_tool_with_json_v2) "serialNumber": "10", "toolId": "123456" } -})", jdoc); +})", + jdoc); } TEST_F(CuttingToolTest, test_xmlns_with_top_element_alias) diff --git a/test_package/data_item_test.cpp b/test_package/data_item_test.cpp index 7932e387e..b0aae21d4 100644 --- a/test_package/data_item_test.cpp +++ b/test_package/data_item_test.cpp @@ -88,7 +88,7 @@ class DataItemTest : public testing::Test DataItemPtr m_dataItemC; }; -TEST_F(DataItemTest, Getters) +TEST_F(DataItemTest, data_item_getters_return_correct_id_name_type_and_units) { ASSERT_EQ("1", m_dataItemA->getId()); ASSERT_EQ("DataItemTest1", m_dataItemA->getName()); @@ -107,7 +107,7 @@ TEST_F(DataItemTest, Getters) ASSERT_EQ(1.0, m_dataItemB->get("nativeScale")); } -TEST_F(DataItemTest, HasNameAndSource) +TEST_F(DataItemTest, has_name_matches_source_value_when_source_is_set) { namespace di = mtconnect::device_model::data_item; @@ -140,13 +140,13 @@ TEST_F(DataItemTest, HasNameAndSource) ASSERT_EQ("DataItemTest2Source", dataItem->getPreferredName()); } -TEST_F(DataItemTest, IsSample) +TEST_F(DataItemTest, is_sample_returns_true_for_sample_category_and_false_for_condition) { ASSERT_TRUE(m_dataItemA->isSample()); ASSERT_FALSE(m_dataItemC->isSample()); } -TEST_F(DataItemTest, GetCamel) +TEST_F(DataItemTest, pascalize_converts_screaming_snake_case_to_pascal_case) { std::optional prefix; ASSERT_TRUE(pascalize("", prefix).empty()); @@ -173,9 +173,9 @@ TEST_F(DataItemTest, GetCamel) ASSERT_EQ((string) "y", *prefix); } -TEST_F(DataItemTest, Condition) { ASSERT_EQ(DataItem::CONDITION, m_dataItemC->getCategory()); } +TEST_F(DataItemTest, condition_category_data_item_has_condition_category) { ASSERT_EQ(DataItem::CONDITION, m_dataItemC->getCategory()); } -TEST_F(DataItemTest, TimeSeries) +TEST_F(DataItemTest, time_series_representation_appends_time_series_to_observation_name) { { Properties props {{"id", "1"s}, @@ -208,7 +208,7 @@ TEST_F(DataItemTest, TimeSeries) } } -TEST_F(DataItemTest, Statistic) +TEST_F(DataItemTest, statistic_attribute_is_stored_on_data_item) { Properties props {{"id", "1"s}, {"name", "DataItemTest1"s}, @@ -224,7 +224,7 @@ TEST_F(DataItemTest, Statistic) ASSERT_EQ("AVERAGE", d->get("statistic")); } -TEST_F(DataItemTest, SampleRate) +TEST_F(DataItemTest, sample_rate_attribute_is_stored_on_data_item) { Properties props {{"id", "1"s}, {"name", "DataItemTest1"s}, diff --git a/test_package/data_set_test.cpp b/test_package/data_set_test.cpp index 48464d87a..c25a18dc1 100644 --- a/test_package/data_set_test.cpp +++ b/test_package/data_set_test.cpp @@ -79,7 +79,7 @@ using namespace date::literals; inline DataSetEntry operator""_E(const char *c, std::size_t) { return DataSetEntry(c); } -TEST_F(DataSetTest, DataItem) +TEST_F(DataSetTest, data_item_is_identified_as_data_set_representation) { ASSERT_TRUE(m_dataItem1->isDataSet()); @@ -87,7 +87,7 @@ TEST_F(DataSetTest, DataItem) ASSERT_EQ("VariableDataSet", m_dataItem1->getObservationName()); } -TEST_F(DataSetTest, InitialSet) +TEST_F(DataSetTest, initial_set_parses_key_value_pairs_and_stores_in_checkpoint) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -201,7 +201,7 @@ TEST_F(DataSetTest, parser_with_partial_number) ASSERT_EQ(4.56, get(set.find("d"_E)->m_value)); } -TEST_F(DataSetTest, UpdateOneElement) +TEST_F(DataSetTest, checkpoint_merges_single_element_update_into_existing_set) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -243,7 +243,7 @@ TEST_F(DataSetTest, UpdateOneElement) ASSERT_EQ(6, get(map2.find("e"_E)->m_value)); } -TEST_F(DataSetTest, UpdateMany) +TEST_F(DataSetTest, checkpoint_merges_multiple_element_updates_into_existing_set) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -288,7 +288,7 @@ TEST_F(DataSetTest, UpdateMany) ASSERT_EQ(9, get(map2.find("f"_E)->m_value)); } -TEST_F(DataSetTest, Reset) +TEST_F(DataSetTest, reset_trigger_clears_existing_entries_in_checkpoint) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -325,7 +325,7 @@ TEST_F(DataSetTest, Reset) ASSERT_EQ((string) "hop", get(map2.find("y"_E)->m_value)); } -TEST_F(DataSetTest, BadData) +TEST_F(DataSetTest, bad_data_is_accepted_with_best_effort_parsing) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -351,7 +351,7 @@ TEST_F(DataSetTest, BadData) #define ASSERT_DATA_SET_ENTRY(doc, var, key, expected) \ ASSERT_XML_PATH_EQUAL(doc, "//m:" var "/m:Entry[@key='" key "']", expected) -TEST_F(DataSetTest, Current) +TEST_F(DataSetTest, current_response_reflects_merged_data_set_state_with_reset_support) { m_agentTestHelper->addAdapter(); @@ -416,7 +416,7 @@ TEST_F(DataSetTest, Current) } } -TEST_F(DataSetTest, Sample) +TEST_F(DataSetTest, sample_response_shows_incremental_data_set_changes_including_removals) { m_agentTestHelper->addAdapter(); @@ -475,7 +475,7 @@ TEST_F(DataSetTest, Sample) } } -TEST_F(DataSetTest, CurrentAt) +TEST_F(DataSetTest, current_at_sequence_reconstructs_data_set_state_at_given_point) { using namespace mtconnect::sink::rest_sink; m_agentTestHelper->addAdapter(); @@ -558,7 +558,7 @@ TEST_F(DataSetTest, CurrentAt) } } -TEST_F(DataSetTest, DeleteKey) +TEST_F(DataSetTest, removed_keys_are_deleted_from_checkpoint_data_set) { ErrorList errors; auto time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -590,7 +590,7 @@ TEST_F(DataSetTest, DeleteKey) ASSERT_TRUE(map1.find("a"_E) == map1.end()); } -TEST_F(DataSetTest, ResetWithNoItems) +TEST_F(DataSetTest, reset_with_no_items_produces_empty_data_set_observation) { m_agentTestHelper->addAdapter(); @@ -624,7 +624,7 @@ TEST_F(DataSetTest, ResetWithNoItems) } } -TEST_F(DataSetTest, DuplicateCompression) +TEST_F(DataSetTest, duplicate_entries_are_suppressed_while_changes_are_forwarded) { m_agentTestHelper->addAdapter(); @@ -684,7 +684,7 @@ TEST_F(DataSetTest, DuplicateCompression) } } -TEST_F(DataSetTest, QuoteDelimeter) +TEST_F(DataSetTest, quoted_delimiters_correctly_group_values_with_spaces_in_data_set) { m_agentTestHelper->addAdapter(); @@ -720,7 +720,7 @@ TEST_F(DataSetTest, QuoteDelimeter) } } -TEST_F(DataSetTest, Discrete) +TEST_F(DataSetTest, discrete_data_set_stores_each_update_as_independent_observation) { m_agentTestHelper->addAdapter(); @@ -755,7 +755,7 @@ TEST_F(DataSetTest, Discrete) } } -TEST_F(DataSetTest, Probe) +TEST_F(DataSetTest, probe_response_shows_data_set_representation_and_discrete_attributes) { m_agentTestHelper->addAdapter(); @@ -767,7 +767,7 @@ TEST_F(DataSetTest, Probe) } } -TEST_F(DataSetTest, JsonCurrent) +TEST_F(DataSetTest, json_current_response_includes_data_set_entries_with_typed_values) { using namespace rest_sink; m_agentTestHelper->addAdapter(); diff --git a/test_package/device_test.cpp b/test_package/device_test.cpp index faa671fc2..5d460ddf9 100644 --- a/test_package/device_test.cpp +++ b/test_package/device_test.cpp @@ -57,7 +57,7 @@ class DeviceTest : public testing::Test DevicePtr m_devA, m_devB; }; -TEST_F(DeviceTest, Getters) +TEST_F(DeviceTest, device_getters_return_correct_name_id_component_name_and_uuid) { ASSERT_EQ((string) "Device", string(m_devA->getName())); ASSERT_EQ((string) "1", m_devA->getId()); @@ -70,7 +70,7 @@ TEST_F(DeviceTest, Getters) ASSERT_EQ((string) "UnivUniqId2", m_devB->getUuid()); } -TEST_F(DeviceTest, Description) +TEST_F(DeviceTest, device_description_stores_manufacturer_serial_number_station_and_value) { ErrorList errors; Properties psA {{"manufacturer", "MANUFACTURER"s}, @@ -103,7 +103,7 @@ TEST_F(DeviceTest, Description) ASSERT_EQ((string) "Machine 2", descB->getValue()); } -TEST_F(DeviceTest, DataItems) +TEST_F(DeviceTest, data_items_are_added_to_device_and_retrievable_in_order) { ASSERT_FALSE(m_devA->getDataItems()); @@ -123,7 +123,7 @@ TEST_F(DeviceTest, DataItems) ASSERT_TRUE(data2 == items->back()); } -TEST_F(DeviceTest, DeviceDataItem) +TEST_F(DeviceTest, device_data_item_is_looked_up_by_id_and_returns_null_when_absent) { ASSERT_FALSE(m_devA->getDataItems()); ASSERT_FALSE(m_devA->getDeviceDataItem("DataItemTest1")); @@ -145,7 +145,7 @@ TEST_F(DeviceTest, DeviceDataItem) ASSERT_TRUE(data2 == m_devA->getDeviceDataItem("DataItemTest2")); } -TEST_F(DeviceTest, GetDataItem) +TEST_F(DeviceTest, get_device_data_item_finds_by_id_name_and_source_name) { ErrorList errors; Properties sp1 {{"VALUE", "by_source"s}}; diff --git a/test_package/entity_parser_test.cpp b/test_package/entity_parser_test.cpp index 61213d293..ff44f70b0 100644 --- a/test_package/entity_parser_test.cpp +++ b/test_package/entity_parser_test.cpp @@ -82,7 +82,7 @@ class EntityParserTest : public testing::Test } }; -TEST_F(EntityParserTest, TestParseSimpleDocument) +TEST_F(EntityParserTest, parses_simple_document_with_entity_list_and_properties) { auto fileProperty = make_shared(Requirements({Requirement("name", true), Requirement("VALUE", true)})); @@ -146,7 +146,7 @@ TEST_F(EntityParserTest, TestParseSimpleDocument) ASSERT_EQ("Flat", get((*it)->getProperty("VALUE"))); } -TEST_F(EntityParserTest, TestRecursiveEntityLists) +TEST_F(EntityParserTest, parses_recursive_entity_lists_with_nested_components) { auto root = components(); @@ -195,7 +195,7 @@ TEST_F(EntityParserTest, TestRecursiveEntityLists) ASSERT_EQ("h1", get((*sli)->getProperty("id"))); } -TEST_F(EntityParserTest, TestRecursiveEntityListFailure) +TEST_F(EntityParserTest, fails_when_recursive_entity_list_has_missing_required_property) { auto root = components(); @@ -221,7 +221,7 @@ TEST_F(EntityParserTest, TestRecursiveEntityListFailure) errors.front()->what()); } -TEST_F(EntityParserTest, TestRecursiveEntityListMissingComponents) +TEST_F(EntityParserTest, reports_error_when_recursive_entity_list_has_empty_components) { auto root = components(); @@ -261,7 +261,7 @@ TEST_F(EntityParserTest, TestRecursiveEntityListMissingComponents) ASSERT_FALSE(sl); } -TEST_F(EntityParserTest, TestRawContent) +TEST_F(EntityParserTest, parses_raw_content_element_preserving_inner_xml) { auto definition = make_shared(Requirements({Requirement("format", false), Requirement("RAW", true)})); diff --git a/test_package/entity_printer_test.cpp b/test_package/entity_printer_test.cpp index b3fa98ac9..4cc4a1e3b 100644 --- a/test_package/entity_printer_test.cpp +++ b/test_package/entity_printer_test.cpp @@ -87,7 +87,7 @@ class EntityPrinterTest : public testing::Test std::unique_ptr m_writer; }; -TEST_F(EntityPrinterTest, TestParseSimpleDocument) +TEST_F(EntityPrinterTest, prints_simple_entity_with_file_properties_back_to_xml) { auto root = createFileArchetypeFactory(); @@ -112,7 +112,7 @@ TEST_F(EntityPrinterTest, TestParseSimpleDocument) ASSERT_EQ(doc, m_writer->getContent()); } -TEST_F(EntityPrinterTest, TestFileArchetypeWithDescription) +TEST_F(EntityPrinterTest, prints_file_archetype_with_description_element) { auto root = createFileArchetypeFactory(); @@ -138,7 +138,7 @@ TEST_F(EntityPrinterTest, TestFileArchetypeWithDescription) ASSERT_EQ(doc, m_writer->getContent()); } -TEST_F(EntityPrinterTest, TestRecursiveEntityLists) +TEST_F(EntityPrinterTest, prints_recursive_entity_lists_as_nested_xml) { auto component = make_shared(Requirements { Requirement("id", true), @@ -186,7 +186,7 @@ TEST_F(EntityPrinterTest, TestRecursiveEntityLists) ASSERT_EQ(doc, m_writer->getContent()); } -TEST_F(EntityPrinterTest, TestEntityOrder) +TEST_F(EntityPrinterTest, prints_entity_children_in_declared_order) { auto component = make_shared(Requirements { Requirement("id", true), @@ -244,7 +244,7 @@ TEST_F(EntityPrinterTest, TestEntityOrder) ASSERT_EQ(expected, m_writer->getContent()); } -TEST_F(EntityPrinterTest, TestRawContent) +TEST_F(EntityPrinterTest, prints_raw_content_element_without_escaping) { auto definition = make_shared(Requirements({Requirement("format", false), Requirement("RAW", true)})); diff --git a/test_package/entity_test.cpp b/test_package/entity_test.cpp index 68f4d926d..55d4e8603 100644 --- a/test_package/entity_test.cpp +++ b/test_package/entity_test.cpp @@ -53,7 +53,7 @@ class EntityTest : public testing::Test void TearDown() override {} }; -TEST_F(EntityTest, TestSimpleFactory) +TEST_F(EntityTest, simple_factory_creates_entity_with_required_and_optional_properties) { FactoryPtr root = make_shared(); FactoryPtr simpleFact = @@ -72,7 +72,7 @@ TEST_F(EntityTest, TestSimpleFactory) ASSERT_EQ(10, get(entity->getProperty("size"))); } -TEST_F(EntityTest, TestSimpleTwoLevelFactory) +TEST_F(EntityTest, two_level_factory_creates_nested_entity_with_sub_entity) { auto root = make_shared(); @@ -115,7 +115,7 @@ TEST_F(EntityTest, TestSimpleTwoLevelFactory) ASSERT_EQ("arf", get(v->getProperty("VALUE"))); } -TEST_F(EntityTest, TestSimpleEntityList) +TEST_F(EntityTest, entity_list_factory_creates_entity_with_list_of_sub_entities) { auto root = make_shared(); @@ -190,7 +190,7 @@ TEST_F(EntityTest, TestSimpleEntityList) ASSERT_EQ("meow", get((*it)->getProperty("VALUE"))); } -TEST_F(EntityTest, MissingProperty) +TEST_F(EntityTest, fails_when_required_property_is_missing) { FactoryPtr root = make_shared(); FactoryPtr simpleFact = @@ -209,7 +209,7 @@ TEST_F(EntityTest, MissingProperty) string(errors.front()->what())); } -TEST_F(EntityTest, MissingOptionalProperty) +TEST_F(EntityTest, succeeds_when_optional_property_is_missing) { FactoryPtr root = make_shared(); FactoryPtr simpleFact = @@ -230,7 +230,7 @@ TEST_F(EntityTest, MissingOptionalProperty) ASSERT_EQ(0, errors.size()); } -TEST_F(EntityTest, UnexpectedProperty) +TEST_F(EntityTest, fails_when_unexpected_property_is_present) { FactoryPtr root = make_shared(); FactoryPtr simpleFact = @@ -249,7 +249,7 @@ TEST_F(EntityTest, UnexpectedProperty) string(errors.front()->what())); } -TEST_F(EntityTest, EntityListAnyEntities) +TEST_F(EntityTest, entity_list_accepts_any_entity_matched_by_regex) { auto root = make_shared(); @@ -328,7 +328,7 @@ TEST_F(EntityTest, EntityListAnyEntities) ASSERT_EQ("meow", get((*it)->getProperty("VALUE"))); } -TEST_F(EntityTest, TestRequirementIntegerConversions) +TEST_F(EntityTest, requirement_converts_values_to_integer_type) { Value v("123"s); ASSERT_TRUE(holds_alternative(v)); @@ -374,7 +374,7 @@ TEST_F(EntityTest, TestRequirementIntegerConversions) ASSERT_THROW(r1.convertType(v), PropertyError); } -TEST_F(EntityTest, TestRequirementStringConversion) +TEST_F(EntityTest, requirement_converts_values_to_string_type) { Value v(1234567890_i64); Requirement r1("string", ValueType::STRING); @@ -398,7 +398,7 @@ TEST_F(EntityTest, TestRequirementStringConversion) ASSERT_FALSE(r1.convertType(v)); } -TEST_F(EntityTest, TestRequirementDoubleConversions) +TEST_F(EntityTest, requirement_converts_values_to_double_type) { Value v("123.24"s); ASSERT_TRUE(holds_alternative(v)); @@ -435,7 +435,7 @@ TEST_F(EntityTest, TestRequirementDoubleConversions) ASSERT_EQ(123.24, get(v)[0]); } -TEST_F(EntityTest, TestRequirementVectorConversions) +TEST_F(EntityTest, requirement_converts_values_to_vector_type) { Value v("1.234 3.456 6.7889"s); ASSERT_TRUE(holds_alternative(v)); @@ -471,7 +471,7 @@ TEST_F(EntityTest, TestRequirementVectorConversions) EXPECT_THROW(r6.convertType(v), PropertyError); } -TEST_F(EntityTest, TestRequirementUpperCaseStringConversion) +TEST_F(EntityTest, requirement_converts_string_to_uppercase) { Value v("hello kitty"s); ASSERT_TRUE(holds_alternative(v)); @@ -480,7 +480,7 @@ TEST_F(EntityTest, TestRequirementUpperCaseStringConversion) ASSERT_EQ("HELLO KITTY", get(v)); } -TEST_F(EntityTest, TestControlledVocabulary) +TEST_F(EntityTest, controlled_vocabulary_rejects_values_not_in_allowed_set) { FactoryPtr root = make_shared(); FactoryPtr simpleFact = make_shared( diff --git a/test_package/file_asset_test.cpp b/test_package/file_asset_test.cpp index 2c1172399..bef43deeb 100644 --- a/test_package/file_asset_test.cpp +++ b/test_package/file_asset_test.cpp @@ -67,7 +67,7 @@ class FileAssetTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(FileAssetTest, TestMinmalArchetype) +TEST_F(FileAssetTest, minimal_file_archetype_is_parsed) { const auto doc = R"DOC( @@ -116,7 +116,7 @@ TEST_F(FileAssetTest, TestMinmalArchetype) ASSERT_EQ(content, doc); } -TEST_F(FileAssetTest, TestMinmalFile) +TEST_F(FileAssetTest, minimal_file_asset_is_parsed) { const auto doc = R"DOC( diff --git a/test_package/file_cache_test.cpp b/test_package/file_cache_test.cpp index 48c5db5af..8e6fc2cf7 100644 --- a/test_package/file_cache_test.cpp +++ b/test_package/file_cache_test.cpp @@ -57,7 +57,7 @@ class FileCacheTest : public testing::Test unique_ptr m_cache; }; -TEST_F(FileCacheTest, FindFiles) +TEST_F(FileCacheTest, finds_registered_files_by_uri) { string uri("/schemas"); @@ -70,7 +70,7 @@ TEST_F(FileCacheTest, FindFiles) EXPECT_EQ("text/xml", file->m_mimeType); } -TEST_F(FileCacheTest, IconMimeType) +TEST_F(FileCacheTest, returns_icon_mime_type_for_ico_extension) { // Register a file with the agent. auto list = m_cache->registerDirectory("/styles", TEST_RESOURCE_DIR "/styles", "1.7"); diff --git a/test_package/json_mapping_test.cpp b/test_package/json_mapping_test.cpp index 975e843f2..dce7b3e46 100644 --- a/test_package/json_mapping_test.cpp +++ b/test_package/json_mapping_test.cpp @@ -1149,7 +1149,7 @@ TEST_F(JsonMappingTest, should_skip_erroneous_table) } // if the tag "blah" is not found in the device file, none of the other tags get processed -TEST_F(JsonMappingTest, should_ignore_Invalid_Tag_DataItem) +TEST_F(JsonMappingTest, should_ignore_invalid_tag_data_item) { auto dev = makeDevice("Device", {{"id", "device"s}, {"name", "device"s}, {"uuid", "device"s}}); makeDataItem("device", {{"id", "a"s}, {"type", "EXECUTION"s}, {"category", "EVENT"s}}); @@ -1189,7 +1189,7 @@ TEST_F(JsonMappingTest, should_ignore_Invalid_Tag_DataItem) ASSERT_EQ("BLAH", obs->getValue()); } -TEST_F(JsonMappingTest, should_ignore_Invalid_make_DataItem) +TEST_F(JsonMappingTest, should_ignore_invalid_make_data_item) { auto dev = makeDevice("Device", {{"id", "device"s}, {"name", "device"s}, {"uuid", "device"s}}); makeDataItem("device", {{"id", "a"s}, {"type", "EXECUTION"s}, {"category", "EVENT"s}}); diff --git a/test_package/json_printer_asset_test.cpp b/test_package/json_printer_asset_test.cpp index fa65800b7..d284891c2 100644 --- a/test_package/json_printer_asset_test.cpp +++ b/test_package/json_printer_asset_test.cpp @@ -91,7 +91,7 @@ class JsonPrinterAssetTest : public testing::Test std::unique_ptr m_parser; }; -TEST_F(JsonPrinterAssetTest, AssetHeader) +TEST_F(JsonPrinterAssetTest, asset_header_contains_instance_id_buffer_size_and_count) { AssetList asset; m_printer->setSenderName("MachineXXX"); @@ -106,7 +106,7 @@ TEST_F(JsonPrinterAssetTest, AssetHeader) ASSERT_EQ("MachineXXX", jdoc.at("/MTConnectAssets/Header/sender"_json_pointer).get()); } -TEST_F(JsonPrinterAssetTest, CuttingTool) +TEST_F(JsonPrinterAssetTest, cutting_tool_asset_is_printed_with_serial_number_and_tool_id) { auto xml = getFile("asset1.xml"); entity::ErrorList errors; @@ -135,7 +135,7 @@ TEST_F(JsonPrinterAssetTest, CuttingTool) cuttingTool.at("/CuttingTool/Description"_json_pointer).get()); } -TEST_F(JsonPrinterAssetTest, CuttingToolLifeCycle) +TEST_F(JsonPrinterAssetTest, cutting_tool_life_cycle_contains_status_tool_life_and_speeds) { auto xml = getFile("asset1.xml"); entity::ErrorList errors; @@ -174,7 +174,7 @@ TEST_F(JsonPrinterAssetTest, CuttingToolLifeCycle) ASSERT_EQ(222.0, feed.at("/value"_json_pointer).get()); } -TEST_F(JsonPrinterAssetTest, CuttingMeasurements) +TEST_F(JsonPrinterAssetTest, cutting_measurements_are_printed_as_array_with_codes_and_values) { auto xml = getFile("asset1.xml"); entity::ErrorList errors; @@ -206,7 +206,7 @@ TEST_F(JsonPrinterAssetTest, CuttingMeasurements) ASSERT_EQ(120.65, length.at("/BodyLengthMax/value"_json_pointer).get()); } -TEST_F(JsonPrinterAssetTest, CuttingItem) +TEST_F(JsonPrinterAssetTest, cutting_items_are_printed_with_indices_grade_and_measurements) { auto xml = getFile("asset1.xml"); entity::ErrorList errors; @@ -244,7 +244,7 @@ TEST_F(JsonPrinterAssetTest, CuttingItem) ASSERT_EQ(0.8, measurements.at("/3/CornerRadius/value"_json_pointer).get()); } -TEST_F(JsonPrinterAssetTest, CuttingToolArchitype) +TEST_F(JsonPrinterAssetTest, cutting_tool_archetype_is_printed_with_definition_and_format) { auto xml = getFile("cutting_tool_archetype.xml"); entity::ErrorList errors; diff --git a/test_package/json_printer_probe_test.cpp b/test_package/json_printer_probe_test.cpp index 2aae84e22..555206a75 100644 --- a/test_package/json_printer_probe_test.cpp +++ b/test_package/json_printer_probe_test.cpp @@ -82,7 +82,7 @@ class JsonPrinterProbeTest : public testing::Test std::unique_ptr m_xmlPrinter; }; -TEST_F(JsonPrinterProbeTest, DeviceRootAndDescription) +TEST_F(JsonPrinterProbeTest, device_root_and_description_are_printed_with_header_attributes) { m_printer->setSenderName("MachineXXX"); auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); @@ -117,7 +117,7 @@ TEST_F(JsonPrinterProbeTest, DeviceRootAndDescription) device2.at("/Description/value"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, TopLevelDataItems) +TEST_F(JsonPrinterProbeTest, top_level_data_items_are_printed_with_type_and_category) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -150,7 +150,7 @@ TEST_F(JsonPrinterProbeTest, TopLevelDataItems) ASSERT_EQ(string("f2df7550"), remove.at("/DataItem/id"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, SubComponents) +TEST_F(JsonPrinterProbeTest, sub_components_are_printed_with_ids_and_data_items) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -189,7 +189,7 @@ TEST_F(JsonPrinterProbeTest, SubComponents) ASSERT_EQ(string("ACTUAL"), ss.at("/subType"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, DataItemConstraints) +TEST_F(JsonPrinterProbeTest, data_item_constraints_are_printed_with_values_and_limits) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -219,7 +219,7 @@ TEST_F(JsonPrinterProbeTest, DataItemConstraints) ASSERT_EQ(7000.0, max.get()); } -TEST_F(JsonPrinterProbeTest, DataItemSource) +TEST_F(JsonPrinterProbeTest, data_item_source_contains_referenced_data_item_id) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); // cout << "\n" << doc << endl; @@ -235,7 +235,7 @@ TEST_F(JsonPrinterProbeTest, DataItemSource) ASSERT_EQ(string("taa7a0f0"), amp.at("/Source/dataItemId"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, InitialValue) +TEST_F(JsonPrinterProbeTest, initial_value_is_printed_in_data_item) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -249,7 +249,7 @@ TEST_F(JsonPrinterProbeTest, InitialValue) ASSERT_EQ("1", count.at("/DataItem/InitialValue"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, DataItemFilters) +TEST_F(JsonPrinterProbeTest, data_item_filters_are_printed_with_type_and_value) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -278,7 +278,7 @@ TEST_F(JsonPrinterProbeTest, DataItemFilters) ASSERT_EQ(10.0, filter2.at("/Filter/value"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, Composition) +TEST_F(JsonPrinterProbeTest, compositions_are_printed_with_name_type_and_id) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -298,7 +298,7 @@ TEST_F(JsonPrinterProbeTest, Composition) ASSERT_EQ(string("a7973930"), comp2.at("/id"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, Configuration) +TEST_F(JsonPrinterProbeTest, configuration_contains_sensor_configuration_with_channels) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -320,7 +320,7 @@ TEST_F(JsonPrinterProbeTest, Configuration) config.at("/Channels/0/Channel/CalibrationDate"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, PrintDeviceMTConnectVersion) +TEST_F(JsonPrinterProbeTest, device_mtconnect_version_is_printed_in_probe) { auto doc = m_printer->printProbe(123, 9999, 1, 1024, 10, m_devices); auto jdoc = json::parse(doc); @@ -330,7 +330,7 @@ TEST_F(JsonPrinterProbeTest, PrintDeviceMTConnectVersion) ASSERT_EQ(string("1.7"), device.at("/mtconnectVersion"_json_pointer).get()); } -TEST_F(JsonPrinterProbeTest, PrintDataItemRelationships) +TEST_F(JsonPrinterProbeTest, data_item_relationships_are_printed_with_type_and_id_ref) { auto server = std::make_unique(m_agentTestHelper->m_ioContext); auto cache = std::make_unique(); diff --git a/test_package/json_printer_stream_test.cpp b/test_package/json_printer_stream_test.cpp index 310d1db7d..658f6ad16 100644 --- a/test_package/json_printer_stream_test.cpp +++ b/test_package/json_printer_stream_test.cpp @@ -135,7 +135,7 @@ Properties operator""_value(const char *value, size_t s) return Properties {{"VALUE", string(value)}}; } -TEST_F(JsonPrinterStreamTest, StreamHeader) +TEST_F(JsonPrinterStreamTest, stream_header_contains_instance_id_buffer_size_and_sequence_numbers) { Checkpoint checkpoint; ObservationList list; @@ -156,7 +156,7 @@ TEST_F(JsonPrinterStreamTest, StreamHeader) ASSERT_EQ("MachineXXX", jdoc.at("/MTConnectStreams/Header/sender"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, DeviceStream) +TEST_F(JsonPrinterStreamTest, device_stream_contains_name_and_uuid_for_device) { Checkpoint checkpoint; addObservationToCheckpoint(checkpoint, "Xpos", 10254804, 100_value); @@ -201,7 +201,7 @@ TEST_F(JsonPrinterStreamTest, should_use_object_for_empty_version_2_stream) ASSERT_EQ(0, stream.size()); } -TEST_F(JsonPrinterStreamTest, DeviceStream_version_2_one_device) +TEST_F(JsonPrinterStreamTest, device_stream_version_2_one_device_contains_name_and_uuid) { m_printer = std::make_unique(2, true); @@ -220,7 +220,7 @@ TEST_F(JsonPrinterStreamTest, DeviceStream_version_2_one_device) stream.at("/uuid"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, DeviceStream_version_2_two_devices) +TEST_F(JsonPrinterStreamTest, device_stream_version_2_two_devices_are_separated) { m_printer = std::make_unique(2, true); m_devices = m_config->parseFile(TEST_RESOURCE_DIR "/samples/min_config2.xml", m_xmlPrinter.get()); @@ -246,7 +246,7 @@ TEST_F(JsonPrinterStreamTest, DeviceStream_version_2_two_devices) ASSERT_EQ(string("001"), stream2.at("/uuid"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, ComponentStream) +TEST_F(JsonPrinterStreamTest, component_stream_contains_component_type_name_and_id) { Checkpoint checkpoint; addObservationToCheckpoint(checkpoint, "Xpos", 10254804, 100_value); @@ -264,7 +264,7 @@ TEST_F(JsonPrinterStreamTest, ComponentStream) ASSERT_EQ(string("e373fec0"), stream.at("/componentId"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, ComponentStreamTwoComponents) +TEST_F(JsonPrinterStreamTest, component_stream_with_two_components_produces_separate_streams) { Checkpoint checkpoint; addObservationToCheckpoint(checkpoint, "Xpos", 10254804, 100_value); @@ -314,7 +314,7 @@ TEST_F(JsonPrinterStreamTest, two_components_version_2) ASSERT_EQ(string("zf476090"), stream2.at("/componentId"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, TwoDevices) +TEST_F(JsonPrinterStreamTest, two_devices_produce_separate_device_streams) { Checkpoint checkpoint; addObservationToCheckpoint(checkpoint, "Xpos", 10254804, 100_value); @@ -340,7 +340,7 @@ TEST_F(JsonPrinterStreamTest, TwoDevices) stream2.at("/uuid"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, SampleAndEventDataItem) +TEST_F(JsonPrinterStreamTest, sample_and_event_data_items_are_serialized_with_properties_in_stream) { mtconnect::buffer::Checkpoint checkpoint; Timestamp now = chrono::system_clock::now(); @@ -442,7 +442,7 @@ TEST_F(JsonPrinterStreamTest, samples_and_events_version_2) ASSERT_EQ(32.0, positions.at("/2/value/2"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, ConditionDataItem) +TEST_F(JsonPrinterStreamTest, condition_data_item_is_serialized_with_level_and_codes_in_stream) { Timestamp now = chrono::system_clock::now(); auto time = format(now); @@ -483,7 +483,7 @@ TEST_F(JsonPrinterStreamTest, ConditionDataItem) ASSERT_EQ(string("Syntax error"), motion.at("/Fault/value"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, TimeSeries) +TEST_F(JsonPrinterStreamTest, time_series_observation_is_serialized_with_sample_count_and_values) { Timestamp now = chrono::system_clock::now(); auto time = format(now); @@ -538,7 +538,7 @@ TEST_F(JsonPrinterStreamTest, TimeSeries) ASSERT_NEAR(10.2, value[9].get(), 0.0001); } -TEST_F(JsonPrinterStreamTest, AssetChanged) +TEST_F(JsonPrinterStreamTest, asset_changed_and_asset_removed_observations_are_included_in_stream) { Timestamp now = chrono::system_clock::now(); auto time = format(now); @@ -585,7 +585,7 @@ TEST_F(JsonPrinterStreamTest, AssetChanged) ASSERT_EQ(string("400477d0-33c7"), removed.at("/AssetRemoved/value"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, ResetTrigger) +TEST_F(JsonPrinterStreamTest, reset_trigger_is_included_in_observation_with_statistic_and_duration) { Timestamp now = chrono::system_clock::now(); auto time = format(now); @@ -623,7 +623,7 @@ TEST_F(JsonPrinterStreamTest, ResetTrigger) ASSERT_EQ(10.0, amp.at("/Amperage/value"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, Message) +TEST_F(JsonPrinterStreamTest, message_observation_is_serialized_with_native_code_and_value) { Timestamp now = chrono::system_clock::now(); auto time = format(now); @@ -658,7 +658,7 @@ TEST_F(JsonPrinterStreamTest, Message) ASSERT_EQ(string("XXX is on the roof"), message.at("/Message/value"_json_pointer).get()); } -TEST_F(JsonPrinterStreamTest, Unavailability) +TEST_F(JsonPrinterStreamTest, unavailable_observations_are_serialized_for_events_samples_and_conditions) { Checkpoint checkpoint; addObservationToCheckpoint(checkpoint, "m17f1750", 10254804, diff --git a/test_package/json_printer_test.cpp b/test_package/json_printer_test.cpp index dd35fc59c..ac5e0d732 100644 --- a/test_package/json_printer_test.cpp +++ b/test_package/json_printer_test.cpp @@ -161,7 +161,7 @@ class JsonPrinterTest : public testing::Test } }; -TEST_F(JsonPrinterTest, Header) +TEST_F(JsonPrinterTest, header_contains_sender_and_asset_buffer_size) { auto root = createFileArchetypeFactory(); @@ -184,7 +184,7 @@ TEST_F(JsonPrinterTest, Header) ASSERT_EQ(8096, header.at("/assetBufferSize"_json_pointer).get()); } -TEST_F(JsonPrinterTest, Devices) +TEST_F(JsonPrinterTest, devices_array_contains_parsed_device_by_name) { auto root = createFileArchetypeFactory(); @@ -206,7 +206,7 @@ TEST_F(JsonPrinterTest, Devices) ASSERT_EQ("foo", devices.at("/0/Device/name"_json_pointer).get()); } -TEST_F(JsonPrinterTest, Components) +TEST_F(JsonPrinterTest, components_contain_nested_sub_components_with_description) { auto root = createFileArchetypeFactory(); @@ -237,7 +237,7 @@ TEST_F(JsonPrinterTest, Components) ASSERT_EQ("h1", systems.at("/Components/1/Heating/id"_json_pointer).get()); } -TEST_F(JsonPrinterTest, TopLevelDataItems) +TEST_F(JsonPrinterTest, top_level_data_items_are_printed_in_json_array) { auto root = createFileArchetypeFactory(); @@ -282,7 +282,7 @@ TEST_F(JsonPrinterTest, data_items_using_version_2) ASSERT_EQ("ASSET_REMOVED", dataitems.at("/2/type"_json_pointer).get()); } -TEST_F(JsonPrinterTest, ElementListWithProperty) +TEST_F(JsonPrinterTest, entity_list_with_property_is_printed_with_list_and_count) { auto item = make_shared(Requirements {{"itemId", true}}); diff --git a/test_package/kinematics_test.cpp b/test_package/kinematics_test.cpp index 119e9705f..e2ebf609a 100644 --- a/test_package/kinematics_test.cpp +++ b/test_package/kinematics_test.cpp @@ -63,7 +63,7 @@ class KinematicsTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(KinematicsTest, ParseZAxisKinematics) +TEST_F(KinematicsTest, z_axis_kinematics_motion_attributes_are_parsed_correctly) { using namespace mtconnect::entity; ASSERT_NE(nullptr, m_device); @@ -97,7 +97,7 @@ TEST_F(KinematicsTest, ParseZAxisKinematics) ASSERT_EQ(1.0, axis[2]); } -TEST_F(KinematicsTest, ParseCAxisKinematics) +TEST_F(KinematicsTest, c_axis_rotary_kinematics_motion_is_parsed_with_transformation) { ASSERT_NE(nullptr, m_device); @@ -135,7 +135,7 @@ TEST_F(KinematicsTest, ParseCAxisKinematics) #define ZAXIS_CONFIGURATION_PATH "//m:Linear[@id='z']/m:Configuration" #define ZAXIS_MOTION_PATH ZAXIS_CONFIGURATION_PATH "/m:Motion" -TEST_F(KinematicsTest, ZAxisXmlPrinting) +TEST_F(KinematicsTest, z_axis_kinematics_motion_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -155,7 +155,7 @@ TEST_F(KinematicsTest, ZAxisXmlPrinting) #define ROTARY_CONFIGURATION_PATH "//m:Rotary[@id='c']/m:Configuration" #define ROTARY_MOTION_PATH ROTARY_CONFIGURATION_PATH "/m:Motion" -TEST_F(KinematicsTest, RotaryXmlPrinting) +TEST_F(KinematicsTest, rotary_kinematics_motion_with_transformation_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -174,7 +174,7 @@ TEST_F(KinematicsTest, RotaryXmlPrinting) } } -TEST_F(KinematicsTest, ZAxisJsonPrinting) +TEST_F(KinematicsTest, z_axis_kinematics_motion_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); @@ -210,7 +210,7 @@ TEST_F(KinematicsTest, ZAxisJsonPrinting) } } -TEST_F(KinematicsTest, RotaryJsonPrinting) +TEST_F(KinematicsTest, rotary_kinematics_motion_with_transformation_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 015a49f20..6acf2cca0 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -364,7 +364,7 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) ASSERT_TRUE(m_client->isConnected()); } -TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) +TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_authentication) { GTEST_SKIP(); @@ -400,7 +400,7 @@ TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) ASSERT_TRUE(m_client->isConnected()); } -TEST_F(MqttIsolatedUnitTest, mqtt_tcp_client_authentication) +TEST_F(MqttIsolatedUnitTest, mqtt_tcp_client_authenticates_with_credentials) { ConfigOptions options {{ServerIp, "127.0.0.1"s}, {MqttPort, 0}, diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index fd32294e1..1f65f212b 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -199,7 +199,7 @@ TEST_F(MqttSinkTest, mqtt_sink_flat_formatt_check) ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe) +TEST_F(MqttSinkTest, mqtt_sink_publishes_probe_response) { ConfigOptions options; createServer(options); @@ -238,7 +238,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) +TEST_F(MqttSinkTest, mqtt_sink_publishes_sample_on_data_change) { ConfigOptions options; createServer(options); @@ -283,7 +283,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Current) +TEST_F(MqttSinkTest, mqtt_sink_publishes_current_on_connection) { ConfigOptions options; createServer(options); @@ -320,7 +320,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Current) ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_with_uuid_first) +TEST_F(MqttSinkTest, mqtt_sink_publishes_probe_with_uuid_first_in_topic) { ConfigOptions options; createServer(options); @@ -359,7 +359,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_with_uuid_first) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_no_device_in_format) +TEST_F(MqttSinkTest, mqtt_sink_publishes_probe_without_device_in_topic) { ConfigOptions options; createServer(options); diff --git a/test_package/observation_test.cpp b/test_package/observation_test.cpp index 15194982d..2fad8a039 100644 --- a/test_package/observation_test.cpp +++ b/test_package/observation_test.cpp @@ -129,7 +129,7 @@ inline ConditionPtr Cond(ObservationPtr ptr) { return dynamic_pointer_castget("dataItemId")); ASSERT_EQ(m_time, m_compEventA->get("timestamp")); @@ -146,7 +146,7 @@ TEST_F(ObservationTest, GetAttributes) ASSERT_EQ(4, m_compEventB->get("sequence")); } -TEST_F(ObservationTest, Getters) +TEST_F(ObservationTest, returns_data_item_and_value_via_getters) { ASSERT_TRUE(m_dataItem1 == m_compEventA->getDataItem()); ASSERT_TRUE(m_dataItem2 == m_compEventB->getDataItem()); @@ -155,7 +155,7 @@ TEST_F(ObservationTest, Getters) ASSERT_EQ(1.1231, m_compEventB->getValue()); } -TEST_F(ObservationTest, ConvertValue) +TEST_F(ObservationTest, converts_value_between_different_unit_systems) { std::map attributes; attributes["id"] = "1"; @@ -174,7 +174,7 @@ TEST_F(ObservationTest, ConvertValue) (2.0f) / (60.0f * 60.0f * 60.0f * 0.5f), 2.0); } -TEST_F(ObservationTest, ConvertSimpleUnits) +TEST_F(ObservationTest, converts_simple_units_across_all_supported_unit_types) { std::map attributes; attributes["id"] = "1"; @@ -197,7 +197,7 @@ TEST_F(ObservationTest, ConvertSimpleUnits) TEST_VALUE(attributes, "PERCENT", "PERCENT", 2.0f, 2.0); } -TEST_F(ObservationTest, ConditionEventChaining) +TEST_F(ObservationTest, conditions_are_chained_in_linked_list_order) { ErrorList errors; auto dataItem = @@ -246,7 +246,7 @@ TEST_F(ObservationTest, subType_prefix_should_be_passed_through) ASSERT_EQ("x:AUTO", event->get("subType")); } -TEST_F(ObservationTest, shoud_handle_asset_type) +TEST_F(ObservationTest, asset_changed_event_stores_asset_type_attribute_and_handles_unavailable) { ErrorList errors; auto dataItem = diff --git a/test_package/pipeline_deliver_test.cpp b/test_package/pipeline_deliver_test.cpp index 1584b0497..7feca2796 100644 --- a/test_package/pipeline_deliver_test.cpp +++ b/test_package/pipeline_deliver_test.cpp @@ -64,7 +64,7 @@ class PipelineDeliverTest : public testing::Test DevicePtr m_device {nullptr}; }; -TEST_F(PipelineDeliverTest, test_simple_flow) +TEST_F(PipelineDeliverTest, observation_is_delivered_to_circular_buffer_with_correct_values) { m_agentTestHelper->addAdapter(); auto &circ = m_agentTestHelper->getAgent()->getCircularBuffer(); @@ -78,7 +78,7 @@ TEST_F(PipelineDeliverTest, test_simple_flow) ASSERT_EQ("2021-01-22T12:33:45.123Z", format(obs->getTimestamp())); } -TEST_F(PipelineDeliverTest, filter_duplicates) +TEST_F(PipelineDeliverTest, duplicate_filter_suppresses_repeated_values_in_circular_buffer) { ConfigOptions options {{configuration::FilterDuplicates, true}}; m_agentTestHelper->addAdapter(options); @@ -102,7 +102,7 @@ TEST_F(PipelineDeliverTest, filter_duplicates) } // a01c7f30 -TEST_F(PipelineDeliverTest, filter_upcase) +TEST_F(PipelineDeliverTest, upcase_filter_converts_event_values_to_uppercase) { ConfigOptions options {{configuration::UpcaseDataItemValue, true}}; m_agentTestHelper->addAdapter(options); diff --git a/test_package/qif_document_test.cpp b/test_package/qif_document_test.cpp index 42d552c3e..5eafca310 100644 --- a/test_package/qif_document_test.cpp +++ b/test_package/qif_document_test.cpp @@ -162,7 +162,7 @@ TEST_F(QIFDocumentTest, minimal_qif_definition) ASSERT_EQ("1"s, root->get("Id")); } -TEST_F(QIFDocumentTest, test_qif_xml_round_trip) +TEST_F(QIFDocumentTest, qif_document_is_round_tripped_to_xml) { using namespace date; const auto doc = diff --git a/test_package/references_test.cpp b/test_package/references_test.cpp index 2b79f546c..39c0aa7aa 100644 --- a/test_package/references_test.cpp +++ b/test_package/references_test.cpp @@ -74,7 +74,7 @@ class ReferencesTest : public testing::Test ComponentPtr m_component; }; -TEST_F(ReferencesTest, References) +TEST_F(ReferencesTest, component_data_item_references_are_parsed_with_name_and_id_ref) { createAgent({}); m_component = m_device->getComponentById("bf"); diff --git a/test_package/relationship_test.cpp b/test_package/relationship_test.cpp index 94174d5b8..d761b5f04 100644 --- a/test_package/relationship_test.cpp +++ b/test_package/relationship_test.cpp @@ -68,7 +68,7 @@ class RelationshipTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(RelationshipTest, ParseDeviceAndComponentRelationships) +TEST_F(RelationshipTest, component_device_and_asset_relationships_are_parsed_with_attributes) { ASSERT_NE(nullptr, m_component); @@ -115,7 +115,7 @@ TEST_F(RelationshipTest, ParseDeviceAndComponentRelationships) #define CONFIGURATION_PATH "//m:Rotary[@id='c']/m:Configuration" #define RELATIONSHIPS_PATH CONFIGURATION_PATH "/m:Relationships" -TEST_F(RelationshipTest, XmlPrinting) +TEST_F(RelationshipTest, relationships_are_printed_with_correct_attributes_in_xml) { { PARSE_XML_RESPONSE("/probe"); @@ -154,7 +154,7 @@ TEST_F(RelationshipTest, XmlPrinting) } } -TEST_F(RelationshipTest, JsonPrinting) +TEST_F(RelationshipTest, relationships_are_printed_with_correct_fields_in_json) { { PARSE_JSON_RESPONSE("/probe"); diff --git a/test_package/routing_test.cpp b/test_package/routing_test.cpp index 489458af7..82756d858 100644 --- a/test_package/routing_test.cpp +++ b/test_package/routing_test.cpp @@ -55,7 +55,7 @@ class RoutingTest : public testing::Test const Routing::Function m_func {[](SessionPtr, const RequestPtr) { return true; }}; }; -TEST_F(RoutingTest, TestSimplePattern) +TEST_F(RoutingTest, matches_simple_path_and_verb_pattern) { RequestPtr request = make_shared(); request->m_verb = verb::get; @@ -82,7 +82,7 @@ TEST_F(RoutingTest, TestSimplePattern) ASSERT_EQ("ABC123", get(request->m_parameters["device"])); } -TEST_F(RoutingTest, TestComplexPatterns) +TEST_F(RoutingTest, matches_complex_path_with_asset_parameter) { RequestPtr request = make_shared(); request->m_verb = verb::get; @@ -98,7 +98,7 @@ TEST_F(RoutingTest, TestComplexPatterns) ASSERT_FALSE(r.matches(0, request)); } -TEST_F(RoutingTest, TestCurrentAtQueryParameter) +TEST_F(RoutingTest, parses_current_at_query_parameter) { Routing r(verb::get, "/{device}/current?at={unsigned_integer}", m_func); ASSERT_EQ(1, r.getPathParameters().size()); @@ -115,7 +115,7 @@ TEST_F(RoutingTest, TestCurrentAtQueryParameter) EXPECT_TRUE(holds_alternative(qp.m_default)); } -TEST_F(RoutingTest, TestSampleQueryParameters) +TEST_F(RoutingTest, parses_sample_query_parameters_with_defaults) { Routing r(verb::get, "/{device}/sample?from={unsigned_integer}&" @@ -156,7 +156,7 @@ TEST_F(RoutingTest, TestSampleQueryParameters) EXPECT_TRUE(holds_alternative(qp->m_default)); } -TEST_F(RoutingTest, TestQueryParameterMatch) +TEST_F(RoutingTest, matches_request_with_query_parameters) { RequestPtr request = make_shared(); request->m_verb = verb::get; @@ -192,7 +192,7 @@ TEST_F(RoutingTest, TestQueryParameterMatch) ASSERT_EQ(request->m_parameters.end(), request->m_parameters.find("dummy")); } -TEST_F(RoutingTest, TestQueryParameterError) +TEST_F(RoutingTest, throws_rest_error_for_invalid_query_parameter_type) { Routing r(verb::get, "/{device}/sample?from={unsigned_integer}&" diff --git a/test_package/sensor_configuration_test.cpp b/test_package/sensor_configuration_test.cpp index 4ea1ddd74..f46515924 100644 --- a/test_package/sensor_configuration_test.cpp +++ b/test_package/sensor_configuration_test.cpp @@ -63,7 +63,7 @@ class SensorConfigurationTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(SensorConfigurationTest, ParseSensorConfiguration) +TEST_F(SensorConfigurationTest, sensor_configuration_channels_are_parsed_with_name) { ASSERT_NE(nullptr, m_device); diff --git a/test_package/solid_model_test.cpp b/test_package/solid_model_test.cpp index 4e81d23d1..cd7f28ed4 100644 --- a/test_package/solid_model_test.cpp +++ b/test_package/solid_model_test.cpp @@ -63,7 +63,7 @@ class SolidModelTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(SolidModelTest, ParseDeviceSolidModel) +TEST_F(SolidModelTest, device_solid_model_attributes_and_scale_are_parsed) { ASSERT_NE(nullptr, m_device); @@ -85,7 +85,7 @@ TEST_F(SolidModelTest, ParseDeviceSolidModel) ASSERT_EQ(4.0, scale[2]); } -TEST_F(SolidModelTest, ParseRotarySolidModel) +TEST_F(SolidModelTest, rotary_solid_model_with_transformation_and_references_is_parsed) { ASSERT_NE(nullptr, m_device); @@ -121,7 +121,7 @@ TEST_F(SolidModelTest, ParseRotarySolidModel) #define DEVICE_CONFIGURATION_PATH "//m:Device/m:Configuration" #define DEVICE_SOLID_MODEL_PATH DEVICE_CONFIGURATION_PATH "/m:SolidModel" -TEST_F(SolidModelTest, DeviceXmlPrinting) +TEST_F(SolidModelTest, device_solid_model_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -139,7 +139,7 @@ TEST_F(SolidModelTest, DeviceXmlPrinting) #define ROTARY_CONFIGURATION_PATH "//m:Rotary[@id='c']/m:Configuration" #define ROTARY_SOLID_MODEL_PATH ROTARY_CONFIGURATION_PATH "/m:SolidModel" -TEST_F(SolidModelTest, RotaryXmlPrinting) +TEST_F(SolidModelTest, rotary_solid_model_with_transformation_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -158,7 +158,7 @@ TEST_F(SolidModelTest, RotaryXmlPrinting) } } -TEST_F(SolidModelTest, DeviceJsonPrinting) +TEST_F(SolidModelTest, device_solid_model_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); @@ -184,7 +184,7 @@ TEST_F(SolidModelTest, DeviceJsonPrinting) } } -TEST_F(SolidModelTest, RotaryJsonPrinting) +TEST_F(SolidModelTest, rotary_solid_model_with_transformation_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); diff --git a/test_package/specification_test.cpp b/test_package/specification_test.cpp index fe7ab06d8..3c9b1a30b 100644 --- a/test_package/specification_test.cpp +++ b/test_package/specification_test.cpp @@ -67,7 +67,7 @@ class SpecificationTest : public testing::Test std::unique_ptr m_agentTestHelper; }; -TEST_F(SpecificationTest, ParseDeviceAndComponentRelationships) +TEST_F(SpecificationTest, specification_attributes_and_limits_are_parsed_for_component) { ASSERT_NE(nullptr, m_component); @@ -119,7 +119,7 @@ TEST_F(SpecificationTest, test_1_6_specification_without_id) #define CONFIGURATION_PATH "//m:Rotary[@id='c']/m:Configuration" #define SPECIFICATIONS_PATH CONFIGURATION_PATH "/m:Specifications" -TEST_F(SpecificationTest, XmlPrinting) +TEST_F(SpecificationTest, rotary_velocity_specification_with_limits_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -152,7 +152,7 @@ TEST_F(SpecificationTest, XmlPrinting) } } -TEST_F(SpecificationTest, XmlPrintingForLoadSpec) +TEST_F(SpecificationTest, load_specification_with_all_limit_types_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -184,7 +184,7 @@ TEST_F(SpecificationTest, XmlPrintingForLoadSpec) } } -TEST_F(SpecificationTest, JsonPrinting) +TEST_F(SpecificationTest, rotary_velocity_specification_with_limits_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); @@ -213,7 +213,7 @@ TEST_F(SpecificationTest, JsonPrinting) } } -TEST_F(SpecificationTest, JsonPrintingForLoadSpec) +TEST_F(SpecificationTest, load_specification_with_all_limit_types_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); @@ -244,7 +244,7 @@ TEST_F(SpecificationTest, JsonPrintingForLoadSpec) } } -TEST_F(SpecificationTest, Parse17SpecificationValues) +TEST_F(SpecificationTest, version_1_7_specification_values_including_limits_and_warnings_are_parsed) { ASSERT_NE(nullptr, m_component); @@ -278,7 +278,7 @@ TEST_F(SpecificationTest, Parse17SpecificationValues) EXPECT_EQ(-200.0, (*si)->get("LowerWarning")); } -TEST_F(SpecificationTest, ParseProcessSpecificationValues) +TEST_F(SpecificationTest, process_specification_with_spec_control_and_alarm_limits_is_parsed) { ASSERT_NE(nullptr, m_component); @@ -328,7 +328,7 @@ TEST_F(SpecificationTest, ParseProcessSpecificationValues) #define CONFIGURATION_PATH "//m:Rotary[@id='c']/m:Configuration" #define PROCESS_PATH CONFIGURATION_PATH "/m:Specifications/m:ProcessSpecification" -TEST_F(SpecificationTest, XmlPrintingForProcessSpecification) +TEST_F(SpecificationTest, process_specification_with_all_limit_groups_is_printed_in_xml) { { PARSE_XML_RESPONSE("/LinuxCNC/probe"); @@ -359,7 +359,7 @@ TEST_F(SpecificationTest, XmlPrintingForProcessSpecification) } } -TEST_F(SpecificationTest, JsonPrintingForProcessSpecification) +TEST_F(SpecificationTest, process_specification_with_all_limit_groups_is_printed_in_json) { { PARSE_JSON_RESPONSE("/LinuxCNC/probe"); diff --git a/test_package/table_test.cpp b/test_package/table_test.cpp index 7df11460a..13f987df6 100644 --- a/test_package/table_test.cpp +++ b/test_package/table_test.cpp @@ -83,7 +83,7 @@ class TableTest : public testing::Test inline DataSetEntry operator""_E(const char *c, std::size_t) { return DataSetEntry(c); } inline TableCell operator""_C(const char *c, std::size_t) { return TableCell(c); } -TEST_F(TableTest, DataItem) +TEST_F(TableTest, data_item_is_identified_as_table_and_data_set_representation) { ASSERT_TRUE(m_dataItem1->isTable()); ASSERT_TRUE(m_dataItem1->isDataSet()); @@ -218,7 +218,7 @@ TEST_F(TableTest, test_non_table_entry_should_fail) ASSERT_EQ(1, set.size()); } -TEST_F(TableTest, InitialSet) +TEST_F(TableTest, initial_table_set_parses_rows_with_multiple_cells) { string value( "G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0} G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); @@ -255,7 +255,7 @@ TEST_F(TableTest, InitialSet) ASSERT_XML_PATH_EQUAL(doc, "//m:" var "/m:Entry[@key='" key "']/m:Cell[@key='" cell "']", \ expected) -TEST_F(TableTest, Current) +TEST_F(TableTest, current_response_shows_merged_table_rows_with_cell_values) { m_agentTestHelper->addAdapter(); @@ -314,7 +314,7 @@ TEST_F(TableTest, Current) } } -TEST_F(TableTest, JsonCurrent) +TEST_F(TableTest, json_current_response_includes_table_rows_with_nested_cell_values) { m_agentTestHelper->addAdapter(); @@ -371,7 +371,7 @@ TEST_F(TableTest, JsonCurrent) } } -TEST_F(TableTest, JsonCurrentText) +TEST_F(TableTest, json_current_response_handles_string_values_with_spaces_in_cells) { m_agentTestHelper->addAdapter(); m_agentTestHelper->m_adapter->processData( @@ -419,7 +419,7 @@ TEST_F(TableTest, JsonCurrentText) } } -TEST_F(TableTest, XmlCellDefinitions) +TEST_F(TableTest, xml_probe_includes_cell_and_entry_definitions_with_types_and_units) { m_agentTestHelper->addAdapter(); @@ -496,7 +496,7 @@ TEST_F(TableTest, XmlCellDefinitions) } } -TEST_F(TableTest, JsonDefinitionTest) +TEST_F(TableTest, json_probe_includes_cell_and_entry_definitions_with_types_and_units) { m_agentTestHelper->addAdapter(); @@ -595,7 +595,7 @@ TEST_F(TableTest, JsonDefinitionTest) } } -TEST_F(TableTest, shoud_correctly_parse_data_with_colon) +TEST_F(TableTest, correctly_parses_table_data_with_colon_in_values) { m_agentTestHelper->addAdapter(); @@ -724,7 +724,7 @@ TEST_F(TableTest, shoud_correctly_parse_data_with_colon) } } -TEST_F(TableTest, shoud_parse_keys_with_hypens) +TEST_F(TableTest, correctly_parses_table_keys_containing_hyphens_and_slashes) { m_agentTestHelper->addAdapter(); @@ -752,7 +752,7 @@ TEST_F(TableTest, shoud_parse_keys_with_hypens) } } -TEST_F(TableTest, shoud_parse_table_with_no_space) +TEST_F(TableTest, correctly_parses_table_entries_with_no_space_between_rows) { m_agentTestHelper->addAdapter(); @@ -779,7 +779,7 @@ TEST_F(TableTest, shoud_parse_table_with_no_space) } } -TEST_F(TableTest, shoud_handle_complex_sequences) +TEST_F(TableTest, current_at_sequence_correctly_reconstructs_table_state_with_removals) { m_agentTestHelper->addAdapter(); diff --git a/test_package/timestamp_extractor_test.cpp b/test_package/timestamp_extractor_test.cpp index 99a314d63..681bf495c 100644 --- a/test_package/timestamp_extractor_test.cpp +++ b/test_package/timestamp_extractor_test.cpp @@ -38,7 +38,7 @@ int main(int argc, char *argv[]) return RUN_ALL_TESTS(); } -TEST(TimestampExtractorTest, TestTimeExtraction) +TEST(TimestampExtractorTest, extracts_iso8601_timestamp_from_token_list) { auto tokens = make_shared("Tokens", Properties()); tokens->m_tokens = {"2021-01-19T12:00:00.12345Z", "hello"}; @@ -55,7 +55,7 @@ TEST(TimestampExtractorTest, TestTimeExtraction) ASSERT_FALSE(timestamped->m_duration); } -TEST(TimestampExtractorTest, TestTimeExtractionWithDuration) +TEST(TimestampExtractorTest, extracts_timestamp_and_duration_when_at_sign_is_present) { auto tokens = make_shared("Tokens", Properties()); tokens->m_tokens = {"2021-01-19T12:00:00.12345Z@100.0", "hello"}; @@ -73,7 +73,7 @@ TEST(TimestampExtractorTest, TestTimeExtractionWithDuration) ASSERT_EQ(100.0, *timestamped->m_duration); } -TEST(TimestampExtractorTest, TestTimeExtractionRelativeTimeOffset) +TEST(TimestampExtractorTest, computes_absolute_timestamp_from_relative_millisecond_offset) { auto tokens = make_shared("Tokens", Properties()); tokens->m_tokens = {"1000.0", "hello"}; @@ -103,7 +103,7 @@ TEST(TimestampExtractorTest, TestTimeExtractionRelativeTimeOffset) ASSERT_EQ("2021-01-19T10:00:01Z", format(timestamped->m_timestamp)); } -TEST(TimestampExtractorTest, TestTimeExtractionRelativeTime) +TEST(TimestampExtractorTest, applies_relative_time_offset_to_parsed_iso8601_timestamps) { auto tokens = make_shared("Tokens", Properties {}); tokens->m_tokens = {"2021-01-19T10:01:00Z", "hello"}; diff --git a/test_package/utilities_test.cpp b/test_package/utilities_test.cpp index 4f43b903c..3dc7a44b3 100644 --- a/test_package/utilities_test.cpp +++ b/test_package/utilities_test.cpp @@ -62,7 +62,7 @@ TEST(UtilitiesTest, should_uppercase_string) ASSERT_EQ((string) "QWERTY.ASDF|", toUpperCase(lower)); } -TEST(UtilitiesTest, IsNonNegativeInteger) +TEST(UtilitiesTest, non_negative_integer_strings_are_validated_correctly) { ASSERT_TRUE(isNonNegativeInteger("12345")); ASSERT_TRUE(isNonNegativeInteger("123456789012345678901234567890")); @@ -72,7 +72,7 @@ TEST(UtilitiesTest, IsNonNegativeInteger) ASSERT_TRUE(!isNonNegativeInteger("123.45")); } -TEST(UtilitiesTest, Time) +TEST(UtilitiesTest, current_time_is_returned_in_utc_and_advances_over_time) { auto time1 = getCurrentTime(GMT); auto time2 = getCurrentTime(GMT); @@ -99,7 +99,7 @@ TEST(UtilitiesTest, Time) ASSERT_TRUE(time7 < time9); } -TEST(UtilitiesTest, IllegalCharacters) +TEST(UtilitiesTest, illegal_xml_characters_are_replaced_with_entities) { string before1("Don't Change Me"), after1("Don't Change Me"); replaceIllegalCharacters(before1); @@ -114,7 +114,7 @@ TEST(UtilitiesTest, IllegalCharacters) ASSERT_EQ(before3, after3); } -TEST(UtilitiesTest, GetCurrentTime) +TEST(UtilitiesTest, get_current_time_returns_parseable_formatted_strings) { auto gmt = getCurrentTime(GMT); auto time = parseTimeMicro(gmt); @@ -140,7 +140,7 @@ TEST(UtilitiesTest, GetCurrentTime) ASSERT_EQ(8, n); } -TEST(UtilitiesTest, GetCurrentTime2) +TEST(UtilitiesTest, get_current_time_formats_known_time_point_correctly) { // Build a known system time point auto knownTimePoint = std::chrono::system_clock::from_time_t(0); // 1 Jan 1970 00:00:00 @@ -173,14 +173,14 @@ TEST(UtilitiesTest, GetCurrentTime2) ASSERT_EQ(string("Thu, 01 Jan 1970 00:00:10 GMT"), humRead); } -TEST(UtilitiesTest, ParseTimeMicro) +TEST(UtilitiesTest, parse_time_micro_converts_iso_timestamp_to_microseconds) { // This time is 123456 microseconds after the epoch auto v = parseTimeMicro("1970-01-01T00:00:00.123456Z"); ASSERT_EQ(uint64_t {123456}, v); } -TEST(UtilitiesTest, AddNamespace) +TEST(UtilitiesTest, add_namespace_prepends_prefix_to_xpath_elements) { auto result = addNamespace("//Device//Foo", "m"); ASSERT_EQ(string("//m:Device//m:Foo"), result); @@ -201,7 +201,7 @@ TEST(UtilitiesTest, AddNamespace) ASSERT_EQ(string("//m:Device/m:DataItems/"), result); } -TEST(UtilitiesTest, ParseTimeMilli) +TEST(UtilitiesTest, parse_time_micro_handles_millisecond_and_microsecond_timestamps) { string v = "2012-11-20T12:33:22.123456"; @@ -213,4 +213,4 @@ TEST(UtilitiesTest, ParseTimeMilli) ASSERT_TRUE(1353414802123000LL == time); } -TEST(UtilitiesTest, Int64ToString) { ASSERT_EQ((string) "8805345009", to_string(8805345009ULL)); } +TEST(UtilitiesTest, int64_to_string_converts_large_unsigned_integer) { ASSERT_EQ((string) "8805345009", to_string(8805345009ULL)); } diff --git a/test_package/xml_parser_test.cpp b/test_package/xml_parser_test.cpp index f2735bead..ab1f61654 100644 --- a/test_package/xml_parser_test.cpp +++ b/test_package/xml_parser_test.cpp @@ -76,7 +76,7 @@ class XmlParserTest : public testing::Test std::list m_devices; }; -TEST_F(XmlParserTest, Constructor) +TEST_F(XmlParserTest, parse_file_throws_fatal_on_missing_file) { if (m_xmlParser) { @@ -95,7 +95,7 @@ TEST_F(XmlParserTest, Constructor) m_xmlParser->parseFile(TEST_RESOURCE_DIR "/samples/test_config.xml", printer.get())); } -TEST_F(XmlParserTest, GetDevices) +TEST_F(XmlParserTest, parse_file_returns_devices_with_description_and_data_items) { ASSERT_EQ((size_t)1, m_devices.size()); @@ -127,7 +127,7 @@ TEST_F(XmlParserTest, GetDevices) ASSERT_TRUE(hasZcom); } -TEST_F(XmlParserTest, Condition) +TEST_F(XmlParserTest, data_item_with_condition_category_is_parsed) { ASSERT_EQ((size_t)1, m_devices.size()); @@ -140,7 +140,7 @@ TEST_F(XmlParserTest, Condition) ASSERT_TRUE(item->isCondition()); } -TEST_F(XmlParserTest, GetDataItems) +TEST_F(XmlParserTest, get_data_items_filters_nodes_by_xpath_expressions) { std::set filter; @@ -173,7 +173,7 @@ TEST_F(XmlParserTest, GetDataItems) ASSERT_EQ(5, (int)filter.size()); } -TEST_F(XmlParserTest, GetDataItemsExt) +TEST_F(XmlParserTest, get_data_items_supports_extended_namespace_prefixes) { std::set filter; @@ -205,7 +205,7 @@ TEST_F(XmlParserTest, GetDataItemsExt) ASSERT_EQ(1, (int)filter.size()); } -TEST_F(XmlParserTest, ExtendedSchema) +TEST_F(XmlParserTest, parse_file_with_extended_schema_loads_namespaced_components) { if (m_xmlParser) { @@ -245,7 +245,7 @@ TEST_F(XmlParserTest, ExtendedSchema) ASSERT_EQ((string) "x", item->getObservationName().getNs()); } -TEST_F(XmlParserTest, TimeSeries) +TEST_F(XmlParserTest, data_item_time_series_representation_is_parsed) { const auto dev = m_devices.front(); ASSERT_TRUE(dev); @@ -262,7 +262,7 @@ TEST_F(XmlParserTest, TimeSeries) ASSERT_EQ((string) "TIME_SERIES", item->get("representation")); } -TEST_F(XmlParserTest, Configuration) +TEST_F(XmlParserTest, component_configuration_property_is_present) { const auto dev = m_devices.front(); ASSERT_TRUE(dev); @@ -280,7 +280,7 @@ TEST_F(XmlParserTest, Configuration) ASSERT_TRUE(power->hasProperty("Configuration")); } -TEST_F(XmlParserTest, NoNamespace) +TEST_F(XmlParserTest, parse_file_without_namespace_declaration_succeeds) { if (m_xmlParser) { @@ -294,7 +294,7 @@ TEST_F(XmlParserTest, NoNamespace) m_xmlParser->parseFile(TEST_RESOURCE_DIR "/samples/NoNamespace.xml", printer.get())); } -TEST_F(XmlParserTest, FilteredDataItem13) +TEST_F(XmlParserTest, data_item_minimum_delta_filter_is_parsed_from_1_3_schema) { delete m_xmlParser; m_xmlParser = nullptr; @@ -318,7 +318,7 @@ TEST_F(XmlParserTest, FilteredDataItem13) ASSERT_EQ(5.0, *di->getMinimumDelta()); } -TEST_F(XmlParserTest, FilteredDataItem) +TEST_F(XmlParserTest, data_item_minimum_delta_and_period_filters_are_parsed) { if (m_xmlParser) { @@ -349,7 +349,7 @@ TEST_F(XmlParserTest, FilteredDataItem) ASSERT_EQ(10.0, di->getMinimumPeriod()); } -TEST_F(XmlParserTest, References) +TEST_F(XmlParserTest, component_data_item_and_component_references_are_resolved) { using namespace device_model; @@ -414,7 +414,7 @@ TEST_F(XmlParserTest, References) ASSERT_EQ((size_t)1, filter.count("eps")); } -TEST_F(XmlParserTest, SourceReferences) +TEST_F(XmlParserTest, data_item_source_has_data_item_id_and_component_id) { if (m_xmlParser) { @@ -446,7 +446,7 @@ TEST_F(XmlParserTest, SourceReferences) ASSERT_EQ("xxx", (*source)->get("compositionId")); } -TEST_F(XmlParserTest, DataItemRelationships) +TEST_F(XmlParserTest, data_item_relationships_contain_type_and_id_ref) { if (m_xmlParser) { @@ -496,10 +496,68 @@ TEST_F(XmlParserTest, DataItemRelationships) ASSERT_EQ(string("xlc"), (*rel2)->get("idRef")); } -TEST_F(XmlParserTest, ParseDeviceMTConnectVersion) +TEST_F(XmlParserTest, device_has_mtconnect_version_attribute) { const auto dev = m_devices.front(); ASSERT_TRUE(dev); ASSERT_EQ(string("1.7"), dev->get("mtconnectVersion")); } + +TEST_F(XmlParserTest, parse_device_with_bare_device_root_returns_device) +{ + const string deviceXml = R"( + + + + + + )"; + + auto device = m_xmlParser->parseDevice(deviceXml, nullptr); + ASSERT_TRUE(device); + ASSERT_EQ(string("TestDevice"), device->get("name")); + ASSERT_EQ(string("test-001"), device->get("uuid")); +} + +TEST_F(XmlParserTest, parse_device_with_mtconnect_devices_wrapper_returns_first_device) +{ + const string deviceXml = R"( + +
+ + + + + + + + + )"; + + auto device = m_xmlParser->parseDevice(deviceXml, nullptr); + ASSERT_TRUE(device); + ASSERT_EQ(string("WrappedDevice"), device->get("name")); + ASSERT_EQ(string("test-002"), device->get("uuid")); +} + +TEST_F(XmlParserTest, parse_device_with_invalid_xml_returns_null) +{ + auto device = m_xmlParser->parseDevice("not valid xml <><>", nullptr); + ASSERT_FALSE(device); +} + +TEST_F(XmlParserTest, parse_device_with_empty_devices_node_returns_null) +{ + const string deviceXml = R"( + +
+ + + )"; + + auto device = m_xmlParser->parseDevice(deviceXml, nullptr); + ASSERT_FALSE(device); +} From f2474bee7fc4186c7983022a9d7c96916fca3a61 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 6 May 2026 21:35:03 +0200 Subject: [PATCH 2/2] Default bind address to :: for dual stack v6 and v4 support --- src/mtconnect/sink/rest_sink/server.cpp | 6 ++++++ src/mtconnect/sink/rest_sink/server.hpp | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/server.cpp b/src/mtconnect/sink/rest_sink/server.cpp index 9c75c40b6..6821f8bc0 100644 --- a/src/mtconnect/sink/rest_sink/server.cpp +++ b/src/mtconnect/sink/rest_sink/server.cpp @@ -121,6 +121,12 @@ namespace mtconnect::sink::rest_sink { fail(ec, "Cannot open server socket"); return; } + if (m_address.is_v6()) + { + // Enable dual-stack by default. It will allow 0.0.0.0 if :: + m_acceptor.set_option(boost::asio::ip::v6_only(false), ec); + ec = {}; // not fatal if unsupported + } m_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); if (ec) { diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 450233a96..d6aece965 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -52,7 +52,7 @@ namespace mtconnect::sink::rest_sink { /// @param options configuration options /// - Port, defaults to 5000 /// - AllowPut, defaults to false - /// - ServerIp, defaults to 0.0.0.0 + /// - ServerIp, defaults to :: /// - HttpHeaders Server(boost::asio::io_context &context, const ConfigOptions &options = {}) : m_context(context), @@ -65,7 +65,7 @@ namespace mtconnect::sink::rest_sink { auto inter = GetOption(options, configuration::ServerIp); if (!inter) { - m_address = boost::asio::ip::make_address("0.0.0.0"); + m_address = boost::asio::ip::make_address("::"); } else {