Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mmyster/feature/config kit #598

Merged
merged 4 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_subdirectory(${LIBS_DIR}/BehaviorKit)
add_subdirectory(${LIBS_DIR}/BLEKit)
add_subdirectory(${LIBS_DIR}/ColorKit)
add_subdirectory(${LIBS_DIR}/CommandKit)
add_subdirectory(${LIBS_DIR}/ConfigKit)
add_subdirectory(${LIBS_DIR}/ContainerKit)
add_subdirectory(${LIBS_DIR}/FileManagerKit)
add_subdirectory(${LIBS_DIR}/FirmwareKit)
Expand Down
28 changes: 28 additions & 0 deletions libs/ConfigKit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Leka - LekaOS
# Copyright 2022 APF France handicap
# SPDX-License-Identifier: Apache-2.0

add_library(ConfigKit STATIC)

target_include_directories(ConfigKit
PUBLIC
include
)

target_sources(ConfigKit
PRIVATE
source/Config.cpp
)

target_link_libraries(ConfigKit
mbed-os
FileManagerKit
)

if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests")

leka_unit_tests_sources(
tests/Config_test.cpp
)

endif()
28 changes: 28 additions & 0 deletions libs/ConfigKit/include/Config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <filesystem>

namespace leka {

struct Config {
public:
explicit Config(const std::filesystem::path &path, uint8_t default_value = 0xFF)
: _path(_default_parent_path / path), _default_value(default_value)
{
// nothing to do
}

[[nodiscard]] auto path() const -> std::filesystem::path { return _path; }
[[nodiscard]] auto default_value() const -> uint8_t { return _default_value; }

private:
const std::filesystem::path _default_parent_path = "/fs/conf";
const std::filesystem::path _path;
const uint8_t _default_value;
};

} // namespace leka
21 changes: 21 additions & 0 deletions libs/ConfigKit/include/ConfigKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <filesystem>

#include "Config.h"

namespace leka {

class ConfigKit
{
public:
explicit ConfigKit() = default;
[[nodiscard]] auto read(Config const &config) const -> uint8_t;
[[nodiscard]] auto write(Config const &config, uint8_t data) const -> bool;
};

} // namespace leka
15 changes: 15 additions & 0 deletions libs/ConfigKit/include/ConfigList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <filesystem>

#include "ConfigKit.h"

namespace leka::config::bootloader {

inline const auto battery_level_hysteresis = Config {"bootloader_battery_level_hysteresis", 42};

} // namespace leka::config::bootloader
36 changes: 36 additions & 0 deletions libs/ConfigKit/source/Config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "ConfigKit.h"
#include "FileManagerKit.h"

using namespace leka;

auto ConfigKit::read(Config const &config) const -> uint8_t
{
FileManagerKit::File file {config.path(), "r"};

if (!file.is_open()) {
return config.default_value();
}

auto data = std::array<uint8_t, 1> {};
file.read(data);

return data.front();
}

auto ConfigKit::write(Config const &config, uint8_t data) const -> bool
{
FileManagerKit::File file {config.path(), "r+"};

if (!file.is_open()) {
return false;
}

auto output = std::to_array<uint8_t>({data});
file.write(output);

return true;
}
122 changes: 122 additions & 0 deletions libs/ConfigKit/tests/Config_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Leka - LekaOS
// Copyright 2021 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include <array>
#include <fstream>
#include <iostream>
#include <span>
#include <string>

#include "ConfigKit.h"
#include "FileManagerKit.h"
#include "LogKit.h"
#include "gtest/gtest.h"
#include "mocks/leka/File.h"

using namespace leka;

class ConfigTest : public ::testing::Test
{
protected:
// void SetUp() override {}
// void TearDown() override {}

auto spy_readConfigValue() -> uint8_t
{
auto input_data = std::array<uint8_t, 1> {};
FileManagerKit::File file {config_path.c_str()};
file.read(input_data);
file.close();
return input_data.front();
}

void spy_writeConfigValue(uint8_t data)
{
auto output_data = std::array<uint8_t, 1> {data};
FileManagerKit::File file {config_path.c_str(), "r+"};
file.write(output_data);
file.close();
}

void spy_touchConfigFile()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi touch?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

touch filename c'est la commande pour créer un fichier sur unix

{
FileManagerKit::File file {config_path.c_str(), "w"};
file.close();
}
void spy_removeConfigFile() { std::remove(config_path.c_str()); }

const std::filesystem::path config_path = "/tmp/test_config.conf";
};

TEST_F(ConfigTest, initializationConfigFullPath)
{
const std::filesystem::path custom_full_path = "/tmp/test_config.conf";
Config config {custom_full_path};
ASSERT_NE(nullptr, &config);
const std::filesystem::path expected_path = "/tmp/test_config.conf";
ASSERT_EQ(expected_path, config.path());
}

TEST_F(ConfigTest, initializationWithDefaultParentPathConfig)
{
const std::filesystem::path custom_filename = "test_config.conf";
Config config {custom_filename};
ASSERT_NE(nullptr, &config);
const std::filesystem::path expected_path = "/fs/conf/test_config.conf";
ASSERT_EQ(expected_path, config.path());
}

TEST_F(ConfigTest, initializationConfigKit)
{
auto configkit = ConfigKit();
ASSERT_NE(nullptr, &configkit);
}

TEST_F(ConfigTest, readNotOpenFile)
{
Config config {config_path};
auto configkit = ConfigKit();
spy_removeConfigFile();
auto data = configkit.read(config);
ASSERT_EQ(config.default_value(), data);
}

TEST_F(ConfigTest, readEmptyFile)
{
Config config {config_path};
auto configkit = ConfigKit();
spy_removeConfigFile();
spy_touchConfigFile();
auto data = configkit.read(config);
ASSERT_EQ(0, data);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si le fichier ne contient aucun byte de donnée, c'est ConfigKit qui définit la valeur 0 par défaut?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c'est une bonne question !

est-ce que pas de valeur == 0 ou == default_value.

je pencherai pour default_value puisque pas de fichier ou rien dedans c'est un peu la même chose --> la config n'existe pas vraiment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valeur = 0

Rien n'est lue effectivement mais la variable input est vide par défault (donc élément 0 par défault)

}

TEST_F(ConfigTest, read)
{
Config config {config_path};
auto configkit = ConfigKit();
spy_writeConfigValue(5);
auto data = configkit.read(config);
ASSERT_EQ(5, data);
}

TEST_F(ConfigTest, writeNotOpenFile)
{
Config config {config_path};
auto configkit = ConfigKit();
spy_removeConfigFile();
auto write = configkit.write(config, 5);
ASSERT_FALSE(write);
}

TEST_F(ConfigTest, write)
{
Config config {config_path};
auto configkit = ConfigKit();
spy_touchConfigFile();
auto write = configkit.write(config, 5);
ASSERT_TRUE(write);
auto data = spy_readConfigValue();
ASSERT_EQ(5, data);
}
1 change: 1 addition & 0 deletions spikes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_subdirectory(${SPIKES_DIR}/lk_bluetooth)
add_subdirectory(${SPIKES_DIR}/lk_cg_animations)
add_subdirectory(${SPIKES_DIR}/lk_color_kit)
add_subdirectory(${SPIKES_DIR}/lk_command_kit)
add_subdirectory(${SPIKES_DIR}/lk_config_kit)
add_subdirectory(${SPIKES_DIR}/lk_coreled)
add_subdirectory(${SPIKES_DIR}/lk_event_queue)
add_subdirectory(${SPIKES_DIR}/lk_file_reception)
Expand Down
22 changes: 22 additions & 0 deletions spikes/lk_config_kit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Leka - LekaOS
# Copyright 2022 APF France handicap
# SPDX-License-Identifier: Apache-2.0

add_mbed_executable(spike_lk_config_kit)

target_include_directories(spike_lk_config_kit
PRIVATE
.
)

target_sources(spike_lk_config_kit
PRIVATE
main.cpp
)

target_link_libraries(spike_lk_config_kit
FileManagerKit
ConfigKit
)

target_link_custom_leka_targets(spike_lk_config_kit)
71 changes: 71 additions & 0 deletions spikes/lk_config_kit/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include <cstddef>
#include <filesystem>

#include "drivers/BufferedSerial.h"
#include "rtos/ThisThread.h"

#include "ConfigKit.h"
#include "ConfigList.h"
#include "FATFileSystem.h"
#include "FileManagerKit.h"
#include "HelloWorld.h"
#include "LogKit.h"
#include "SDBlockDevice.h"

using namespace leka;
using namespace std::chrono_literals;

SDBlockDevice sd_blockdevice(SD_SPI_MOSI, SD_SPI_MISO, SD_SPI_SCK);
FATFileSystem fatfs("fs");

auto configkit = ConfigKit();

void initializeSD()
{
constexpr auto default_sd_blockdevice_frequency = uint64_t {25'000'000};

sd_blockdevice.init();
sd_blockdevice.frequency(default_sd_blockdevice_frequency);

fatfs.mount(&sd_blockdevice);
}

auto main() -> int
{
logger::init();

log_info("Hello, World!\n\n");

auto start = rtos::Kernel::Clock::now();

auto hello = HelloWorld();

rtos::ThisThread::sleep_for(1s);

hello.start();

initializeSD();

auto custom_data = uint8_t {0};

rtos::ThisThread::sleep_for(1s);

while (true) {
auto t = rtos::Kernel::Clock::now() - start;
log_info("A message from your board %s --> \"%s\" at %i s", MBED_CONF_APP_TARGET_NAME, hello.world,
int(t.count() / 1000));

++custom_data;
if (auto write = configkit.write(config::bootloader::battery_level_hysteresis, custom_data); !write) {
log_error("Fail to write in hysteresis config file");
return EXIT_FAILURE;
}
auto battery_level_hysteresis = configkit.read(config::bootloader::battery_level_hysteresis);
log_info("Battery level hysteresis : %d", battery_level_hysteresis);
rtos::ThisThread::sleep_for(10s);
}
}
1 change: 1 addition & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ leka_register_unit_tests_for_library(BehaviorKit)
leka_register_unit_tests_for_library(BLEKit)
leka_register_unit_tests_for_library(ColorKit)
leka_register_unit_tests_for_library(CommandKit)
leka_register_unit_tests_for_library(ConfigKit)
leka_register_unit_tests_for_library(ContainerKit)
leka_register_unit_tests_for_library(FileManagerKit)
leka_register_unit_tests_for_library(FirmwareKit)
Expand Down