1 1.1 christos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 1.1 christos * 3 1.1 christos * Permission is hereby granted, free of charge, to any person obtaining a copy 4 1.1 christos * of this software and associated documentation files (the "Software"), to 5 1.1 christos * deal in the Software without restriction, including without limitation the 6 1.1 christos * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 1.1 christos * sell copies of the Software, and to permit persons to whom the Software is 8 1.1 christos * furnished to do so, subject to the following conditions: 9 1.1 christos * 10 1.1 christos * The above copyright notice and this permission notice shall be included in 11 1.1 christos * all copies or substantial portions of the Software. 12 1.1 christos * 13 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 1.1 christos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 1.1 christos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 1.1 christos * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 1.1 christos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 1.1 christos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 1.1 christos * IN THE SOFTWARE. 20 1.1 christos */ 21 1.1 christos 22 1.1 christos #include "uv.h" 23 1.1 christos #include "task.h" 24 1.1 christos #include <stdlib.h> 25 1.1 christos 26 1.1 christos #define CONCURRENT_COUNT 10 27 1.1 christos 28 1.1 christos static const char* name = "localhost"; 29 1.1 christos 30 1.1 christos static int getaddrinfo_cbs = 0; 31 1.1 christos 32 1.1 christos /* data used for running multiple calls concurrently */ 33 1.1 christos static uv_getaddrinfo_t* getaddrinfo_handle; 34 1.1 christos static uv_getaddrinfo_t getaddrinfo_handles[CONCURRENT_COUNT]; 35 1.1 christos static int callback_counts[CONCURRENT_COUNT]; 36 1.1 christos static int fail_cb_called; 37 1.1 christos 38 1.1 christos 39 1.1 christos static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req, 40 1.1 christos int status, 41 1.1 christos struct addrinfo* res) { 42 1.1.1.2 christos 43 1.1.1.3 christos ASSERT_OK(fail_cb_called); 44 1.1.1.3 christos ASSERT_LT(status, 0); 45 1.1.1.2 christos ASSERT_NULL(res); 46 1.1 christos uv_freeaddrinfo(res); /* Should not crash. */ 47 1.1 christos fail_cb_called++; 48 1.1 christos } 49 1.1 christos 50 1.1 christos 51 1.1 christos static void getaddrinfo_basic_cb(uv_getaddrinfo_t* handle, 52 1.1 christos int status, 53 1.1 christos struct addrinfo* res) { 54 1.1.1.3 christos ASSERT_PTR_EQ(handle, getaddrinfo_handle); 55 1.1 christos getaddrinfo_cbs++; 56 1.1 christos free(handle); 57 1.1 christos uv_freeaddrinfo(res); 58 1.1 christos } 59 1.1 christos 60 1.1 christos 61 1.1 christos static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle, 62 1.1 christos int status, 63 1.1 christos struct addrinfo* res) { 64 1.1 christos int i; 65 1.1 christos int* data = (int*)handle->data; 66 1.1 christos 67 1.1 christos for (i = 0; i < CONCURRENT_COUNT; i++) { 68 1.1 christos if (&getaddrinfo_handles[i] == handle) { 69 1.1.1.3 christos ASSERT_EQ(i, *data); 70 1.1 christos 71 1.1 christos callback_counts[i]++; 72 1.1 christos break; 73 1.1 christos } 74 1.1 christos } 75 1.1 christos ASSERT (i < CONCURRENT_COUNT); 76 1.1 christos 77 1.1 christos free(data); 78 1.1 christos uv_freeaddrinfo(res); 79 1.1 christos 80 1.1 christos getaddrinfo_cbs++; 81 1.1 christos } 82 1.1 christos 83 1.1 christos 84 1.1 christos TEST_IMPL(getaddrinfo_fail) { 85 1.1.1.2 christos /* TODO(gengjiawen): Fix test on QEMU. */ 86 1.1.1.2 christos #if defined(__QEMU__) 87 1.1.1.2 christos RETURN_SKIP("Test does not currently work in QEMU"); 88 1.1.1.2 christos #endif 89 1.1.1.2 christos 90 1.1 christos uv_getaddrinfo_t req; 91 1.1 christos 92 1.1.1.3 christos ASSERT_EQ(UV_EINVAL, uv_getaddrinfo(uv_default_loop(), 93 1.1.1.3 christos &req, 94 1.1.1.3 christos (uv_getaddrinfo_cb) abort, 95 1.1.1.3 christos NULL, 96 1.1.1.3 christos NULL, 97 1.1.1.3 christos NULL)); 98 1.1 christos 99 1.1 christos /* Use a FQDN by ending in a period */ 100 1.1.1.3 christos ASSERT_OK(uv_getaddrinfo(uv_default_loop(), 101 1.1.1.3 christos &req, 102 1.1.1.3 christos getaddrinfo_fail_cb, 103 1.1.1.3 christos "example.invalid.", 104 1.1.1.3 christos NULL, 105 1.1.1.3 christos NULL)); 106 1.1.1.3 christos ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT)); 107 1.1.1.3 christos ASSERT_EQ(1, fail_cb_called); 108 1.1 christos 109 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 110 1.1 christos return 0; 111 1.1 christos } 112 1.1 christos 113 1.1 christos 114 1.1 christos TEST_IMPL(getaddrinfo_fail_sync) { 115 1.1 christos /* TODO(gengjiawen): Fix test on QEMU. */ 116 1.1 christos #if defined(__QEMU__) 117 1.1 christos RETURN_SKIP("Test does not currently work in QEMU"); 118 1.1 christos #endif 119 1.1 christos uv_getaddrinfo_t req; 120 1.1 christos 121 1.1 christos /* Use a FQDN by ending in a period */ 122 1.1.1.3 christos ASSERT_GT(0, uv_getaddrinfo(uv_default_loop(), 123 1.1.1.3 christos &req, 124 1.1.1.3 christos NULL, 125 1.1.1.3 christos "example.invalid.", 126 1.1.1.3 christos NULL, 127 1.1.1.3 christos NULL)); 128 1.1 christos uv_freeaddrinfo(req.addrinfo); 129 1.1 christos 130 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 131 1.1 christos return 0; 132 1.1 christos } 133 1.1 christos 134 1.1 christos 135 1.1 christos TEST_IMPL(getaddrinfo_basic) { 136 1.1.1.2 christos /* TODO(gengjiawen): Fix test on QEMU. */ 137 1.1.1.2 christos #if defined(__QEMU__) 138 1.1.1.2 christos RETURN_SKIP("Test does not currently work in QEMU"); 139 1.1.1.2 christos #endif 140 1.1.1.2 christos 141 1.1 christos int r; 142 1.1 christos getaddrinfo_handle = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t)); 143 1.1 christos 144 1.1 christos r = uv_getaddrinfo(uv_default_loop(), 145 1.1 christos getaddrinfo_handle, 146 1.1 christos &getaddrinfo_basic_cb, 147 1.1 christos name, 148 1.1 christos NULL, 149 1.1 christos NULL); 150 1.1.1.3 christos ASSERT_OK(r); 151 1.1 christos 152 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 153 1.1 christos 154 1.1.1.3 christos ASSERT_EQ(1, getaddrinfo_cbs); 155 1.1 christos 156 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 157 1.1 christos return 0; 158 1.1 christos } 159 1.1 christos 160 1.1 christos 161 1.1 christos TEST_IMPL(getaddrinfo_basic_sync) { 162 1.1 christos /* TODO(gengjiawen): Fix test on QEMU. */ 163 1.1 christos #if defined(__QEMU__) 164 1.1 christos RETURN_SKIP("Test does not currently work in QEMU"); 165 1.1 christos #endif 166 1.1 christos uv_getaddrinfo_t req; 167 1.1 christos 168 1.1.1.3 christos ASSERT_OK(uv_getaddrinfo(uv_default_loop(), 169 1.1.1.3 christos &req, 170 1.1.1.3 christos NULL, 171 1.1.1.3 christos name, 172 1.1.1.3 christos NULL, 173 1.1.1.3 christos NULL)); 174 1.1 christos uv_freeaddrinfo(req.addrinfo); 175 1.1 christos 176 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 177 1.1 christos return 0; 178 1.1 christos } 179 1.1 christos 180 1.1 christos 181 1.1 christos TEST_IMPL(getaddrinfo_concurrent) { 182 1.1.1.2 christos /* TODO(gengjiawen): Fix test on QEMU. */ 183 1.1.1.2 christos #if defined(__QEMU__) 184 1.1.1.2 christos RETURN_SKIP("Test does not currently work in QEMU"); 185 1.1.1.2 christos #endif 186 1.1.1.2 christos 187 1.1 christos int i, r; 188 1.1 christos int* data; 189 1.1 christos 190 1.1 christos for (i = 0; i < CONCURRENT_COUNT; i++) { 191 1.1 christos callback_counts[i] = 0; 192 1.1 christos 193 1.1 christos data = (int*)malloc(sizeof(int)); 194 1.1.1.2 christos ASSERT_NOT_NULL(data); 195 1.1 christos *data = i; 196 1.1 christos getaddrinfo_handles[i].data = data; 197 1.1 christos 198 1.1 christos r = uv_getaddrinfo(uv_default_loop(), 199 1.1 christos &getaddrinfo_handles[i], 200 1.1 christos &getaddrinfo_cuncurrent_cb, 201 1.1 christos name, 202 1.1 christos NULL, 203 1.1 christos NULL); 204 1.1.1.3 christos ASSERT_OK(r); 205 1.1 christos } 206 1.1 christos 207 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 208 1.1 christos 209 1.1 christos for (i = 0; i < CONCURRENT_COUNT; i++) { 210 1.1.1.3 christos ASSERT_EQ(1, callback_counts[i]); 211 1.1 christos } 212 1.1 christos 213 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 214 1.1 christos return 0; 215 1.1 christos } 216