[WS2_32_APITEST]
authorThomas Faber <thomas.faber@reactos.org>
Sat, 23 Jun 2012 12:40:36 +0000 (12:40 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 23 Jun 2012 12:40:36 +0000 (12:40 +0000)
- Add a test for basic functionality of getaddrinfo

svn path=/trunk/; revision=56787

rostests/apitests/ws2_32/CMakeLists.txt
rostests/apitests/ws2_32/getaddrinfo.c [new file with mode: 0644]
rostests/apitests/ws2_32/testlist.c

index 4f43560..bbf35a0 100644 (file)
@@ -1,14 +1,13 @@
 
-add_definitions(-D_DLL -D__USE_CRTIMP)
-
 list(APPEND SOURCE
+    getaddrinfo.c
     helpers.c
     ioctlsocket.c
     recv.c
     testlist.c)
 
 add_executable(ws2_32_apitest ${SOURCE})
-target_link_libraries(ws2_32_apitest wine)
+target_link_libraries(ws2_32_apitest wine ${PSEH_LIB})
 set_module_type(ws2_32_apitest win32cui)
 add_importlibs(ws2_32_apitest ws2_32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET ws2_32_apitest DESTINATION reactos/bin FOR all)
diff --git a/rostests/apitests/ws2_32/getaddrinfo.c b/rostests/apitests/ws2_32/getaddrinfo.c
new file mode 100644 (file)
index 0000000..26f41be
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Test for getaddrinfo
+ * PROGRAMMER:      Thomas Faber <thfabba@gmx.de>
+ */
+
+#define WIN32_NO_STATUS
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <wine/test.h>
+#include <pseh/pseh2.h>
+#include <ndk/umtypes.h>
+
+#define StartSeh()              ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
+#define EndSeh(ExpectedStatus)  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
+
+#define ok_addrinfo(ai, flags, family, socktype, protocol, addrlen) do  \
+{                                                                       \
+    ok_hex((ai)->ai_flags, flags);                                      \
+    ok_dec((ai)->ai_family, family);                                    \
+    ok_dec((ai)->ai_socktype, socktype);                                \
+    ok_dec((ai)->ai_protocol, protocol);                                \
+    ok_dec((ai)->ai_addrlen, addrlen);                                  \
+} while (0)
+
+#define ok_sockaddr_in(sockaddr, family, port, addr) do                 \
+{                                                                       \
+    int _i;                                                             \
+    ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_family, family);            \
+    ok_dec(ntohs(((SOCKADDR_IN *)(sockaddr))->sin_port), port);         \
+    ok_hex(((SOCKADDR_IN *)(sockaddr))->sin_addr.S_un.S_addr,           \
+           inet_addr(addr));                                            \
+    for (_i = 0; _i < 7; _i++)                                          \
+        ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_zero[_i], 0);           \
+} while (0)
+
+#define InvalidPointer ((PVOID)0x5555555555555555ULL)
+
+CHAR LocalAddress[sizeof("255.255.255.255")];
+
+static
+VOID
+TestNodeName(VOID)
+{
+    int Error;
+    PADDRINFOA AddrInfo;
+    ADDRINFOA Hints;
+    NTSTATUS ExceptionStatus;
+    struct
+    {
+        PCSTR NodeName;
+        PCSTR ExpectedAddress;
+        INT Flags;
+    } Tests[] =
+    {
+        { "",                               LocalAddress },
+        { " ",                              NULL },
+        { "doesntexist.reactos.org",        NULL },
+        { "localhost",                      "127.0.0.1" },
+        { "localhost:80",                   NULL },
+        { "7.8.9.10",                       "7.8.9.10",         AI_NUMERICHOST },
+        { "0.0.0.0",                        "0.0.0.0",          AI_NUMERICHOST },
+        { "255.255.255.255",                "255.255.255.255",  AI_NUMERICHOST },
+        { "0.0.0.0 ",                       "0.0.0.0",    /* no AI_NUMERICHOST */ },
+        { "0.0.0.0:80",                     NULL },
+        { "0.0.0.0.0",                      NULL },
+        { "1.1.1.256",                      NULL },
+        /* let's just assume this one doesn't change any time soon ;) */
+        { "google-public-dns-a.google.com", "8.8.8.8" },
+    };
+    const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
+    INT i;
+
+    /* make sure we don't get IPv6 responses */
+    ZeroMemory(&Hints, sizeof(Hints));
+    Hints.ai_family = AF_INET;
+
+    trace("Nodes\n");
+    for (i = 0; i < TestCount; i++)
+    {
+        trace("%d: '%s'\n", i, Tests[i].NodeName);
+        StartSeh();
+            AddrInfo = InvalidPointer;
+            Error = getaddrinfo(Tests[i].NodeName, NULL, &Hints, &AddrInfo);
+            if (Tests[i].ExpectedAddress)
+            {
+                ok_dec(Error, 0);
+                ok_dec(WSAGetLastError(), 0);
+                ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
+                   "AddrInfo = %p\n", AddrInfo);
+            }
+            else
+            {
+                ok_dec(Error, WSAHOST_NOT_FOUND);
+                ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
+                ok_ptr(AddrInfo, NULL);
+            }
+            if (!Error && AddrInfo && AddrInfo != InvalidPointer)
+            {
+                ok_addrinfo(AddrInfo, Tests[i].Flags, AF_INET,
+                            0, 0, sizeof(SOCKADDR_IN));
+                ok_ptr(AddrInfo->ai_canonname, NULL);
+                ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
+                               0, Tests[i].ExpectedAddress);
+                ok_ptr(AddrInfo->ai_next, NULL);
+                freeaddrinfo(AddrInfo);
+            }
+        EndSeh(STATUS_SUCCESS);
+    }
+}
+
+static
+VOID
+TestServiceName(VOID)
+{
+    int Error;
+    PADDRINFOA AddrInfo;
+    ADDRINFOA Hints;
+    NTSTATUS ExceptionStatus;
+    struct
+    {
+        PCSTR ServiceName;
+        INT ExpectedPort;
+        INT SockType;
+    } Tests[] =
+    {
+        { "", 0 },
+        { "0", 0 },
+        { "1", 1 },
+        { "a", -1 },
+        { "010", 10 },
+        { "0x1a", -1 },
+        { "http", 80, SOCK_STREAM },
+        { "smtp", 25, SOCK_STREAM },
+        { "mail", 25, SOCK_STREAM }, /* alias for smtp */
+        { "router", 520, SOCK_DGRAM },
+        { "domain", 53, 0 /* DNS supports both UDP and TCP */ },
+        { ":0", -1 },
+        { "123", 123 },
+        { " 123", 123 },
+        { "    123", 123 },
+        { "32767", 32767 },
+        { "32768", 32768 },
+        { "65535", 65535 },
+        { "65536", 0 },
+        { "65537", 1 },
+        { "65540", 4 },
+        { "65536", 0 },
+        { "4294967295", 65535 },
+        { "4294967296", 65535 },
+        { "9999999999", 65535 },
+        { "999999999999999999999999999999999999", 65535 },
+        { "+5", 5 },
+        { "-1", 65535 },
+        { "-4", 65532 },
+        { "-65534", 2 },
+        { "-65535", 1 },
+        { "-65536", 0 },
+        { "-65537", 65535 },
+        { "28a", -1 },
+        { "28 ", -1 },
+        { "a28", -1 },
+    };
+    const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
+    INT i;
+
+    /* make sure we don't get IPv6 responses */
+    ZeroMemory(&Hints, sizeof(Hints));
+    Hints.ai_family = AF_INET;
+
+    trace("Services\n");
+    for (i = 0; i < TestCount; i++)
+    {
+        trace("%d: '%s'\n", i, Tests[i].ServiceName);
+        StartSeh()
+            AddrInfo = InvalidPointer;
+            Error = getaddrinfo(NULL, Tests[i].ServiceName, &Hints, &AddrInfo);
+            if (Tests[i].ExpectedPort != -1)
+            {
+                ok_dec(Error, 0);
+                ok_dec(WSAGetLastError(), 0);
+                ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
+                   "AddrInfo = %p\n", AddrInfo);
+            }
+            else
+            {
+                ok_dec(Error, WSATYPE_NOT_FOUND);
+                ok_dec(WSAGetLastError(), WSATYPE_NOT_FOUND);
+                ok_ptr(AddrInfo, NULL);
+            }
+            if (!Error && AddrInfo && AddrInfo != InvalidPointer)
+            {
+                ok_addrinfo(AddrInfo, 0, AF_INET,
+                            Tests[i].SockType, 0, sizeof(SOCKADDR_IN));
+                ok_ptr(AddrInfo->ai_canonname, NULL);
+                ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
+                               Tests[i].ExpectedPort, "127.0.0.1");
+                ok_ptr(AddrInfo->ai_next, NULL);
+                freeaddrinfo(AddrInfo);
+            }
+        EndSeh(STATUS_SUCCESS);
+    }
+}
+
+START_TEST(getaddrinfo)
+{
+    WSADATA WsaData;
+    int Error;
+    PADDRINFOA AddrInfo;
+    ADDRINFOA Hints;
+    NTSTATUS ExceptionStatus;
+    CHAR LocalHostName[128];
+    struct hostent *Hostent;
+
+    /* not yet initialized */
+    Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
+    ok_dec(Error, WSANOTINITIALISED);
+
+    Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
+    ok_dec(Error, 0);
+
+    /* initialize LocalAddress for tests */
+    Error = gethostname(LocalHostName, sizeof(LocalHostName));
+    ok_dec(Error, 0);
+    ok_dec(WSAGetLastError(), 0);
+    trace("Local host name is '%s'\n", LocalHostName);
+    Hostent = gethostbyname(LocalHostName);
+    ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
+    if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
+    {
+        IN_ADDR Address;
+        memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
+        strcpy(LocalAddress, inet_ntoa(Address));
+    }
+    trace("Local address is '%s'\n", LocalAddress);
+    ok(LocalAddress[0] != '\0',
+       "Could not determine local address. Following test results may be wrong.\n");
+
+    ZeroMemory(&Hints, sizeof(Hints));
+    /* parameter tests */
+    StartSeh(); getaddrinfo(NULL, NULL, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
+    StartSeh(); getaddrinfo("", "", &Hints, NULL);   EndSeh(STATUS_ACCESS_VIOLATION);
+    StartSeh();
+        AddrInfo = InvalidPointer;
+        Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo);
+        ok_dec(Error, WSAHOST_NOT_FOUND);
+        ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
+        ok_ptr(AddrInfo, NULL);
+    EndSeh(STATUS_SUCCESS);
+
+    TestNodeName();
+    TestServiceName();
+    /* TODO: test passing both node name and service name */
+    /* TODO: test hints */
+    /* TODO: test IPv6 */
+
+    Error = WSACleanup();
+    ok_dec(Error, 0);
+
+    /* not initialized anymore */
+    Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
+    ok_dec(Error, WSANOTINITIALISED);
+}
index e760096..9c08f5e 100644 (file)
@@ -5,11 +5,13 @@
 #define STANDALONE
 #include "wine/test.h"
 
+extern void func_getaddrinfo(void);
 extern void func_ioctlsocket(void);
 extern void func_recv(void);
 
 const struct test winetest_testlist[] =
 {
+    { "getaddrinfo", func_getaddrinfo },
     { "ioctlsocket", func_ioctlsocket },
     { "recv", func_recv },