aboutsummaryrefslogtreecommitdiff
path: root/tests/safe_tests.c
blob: 8f94bd31234583c3bd8344ca2de8edff5a900172 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "safe_tests.h"
#include "moslib/safe.h"

#include <limits.h>
#include <stdlib.h>
#include <string.h>

#ifndef _WIN32
#define mos_close close
#else
#define mos_close _close
#endif

TEST_HELPER(malloc_exit) {
    safe_malloc(ULLONG_MAX);
}

TEST(test_safe_malloc) {
    void *p = safe_malloc(1024);
    test_assert(p != NULL, "Failed to malloc 1KiB");

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(malloc_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

TEST_HELPER(calloc_exit) {
    safe_calloc(ULLONG_MAX, ULLONG_MAX);
}

TEST(test_safe_calloc) {
    void *p = safe_calloc(16, 16);
    test_assert(p != NULL, "Failed to calloc 16 items of 16 bytes");

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(calloc_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

TEST_HELPER(realloc_exit) {
    void *p = NULL;
    safe_realloc(p, ULLONG_MAX);
}

TEST(test_safe_realloc) {
    void *p = NULL;
    p = safe_realloc(p, 1024);
    test_assert(p != NULL, "Failed to realloc NULL to 1KiB");

    p = safe_realloc(p, 4096);
    test_assert(p != NULL, "Failed to realloc 1KiB to 4KiB");

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(realloc_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

TEST_HELPER(fopen_exit) {
    safe_fopen("/non-existing-file-name", "r");
}

TEST(test_safe_fopen) {
    FILE *fp = safe_fopen(__FILE__, "r");
    test_assert(fp != NULL, "Failed to fopen current file");

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(fopen_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

TEST(test_safe_tmpfile) {
    FILE *fp = safe_tmpfile();
    test_assert(fp != NULL, "Failed to create a tmpfile");
}

TEST_HELPER(dup_exit) {
    safe_dup(-1);
}

TEST(test_safe_dup) {
    int fd = safe_dup(1);
    test_assert(fd != -1, "Failed to dup stdout");
    mos_close(fd);

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(dup_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

TEST_HELPER(dup2_exit) {
    safe_dup2(-1, 1);
}

TEST(test_safe_dup2) {
    int res = safe_dup2(1, 1);
    test_assert(res != -1, "Failed to dup stdout 2 itself");

    int fd = safe_dup(1);
    res = safe_dup2(2, 1);
    test_assert(res != -1, "Failed to dup stderr 2 stdout");
    res = safe_dup2(fd, 1);
    test_assert(res != -1, "Failed to restore stdout");
    mos_close(fd);

#ifndef NO_FS
    suppress_output(stderr);
#endif
    test_assert_exit(dup2_exit, EXIT_FAILURE);
    unsuppress_outputs();
}

#ifndef _WIN32
TEST(test_safe_fork) {
    pid_t pid = safe_fork();
    test_assert(pid != -1, "Failed to create a child process");
    if (pid == 0)
        exit(EXIT_SUCCESS);
}

TEST(test_safe_pipe) {
    int fd[2];
    int res = safe_pipe(fd);
    test_assert(res != -1, "Failed to create a pipe");
    mos_close(fd[0]);
    mos_close(fd[1]);
}
#endif

void safe_tests(Tester *tester) {
    TestGroup *group = add_test_group(tester, "moslib/safe.h");
    add_test(group, test_safe_malloc);
    add_test(group, test_safe_calloc);
    add_test(group, test_safe_realloc);
    add_test(group, test_safe_fopen);
    add_test(group, test_safe_tmpfile);
    add_test(group, test_safe_dup);
    add_test(group, test_safe_dup2);

#ifndef _WIN32
    add_test(group, test_safe_fork);
    add_test(group, test_safe_pipe);
#endif
}