|
|
#include "../../unity/unity.h" |
|
|
#include <errno.h> |
|
|
#include <stdbool.h> |
|
|
#include <stddef.h> |
|
|
#include <stdint.h> |
|
|
#include <string.h> |
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
int ret; |
|
|
int err; |
|
|
} mock_fsync_step_t; |
|
|
|
|
|
static mock_fsync_step_t mock_fsync_steps[64]; |
|
|
static int mock_fsync_len = 0; |
|
|
static int mock_fsync_pos = 0; |
|
|
static int mock_fsync_calls = 0; |
|
|
|
|
|
static void mock_fsync_reset(void) |
|
|
{ |
|
|
mock_fsync_len = 0; |
|
|
mock_fsync_pos = 0; |
|
|
mock_fsync_calls = 0; |
|
|
} |
|
|
|
|
|
static void mock_fsync_set_steps(const mock_fsync_step_t *steps, int len) |
|
|
{ |
|
|
if (len > (int)(sizeof(mock_fsync_steps) / sizeof(mock_fsync_steps[0]))) |
|
|
len = (int)(sizeof(mock_fsync_steps) / sizeof(mock_fsync_steps[0])); |
|
|
for (int i = 0; i < len; i++) |
|
|
mock_fsync_steps[i] = steps[i]; |
|
|
mock_fsync_len = len; |
|
|
mock_fsync_pos = 0; |
|
|
mock_fsync_calls = 0; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int fsync(int fd) |
|
|
{ |
|
|
(void)fd; |
|
|
mock_fsync_calls++; |
|
|
if (mock_fsync_pos < mock_fsync_len) { |
|
|
int r = mock_fsync_steps[mock_fsync_pos].ret; |
|
|
errno = mock_fsync_steps[mock_fsync_pos].err; |
|
|
mock_fsync_pos++; |
|
|
return r; |
|
|
} |
|
|
|
|
|
errno = 0; |
|
|
return 0; |
|
|
} |
|
|
|
|
|
void setUp(void) |
|
|
{ |
|
|
mock_fsync_reset(); |
|
|
} |
|
|
|
|
|
void tearDown(void) |
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void test_ifsync_immediate_success(void) |
|
|
{ |
|
|
mock_fsync_step_t seq[] = { |
|
|
{ 0, 0 } |
|
|
}; |
|
|
mock_fsync_set_steps(seq, 1); |
|
|
|
|
|
int rc = ifsync(123); |
|
|
TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
TEST_ASSERT_EQUAL_INT(1, mock_fsync_calls); |
|
|
} |
|
|
|
|
|
|
|
|
void test_ifsync_eintr_then_success(void) |
|
|
{ |
|
|
mock_fsync_step_t seq[] = { |
|
|
{ -1, EINTR }, |
|
|
{ 0, 0 } |
|
|
}; |
|
|
mock_fsync_set_steps(seq, 2); |
|
|
|
|
|
int rc = ifsync(5); |
|
|
TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
TEST_ASSERT_EQUAL_INT(2, mock_fsync_calls); |
|
|
} |
|
|
|
|
|
|
|
|
void test_ifsync_multiple_eintr_then_success(void) |
|
|
{ |
|
|
mock_fsync_step_t seq[] = { |
|
|
{ -1, EINTR }, |
|
|
{ -1, EINTR }, |
|
|
{ -1, EINTR }, |
|
|
{ 0, 0 } |
|
|
}; |
|
|
mock_fsync_set_steps(seq, 4); |
|
|
|
|
|
int rc = ifsync(7); |
|
|
TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
TEST_ASSERT_EQUAL_INT(4, mock_fsync_calls); |
|
|
} |
|
|
|
|
|
|
|
|
void test_ifsync_immediate_non_eintr_failure(void) |
|
|
{ |
|
|
mock_fsync_step_t seq[] = { |
|
|
{ -1, EIO } |
|
|
}; |
|
|
mock_fsync_set_steps(seq, 1); |
|
|
|
|
|
errno = 0; |
|
|
int rc = ifsync(9); |
|
|
TEST_ASSERT_EQUAL_INT(-1, rc); |
|
|
TEST_ASSERT_EQUAL_INT(EIO, errno); |
|
|
TEST_ASSERT_EQUAL_INT(1, mock_fsync_calls); |
|
|
} |
|
|
|
|
|
|
|
|
void test_ifsync_eintr_then_non_eintr_failure(void) |
|
|
{ |
|
|
mock_fsync_step_t seq[] = { |
|
|
{ -1, EINTR }, |
|
|
{ -1, EFAULT } |
|
|
}; |
|
|
mock_fsync_set_steps(seq, 2); |
|
|
|
|
|
errno = 0; |
|
|
int rc = ifsync(11); |
|
|
TEST_ASSERT_EQUAL_INT(-1, rc); |
|
|
TEST_ASSERT_EQUAL_INT(EFAULT, errno); |
|
|
TEST_ASSERT_EQUAL_INT(2, mock_fsync_calls); |
|
|
} |
|
|
|
|
|
int main(void) |
|
|
{ |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_ifsync_immediate_success); |
|
|
RUN_TEST(test_ifsync_eintr_then_success); |
|
|
RUN_TEST(test_ifsync_multiple_eintr_then_success); |
|
|
RUN_TEST(test_ifsync_immediate_non_eintr_failure); |
|
|
RUN_TEST(test_ifsync_eintr_then_non_eintr_failure); |
|
|
return UNITY_END(); |
|
|
} |