blob: de664e3b9eb33af701072c5da834ca6894e99c0e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <gtest/gtest.h>
#include "celix_properties.h"
#include "celix/Properties.h"
#include "celix_err.h"
#include "celix_array_list_ei.h"
#include "celix_utils_ei.h"
#include "celix_version_ei.h"
#include "jansson_ei.h"
#include "malloc_ei.h"
#include "stdio_ei.h"
class PropertiesEncodingErrorInjectionTestSuite : public ::testing::Test {
public:
PropertiesEncodingErrorInjectionTestSuite() = default;
~PropertiesEncodingErrorInjectionTestSuite() override {
celix_ei_expect_json_object(nullptr, 0, nullptr);
celix_ei_expect_open_memstream(nullptr, 0, nullptr);
celix_ei_expect_celix_utils_writeOrCreateString(nullptr, 0, nullptr);
celix_ei_expect_json_object_set_new(nullptr, 0, -1);
celix_ei_expect_json_sprintf(nullptr, 0, nullptr);
celix_ei_expect_celix_version_toString(nullptr, 0, nullptr);
celix_ei_expect_malloc(nullptr, 0, nullptr);
celix_ei_expect_celix_arrayList_createWithOptions(nullptr, 0, nullptr);
celix_ei_expect_celix_arrayList_addString(nullptr, 0, CELIX_SUCCESS);
celix_err_resetErrors();
}
};
TEST_F(PropertiesEncodingErrorInjectionTestSuite, SaveErrorTest) {
//Given a dummy properties object
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_set(props, "key", "value");
//When an error injected is prepared for json_object() from saveToStream
celix_ei_expect_json_object((void*)celix_properties_saveToStream, 0, nullptr);
//And a dummy stream is created
FILE* stream = fopen("/dev/null", "w");
//When I call celix_properties_saveToStream
celix_status_t status = celix_properties_saveToStream(props, stream, 0);
//Then I expect an error
EXPECT_EQ(CELIX_ENOMEM, status);
fclose(stream);
//When an error injected is prepared for open_memstream()n from save
celix_ei_expect_open_memstream((void*)celix_properties_saveToString, 0, nullptr);
//When I call celix_properties_saveToString
char* out;
status = celix_properties_saveToString(props, 0, &out);
//Then I expect an error
EXPECT_EQ(ENOMEM, status);
//And I expect 2 error messages in celix_err
EXPECT_EQ(2, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, FcloseErrorWhenSaveTest) {
//Given a dummy properties object
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_set(props, "key", "value");
//When an error injected is prepared for fclose() from save
celix_ei_expect_fclose((void*)celix_properties_save, 0, -1);
//And I call celix_properties_save
auto status = celix_properties_save(props, "somefile.json", 0);
//Then I expect an error
EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, status);
//And I expect 1 error message in celix_err
EXPECT_EQ(1, celix_err_getErrorCount());
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, EncodeErrorTest) {
// Given a dummy properties object
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_set(props, "key.with.slash", "value");
celix_properties_set(props, "key-with-out-slash", "value");
// When an error injected is prepared for celix_utils_writeOrCreateString() from celix_properties_saveToString
celix_ei_expect_celix_utils_writeOrCreateString((void*)celix_properties_saveToString, 2, nullptr);
// And I call celix_properties_saveToString using NESTED encoding (whitebox-knowledge)
char* out;
auto status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// When an error injected is prepared for json_object() from celix_properties_saveToString
celix_ei_expect_json_object((void*)celix_properties_saveToString, 2, nullptr);
// And I call celix_properties_saveToString using NESTED encoding (whitebox-knowledge)
status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// When an error injected is prepared for json_object_set_new() from celix_properties_saveToString
celix_ei_expect_json_object_set_new((void*)celix_properties_saveToString, 2, -1);
// And I call celix_properties_saveToString using NESTED encoding (whitebox-knowledge)
status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// When an error injected is prepared for json_string() from celix_properties_saveToString
celix_ei_expect_json_string((void*)celix_properties_saveToString, 3, nullptr);
// And I call celix_properties_saveToString using NESTED encoding (whitebox-knowledge)
status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// When an error injected is prepared for json_object_set_new() from celix_properties_saveToString
celix_ei_expect_json_object_set_new((void*)celix_properties_saveToString, 3, -1);
// And I call celix_properties_saveToString using FLAT encoding (whitebox-knowledge)
status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_FLAT_STYLE, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 5 error message in celix_err
EXPECT_EQ(5, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, EncodeArrayErrorTest) {
// Given a dummy properties object with an array
celix_autoptr(celix_properties_t) props = celix_properties_create();
auto* arr = celix_arrayList_createStringArray();
celix_arrayList_addString(arr, "value1");
celix_arrayList_addString(arr, "value2");
celix_properties_assignArrayList(props, "key", arr);
// When an error injected is prepared for json_array() from celix_properties_saveToString
celix_ei_expect_json_array((void*)celix_properties_saveToString, 5, nullptr);
// And I call celix_properties_saveToString
char* out;
auto status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 2 error message in celix_err
EXPECT_EQ(2, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, EncodeVersionErrorTest) {
// Given a dummy properties object with a version
celix_autoptr(celix_properties_t) props = celix_properties_create();
auto* version = celix_version_create(1, 2, 3, "qualifier");
celix_properties_assignVersion(props, "key", version);
// When an error injected is prepared for json_sprintf() from celix_properties_saveToString
celix_ei_expect_json_sprintf((void*)celix_properties_saveToString, 4, nullptr);
// And I call celix_properties_saveToString
char* out;
auto status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// When an error injected is prepared for celix_version_toString() from celix_properties_saveToString
celix_ei_expect_celix_version_toString((void*)celix_properties_saveToString, 4, nullptr);
// And I call celix_properties_saveToString
status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 2 error message in celix_err
EXPECT_EQ(2, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, EncodeDumpfErrorTest) {
// Given a dummy properties object
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_set(props, "key", "value");
// When an error injected is prepared for json_dumpf() from celix_properties_saveToString
celix_ei_expect_json_dumpf((void*)celix_properties_saveToStream, 0, -1);
// And I call celix_properties_saveToString
char* out;
auto status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 1 error message in celix_err
EXPECT_EQ(1, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, LoadErrorTest) {
//Given a dummy json string
const char* json = R"({"key":"value"})";
//When an error injected is prepared for fmemopen() from loadFromString2
celix_ei_expect_fmemopen((void*)celix_properties_loadFromString, 0, nullptr);
//When I call celix_properties_loadFromString
celix_properties_t* props;
auto status = celix_properties_loadFromString(json, 0, &props);
//Then I expect an error
EXPECT_EQ(ENOMEM, status);
//And I expect 1 error message in celix_err
EXPECT_EQ(1, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, DecodeErrorTest) {
//Given a dummy json string
const char* json = R"({"key":"value", "object": {"key":"value"}})";
//When an error injected is prepared for celix_properties_create()->malloc() from celix_properties_loadFromString2
celix_ei_expect_malloc((void*)celix_properties_loadFromString, 3, nullptr);
//When I call celix_properties_loadFromString
celix_properties_t* props;
auto status = celix_properties_loadFromString(json, 0, &props);
//Then I expect an error
EXPECT_EQ(ENOMEM, status);
//When an error injected is prepared for celix_utils_writeOrCreateString() from celix_properties_loadFromString2
celix_ei_expect_celix_utils_writeOrCreateString((void*)celix_properties_loadFromString, 3, nullptr);
//When I call celix_properties_loadFromString
status = celix_properties_loadFromString(json, 0, &props);
//Then I expect an error
EXPECT_EQ(ENOMEM, status);
//And I expect 2 error message in celix_err
EXPECT_EQ(2, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, DecodeArrayErrorTest) {
//Given a dummy json string
const char* json = R"({"key":["value1", "value2"]})";
// When an error injected is prepared for celix_arrayList_createWithOptions() from celix_properties_loadFromString
celix_ei_expect_celix_arrayList_createWithOptions((void*)celix_properties_loadFromString, 5, nullptr);
//When I call celix_properties_loadFromString
celix_properties_t* props;
auto status = celix_properties_loadFromString(json, 0, &props);
//Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 1 error message in celix_err.
EXPECT_EQ(1, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, DecodeVersionErrorTest) {
// Given a dummy json version string
const char* json = R"({"key":"version<1.2.3.qualifier>"})";
// When an error injected is prepared for celix_utils_writeOrCreateString() from celix_properties_loadFromString2
celix_ei_expect_celix_utils_writeOrCreateString((void*)celix_properties_loadFromString, 4, nullptr);
// And I call celix_properties_loadFromString
celix_properties_t* props;
auto status = celix_properties_loadFromString(json, 0, &props);
// Then I expect an error
EXPECT_EQ(ENOMEM, status);
// And I expect 1 error message in celix_err
EXPECT_EQ(1, celix_err_getErrorCount());
celix_err_printErrors(stderr, "Test Error: ", "\n");
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, SaveCxxPropertiesErrorTest) {
//Given a dummy Properties object
celix::Properties props{};
props.set("key", "value");
//When an error injected is prepared for json_object() from saveToStream
celix_ei_expect_json_object((void*)celix_properties_saveToStream, 0, nullptr);
//Then saving to file throws a bad alloc exception
EXPECT_THROW(props.save("somefile.json"), std::bad_alloc);
//When an error injected is prepared for json_object() from saveToStream
celix_ei_expect_json_object((void*)celix_properties_saveToStream, 0, nullptr);
//Then saving to string throws a bad alloc exception
EXPECT_THROW(props.saveToString(), std::bad_alloc);
}
TEST_F(PropertiesEncodingErrorInjectionTestSuite, LoadCxxPropertiesErrorTest) {
//Given a dummy json string
const char* json = R"({"key":"value"})";
//When an error injected is prepared for malloc() from celix_properties_create
celix_ei_expect_malloc((void*)celix_properties_create, 0, nullptr);
//Then loading from string throws a bad alloc exception
EXPECT_THROW(celix::Properties::loadFromString(json), std::bad_alloc);
//When an error injected is prepared for malloc() from celix_properties_create
celix_ei_expect_malloc((void*)celix_properties_create, 0, nullptr);
//And an empty json file exists
FILE* file = fopen("empty.json", "w");
fprintf(file, "{}");
fclose(file);
//Then loading from file throws a bad alloc exception
EXPECT_THROW(celix::Properties::load2("empty.json"), std::bad_alloc);
}