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