Implemented smartctl output format detection function, along with its test.

This commit is contained in:
Alexander Shaduri
2022-02-16 17:33:05 +04:00
parent 5b7c2f6dbb
commit 70967beebf
5 changed files with 80 additions and 13 deletions
+1
View File
@@ -66,6 +66,7 @@ target_link_libraries(applib
libdebug
hz
rconfig
boost_leaf
app_gtkmm_interface
app_pcrecpp_interface
app_gettext_interface
+16 -11
View File
@@ -33,18 +33,23 @@ std::unique_ptr<SmartctlParser> SmartctlParser::create(SmartctlParserType type)
// std::optional<SmartctlParserType> SmartctlParser::detect_output_type(const std::string& output) const
// {
leaf::result<SmartctlParserType> SmartctlParser::detect_output_type(const std::string& output)
{
// Look for the first non-whitespace symbol
// auto first_symbol = std::find_if(output.begin(), output.end(), [&](char c) {
// return !std::isspace(c, std::locale::classic());
// });
// if (first_symbol != output.end() && *first_symbol == '-'
// }
auto first_symbol = std::find_if(output.begin(), output.end(), [&](char c) {
return !std::isspace(c, std::locale::classic());
});
if (first_symbol != output.end()) {
if (*first_symbol == '{') {
return SmartctlParserType::Json;
}
if (output.rfind("smartctl", static_cast<std::size_t>(first_symbol - output.begin())) == 0) {
return SmartctlParserType::Text;
}
return leaf::new_error(SmartctlParserError::UnsupportedFormat);
}
return leaf::new_error(SmartctlParserError::EmptyInput);
}
+9 -2
View File
@@ -16,12 +16,19 @@ Copyright:
#include <vector>
#include <memory>
// #include "leaf_ns.h"
#include "leaf_ns.h"
#include "ata_storage_property.h"
#include "smartctl_parser_types.h"
enum class SmartctlParserError {
EmptyInput,
UnsupportedFormat,
};
/// Smartctl (S)ATA text output parser.
/// Note: ALL parse_* functions (except parse_full() and parse_version())
/// expect data in unix-newline format!
@@ -66,7 +73,7 @@ class SmartctlParser {
/// Detect smartctl output type (text, json).
// [[nodiscard]] leaf::result<SmartctlParserType> detect_output_type(const std::string& output) const;
[[nodiscard]] static leaf::result<SmartctlParserType> detect_output_type(const std::string& output);
/// Get "full" data, as passed to parse_full().
+1
View File
@@ -15,6 +15,7 @@ endif()
add_library(applib_tests OBJECT)
target_sources(applib_tests PRIVATE
test_app_pcrecpp.cpp
test_smartctl_parser.cpp
test_smartctl_version_parser.cpp
)
target_link_libraries(applib_tests PRIVATE
+53
View File
@@ -0,0 +1,53 @@
/******************************************************************************
License: BSD Zero Clause License
Copyright:
(C) 2022 Alexander Shaduri <ashaduri@gmail.com>
******************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup applib_tests
/// \weakgroup applib_tests
/// @{
// Catch2 v3
//#include "catch2/catch_test_macros.hpp"
// Catch2 v2
#include "catch2/catch.hpp"
#include "test_helpers/test_helpers.h"
#include "applib/smartctl_parser.h"
TEST_CASE("SmartctlFormatDetection", "[app][parser]")
{
REQUIRE( try_expect_errors([] {
return SmartctlParser::detect_output_type({});
}, SmartctlParserError::EmptyInput) );
REQUIRE( try_expect_errors([] {
return SmartctlParser::detect_output_type("smart");
}, SmartctlParserError::UnsupportedFormat) );
REQUIRE(SmartctlParser::detect_output_type("{ }").value() == SmartctlParserType::Json);
REQUIRE(SmartctlParser::detect_output_type(" \n { } ").value() == SmartctlParserType::Json);
REQUIRE(SmartctlParser::detect_output_type("smartctl").value() == SmartctlParserType::Text);
REQUIRE(SmartctlParser::detect_output_type(
R"(smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.3.18-lp152.66-default] (SUSE RPM)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org
)").value() == SmartctlParserType::Text);
}
/// @}