Make server_cat(..)
handle short receives
In short, the prior code was far too simplistic when it came to calling recv(2) and failed intermittently (or in the case of Jenkins, deterministically). Handle short recv(2)s by checking the return code and incrementing the window into the buffer by the number of received bytes. If the number of received bytes <= 0, then bail out of the loop, and test the total number of received bytes vs the expected number of bytes sent for equality, and base whether or not the test passes/fails on that fact. Remove the expected failure, now that the hdtr testcases deterministically pass on my host after this change [1]. PR: 234809 [1], 235200 Reviewed by: asomers Approved by: emaste (mentor) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D19188
This commit is contained in:
parent
e06f6f7311
commit
c90e23db39
@ -156,6 +156,8 @@ setup_client(int domain, int type, int port)
|
||||
"Will try to connect to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
@ -187,6 +189,8 @@ setup_server(int domain, int type, int port)
|
||||
"Will try to bind socket to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
error = bind(sock, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno));
|
||||
@ -204,11 +208,17 @@ setup_server(int domain, int type, int port)
|
||||
static void
|
||||
server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
{
|
||||
char *buffer;
|
||||
char *buffer, *buf_window_ptr;
|
||||
int recv_sock;
|
||||
ssize_t received_bytes;
|
||||
size_t buffer_size;
|
||||
ssize_t received_bytes, recv_ret;
|
||||
|
||||
buffer = calloc(len + 1, sizeof(char));
|
||||
/*
|
||||
* Ensure that there isn't excess data sent across the wire by
|
||||
* capturing 10 extra bytes (plus 1 for nul).
|
||||
*/
|
||||
buffer_size = len + 10 + 1;
|
||||
buffer = calloc(buffer_size, sizeof(char));
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc failed");
|
||||
|
||||
@ -216,32 +226,26 @@ server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
if (recv_sock == -1)
|
||||
err(1, "accept failed");
|
||||
|
||||
/*
|
||||
* XXX: this assumes the simplest case where all data is received in a
|
||||
* single recv(2) call.
|
||||
*/
|
||||
if (recv(recv_sock, buffer, len, 0) == -1)
|
||||
err(1, "recv failed");
|
||||
buf_window_ptr = buffer;
|
||||
received_bytes = 0;
|
||||
do {
|
||||
recv_ret = recv(recv_sock, buf_window_ptr,
|
||||
buffer_size - received_bytes, 0);
|
||||
if (recv_ret <= 0)
|
||||
break;
|
||||
buf_window_ptr += recv_ret;
|
||||
received_bytes += recv_ret;
|
||||
} while (received_bytes < buffer_size);
|
||||
|
||||
atf_utils_create_file(dest_filename, "%s", buffer);
|
||||
|
||||
/*
|
||||
* This recv(2) call helps ensure the amount of sent data is exactly
|
||||
* what was specified by `len`.
|
||||
*/
|
||||
received_bytes = recv(recv_sock, buffer, len, 0);
|
||||
switch (received_bytes) {
|
||||
case -1:
|
||||
err(1, "recv failed");
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
errx(1, "received unexpected data: %s", buffer);
|
||||
}
|
||||
|
||||
(void)close(recv_sock);
|
||||
(void)close(server_sock);
|
||||
free(buffer);
|
||||
|
||||
if (received_bytes != len)
|
||||
errx(1, "received unexpected data: %zd != %zd", received_bytes,
|
||||
len);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -667,10 +671,6 @@ hdtr_positive_test(int domain)
|
||||
offset = 0;
|
||||
nbytes = 0;
|
||||
|
||||
atf_tc_expect_fail(
|
||||
"The header/trailer testcases fail today with a data mismatch; "
|
||||
"bug # 234809");
|
||||
|
||||
for (i = 0; i < nitems(testcases); i++) {
|
||||
struct sf_hdtr hdtr;
|
||||
char *pattern;
|
||||
|
Loading…
Reference in New Issue
Block a user