Skip to content

Commit aaa64f4

Browse files
committed
more tests and cleanup
1 parent 40c5591 commit aaa64f4

File tree

5 files changed

+115
-70
lines changed

5 files changed

+115
-70
lines changed

src/external.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ size_t external_read_file(struct input *in,
231231
path, strerror(err), err);
232232
free(line);
233233
line = NULL;
234+
len = 0;
234235
continue;
235236
}
236237

src/parallel_cpr.c

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ struct work_data {
112112
struct entry_data ed;
113113
};
114114

115+
#define print_error_and_goto(msg, path, label) \
116+
const int err = errno; \
117+
fprintf(stderr, "Error: %s \"%s\": %s (%d)\n", \
118+
msg, path, strerror(err), err); \
119+
rc = 1; \
120+
goto label
121+
115122
/* copy a single file in a single thread */
116123
/* TODO: if file is too big, split up copy */
117124
static int cpr_file(QPTPool_t *ctx, const size_t id, void *data, void *args) {
@@ -127,39 +134,23 @@ static int cpr_file(QPTPool_t *ctx, const size_t id, void *data, void *args) {
127134

128135
struct stat st;
129136
if (lstat(work->name, &st) != 0) {
130-
const int err = errno;
131-
fprintf(stderr, "Error: Could not lstat file \"%s\": %s (%d)\n",
132-
work->name, strerror(err), err);
133-
rc = 1;
134-
goto cleanup;
137+
print_error_and_goto("Could not lstat file", work->name, cleanup);
135138
}
136139

137140
const int src_fd = open(work->name, O_RDONLY);
138141
if (src_fd < 0) {
139-
const int err = errno;
140-
fprintf(stderr, "Error: Could not open file \"%s\": %s (%d)\n",
141-
work->name, strerror(err), err);
142-
rc = 1;
143-
goto cleanup;
142+
print_error_and_goto("Could not open file", work->name, cleanup);
144143
}
145144

146145
str_t dst = create_dst_name(in, work);
147146

148147
const int dst_fd = open(dst.data, O_CREAT | O_WRONLY, st.st_mode);
149148
if (dst_fd < 0) {
150-
const int err = errno;
151-
fprintf(stderr, "Error: Could not open file \"%s\": %s (%d)\n",
152-
dst.data, strerror(err), err);
153-
rc = 1;
154-
goto free_name;
149+
print_error_and_goto("Could not opent file", dst.data, free_name);
155150
}
156151

157152
if (copyfd(src_fd, 0, dst_fd, 0, st.st_size) != st.st_size) {
158-
const int err = errno;
159-
fprintf(stderr, "Error: Could not copy file \"%s\": %s (%d)\n",
160-
work->name, strerror(err), err);
161-
rc = 1;
162-
goto free_name;
153+
print_error_and_goto("Could not copy file", work->name, free_name);
163154
}
164155

165156
rc = set_xattrs(dst.data, &ed->xattrs);
@@ -182,36 +173,20 @@ static int cpr_file(QPTPool_t *ctx, const size_t id, void *data, void *args) {
182173
static int cpr_link(struct work *work, struct entry_data *ed, struct input *in) {
183174
int rc = 0;
184175

185-
struct stat st;
186-
if (lstat(work->name, &st) != 0) {
187-
const int err = errno;
188-
fprintf(stderr, "Error: Could not lstat link \"%s\": %s (%d)\n",
189-
work->name, strerror(err), err);
190-
rc = 1;
191-
goto cleanup;
192-
}
193-
194176
/* need to give users ability to force overwriting of links */
195177

196178
str_t dst = create_dst_name(in, work);
197179

198180
/* see man 2 readlink */
199181
const ssize_t len = readlink(work->name, ed->linkname, sizeof(ed->linkname));
200182
if ((len < 0) || (len == sizeof(ed->linkname))) {
201-
const int err = errno;
202-
fprintf(stderr, "Error: Could not readlink \"%s\": %s (%d)\n",
203-
work->name, strerror(err), err);
204-
rc = 1;
205-
goto cleanup;
183+
print_error_and_goto("Could not readlink", work->name, cleanup);
206184
}
207185

208186
ed->linkname[len] = '\0';
209187

210188
if (symlink(ed->linkname, dst.data) != 0) {
211-
const int err = errno;
212-
fprintf(stderr, "Error: Could not create link \"%s\": %s (%d)\n",
213-
dst.data, strerror(err), err);
214-
rc = 1;
189+
print_error_and_goto("Could not create link", dst.data, cleanup);
215190
}
216191

217192
cleanup:
@@ -261,41 +236,25 @@ static int cpr_dir(QPTPool_t *ctx, const size_t id, void *data, void *args) {
261236

262237
DIR *dir = opendir(work->name);
263238
if (!dir) {
264-
const int err = errno;
265-
fprintf(stderr, "Error: Could not open directory \"%s\": %s (%d)\n",
266-
work->name, strerror(err), err);
267-
rc = 1;
268-
goto cleanup;
239+
print_error_and_goto("Could not open_directory", work->name, cleanup);
269240
}
270241

271242
struct stat st;
272243
if (lstat(work->name, &st) != 0) {
273-
const int err = errno;
274-
fprintf(stderr, "Error: Could not lstat directory \"%s\": %s (%d)\n",
275-
work->name, strerror(err), err);
276-
rc = 1;
277-
goto cleanup;
244+
print_error_and_goto("Could not lstat directory", work->name, cleanup);
278245
}
279246

280247
str_t dst = create_dst_name(in, work);
281248

282249
/* ensure parent directory exists before processing children */
283250
if (mkdir(dst.data, st.st_mode & 0777) != 0) {
284-
const int err = errno;
285-
if (err != EEXIST) {
286-
fprintf(stderr, "Error: Could not create directory \"%s\": %s (%d)\n",
287-
dst.data, strerror(err), err);
288-
rc = 1;
289-
goto cleanup;
251+
if (errno != EEXIST) {
252+
print_error_and_goto("Could not create directory", dst.data, cleanup);
290253
}
291254
}
292255

293256
if (chown(dst.data, st.st_uid, st.st_gid) != 0) {
294-
const int err = errno;
295-
fprintf(stderr, "Error: Could not chown directory \"%s\": %s (%d)\n",
296-
dst.data, strerror(err), err);
297-
rc = 1;
298-
goto cleanup;
257+
print_error_and_goto("Could not chown directory", dst.data, cleanup);
299258
}
300259

301260
struct QPTPool_vals qptp_vals = {

test/regression/parallel_cpr.expected

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,15 @@ prefix/1KB
110110

111111
$ rm -rf "copy"
112112

113-
$ parallel_cpr "prefix" "prefix"
113+
$ parallel_cpr "prefix" "prefix"
114114
Not copying into itself: "prefix" -> "prefix"
115115

116-
$ parallel_cpr "prefix" "prefix/directory"
116+
$ parallel_cpr "prefix" "prefix/directory"
117117
Not copying into itself: "prefix" -> "prefix/directory"
118118

119-
$ parallel_cpr /dev/null "copy"
119+
$ parallel_cpr "badtrace" "copy"
120+
Error: Cannot lstat "badtrace": No such file or directory (2)
121+
122+
$ parallel_cpr /dev/null "copy"
120123
Not copying "/dev/null"
121124

test/regression/parallel_cpr.sh.in

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,15 @@ run_no_sort "readlink \"${CPR_ROOT}/file_symlink\""
130130
run_no_sort "rm -rf \"${CPR_ROOT}\""
131131

132132
set +e
133-
run_no_sort "${PARALLEL_CPR} \"${SRCDIR}\" \"${SRCDIR}\""
134-
run_no_sort "${PARALLEL_CPR} \"${SRCDIR}\" \"${SRCDIR}/directory\""
135-
run_no_sort "${PARALLEL_CPR} /dev/null \"${CPR_ROOT}\""
133+
# copy into self
134+
run_no_sort "${PARALLEL_CPR} \"${SRCDIR}\" \"${SRCDIR}\""
135+
run_no_sort "${PARALLEL_CPR} \"${SRCDIR}\" \"${SRCDIR}/directory\""
136+
137+
# non-existant source
138+
run_no_sort "${PARALLEL_CPR} \"${BADTRACE}\" \"${CPR_ROOT}\""
139+
140+
# non-directory/link/file source
141+
run_no_sort "${PARALLEL_CPR} /dev/null \"${CPR_ROOT}\""
136142
set -e
137143
) | tee "${OUTPUT}"
138144

test/unit/googletest/external.cpp.in

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ OF SUCH DAMAGE.
6363

6464

6565
#include <cstddef>
66+
#include <cstdlib>
6667

6768
#include <gtest/gtest.h>
6869

@@ -75,6 +76,50 @@ static size_t bad_filename(char **dst, const size_t dst_size,
7576
return SNPRINTF(*dst, dst_size, "@CMAKE_BINARY_DIR@");
7677
}
7778

79+
TEST(external, read_file) {
80+
const char DEVNULL[] = "/dev/null";
81+
const std::size_t DEVNULL_LEN = strlen(DEVNULL);
82+
83+
struct input in;
84+
in.check_extdb_valid = true;
85+
86+
struct work work;
87+
memset(&work, 0, sizeof(work));
88+
89+
char filename[] = "XXXXXX";
90+
const int fd = mkstemp(filename);
91+
ASSERT_GE(fd, 0);
92+
EXPECT_EQ(strncpy(work.name, filename, 6), work.name);
93+
EXPECT_EQ(write(fd, DEVNULL, DEVNULL_LEN), (ssize_t) DEVNULL_LEN);
94+
EXPECT_EQ(write(fd, "\n", (std::size_t) 1), (ssize_t) 1);
95+
96+
char extdb_filename[] = "XXXXXX";
97+
const int extdb_fd = mkstemp(extdb_filename);
98+
ASSERT_GE(extdb_fd, 0);
99+
EXPECT_EQ(close(extdb_fd), 0);
100+
EXPECT_EQ(remove(extdb_filename), 0);
101+
EXPECT_EQ(write(fd, extdb_filename, (std::size_t) 6), (ssize_t) 6);
102+
EXPECT_EQ(write(fd, "\n", (std::size_t) 1), (ssize_t) 1);
103+
104+
EXPECT_EQ(close(fd), 0);
105+
106+
EXPECT_EQ(external_read_file(&in, &work,
107+
[](struct input *, void *,
108+
const long long int,
109+
const char *) -> int { return 0; },
110+
nullptr),
111+
(std::size_t) 1);
112+
113+
EXPECT_EQ(remove(filename), 0);
114+
115+
EXPECT_EQ(external_read_file(&in, &work,
116+
[](struct input *, void *,
117+
const long long int,
118+
const char *) -> int { return 0; },
119+
nullptr),
120+
(std::size_t) 0);
121+
}
122+
78123
TEST(external, concatenate) {
79124
// type is used when querying the external database table,
80125
// not for attching the individual external databases
@@ -144,8 +189,8 @@ TEST(external, concatenate) {
144189

145190
external_concatenate_cleanup(db, drop_view,
146191
&type,
147-
NULL,
148-
NULL, NULL
192+
nullptr,
193+
nullptr, nullptr
149194
#if defined(DEBUG) && defined(CUMULATIVE_TIMES)
150195
, &query_count
151196
#endif
@@ -176,8 +221,8 @@ TEST(external, concatenate) {
176221

177222
external_concatenate_cleanup(db, drop_view,
178223
&type,
179-
NULL,
180-
NULL, NULL
224+
nullptr,
225+
nullptr, nullptr
181226
#if defined(DEBUG) && defined(CUMULATIVE_TIMES)
182227
, &query_count
183228
#endif
@@ -200,6 +245,28 @@ TEST(external, concatenate) {
200245
EXPECT_EQ(rc, 0);
201246

202247
external_concatenate_cleanup(db, drop_view,
248+
&type,
249+
nullptr,
250+
nullptr, nullptr
251+
#if defined(DEBUG) && defined(CUMULATIVE_TIMES)
252+
, &query_count
253+
#endif
254+
);
255+
256+
sqlite3_close(db);
257+
258+
// drop view but bad db
259+
external_concatenate_cleanup(nullptr, drop_view,
260+
&type,
261+
nullptr,
262+
nullptr, nullptr
263+
#if defined(DEBUG) && defined(CUMULATIVE_TIMES)
264+
, &query_count
265+
#endif
266+
);
267+
268+
// no drop view, drop type but bad db
269+
external_concatenate_cleanup(nullptr, drop_view,
203270
&type,
204271
NULL,
205272
NULL, NULL
@@ -208,5 +275,14 @@ TEST(external, concatenate) {
208275
#endif
209276
);
210277

211-
sqlite3_close(db);
278+
279+
// no drop view, no type
280+
external_concatenate_cleanup(db, nullptr,
281+
nullptr,
282+
nullptr,
283+
nullptr, nullptr
284+
#if defined(DEBUG) && defined(CUMULATIVE_TIMES)
285+
, &query_count
286+
#endif
287+
);
212288
}

0 commit comments

Comments
 (0)