]> granicus.if.org Git - libevent/commitdiff
Test case for 0848814ac49616
authorKevin Ko <kevin.s.ko@gmail.com>
Mon, 23 May 2011 05:40:05 +0000 (01:40 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 23 May 2011 05:40:05 +0000 (01:40 -0400)
 "I'm not sure if you'll like my use of the limited broadcast address
  for simulating an ENETUNREACH error with a TCP connection, but it's
  the best that I could think of.  Basically, we want to trigger a
  non-EINPROGRESS error in evutil_socket_connect() immediately at the
  connect() in order to bring about the assertion in the
  evhttp_connection_fail() error handling code."

test/regress_http.c

index 95511ae9f821b450d32762af74363931bbdeee0d..cf0fb97147734fffa07f09a760e957206c9bb467 100644 (file)
@@ -3007,6 +3007,65 @@ http_stream_in_cancel_test(void *arg)
 
 }
 
+static void
+http_connection_fail_done(struct evhttp_request *req, void *arg)
+{
+       /* An ENETUNREACH error results in an unrecoverable
+        * evhttp_connection error (see evhttp_connection_fail()).  The
+        * connection will be reset, and the user will be notified with a NULL
+        * req parameter. */
+       tt_assert(!req);
+
+       test_ok = 1;
+
+ end:
+       event_base_loopexit(arg, NULL);
+}
+
+/* Test unrecoverable evhttp_connection errors by generating an ENETUNREACH
+ * error on connection. */
+static void
+http_connection_fail_test(void *arg)
+{
+       struct basic_test_data *data = arg;
+       ev_uint16_t port = 0;
+       struct evhttp_connection *evcon = NULL;
+       struct evhttp_request *req = NULL;
+
+       exit_base = data->base;
+       test_ok = 0;
+
+       /* auto detect a port */
+       http = http_setup(&port, data->base);
+       evhttp_free(http);
+       http = NULL;
+
+       /* Pick an unroutable address.  The limited broadcast address should do
+        * when working with TCP. */
+       evcon = evhttp_connection_base_new(data->base, NULL, "255.255.255.255", 80);
+       tt_assert(evcon);
+
+       /*
+        * At this point, we want to schedule an HTTP GET request
+        * server using our make request method.
+        */
+
+       req = evhttp_request_new(http_connection_fail_done, data->base);
+       tt_assert(req);
+
+       if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/") == -1) {
+               tt_abort_msg("Couldn't make request");
+       }
+
+       event_base_dispatch(data->base);
+
+       tt_int_op(test_ok, ==, 1);
+
+ end:
+       if (evcon)
+               evhttp_connection_free(evcon);
+}
+
 static void
 http_connection_retry_done(struct evhttp_request *req, void *arg)
 {
@@ -3546,6 +3605,7 @@ struct testcase_t http_testcases[] = {
        HTTP(stream_in),
        HTTP(stream_in_cancel),
 
+       HTTP(connection_fail),
        HTTP(connection_retry),
        HTTP(data_length_constraints),