Skip to content

Commit

Permalink
More tests for jsonSerializer_parseAny.
Browse files Browse the repository at this point in the history
  • Loading branch information
PengZheng committed Jan 16, 2024
1 parent 4c2b4d4 commit 4c6d4db
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 21 deletions.
2 changes: 2 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ def generate(self):
lst = [x.ref.name for x in self.requires.values()]
if "mdnsresponder" in lst:
tc.cache_variables["BUILD_ERROR_INJECTOR_MDNSRESPONDER"] = "ON"
if "jansson" in lst:
tc.cache_variables["BUILD_ERROR_INJECTOR_JANSSON"] = "ON"
tc.cache_variables["CELIX_ERR_BUFFER_SIZE"] = str(self.options.celix_err_buffer_size)
# tc.cache_variables["CMAKE_PROJECT_Celix_INCLUDE"] = os.path.join(self.build_folder, "conan_paths.cmake")
# the following is workaround for https://github.com/conan-io/conan/issues/7192
Expand Down
1 change: 1 addition & 0 deletions libs/dfi/gtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ if (EI_TESTS)
Celix::string_ei
Celix::ffi_ei
Celix::asprintf_ei
Celix::jansson_ei
GTest::gtest GTest::gtest_main
)
add_test(NAME run_test_dfi_with_ei COMMAND test_dfi_with_ei)
Expand Down
4 changes: 2 additions & 2 deletions libs/dfi/gtest/src/dyn_type_ei_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ TEST_F(DynTypeErrorInjectionTestSuite, SequenceAllocateError) {
celix_ei_expect_calloc((void*)dynType_sequence_alloc, 0, nullptr);
rc = dynType_sequence_alloc(type, seq, 1);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error allocating memory for buf", celix_err_popLastError());
ASSERT_STREQ("Error allocating memory for seq buf", celix_err_popLastError());

dynType_free(type, seq);
dynType_destroy(type);
Expand All @@ -167,7 +167,7 @@ TEST_F(DynTypeErrorInjectionTestSuite, SequenceReserveError) {
celix_ei_expect_realloc((void*)dynType_sequence_reserve, 0, nullptr);
rc = dynType_sequence_reserve(type, seq, 1);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error allocating memory for buf", celix_err_popLastError());
ASSERT_STREQ("Error allocating memory for seq buf", celix_err_popLastError());

dynType_free(type, seq);
dynType_destroy(type);
Expand Down
44 changes: 43 additions & 1 deletion libs/dfi/gtest/src/json_serializer_ei_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@
#include "json_serializer.h"
#include "dyn_type.h"
#include "celix_err.h"
#include "jansson_ei.h"
#include "malloc_ei.h"
#include "string_ei.h"

#include <gtest/gtest.h>
#include <stdint.h>

class JsonSerializerErrorInjectionTestSuite : public ::testing::Test {
public:
JsonSerializerErrorInjectionTestSuite() = default;
~JsonSerializerErrorInjectionTestSuite() override {
celix_ei_expect_json_array_size(nullptr, 0, 0);
celix_ei_expect_strdup(nullptr, 0, nullptr);
celix_ei_expect_calloc(nullptr, 0, nullptr);
celix_err_resetErrors();
}
Expand All @@ -38,7 +43,6 @@ TEST_F(JsonSerializerErrorInjectionTestSuite, SerilizationError) {
dyn_type *type;
void *inst;

//simple string
type = nullptr;
inst = nullptr;
rc = dynType_parseWithStr("t", nullptr, nullptr, &type);
Expand All @@ -50,4 +54,42 @@ TEST_F(JsonSerializerErrorInjectionTestSuite, SerilizationError) {
EXPECT_STREQ("Error cannot deserialize json. Input is '\"hello\"'", celix_err_popLastError());
EXPECT_STREQ("Error allocating memory for type 't'", celix_err_popLastError());
dynType_destroy(type);

type = nullptr;
inst = nullptr;
rc = dynType_parseWithStr("t", nullptr, nullptr, &type);
ASSERT_EQ(0, rc);
inputStr = R"("hello")";
celix_ei_expect_strdup((void*) dynType_text_allocAndInit, 0, nullptr);
rc = jsonSerializer_deserialize(type, inputStr, strlen(inputStr), &inst);
ASSERT_NE(0, rc);
EXPECT_STREQ("Error cannot deserialize json. Input is '\"hello\"'", celix_err_popLastError());
EXPECT_STREQ("Cannot allocate memory for string", celix_err_popLastError());
dynType_destroy(type);


type = nullptr;
inst = nullptr;
rc = dynType_parseWithStr("[t", nullptr, nullptr, &type);
ASSERT_EQ(0, rc);
inputStr = R"(["hello", "world"])";
celix_ei_expect_json_array_size((void*)jsonSerializer_deserializeJson, 3, (size_t)UINT32_MAX+1);
rc = jsonSerializer_deserialize(type, inputStr, strlen(inputStr), &inst);
ASSERT_NE(0, rc);
EXPECT_STREQ("Error cannot deserialize json. Input is '[\"hello\", \"world\"]'", celix_err_popLastError());
EXPECT_STREQ("Error array size(4294967296) too large", celix_err_popLastError());
dynType_destroy(type);


type = nullptr;
inst = nullptr;
rc = dynType_parseWithStr("[t", nullptr, nullptr, &type);
ASSERT_EQ(0, rc);
inputStr = R"(["hello", "world"])";
celix_ei_expect_calloc((void*) dynType_sequence_alloc, 0, nullptr);
rc = jsonSerializer_deserialize(type, inputStr, strlen(inputStr), &inst);
ASSERT_NE(0, rc);
EXPECT_STREQ("Error cannot deserialize json. Input is '[\"hello\", \"world\"]'", celix_err_popLastError());
EXPECT_STREQ("Error allocating memory for seq buf", celix_err_popLastError());
dynType_destroy(type);
}
9 changes: 9 additions & 0 deletions libs/dfi/gtest/src/json_serializer_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,15 @@ static void parseTests() {
celix_err_printErrors(stderr, nullptr, nullptr);
dynType_destroy(type);

// parse complex from non-object
rc = dynType_parseWithStr("{t a}", nullptr, nullptr, &type);
ASSERT_EQ(0, rc);
inputStr = R"(["a"])";
rc = jsonSerializer_deserialize(type, inputStr, strlen(inputStr), &inst);
ASSERT_EQ(1, rc);
celix_err_printErrors(stderr, nullptr, nullptr);
dynType_destroy(type);

//simple string
rc = dynType_parseWithStr("t", nullptr, nullptr, &type);
ASSERT_EQ(0, rc);
Expand Down
4 changes: 2 additions & 2 deletions libs/dfi/src/dyn_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ int dynType_sequence_alloc(const dyn_type* type, void* inst, uint32_t cap) {
seq->buf = calloc(cap, size);
if (seq->buf == NULL) {
seq->cap = 0;
celix_err_pushf("Error allocating memory for buf");
celix_err_pushf("Error allocating memory for seq buf");
return MEM_ERROR;
}
seq->cap = cap;
Expand All @@ -613,7 +613,7 @@ int dynType_sequence_reserve(const dyn_type* type, void* inst, uint32_t cap) {
seq->buf = realloc(seq->buf, (size_t)(cap * size));
if (seq->buf == NULL) {
seq->cap = 0;
celix_err_pushf("Error allocating memory for buf");
celix_err_pushf("Error allocating memory for seq buf");
return MEM_ERROR;
}
memset(seq->buf+seq->cap*size, 0, (cap-seq->cap)*size);
Expand Down
37 changes: 21 additions & 16 deletions libs/dfi/src/json_serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,11 @@ static int jsonSerializer_parseAny(const dyn_type* type, void* loc, json_t* val)
}
break;
case '{' :
if (status == OK) {
if (json_is_object(val)) {
status = jsonSerializer_parseObject(type, val, loc);
} else {
status = ERROR;
celix_err_pushf("Expected json object type got '%i'", json_typeof(val));
}
break;
case '*' :
Expand All @@ -202,7 +205,7 @@ static int jsonSerializer_parseAny(const dyn_type* type, void* loc, json_t* val)
case 'P' :
default :
status = ERROR;
celix_err_pushf("Error provided type '%c' not supported for JSON\n", dynType_descriptorType(type));
celix_err_pushf("Error provided type '%c' not supported for JSON\n", c);
break;
}

Expand All @@ -214,21 +217,23 @@ static int jsonSerializer_parseSequence(const dyn_type* seq, json_t* array, void
int status = OK;

size_t size = json_array_size(array);
status = dynType_sequence_alloc(seq, seqLoc, (int) size);
if (size > UINT32_MAX) {
celix_err_pushf("Error array size(%zu) too large", size);
return ERROR;
}
if ((status = dynType_sequence_alloc(seq, seqLoc, (uint32_t) size)) != OK) {
return status;
}

if (status == OK) {
const dyn_type* itemType = dynType_sequence_itemType(seq);
size_t index;
json_t* val;
json_array_foreach(array, index, val) {
void* valLoc = NULL;
status = dynType_sequence_increaseLengthAndReturnLastLoc(seq, seqLoc, &valLoc);
if (status == OK) {
status = jsonSerializer_parseAny(itemType, valLoc, val);
if (status != OK) {
break;
}
}
const dyn_type* itemType = dynType_sequence_itemType(seq);
size_t index;
json_t* val;
json_array_foreach(array, index, val) {
void* valLoc = NULL;
(void)dynType_sequence_increaseLengthAndReturnLastLoc(seq, seqLoc, &valLoc);
status = jsonSerializer_parseAny(itemType, valLoc, val);
if (status != OK) {
break;
}
}

Expand Down
6 changes: 6 additions & 0 deletions libs/error_injector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ add_subdirectory(sys_shm)
add_subdirectory(socket)
add_subdirectory(pthread)
add_subdirectory(unistd)

celix_subproject(ERROR_INJECTOR_MDNSRESPONDER "Option to enable building the mdnsresponder error injector" OFF)
if (ERROR_INJECTOR_MDNSRESPONDER)
add_subdirectory(mdnsresponder)
endif ()

celix_subproject(ERROR_INJECTOR_JANSSON "Option to enable building the jansson error injector", OFF)
if (ERROR_INJECTOR_JANSSON)
add_subdirectory(jansson)
endif ()
28 changes: 28 additions & 0 deletions libs/error_injector/jansson/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 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.

find_package(jansson REQUIRED)

add_library(jansson_ei STATIC src/jansson_ei.cc)

target_include_directories(jansson_ei PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(jansson_ei PUBLIC Celix::error_injector jansson::jansson)

target_link_options(jansson_ei INTERFACE
LINKER:--wrap,json_array_size
)
add_library(Celix::jansson_ei ALIAS jansson_ei)
33 changes: 33 additions & 0 deletions libs/error_injector/jansson/include/jansson_ei.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
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.
*/
#ifndef CELIX_JANSSON_EI_H
#define CELIX_JANSSON_EI_H
#ifdef __cplusplus
extern "C" {
#endif

#include <jansson.h>
#include "celix_error_injector.h"

CELIX_EI_DECLARE(json_array_size, size_t);

#ifdef __cplusplus
}
#endif
#endif //CELIX_JANSSON_EI_H
31 changes: 31 additions & 0 deletions libs/error_injector/jansson/src/jansson_ei.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
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 "jansson_ei.h"

extern "C" {

size_t __real_json_array_size(const json_t *array);
CELIX_EI_DEFINE(json_array_size, size_t)
size_t __wrap_json_array_size(const json_t *array) {
CELIX_EI_IMPL(json_array_size);
return __real_json_array_size(array);
}

}

0 comments on commit 4c6d4db

Please sign in to comment.