Skip to content
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
2 changes: 1 addition & 1 deletion cmake/project.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
set(SAMCONF_VERSION 0.75.4)
set(SAMCONF_VERSION 0.75.8)

# Attention: Aside from the version, as many things as possible in this file
# should be put into functions, as this solves potential issues with commands
Expand Down
10 changes: 10 additions & 0 deletions src/samconf/private/json_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@
#include <safu/common.h>
#include <safu/log.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "samconf/config_backend.h"
#include "samconf/samconf.h"
#include "samconf/samconf_types.h"

samconfConfigStatusE_t samconfJsonBackendOpen(const char *location, samconfConfigBackend_t *backend) {
json_object *root = NULL;

struct stat sb;
int s = stat(location, &sb);
if (s == -1 && errno == ENOENT) {
safuLogDebugF("%s does not exist", location);
return SAMCONF_CONFIG_NOT_FOUND;
}

root = json_object_from_file(location);

if (!root) {
Expand Down
53 changes: 26 additions & 27 deletions src/samconf/private/samconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ samconfConfigStatusE_t samconfLoad(const char *location, bool enforceSignature,
}
} else {
safuLogErrF("Failed to lookup backend for %s.\n", location);
status = SAMCONF_CONFIG_NOT_FOUND;
}
} else {
safuLogErrF("Failed to verify signature for %s.", location);
Expand Down Expand Up @@ -234,25 +235,27 @@ static samconfConfigStatusE_t _extendWithDirectory(DIR *confDir, bool enforceSig
static samconfConfigStatusE_t _extendWithLocation(const samconfConfigLocation_t *location,
samconfConfig_t **const conf) {
samconfConfigStatusE_t result = SAMCONF_CONFIG_NOT_FOUND;
DIR *confDir = opendir(location->path);
if (confDir != NULL) {
result = _extendWithDirectory(confDir, location->enforceSignature, location->path, conf);
if (result == SAMCONF_CONFIG_NOT_FOUND) {
safuLogWarnF("No config found in \"%s\"", location->path);
} else if (result == SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED) {
safuLogWarnF("merge rules don't allow anything in \"%s\" to be merged", location->path);
} else if (result != SAMCONF_CONFIG_OK) {
safuLogErrF("couldn't extend with \"%s\" (%d)", location->path, result);
}
closedir(confDir);
} else {
result = _extendWithSinglePath(location->path, location->enforceSignature, conf);
if (result == SAMCONF_CONFIG_NOT_FOUND) {
safuLogWarnF("no config could be found at \"%s\"", location->path);
} else if (result == SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED) {
safuLogWarnF("extending with \"%s\" not allowed by merge rules", location->path);
} else if (result != SAMCONF_CONFIG_OK) {
safuLogErrF("couldn't extend with \"%s\"", location->path);
if (location->path != NULL) {
DIR *confDir = opendir(location->path);
if (confDir != NULL) {
result = _extendWithDirectory(confDir, location->enforceSignature, location->path, conf);
if (result == SAMCONF_CONFIG_NOT_FOUND) {
safuLogWarnF("No config found in \"%s\"", location->path);
} else if (result == SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED) {
safuLogWarnF("merge rules don't allow anything in \"%s\" to be merged", location->path);
} else if (result != SAMCONF_CONFIG_OK) {
safuLogErrF("couldn't extend with \"%s\" (%d)", location->path, result);
}
closedir(confDir);
} else {
result = _extendWithSinglePath(location->path, location->enforceSignature, conf);
if (result == SAMCONF_CONFIG_NOT_FOUND) {
safuLogWarnF("no config could be found at \"%s\"", location->path);
} else if (result == SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED) {
safuLogWarnF("extending with \"%s\" not allowed by merge rules", location->path);
} else if (result != SAMCONF_CONFIG_OK) {
safuLogErrF("couldn't extend with \"%s\"", location->path);
}
}
}
return result;
Expand Down Expand Up @@ -285,9 +288,6 @@ samconfConfigStatusE_t samconfLoadAndMerge(const samconfConfigLocation_t locatio
for (size_t i = 0; i < locationsSize; i++) {
switch (locations[i].type) {
case SAMCONF_CONFIG_LOCATION_TYPE_CONFIG:
if (locations[i].path == NULL) {
continue;
}
tmpRes = samconfConfigMergeConfig(config, locations[i].config);
break;
case SAMCONF_CONFIG_LOCATION_TYPE_PATH:
Expand All @@ -297,12 +297,11 @@ samconfConfigStatusE_t samconfLoadAndMerge(const samconfConfigLocation_t locatio
safuLogWarn("not a valid config location");
continue;
}
if (tmpRes == SAMCONF_CONFIG_OK) {
if (tmpRes == SAMCONF_CONFIG_INVALID_SIGNATURE ||
(tmpRes == SAMCONF_CONFIG_ERROR && status != SAMCONF_CONFIG_INVALID_SIGNATURE)) {
status = tmpRes;
} else if (status == SAMCONF_CONFIG_NOT_FOUND && tmpRes == SAMCONF_CONFIG_OK) {
status = SAMCONF_CONFIG_OK;
} else if (tmpRes == SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED && status == SAMCONF_CONFIG_OK) {
status = SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED;
} else {
safuLogWarnF("some error extending With location \"%s\"", locations[i].path);
}
}
return status;
Expand Down
11 changes: 6 additions & 5 deletions src/samconf/public/samconf/samconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ samconfConfigStatusE_t samconfVerifySignature(const char *location);
*
* Returns:
* SAMCONF_CONFIG_OK – on success.
* SAMCONF_CONFIG_NOT_FOUND - when path doesn't point to a configuration..
* SAMCONF_CONFIG_ERROR – on failure.
******************************************************************/
samconfConfigStatusE_t samconfLoad(const char *location, bool enforceSignature, samconfConfig_t **const config);

/*******************************************************************
* Create a path to the config, upto the top most parent.
* Load all configs from multiple locations and merge them together
*
* Parameters:
* locations : a lisit of locations from where to assemble the configuration
* locations : a list of locations from where to assemble the configuration
* locationsSize : the size of the locations list
* config : the pointer in which to store the resulting config
*
* Returns:
* SAMCONF_CONFIG_OK – when at least one config could be loaded and merged successfully
* SAMCONF_CONFIG_OVERWRITE_NOT_ALLOWED - when the merge rules forbitt all the configs to be merged
* SAMCONF_CONFIG_NOT_FOUND - if none of the locations have any configs
* SAMCONF_CONFIG_OK – when nothing failed
* SAMCONF_CONFIG_INVALID_SIGNATURE - when at least one config has an invalid signature
* SAMCONF_CONFIG_NOT_FOUND - when no configuration was found.
* SAMCONF_CONFIG_ERROR – on failure.
******************************************************************/
samconfConfigStatusE_t samconfLoadAndMerge(const samconfConfigLocation_t *locations, size_t locationsSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ create_unit_test(
test_samconfJsonBackendOpen_utest
SOURCES
case_success_file.c
case_error_file.c
case_err_reading_file.c
case_err_file_not_found.c
samconfJsonBackendOpen_utest.c
LIBRARIES
samconf_static
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT

#include <asm-generic/errno-base.h>
#include <asm-generic/errno.h>
#include <cmocka_extensions/cmocka_extensions.h>
#include <samconf/json_backend.h>

#include "cmocka_mocks/mock_libc.h"
#include "samconf/samconf_types.h"
#include "samconfJsonBackendOpen_utest.h"

int samconfTestSamconfJsonBackendOpenFileErrFileNotFoundSetup(UNUSED void **state) {
json_object *jobjDummy = malloc(sizeof(json_object *));
*state = jobjDummy;
return 0;
}

int samconfTestSamconfJsonBackendOpenFileErrFileNotFoundTeardown(UNUSED void **state) {
__real_free(*state);
return 0;
}

void samconfTestSamconfJsonBackendOpenFileErrFileNotFound(UNUSED void **state) {
char path[] = "test.json";
samconfConfigStatusE_t result = SAMCONF_CONFIG_ERROR;
samconfConfigBackend_t backend = {
.originalHandle = path,
.backendHandle = NULL,
};

TEST("samconfJsonBackendOpen with existing File input");
SHOULD("%s", "return expected json_object inside struct");

MOCK_FUNC_AFTER_CALL(stat, 0);
expect_string(__wrap_stat, pathname, path);
expect_any(__wrap_stat, statbuf);
will_return_and_set_errno(__wrap_stat, -1, ENOENT);

result = samconfJsonBackendOpen(path, &backend);

assert_int_equal(result, SAMCONF_CONFIG_NOT_FOUND);
assert_string_equal(backend.originalHandle, path);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
#include <samconf/json_backend.h>

#include "cmocka_mocks/mock_jsonc.h"
#include "cmocka_mocks/mock_libc.h"
#include "safu/mock_log.h"
#include "samconf/samconf_types.h"
#include "samconfJsonBackendOpen_utest.h"

int samconfTestSamconfJsonBackendOpenFileErrorSetup(UNUSED void **state) {
int samconfTestSamconfJsonBackendOpenFileErrReadingFileSetup(UNUSED void **state) {
return 0;
}

int samconfTestSamconfJsonBackendOpenFileErrorTeardown(UNUSED void **state) {
int samconfTestSamconfJsonBackendOpenFileErrReadingFileTeardown(UNUSED void **state) {
return 0;
}

void samconfTestSamconfJsonBackendOpenFileError(UNUSED void **state) {
void samconfTestSamconfJsonBackendOpenFileErrReadingFile(UNUSED void **state) {
samconfConfigStatusE_t result = SAMCONF_CONFIG_OK;
char *path = "test.json";

Expand All @@ -26,6 +28,11 @@ void samconfTestSamconfJsonBackendOpenFileError(UNUSED void **state) {
TEST("samconfJsonBackendOpen File Input with error");
SHOULD("%s", "Return Error Status and log error message");

MOCK_FUNC_AFTER_CALL(stat, 0);
expect_string(__wrap_stat, pathname, path);
expect_any(__wrap_stat, statbuf);
will_return(__wrap_stat, 0);

MOCK_FUNC_AFTER_CALL(json_object_from_file, 0);
expect_not_value(__wrap_json_object_from_file, filename, NULL);
will_return(__wrap_json_object_from_file, NULL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ void samconfTestSamconfJsonBackendOpenFileSuccess(UNUSED void **state) {
.backendHandle = NULL,
};

TEST("samconfJsonBackendOpen with File input");
TEST("samconfJsonBackendOpen with existing File input");
SHOULD("%s", "return expected json_object inside struct");

MOCK_FUNC_AFTER_CALL(stat, 0);
expect_string(__wrap_stat, pathname, path);
expect_any(__wrap_stat, statbuf);
will_return(__wrap_stat, 0);

MOCK_FUNC_AFTER_CALL(json_object_from_file, 0);
expect_string(__wrap_json_object_from_file, filename, path);
will_return(__wrap_json_object_from_file, *state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ TEST_SUITE_FUNC_PROTOTYPES(samconfJsonBackendOpenUtest)
int main() {
const struct CMUnitTest tests[] = {
TEST_CASE(samconfTestSamconfJsonBackendOpenFileSuccess),
TEST_CASE(samconfTestSamconfJsonBackendOpenFileError),
TEST_CASE(samconfTestSamconfJsonBackendOpenFileErrReadingFile),
TEST_CASE(samconfTestSamconfJsonBackendOpenFileErrFileNotFound),
};

return RUN_TEST_SUITE(tests, samconfJsonBackendOpenUtest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
#ifndef SAMCONF_JSONBACKENDLOAD_UTEST_H
#define SAMCONF_JSONBACKENDLOAD_UTEST_H

#include <cmocka_extensions/cmocka_extensions.h>

#include "json_backend_utest.h"

TEST_CASE_FUNC_PROTOTYPES(samconfTestSamconfJsonBackendOpenFileSuccess)
TEST_CASE_FUNC_PROTOTYPES(samconfTestSamconfJsonBackendOpenFileError)
TEST_CASE_FUNC_PROTOTYPES(samconfTestSamconfJsonBackendOpenFileErrReadingFile)
TEST_CASE_FUNC_PROTOTYPES(samconfTestSamconfJsonBackendOpenFileErrFileNotFound)
#endif /* SAMCONF_JSONBACKENDLOAD_UTEST_H */
2 changes: 1 addition & 1 deletion test/utest/samconf/samconf/samconfLoad/case_lookuperr.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ void samconfTestSamconfLoadLookupError(UNUSED void **state) {
status = samconfLoad(location, false, &config);

assert_ptr_equal(backend, (void *)0xdeadc0de);
assert_int_equal(status, SAMCONF_CONFIG_ERROR);
assert_int_equal(status, SAMCONF_CONFIG_NOT_FOUND);
}
Loading