forked from nnstreamer/nnstreamer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Filter/MLAgent: Add unit test cases for parsing MLAgent URIs
This patch adds test cases for unit testing of parsing the MLAgent URIs. Signed-off-by: Wook Song <[email protected]>
- Loading branch information
Showing
4 changed files
with
514 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1-only */ | ||
/** | ||
* @file mlagent_mock.cc | ||
* @date 30 Nov 2023 | ||
* @brief A class that mocks the ML Agent instance | ||
* @author Wook Song <[email protected]> | ||
* @see http://github.com/nnstreamer/nnstreamer | ||
* @bug No known bugs | ||
* | ||
*/ | ||
|
||
#include <glib.h> | ||
#include <json-glib/json-glib.h> | ||
#include <nnstreamer_util.h> | ||
|
||
#include <functional> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
#include "mock_mlagent.h" | ||
|
||
static std::unique_ptr<MockMLAgent> uptr_mock; | ||
|
||
/** | ||
* @brief Generate C-stringified JSON | ||
*/ | ||
gchar * | ||
MockModel::to_cstr_json () | ||
{ | ||
using json_member_name_to_cb_t | ||
= std::pair<std::string, std::function<std::string ()>>; | ||
|
||
const std::vector<json_member_name_to_cb_t> json_mem_to_cb_map{ | ||
json_member_name_to_cb_t ( | ||
"path", [this] () -> std::string { return path (); }), | ||
json_member_name_to_cb_t ( | ||
"description", [this] () -> std::string { return desc (); }), | ||
json_member_name_to_cb_t ( | ||
"app_info", [this] () -> std::string { return app_info (); }), | ||
json_member_name_to_cb_t ("version", | ||
[this] () -> std::string { return std::to_string (version ()); }), | ||
json_member_name_to_cb_t ("active", | ||
[this] () -> std::string { return (is_activated () ? "T" : "F"); }), | ||
}; | ||
|
||
g_autoptr (JsonBuilder) builder = json_builder_new (); | ||
g_autoptr (JsonGenerator) gen = NULL; | ||
|
||
json_builder_begin_object (builder); | ||
for (auto iter : json_mem_to_cb_map) { | ||
json_builder_set_member_name (builder, iter.first.c_str ()); | ||
json_builder_add_string_value (builder, iter.second ().c_str ()); | ||
} | ||
json_builder_end_object (builder); | ||
|
||
{ | ||
g_autoptr (JsonNode) root = json_builder_get_root (builder); | ||
|
||
gen = json_generator_new (); | ||
json_generator_set_root (gen, root); | ||
json_generator_set_pretty (gen, TRUE); | ||
} | ||
|
||
return json_generator_to_data (gen, NULL); | ||
} | ||
|
||
/** | ||
* @brief Initialize the static unique_ptr of MockMLAgent | ||
*/ | ||
void | ||
ml_agent_mock_init () | ||
{ | ||
uptr_mock = std::make_unique<MockMLAgent> (); | ||
} | ||
|
||
/** | ||
* @brief C-wrapper for the MockModel's method add_model. | ||
*/ | ||
bool | ||
ml_agent_mock_add_model (const gchar *name, const gchar *path, const gchar *app_info, | ||
const bool is_activated, const char *desc, const guint version) | ||
{ | ||
MockModel model{ name, path, app_info, is_activated, desc, version }; | ||
|
||
return uptr_mock->add_model (model); | ||
} | ||
|
||
/** | ||
* @brief C-wrapper for the MockModel's method get_model. | ||
*/ | ||
MockModel * | ||
ml_agent_mock_model_get (const gchar *name, const guint version) | ||
{ | ||
return uptr_mock->get_model (name, version); | ||
} | ||
|
||
/** | ||
* @brief Pass the JSON c-string generated by the ML Agent mock class to the caller. | ||
*/ | ||
gint | ||
ml_agent_model_get (const gchar *name, const guint version, gchar **description, GError **err) | ||
{ | ||
MockModel *model_ptr = ml_agent_mock_model_get (name, version); | ||
|
||
g_return_val_if_fail (err == NULL || *err == NULL, -EINVAL); | ||
|
||
if (model_ptr == nullptr) { | ||
return -EINVAL; | ||
} | ||
|
||
*description = model_ptr->to_cstr_json (); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
/** | ||
* SPDX-License-Identifier: LGPL-2.1-only | ||
* | ||
* @file mlagent_mock.h | ||
* @date 29 Nov 2023 | ||
* @brief Mocking ML Agent APIs | ||
* @see https://github.com/nnstreamer/nnstreamer | ||
* @author Wook Song <[email protected]> | ||
* @bug No known bugs | ||
*/ | ||
#ifndef __NNS_MLAGENT_MOCK_H__ | ||
#define __NNS_MLAGENT_MOCK_H__ | ||
|
||
#include <glib.h> | ||
|
||
#include <unordered_map> | ||
#include <vector> | ||
|
||
struct MockModel; | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif /* __cplusplus */ | ||
|
||
/** | ||
* @brief Initialize the static unique_ptr of MockMLAgent | ||
*/ | ||
void ml_agent_mock_init (); | ||
|
||
/** | ||
* @brief C-wrapper for the MockModel's method add_model. | ||
* @param[in] name The model's name to add | ||
* @param[in] path The model's name to add | ||
* @param[in] app_info The model's name to add | ||
* @param[in] is_activated The model's name to add | ||
* @param[in] desc The model's version to add | ||
* @param[in] version The JSON c-string containing the information of the model matching to the given name and version | ||
* @return true if there is a matching model to the given name and version, otherwise a negative integer | ||
* @note ML Agent provides the original implementation of this function and | ||
* the following implementation is only for testing purposes. | ||
*/ | ||
bool ml_agent_mock_add_model (const gchar *name, const gchar *path, const gchar *info, | ||
const bool is_activated, const char *desc, const guint version); | ||
|
||
/** | ||
* @brief C-wrapper for the MockModel's method get_model. | ||
* @param[in] name The model's name to retreive | ||
* @param[in] version The model's version to retreive | ||
* @return A pointer to the model matching the given information. If there is no model possible, NULL is returned. | ||
*/ | ||
MockModel *ml_agent_mock_get_model (const gchar *name, const guint version); | ||
|
||
/** | ||
* @brief Pass the JSON c-string generated by the ML Agent mock class to the caller. | ||
* @param[in] name The model's name to retreive | ||
* @param[in] version The model's version to retreive | ||
* @param[out] description The JSON c-string, containing the information of the model matching the given name and version | ||
* @param[out] err The return location for a recoverable error. This can be NULL. | ||
* @return 0 if there is a matching model to the given name and version otherwise a negative integer | ||
* @note ML Agent provides the original implementation of this function and | ||
* the following implementation is only for testing purposes. | ||
*/ | ||
gint ml_agent_model_get ( | ||
const gchar *name, const guint version, gchar **description, GError **err); | ||
#ifdef __cplusplus | ||
} | ||
#endif /* __cplusplus */ | ||
|
||
/** | ||
* @brief Class for mock Model object | ||
*/ | ||
struct MockModel { | ||
// Constructors | ||
MockModel () = delete; | ||
MockModel (std::string name, std::string path = {}, std::string app_info = {}, | ||
bool is_activated = false, std::string desc = {}, guint version = 0U) | ||
: name_{ name }, path_{ path }, app_info_{ app_info }, | ||
is_activated_{ is_activated }, desc_{ desc }, version_{ version } { | ||
|
||
}; | ||
// Copy constructor | ||
MockModel (const MockModel &other) | ||
: MockModel (other.name_, other.path_, other.app_info_, | ||
other.is_activated_, other.desc_, other.version_){ | ||
|
||
}; | ||
// Move constructor | ||
MockModel (MockModel &&other) noexcept | ||
{ | ||
*this = std::move (other); | ||
} | ||
MockModel &operator= (const MockModel &other) = delete; | ||
MockModel &operator= (MockModel &&other) noexcept | ||
{ | ||
if (this == &other) | ||
return *this; | ||
|
||
this->name_ = std::move (other.name_); | ||
this->path_ = std::move (other.path_); | ||
this->app_info_ = std::move (other.app_info_); | ||
this->is_activated_ = std::exchange (other.is_activated_, false); | ||
this->desc_ = std::move (other.desc_); | ||
this->version_ = std::exchange (other.version_, 0U); | ||
|
||
return *this; | ||
} | ||
|
||
bool operator== (const MockModel &model) const | ||
{ | ||
if (name_ == model.name_ && version_ == model.version_) | ||
return true; | ||
return false; | ||
} | ||
|
||
// Getters | ||
std::string name () const | ||
{ | ||
return name_; | ||
} | ||
|
||
std::string path () const | ||
{ | ||
return path_; | ||
} | ||
std::string app_info () const | ||
{ | ||
return app_info_; | ||
} | ||
bool is_activated () const | ||
{ | ||
return is_activated_; | ||
} | ||
|
||
std::string desc () const | ||
{ | ||
return desc_; | ||
} | ||
|
||
guint version () const | ||
{ | ||
return version_; | ||
} | ||
|
||
// Setters | ||
void path (const std::string &path) | ||
{ | ||
path_ = path; | ||
} | ||
|
||
void is_activated (bool flag) | ||
{ | ||
is_activated_ = flag; | ||
} | ||
|
||
void desc (const std::string &description) | ||
{ | ||
desc_ = description; | ||
} | ||
|
||
void app_info (const std::string &info) | ||
{ | ||
app_info_ = info; | ||
} | ||
|
||
void version (guint ver) | ||
{ | ||
version_ = ver; | ||
} | ||
|
||
/** | ||
* @brief Generate C-stringified JSON | ||
* @return C-stringified JSON | ||
*/ | ||
gchar *to_cstr_json (); | ||
|
||
private: | ||
std::string name_; | ||
std::string path_{}; | ||
std::string app_info_{}; | ||
bool is_activated_{ false }; | ||
std::string desc_{}; | ||
guint version_{ 0U }; | ||
}; | ||
|
||
struct MockMLAgent { | ||
MockMLAgent () | ||
{ | ||
} | ||
|
||
bool add_model (MockModel model) | ||
{ | ||
std::string key = model.name (); | ||
|
||
{ | ||
auto range = models_dict_.equal_range (key); | ||
|
||
for (auto it = range.first; it != range.second; ++it) { | ||
if (model == it->second) | ||
return false; | ||
} | ||
} | ||
|
||
models_dict_.insert (std::make_pair (key, model)); | ||
|
||
return true; | ||
} | ||
|
||
MockModel *get_model (const gchar *name, guint version) | ||
{ | ||
std::string key{ name }; | ||
auto range = models_dict_.equal_range (key); | ||
|
||
for (auto it = range.first; it != range.second; ++it) { | ||
if (version == it->second.version ()) | ||
return &it->second; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
private: | ||
std::unordered_multimap<std::string, MockModel> models_dict_; | ||
}; | ||
|
||
#endif /* __NNS_MLAGENT_MOCK_H__ */ |
Oops, something went wrong.