Imported Upstream version 1.41.0
[platform/upstream/grpc.git] / test / core / http / httpcli_test.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include "src/core/lib/http/httpcli.h"
20
21 #include <string.h>
22
23 #include <grpc/grpc.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
26 #include <grpc/support/string_util.h>
27 #include <grpc/support/sync.h>
28
29 #include "src/core/lib/iomgr/iomgr.h"
30 #include "test/core/util/port.h"
31 #include "test/core/util/subprocess.h"
32 #include "test/core/util/test_config.h"
33
34 static int g_done = 0;
35 static grpc_httpcli_context g_context;
36 static gpr_mu* g_mu;
37 static grpc_polling_entity g_pops;
38
39 static grpc_millis n_seconds_time(int seconds) {
40   return grpc_timespec_to_millis_round_up(
41       grpc_timeout_seconds_to_deadline(seconds));
42 }
43
44 static void on_finish(void* arg, grpc_error_handle error) {
45   const char* expect =
46       "<html><head><title>Hello world!</title></head>"
47       "<body><p>This is a test</p></body></html>";
48   grpc_http_response* response = static_cast<grpc_http_response*>(arg);
49   GPR_ASSERT(response);
50   gpr_log(GPR_INFO, "response status=%d error=%s", response->status,
51           grpc_error_std_string(error).c_str());
52   GPR_ASSERT(response->status == 200);
53   GPR_ASSERT(response->body_length == strlen(expect));
54   GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
55   gpr_mu_lock(g_mu);
56   g_done = 1;
57   GPR_ASSERT(GRPC_LOG_IF_ERROR(
58       "pollset_kick",
59       grpc_pollset_kick(grpc_polling_entity_pollset(&g_pops), nullptr)));
60   gpr_mu_unlock(g_mu);
61 }
62
63 static void test_get(int port) {
64   grpc_httpcli_request req;
65   char* host;
66   grpc_core::ExecCtx exec_ctx;
67
68   g_done = 0;
69   gpr_log(GPR_INFO, "test_get");
70
71   gpr_asprintf(&host, "localhost:%d", port);
72   gpr_log(GPR_INFO, "requesting from %s", host);
73
74   memset(&req, 0, sizeof(req));
75   req.host = host;
76   req.http.path = const_cast<char*>("/get");
77   req.handshaker = &grpc_httpcli_plaintext;
78
79   grpc_http_response response;
80   response = {};
81   grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_get");
82   grpc_httpcli_get(
83       &g_context, &g_pops, resource_quota, &req, n_seconds_time(15),
84       GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx),
85       &response);
86   gpr_mu_lock(g_mu);
87   while (!g_done) {
88     grpc_pollset_worker* worker = nullptr;
89     GPR_ASSERT(GRPC_LOG_IF_ERROR(
90         "pollset_work", grpc_pollset_work(grpc_polling_entity_pollset(&g_pops),
91                                           &worker, n_seconds_time(1))));
92     gpr_mu_unlock(g_mu);
93
94     gpr_mu_lock(g_mu);
95   }
96   gpr_mu_unlock(g_mu);
97   gpr_free(host);
98   grpc_http_response_destroy(&response);
99 }
100
101 static void test_post(int port) {
102   grpc_httpcli_request req;
103   char* host;
104   grpc_core::ExecCtx exec_ctx;
105
106   g_done = 0;
107   gpr_log(GPR_INFO, "test_post");
108
109   gpr_asprintf(&host, "localhost:%d", port);
110   gpr_log(GPR_INFO, "posting to %s", host);
111
112   memset(&req, 0, sizeof(req));
113   req.host = host;
114   req.http.path = const_cast<char*>("/post");
115   req.handshaker = &grpc_httpcli_plaintext;
116
117   grpc_http_response response;
118   response = {};
119   grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_post");
120   grpc_httpcli_post(
121       &g_context, &g_pops, resource_quota, &req, "hello", 5, n_seconds_time(15),
122       GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx),
123       &response);
124   gpr_mu_lock(g_mu);
125   while (!g_done) {
126     grpc_pollset_worker* worker = nullptr;
127     GPR_ASSERT(GRPC_LOG_IF_ERROR(
128         "pollset_work", grpc_pollset_work(grpc_polling_entity_pollset(&g_pops),
129                                           &worker, n_seconds_time(1))));
130     gpr_mu_unlock(g_mu);
131
132     gpr_mu_lock(g_mu);
133   }
134   gpr_mu_unlock(g_mu);
135   gpr_free(host);
136   grpc_http_response_destroy(&response);
137 }
138
139 static void destroy_pops(void* p, grpc_error_handle /*error*/) {
140   grpc_pollset_destroy(
141       grpc_polling_entity_pollset(static_cast<grpc_polling_entity*>(p)));
142 }
143
144 int main(int argc, char** argv) {
145   gpr_subprocess* server;
146   grpc::testing::TestEnvironment env(argc, argv);
147   grpc_init();
148   {
149     grpc_closure destroyed;
150     grpc_core::ExecCtx exec_ctx;
151     char* me = argv[0];
152     char* lslash = strrchr(me, '/');
153     char* args[4];
154     int port = grpc_pick_unused_port_or_die();
155     int arg_shift = 0;
156     /* figure out where we are */
157     char* root;
158     if (lslash != nullptr) {
159       /* Hack for bazel target */
160       if (static_cast<unsigned>(lslash - me) >= (sizeof("http") - 1) &&
161           strncmp(me + (lslash - me) - sizeof("http") + 1, "http",
162                   sizeof("http") - 1) == 0) {
163         lslash = me + (lslash - me) - sizeof("http");
164       }
165       root = static_cast<char*>(
166           gpr_malloc(static_cast<size_t>(lslash - me + sizeof("/../.."))));
167       memcpy(root, me, static_cast<size_t>(lslash - me));
168       memcpy(root + (lslash - me), "/../..", sizeof("/../.."));
169     } else {
170       root = gpr_strdup(".");
171     }
172
173     GPR_ASSERT(argc <= 2);
174     if (argc == 2) {
175       args[0] = gpr_strdup(argv[1]);
176     } else {
177       arg_shift = 1;
178       gpr_asprintf(&args[0], "%s/test/core/http/python_wrapper.sh", root);
179       gpr_asprintf(&args[1], "%s/test/core/http/test_server.py", root);
180     }
181
182     /* start the server */
183     args[1 + arg_shift] = const_cast<char*>("--port");
184     gpr_asprintf(&args[2 + arg_shift], "%d", port);
185     server =
186         gpr_subprocess_create(3 + arg_shift, const_cast<const char**>(args));
187     GPR_ASSERT(server);
188     gpr_free(args[0]);
189     if (arg_shift) gpr_free(args[1]);
190     gpr_free(args[2 + arg_shift]);
191     gpr_free(root);
192
193     gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
194                                  gpr_time_from_seconds(5, GPR_TIMESPAN)));
195
196     grpc_httpcli_context_init(&g_context);
197     grpc_pollset* pollset =
198         static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
199     grpc_pollset_init(pollset, &g_mu);
200     g_pops = grpc_polling_entity_create_from_pollset(pollset);
201
202     test_get(port);
203     test_post(port);
204
205     grpc_httpcli_context_destroy(&g_context);
206     GRPC_CLOSURE_INIT(&destroyed, destroy_pops, &g_pops,
207                       grpc_schedule_on_exec_ctx);
208     grpc_pollset_shutdown(grpc_polling_entity_pollset(&g_pops), &destroyed);
209   }
210   grpc_shutdown();
211
212   gpr_free(grpc_polling_entity_pollset(&g_pops));
213
214   gpr_subprocess_destroy(server);
215
216   return 0;
217 }