From: Agnieszka Baumann Date: Tue, 7 Apr 2020 13:24:22 +0000 (+0200) Subject: fdi_pipe divided into positive and negative tests X-Git-Tag: accepted/tizen/unified/20200422.123150~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F46%2F230846%2F2;p=platform%2Fcore%2Fsystem%2Fdlog.git fdi_pipe divided into positive and negative tests Change-Id: I46bfa31f37391a478691428909b529e70cc89309 --- diff --git a/Makefile.am b/Makefile.am index fdfb7f6..dead712 100644 --- a/Makefile.am +++ b/Makefile.am @@ -278,7 +278,8 @@ check_PROGRAMS = \ src/tests/fd_info_neg \ src/tests/fdi_logger_pos \ src/tests/fdi_logger_neg \ - src/tests/fdi_pipe \ + src/tests/fdi_pipe_pos \ + src/tests/fdi_pipe_neg \ src/tests/libdlog_pipe \ src/tests/libdlog_android_pos \ src/tests/libdlog_android_neg \ @@ -371,9 +372,13 @@ src_tests_fdi_logger_neg_SOURCES = src/tests/fdi_logger_neg.c src/libdlogutil/fd src_tests_fdi_logger_neg_CFLAGS = $(check_CFLAGS) src_tests_fdi_logger_neg_LDFLAGS = $(AM_LDFLAGS) -Wl,--wrap=logger_open_buffer_from_config_get_path,--wrap=dlogutil_filter_options_set_filterspec,--wrap=parse_androidlogger_message,--wrap=copy_recv_timestamp,--wrap=malloc,--wrap=read,--wrap=close,--wrap=ioctl,--wrap=calloc -src_tests_fdi_pipe_SOURCES = src/tests/fdi_pipe.c src/libdlogutil/fdi_pipe.c src/shared/logconfig.c src/shared/ptrs_list.c src/shared/logprint.c src/shared/parsers.c src/shared/logcommon.c -src_tests_fdi_pipe_CFLAGS = $(check_CFLAGS) -src_tests_fdi_pipe_LDFLAGS = $(AM_LDFLAGS) -Wl,--wrap=connect_sock,--wrap=close,--wrap=malloc,--wrap=free,--wrap=send_dlog_request,--wrap=recv_dlog_reply,--wrap=read,--wrap=recv_pipe +src_tests_fdi_pipe_pos_SOURCES = src/tests/fdi_pipe_pos.c src/libdlogutil/fdi_pipe.c src/shared/logconfig.c src/shared/ptrs_list.c src/shared/logprint.c src/shared/parsers.c src/shared/logcommon.c +src_tests_fdi_pipe_pos_CFLAGS = $(check_CFLAGS) +src_tests_fdi_pipe_pos_LDFLAGS = $(AM_LDFLAGS) -Wl,--wrap=connect_sock,--wrap=close,--wrap=malloc,--wrap=free,--wrap=send_dlog_request,--wrap=recv_dlog_reply,--wrap=read,--wrap=recv_pipe + +src_tests_fdi_pipe_neg_SOURCES = src/tests/fdi_pipe_neg.c src/libdlogutil/fdi_pipe.c src/shared/logconfig.c src/shared/ptrs_list.c src/shared/logprint.c src/shared/parsers.c src/shared/logcommon.c +src_tests_fdi_pipe_neg_CFLAGS = $(check_CFLAGS) +src_tests_fdi_pipe_neg_LDFLAGS = $(AM_LDFLAGS) -Wl,--wrap=connect_sock,--wrap=close,--wrap=malloc,--wrap=free,--wrap=send_dlog_request,--wrap=recv_dlog_reply,--wrap=read,--wrap=recv_pipe src_tests_libdlog_pipe_SOURCES = src/tests/libdlog_pipe.c src/libdlog/log_pipe.c src/shared/logcommon.c src/shared/logconfig.c src/shared/queued_entry.c src/shared/translate_syslog.c src/shared/parsers.c src_tests_libdlog_pipe_CFLAGS = $(check_CFLAGS) -pthread diff --git a/src/tests/fdi_pipe.c b/src/tests/fdi_pipe.c deleted file mode 100644 index a022f05..0000000 --- a/src/tests/fdi_pipe.c +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include -#include -#include -#include -#include - -const char *the_right_path = "the_right_path"; - -int last_sock = 0; -int __wrap_connect_sock(const char *path) -{ - return strcmp(path, the_right_path) ? -ECONNREFUSED : ++last_sock; -} - -#define MAX_FD 3 -bool closed[MAX_FD]; -int __wrap_close(int fd) -{ - if (fd <= 0 || fd > MAX_FD || closed[fd - 1]) - return -1; - closed[fd - 1] = true; - return 0; -} - -bool malloc_fail = false; -void *__real_malloc(size_t size); -void *__wrap_malloc(size_t size) -{ - return malloc_fail ? NULL : __real_malloc(size); -} - -void *ptr_to_free = NULL; -void __real_free(void *ptr); -void __wrap_free(void *ptr) -{ - if (ptr == ptr_to_free) - ptr_to_free = NULL; - __real_free(ptr); -} - -int correct_sockfd = 0; -int correct_request = 0; - -void *correct_send_data = NULL; -int correct_send_datalen = 0; -int send_return = 0; -int __wrap_send_dlog_request(int sockfd, int request, void *data, int datalen) -{ - assert(sockfd == correct_sockfd); - assert(request == correct_request); - assert(datalen == correct_send_datalen); - assert((data == correct_send_data) || (data && correct_send_data && !memcmp(data, correct_send_data, datalen))); - return send_return; -} - -void *recv_data = NULL; -int recv_datalen = 0; -int recv_return = 0; -int __wrap_recv_dlog_reply(int sockfd, int request, void **data, int *datalen) -{ - assert(sockfd == correct_sockfd); - assert(request == correct_request); - if (recv_return != 0) { - *data = NULL; - return recv_return; - } - - *data = recv_data; - *datalen = recv_datalen; - return 0; -} - -void *read_data = NULL; -int read_datalen = 0; -int read_pos = 0; -int read_errno = 0; -ssize_t __wrap_read(int fildes, void *buf, size_t nbyte) -{ - assert(fildes == correct_sockfd); - if (read_errno != 0) { - errno = read_errno; - return -1; - } - - int left = read_datalen - read_pos; - if (nbyte < left) - left = nbyte; - - memcpy(buf, read_data + read_pos, left); - read_pos += left; - return left; -} - -bool recv_pipe_fail = false; -int __wrap_recv_pipe(int sockfd, int timeout_ms) -{ - assert(sockfd == correct_sockfd); - return recv_pipe_fail ? -EIO : ++last_sock; -} - - -int main() -{ - struct fd_info info = { - .ops = &ops_pipe, - .name = "test", - }; - - struct log_config conf = {}; - - list_head *fake_list = (list_head *)54321; // It's not used anyway :) - - assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ENOENT); - - log_config_set(&conf, "hi_ctl_sock", "the_wrong_path"); - assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ECONNREFUSED); - assert(last_sock == 0); - log_config_set(&conf, "hi_ctl_sock", the_right_path); - - malloc_fail = true; - assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ENOMEM); - assert(last_sock == 1 && closed[0]); - malloc_fail = false; - - assert(ops_pipe.create(&info, &conf, "hi", fake_list) == 0); - assert(last_sock == 2 && !closed[1]); - struct pipe_priv_data *ppd = info.priv_data; - assert(ppd->data_len == 0); - assert(ppd->offset == 0); - assert(ppd->sock_fd == 2); - - assert(!ops_pipe.has_log(&info)); - - dlogutil_filter_options_s *filter = log_filter_new(); - assert(filter); - dlogutil_filter_options_set_filterspec(filter, "filter0"); - - correct_sockfd = 2; - correct_request = DLOG_REQ_HANDLE_LOGUTIL; - correct_send_data = "dlogutil filter0:V *:S"; - correct_send_datalen = strlen(correct_send_data) + 1; - send_return = -1; - assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); - - correct_send_data = "dlogutil -d filter0:V *:S"; - correct_send_datalen = strlen(correct_send_data) + 1; - assert(ops_pipe.prepare_print(&info, true, false, filter) == -1); - - dlogutil_filter_options_set_filterspec(filter, "filter1"); - correct_send_data = "dlogutil filter1:V filter0:V *:S"; - correct_send_datalen = strlen(correct_send_data) + 1; - assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); - - dlogutil_filter_options_set_tid(filter, 123); - dlogutil_filter_options_set_pid(filter, 456); - correct_send_data = "dlogutil --pid 456 --tid 123 filter1:V filter0:V *:S"; - correct_send_datalen = strlen(correct_send_data) + 1; - assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); - - send_return = 0; - recv_pipe_fail = true; - assert(ops_pipe.prepare_print(&info, false, false, filter) == -EIO); - - recv_pipe_fail = false; - correct_send_data = "dlogutil --pid 456 --tid 123 filter1:V filter0:V *:S"; - correct_send_datalen = strlen(correct_send_data) + 1; - assert(ops_pipe.prepare_print(&info, false, false, filter) == 0); - assert(info.fd == 3); - - dlogutil_filter_options_set_filterspec(filter, "This is a long and complicated filter. In fact, it's way too long to be accepted by ops_pipe.prepare_print, which should return -E2BIG."); - assert(ops_pipe.prepare_print(&info, false, false, filter) == -E2BIG); - - log_filter_free(filter); - - correct_sockfd = 3; - - read_errno = EIO; - assert(ops_pipe.read(&info) == -EIO); - read_errno = 0; - - read_datalen = sizeof(dlogutil_entry_s) + 4; - dlogutil_entry_s *ent = read_data = malloc(read_datalen); - assert(ent); - read_pos = 0; - ent->len = read_datalen; - memcpy(ent->msg, "abc", 4); - assert(ops_pipe.read(&info) == read_datalen); - assert(read_pos == read_datalen); - - assert(ops_pipe.has_log(&info)); - - assert(!memcmp(ent, ops_pipe.peek_entry(&info), ent->len)); - - malloc_fail = true; - assert(!ops_pipe.extract_entry(&info)); - malloc_fail = false; - - dlogutil_entry_s *ent2 = ops_pipe.extract_entry(&info); - assert(!memcmp(ent, ent2, ent->len)); - __real_free(ent2); - - int multiplier = RECEIVE_BUFFER_SIZE / ent->len + 1; - read_datalen = ent->len * multiplier; - ent = read_data = realloc(ent, read_datalen); - assert(ent); - read_pos = 0; - for (int i = 1; i < multiplier; ++i) - memcpy(read_data + ent->len * i, ent, ent->len); - - for (;;) { - int ret = ops_pipe.read(&info); - switch (ret) { - case 0: - assert(read_pos == read_datalen); - goto ok; - case -EAGAIN: - assert(ops_pipe.has_log(&info)); - ent2 = ops_pipe.extract_entry(&info); - assert(!memcmp(ent, ent2, ent->len)); - __real_free(ent2); - break; - default: - assert(ret > 0); - break; - } - } -ok: - while (ops_pipe.has_log(&info)) { - ent2 = ops_pipe.extract_entry(&info); - assert(!memcmp(ent, ent2, ent->len)); - __real_free(ent2); - } - __real_free(ent); - - read_datalen = sizeof(dlogutil_entry_s); - read_data = calloc(1, read_datalen); - read_pos = 0; - assert(ops_pipe.read(&info) == read_datalen); - assert(read_pos == read_datalen); - assert(ops_pipe.has_log(&info)); - assert(!ops_pipe.extract_entry(&info)); - __real_free(read_data); - - correct_sockfd = 2; - correct_request = DLOG_REQ_CLEAR; - correct_send_data = NULL; - correct_send_datalen = 0; - send_return = -1; - assert(ops_pipe.clear(&info) == -1); - - send_return = 0; - assert(ops_pipe.clear(&info) == 0); - - correct_request = DLOG_REQ_GETSIZE; - correct_send_data = NULL; - correct_send_datalen = 0; - unsigned int size_target = 0; - - send_return = -1; - assert(ops_pipe.getsize(&info, &size_target) == -1); - - send_return = 0; - recv_return = -1; - assert(ops_pipe.getsize(&info, &size_target) == -1); - - recv_return = 0; - const char *wrong_ans = "I won't tell you the pipe size :)"; - recv_datalen = strlen(wrong_ans) + 1; - recv_data = malloc(recv_datalen); - assert(recv_data); - memcpy(recv_data, wrong_ans, recv_datalen); - ptr_to_free = recv_data; - assert(ops_pipe.getsize(&info, &size_target) == -EINVAL); - assert(ptr_to_free == NULL); - - recv_datalen = 0; - recv_data = NULL; - assert(ops_pipe.getsize(&info, &size_target) == -EINVAL); - - recv_datalen = sizeof(unsigned int); - recv_data = malloc(recv_datalen); - assert(recv_data); - *(int *)recv_data = (unsigned int)17; - ptr_to_free = recv_data; - assert(ops_pipe.getsize(&info, &size_target) == 0); - assert(ptr_to_free == NULL); - assert(size_target == 17); - - ptr_to_free = ppd; - ops_pipe.destroy(&info); - assert(closed[1]); - assert(ptr_to_free == NULL); - - ops_pipe.destroy(&info); - - // Note that one case of ops_pipe.destroy is not checked, namely the one in which ppd exists but sock_fd is invalid. - // However, it's difficult, if not impossible, to get this case in practice, as ops_pipe.create does both (and we try to check that). -} diff --git a/src/tests/fdi_pipe_neg.c b/src/tests/fdi_pipe_neg.c new file mode 100644 index 0000000..9a55ce6 --- /dev/null +++ b/src/tests/fdi_pipe_neg.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019-2020, Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed 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 "fdi_pipe_wrap.c" + +int main() +{ + struct fd_info info = { + .ops = &ops_pipe, + .name = "test", + }; + + struct log_config conf = {}; + + list_head *fake_list = (list_head *)54321; // It's not used anyway :) + + assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ENOENT); + + log_config_set(&conf, "hi_ctl_sock", "the_wrong_path"); + assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ECONNREFUSED); + assert(last_sock == 0); + log_config_set(&conf, "hi_ctl_sock", the_right_path); + + malloc_fail = true; + assert(ops_pipe.create(&info, &conf, "hi", fake_list) == -ENOMEM); + assert(last_sock == 1 && closed[0]); + malloc_fail = false; + + assert(ops_pipe.create(&info, &conf, "hi", fake_list) == 0); + + dlogutil_filter_options_s *filter = log_filter_new(); + assert(filter); + dlogutil_filter_options_set_filterspec(filter, "filter0"); + + correct_sockfd = 2; + correct_request = DLOG_REQ_HANDLE_LOGUTIL; + correct_send_data = "dlogutil filter0:V *:S"; + correct_send_datalen = strlen(correct_send_data) + 1; + send_return = -1; + assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); + + correct_send_data = "dlogutil -d filter0:V *:S"; + correct_send_datalen = strlen(correct_send_data) + 1; + assert(ops_pipe.prepare_print(&info, true, false, filter) == -1); + + dlogutil_filter_options_set_filterspec(filter, "filter1"); + correct_send_data = "dlogutil filter1:V filter0:V *:S"; + correct_send_datalen = strlen(correct_send_data) + 1; + assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); + + dlogutil_filter_options_set_tid(filter, 123); + dlogutil_filter_options_set_pid(filter, 456); + correct_send_data = "dlogutil --pid 456 --tid 123 filter1:V filter0:V *:S"; + correct_send_datalen = strlen(correct_send_data) + 1; + assert(ops_pipe.prepare_print(&info, false, false, filter) == -1); + + send_return = 0; + recv_pipe_fail = true; + assert(ops_pipe.prepare_print(&info, false, false, filter) == -EIO); + recv_pipe_fail = false; + + dlogutil_filter_options_set_filterspec(filter, "This is a long and complicated filter. In fact, it's way too long to be accepted by ops_pipe.prepare_print, which should return -E2BIG."); + assert(ops_pipe.prepare_print(&info, false, false, filter) == -E2BIG); + + log_filter_free(filter); + correct_sockfd = 0; + + read_errno = EIO; + assert(ops_pipe.read(&info) == -EIO); + read_errno = 0; + + malloc_fail = true; + assert(!ops_pipe.extract_entry(&info)); + malloc_fail = false; + + correct_sockfd = 2; + correct_request = DLOG_REQ_CLEAR; + correct_send_data = NULL; + correct_send_datalen = 0; + send_return = -1; + assert(ops_pipe.clear(&info) == -1); + + correct_request = DLOG_REQ_GETSIZE; + correct_send_data = NULL; + correct_send_datalen = 0; + unsigned int size_target = 0; + + send_return = -1; + assert(ops_pipe.getsize(&info, &size_target) == -1); + + send_return = 0; + recv_return = -1; + assert(ops_pipe.getsize(&info, &size_target) == -1); + + recv_return = 0; + const char *wrong_ans = "I won't tell you the pipe size :)"; + recv_datalen = strlen(wrong_ans) + 1; + recv_data = malloc(recv_datalen); + assert(recv_data); + memcpy(recv_data, wrong_ans, recv_datalen); + ptr_to_free = recv_data; + assert(ops_pipe.getsize(&info, &size_target) == -EINVAL); + assert(ptr_to_free == NULL); + + recv_datalen = 0; + recv_data = NULL; + assert(ops_pipe.getsize(&info, &size_target) == -EINVAL); + + ops_pipe.destroy(&info); + ops_pipe.destroy(&info); +} diff --git a/src/tests/fdi_pipe_pos.c b/src/tests/fdi_pipe_pos.c new file mode 100644 index 0000000..7c84b4a --- /dev/null +++ b/src/tests/fdi_pipe_pos.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019-2020, Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed 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 "fdi_pipe_wrap.c" + +int main() +{ + struct fd_info info = { + .ops = &ops_pipe, + .name = "test", + }; + + struct log_config conf = {}; + + list_head *fake_list = (list_head *)54321; // It's not used anyway :) + log_config_set(&conf, "hi_ctl_sock", the_right_path); + malloc_fail = false; + + assert(ops_pipe.create(&info, &conf, "hi", fake_list) == 0); + assert(last_sock == 1 && !closed[0]); + + struct pipe_priv_data *ppd = info.priv_data; + assert(ppd->data_len == 0); + assert(ppd->offset == 0); + assert(ppd->sock_fd == 1); + assert(!ops_pipe.has_log(&info)); + + dlogutil_filter_options_s *filter = log_filter_new(); + assert(filter); + dlogutil_filter_options_set_filterspec(filter, "filter0"); + + correct_sockfd = 1; + correct_request = DLOG_REQ_HANDLE_LOGUTIL; + + dlogutil_filter_options_set_filterspec(filter, "filter1"); + dlogutil_filter_options_set_tid(filter, 123); + dlogutil_filter_options_set_pid(filter, 456); + + send_return = 0; + + recv_pipe_fail = false; + correct_send_data = "dlogutil --pid 456 --tid 123 filter1:V filter0:V *:S"; + correct_send_datalen = strlen(correct_send_data) + 1; + assert(ops_pipe.prepare_print(&info, false, false, filter) == 0); + assert(info.fd == 2); + + log_filter_free(filter); + correct_sockfd = 2; + read_errno = 0; + + read_datalen = sizeof(dlogutil_entry_s) + 4; + dlogutil_entry_s *ent = read_data = malloc(read_datalen); + assert(ent); + read_pos = 0; + ent->len = read_datalen; + memcpy(ent->msg, "abc", 4); + assert(ops_pipe.read(&info) == read_datalen); + assert(read_pos == read_datalen); + + assert(ops_pipe.has_log(&info)); + assert(!memcmp(ent, ops_pipe.peek_entry(&info), ent->len)); + malloc_fail = false; + + dlogutil_entry_s *ent2 = ops_pipe.extract_entry(&info); + assert(!memcmp(ent, ent2, ent->len)); + __real_free(ent2); + + int multiplier = RECEIVE_BUFFER_SIZE / ent->len + 1; + read_datalen = ent->len * multiplier; + ent = read_data = realloc(ent, read_datalen); + assert(ent); + read_pos = 0; + for (int i = 1; i < multiplier; ++i) + memcpy(read_data + ent->len * i, ent, ent->len); + + for (;;) { + int ret = ops_pipe.read(&info); + + switch (ret) { + case 0: + assert(read_pos == read_datalen); + goto ok; + case -EAGAIN: + assert(ops_pipe.has_log(&info)); + ent2 = ops_pipe.extract_entry(&info); + assert(!memcmp(ent, ent2, ent->len)); + __real_free(ent2); + break; + default: + assert(ret > 0); + break; + } + } +ok: + while (ops_pipe.has_log(&info)) { + ent2 = ops_pipe.extract_entry(&info); + assert(!memcmp(ent, ent2, ent->len)); + __real_free(ent2); + } + __real_free(ent); + + read_datalen = sizeof(dlogutil_entry_s); + read_data = calloc(1, read_datalen); + read_pos = 0; + assert(ops_pipe.read(&info) == read_datalen); + assert(read_pos == read_datalen); + assert(ops_pipe.has_log(&info)); + assert(!ops_pipe.extract_entry(&info)); + __real_free(read_data); + + correct_sockfd = 1; + correct_request = DLOG_REQ_CLEAR; + correct_send_data = NULL; + correct_send_datalen = 0; + + send_return = 0; + assert(ops_pipe.clear(&info) == 0); + + correct_request = DLOG_REQ_GETSIZE; + unsigned int size_target = 0; + recv_return = 0; + + recv_datalen = sizeof(unsigned int); + recv_data = malloc(recv_datalen); + assert(recv_data); + *(int *)recv_data = (unsigned int)17; + ptr_to_free = recv_data; + assert(ops_pipe.getsize(&info, &size_target) == 0); + assert(ptr_to_free == NULL); + assert(size_target == 17); + + ptr_to_free = ppd; + ops_pipe.destroy(&info); + assert(closed[0]); + assert(ptr_to_free == NULL); +} diff --git a/src/tests/fdi_pipe_wrap.c b/src/tests/fdi_pipe_wrap.c new file mode 100644 index 0000000..f3027b0 --- /dev/null +++ b/src/tests/fdi_pipe_wrap.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019-2020, Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed 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 +#include +#include +#include +#include +#include + +const char *the_right_path = "the_right_path"; + +int last_sock = 0; +int __wrap_connect_sock(const char *path) +{ + return strcmp(path, the_right_path) ? -ECONNREFUSED : ++last_sock; +} + +#define MAX_FD 3 +bool closed[MAX_FD]; +int __wrap_close(int fd) +{ + if (fd <= 0 || fd > MAX_FD || closed[fd - 1]) + return -1; + closed[fd - 1] = true; + return 0; +} + +bool malloc_fail = false; +void *__real_malloc(size_t size); +void *__wrap_malloc(size_t size) +{ + return malloc_fail ? NULL : __real_malloc(size); +} + +void *ptr_to_free = NULL; +void __real_free(void *ptr); +void __wrap_free(void *ptr) +{ + if (ptr == ptr_to_free) + ptr_to_free = NULL; + __real_free(ptr); +} + +int correct_sockfd = 0; +int correct_request = 0; + +void *correct_send_data = NULL; +int correct_send_datalen = 0; +int send_return = 0; +int __wrap_send_dlog_request(int sockfd, int request, void *data, int datalen) +{ + assert(sockfd == correct_sockfd); + assert(request == correct_request); + assert(datalen == correct_send_datalen); + assert((data == correct_send_data) || (data && correct_send_data && !memcmp(data, correct_send_data, datalen))); + return send_return; +} + +void *recv_data = NULL; +int recv_datalen = 0; +int recv_return = 0; +int __wrap_recv_dlog_reply(int sockfd, int request, void **data, int *datalen) +{ + assert(sockfd == correct_sockfd); + assert(request == correct_request); + if (recv_return != 0) { + *data = NULL; + return recv_return; + } + + *data = recv_data; + *datalen = recv_datalen; + return 0; +} + +void *read_data = NULL; +int read_datalen = 0; +int read_pos = 0; +int read_errno = 0; +ssize_t __wrap_read(int fildes, void *buf, size_t nbyte) +{ + assert(fildes == correct_sockfd); + if (read_errno != 0) { + errno = read_errno; + return -1; + } + + int left = read_datalen - read_pos; + if (nbyte < left) + left = nbyte; + + memcpy(buf, read_data + read_pos, left); + read_pos += left; + return left; +} + +bool recv_pipe_fail = false; +int __wrap_recv_pipe(int sockfd, int timeout_ms) +{ + assert(sockfd == correct_sockfd); + return recv_pipe_fail ? -EIO : ++last_sock; +}