Compare commits

..

No commits in common. "d7cfa3f76c81750d80f5998a4b00bab4e01f053b" and "946f93eaca73a96d528a00ef7844852f88644a09" have entirely different histories.

8 changed files with 1 additions and 246 deletions

View File

@ -1,11 +0,0 @@
# Google style C++ Code Style settings
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignOperands: Align
AllowAllArgumentsOnNextLine: true
ColumnLimit: 80
BreakBeforeBraces: Allman

2
.gitignore vendored
View File

@ -1,6 +1,4 @@
# ---> C++
# build artifacts
build/
# Prerequisites
*.d

View File

@ -1,20 +0,0 @@
# Root cmake file sketch (might change it later)
# Author: Unai Blazquez
# License: GPL-3-or-later
cmake_minimum_required(VERSION 3.16)
project(azkoyen_ipc_test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Core library
add_library(core
src/core/SysfsRead.cxx
)
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
#tests
enable_testing()
add_subdirectory(tests)

View File

@ -1,23 +1,3 @@
# azkoyen_technical_test
Azkoyen technical test implementation. Implemented (mostly) on standard c++ 17 framework, but with Qt wherever was necessary.
## Development approach
A Test-Driven Development (TDD) workflow was followed throughout the project. Every component — from the lowest-level file reader to the GUI window — has a corresponding Google Test suite that was written before (or alongside) the production code. This ensures each module behaves correctly in isolation and makes regressions immediately visible.
## SysfsRead class
`SysfsReader` ([include/SysfsRead.hpp](include/SysfsRead.hpp), [src/core/SysfsRead.cxx](src/core/SysfsRead.cxx)) is the lowest-level component. It opens a sysfs-like file and translates its raw text content into a `SysfsStatus` enum:
| File content | Status |
|--------------------------|---------------------|
| `"1"` | `Enabled` |
| `"error: temp too high"` | `ErrorTempTooHigh` |
| empty / whitespace-only | `Empty` |
| file missing | `Unreachable` |
| anything else | `UnexpectedValue` |
The reader never throws on I/O errors; every outcome is expressed through the enum so callers can react without exception handling. A helper `trim_in_place` strips trailing whitespace and newlines before comparison.
**Tests:** [tests/test_sysfs_read.cxx](tests/test_sysfs_read.cxx) — covers all five status branches by writing controlled content to a temporary file.
Azkoyen technical test implementation. Implemented (mostly) on standard c++ 17 framework, but with Qt wherever was necessary

View File

@ -1,44 +0,0 @@
// SysfsRead.hpp
//
// SPDX-License-Identifier GPL-3.0-or-later
// Author: Unai Blazquez Gomez <unaibg2000@gmail.com>
#pragma once
#include <filesystem>
enum class SysfsStatus
{
/// @brief File cannot be opened or does not exist.
Unreachable,
/// @brief File exists but is just empty.
Empty,
/// @brief File content indicates taht production is enabled (e.g. "1")
Enabled,
/// @brief File requests a cooldown ("error: temp too high")
ErrorTempTooHigh,
/// @brief File contains an UnexpectedValue; producer must not send.
UnexpectedValue
};
class SysfsReader
{
public:
/// @brief Construct a SysfsReader bound to a specific input file path.
/// @param input_path Path to the sysfs-like input file.
explicit SysfsReader(const std::filesystem::path& input_path);
/// @brief Read and interpret the current status of the input file.
///
/// This function never throws on common I/O errors; instead it reports them
/// via the SysfsStatus enum.
/// @return Interpreted status of the input file
SysfsStatus read_status() const;
private:
/// @brief Helper method for trimming trailing whitespaces and
/// newline indicators
/// @param String from the m_path file
static void trim_in_place(std::string& string);
std::filesystem::path m_path; // Path to the input file.
};

View File

@ -1,56 +0,0 @@
// SysfsRead.cxx
// SPDX-License-Identifier: GPL-3.0-or-later
// Author: Unai Blazquez <unaibg2000@gmail.com>
#include "SysfsRead.hpp"
#include <algorithm>
#include <fstream>
SysfsReader::SysfsReader(const std::filesystem::path& input_path)
: m_path(input_path)
{
}
SysfsStatus SysfsReader::read_status() const
{
std::ifstream input_file_stream(m_path);
if (!input_file_stream.is_open())
{
return SysfsStatus::Unreachable;
}
std::stringstream buffer;
buffer << input_file_stream.rdbuf(); // read entire stream into buffer
std::string contents = buffer.str();
trim_in_place(contents); // clean input string
// compare
if (contents.empty())
{
return SysfsStatus::Empty;
}
if (contents == "1")
{
return SysfsStatus::Enabled;
}
if (contents == "error: temp too high")
{
return SysfsStatus::ErrorTempTooHigh;
}
return SysfsStatus::UnexpectedValue;
}
void SysfsReader::trim_in_place(std::string& string)
{
// left trim
string.erase(string.begin(),
std::find_if(string.begin(), string.end(), [](unsigned char ch)
{ return !std::isspace(ch); }));
// right trim
string.erase(std::find_if(string.rbegin(), string.rend(),
[](unsigned char ch) { return !std::isspace(ch); })
.base(),
string.end());
}

View File

@ -1,15 +0,0 @@
# Author: Unai Blazquez
# License: GPL-3-only
add_executable(test_sysfs_reader
test_sysfs_read.cxx
)
target_link_libraries(test_sysfs_reader
PRIVATE
core
gtest
gtest_main
)
add_test(NAME test_sysfs_reader COMMAND test_sysfs_reader)

View File

@ -1,77 +0,0 @@
#include <gtest/gtest.h>
#include <fstream>
#include "SysfsRead.hpp"
TEST(SysfsReaderTest, ReturnsEnabledWhenFileContainsOne)
{
// Arrange create the file and write "1\n" into it.
{
std::ofstream out("fake_sysfs_input");
out << "1\n";
// out is closed automatically at the end of this scope
}
// 2) Act: construct the reader and read the status.
SysfsReader reader{"fake_sysfs_input"};
SysfsStatus status = reader.read_status();
// 3) Assert: we expect Enabled.
EXPECT_EQ(status, SysfsStatus::Enabled);
}
TEST(SysfsReaderTest, ReturnsEmptyWhenFileIsEmpty)
{
// Arrange: create the file and don't write anything
{
std::ofstream out("fake_sysfs_input");
out << "";
}
SysfsReader reader{"fake_sysfs_input"};
SysfsStatus status1 = reader.read_status();
{
std::ofstream out("fake_sysfs_input");
out << " ";
}
SysfsReader reader_2{"fake_sysfs_input"};
SysfsStatus status2 = reader_2.read_status();
// Assert
EXPECT_EQ(status1, SysfsStatus::Empty);
EXPECT_EQ(status2, SysfsStatus::Empty);
}
TEST(SysfsReaderTest, ReturnsUnexpectedValue)
{
{
std::ofstream out("fake_sysfs_input");
out << "tdd development";
}
SysfsReader reader{"fake_sysfs_input"};
SysfsStatus status = reader.read_status();
// Assert
EXPECT_EQ(status, SysfsStatus::UnexpectedValue);
}
TEST(SysfsReaderTest, ReturnsErrorTempTooHigh)
{
{
std::ofstream out("fake_sysfs_input");
out << "error: temp too high";
}
SysfsReader reader{"fake_sysfs_input"};
SysfsStatus status = reader.read_status();
// Assert
EXPECT_EQ(status, SysfsStatus::ErrorTempTooHigh);
}
TEST(SysfsReaderTest, ReturnsUnreachableWhenDoesntExist)
{
SysfsReader reader{"nonexistent_sysfs_input"};
SysfsStatus status = reader.read_status();
// Assert
EXPECT_EQ(status, SysfsStatus::Unreachable);
}