svn commit: r344310 - head/lib/libc/tests/sys

Enji Cooper ngie at FreeBSD.org
Tue Feb 19 22:19:33 UTC 2019


Author: ngie
Date: Tue Feb 19 22:19:31 2019
New Revision: 344310
URL: https://svnweb.freebsd.org/changeset/base/344310

Log:
  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

Modified:
  head/lib/libc/tests/sys/sendfile_test.c

Modified: head/lib/libc/tests/sys/sendfile_test.c
==============================================================================
--- head/lib/libc/tests/sys/sendfile_test.c	Tue Feb 19 21:58:23 2019	(r344309)
+++ head/lib/libc/tests/sys/sendfile_test.c	Tue Feb 19 22:19:31 2019	(r344310)
@@ -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,
 	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
@@ -666,10 +670,6 @@ hdtr_positive_test(int domain)
 	trailers[0].iov_len = strlen(trailers[0].iov_base);
 	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;


More information about the svn-src-head mailing list