[7/8] webservices/tests: Add tests for WsSendMessage.
Hans Leidekker
hans at codeweavers.com
Wed Sep 28 05:38:05 CDT 2016
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/tests/Makefile.in | 2 +-
dlls/webservices/tests/proxy.c | 221 ++++++++++++++++++++++++++++++++++++-
2 files changed, 220 insertions(+), 3 deletions(-)
diff --git a/dlls/webservices/tests/Makefile.in b/dlls/webservices/tests/Makefile.in
index afff870..e63952c 100644
--- a/dlls/webservices/tests/Makefile.in
+++ b/dlls/webservices/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = webservices.dll
-IMPORTS = webservices
+IMPORTS = webservices user32 ws2_32
C_SRCS = \
channel.c \
diff --git a/dlls/webservices/tests/proxy.c b/dlls/webservices/tests/proxy.c
index ba0ecd3..ef64faf 100644
--- a/dlls/webservices/tests/proxy.c
+++ b/dlls/webservices/tests/proxy.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include "windows.h"
+#include "winsock2.h"
#include "webservices.h"
#include "wine/test.h"
@@ -29,12 +30,12 @@ static void test_WsCreateServiceProxy(void)
ULONG size, value;
hr = WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL,
- 0, NULL, 0, NULL, NULL ) ;
+ 0, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
proxy = NULL;
hr = WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL,
- 0, NULL, 0, &proxy, NULL ) ;
+ 0, NULL, 0, &proxy, NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( proxy != NULL, "proxy not set\n" );
@@ -104,9 +105,225 @@ static void test_WsOpenServiceProxy(void)
WsFreeServiceProxy( proxy );
}
+static HRESULT create_channel( int port, WS_CHANNEL **ret )
+{
+ static const WCHAR fmt[] =
+ {'h','t','t','p',':','/','/','1','2','7','.','0','.','0','.','1',':','%','u',0};
+ WS_CHANNEL_PROPERTY prop[2];
+ WS_ENVELOPE_VERSION env_version = WS_ENVELOPE_VERSION_SOAP_1_1;
+ WS_ADDRESSING_VERSION addr_version = WS_ADDRESSING_VERSION_TRANSPORT;
+ WS_CHANNEL *channel;
+ WS_ENDPOINT_ADDRESS addr;
+ WCHAR buf[64];
+ HRESULT hr;
+
+ prop[0].id = WS_CHANNEL_PROPERTY_ENVELOPE_VERSION;
+ prop[0].value = &env_version;
+ prop[0].valueSize = sizeof(env_version);
+
+ prop[1].id = WS_CHANNEL_PROPERTY_ADDRESSING_VERSION;
+ prop[1].value = &addr_version;
+ prop[1].valueSize = sizeof(addr_version);
+
+ *ret = NULL;
+ hr = WsCreateChannel( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, prop, 2, NULL, &channel, NULL );
+ if (hr != S_OK) return hr;
+
+ addr.url.length = wsprintfW( buf, fmt, port );
+ addr.url.chars = buf;
+ addr.headers = NULL;
+ addr.extensions = NULL;
+ addr.identity = NULL;
+ hr = WsOpenChannel( channel, &addr, NULL, NULL );
+ if (hr == S_OK) *ret = channel;
+ else WsFreeChannel( channel );
+ return hr;
+}
+
+static const char req_test1[] =
+ "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
+ "<req_test1 xmlns=\"ns\">-1</req_test1>"
+ "</s:Body></s:Envelope>";
+
+static const char resp_test1[] =
+ "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
+ "<resp_test1 xmlns=\"ns\">-2</resp_test1>"
+ "</s:Body></s:Envelope>";
+
+static void test_WsSendMessage( int port, WS_XML_STRING *action )
+{
+ WS_XML_STRING req = {9, (BYTE *)"req_test1"}, ns = {2, (BYTE *)"ns"};
+ WS_CHANNEL *channel;
+ WS_MESSAGE *msg;
+ WS_ELEMENT_DESCRIPTION body;
+ WS_MESSAGE_DESCRIPTION desc;
+ INT32 val = -1;
+ HRESULT hr;
+
+ hr = create_channel( port, &channel );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ body.elementLocalName = &req;
+ body.elementNs = &ns;
+ body.type = WS_INT32_TYPE;
+ body.typeDescription = NULL;
+ desc.action = action;
+ desc.bodyElementDescription = &body;
+ hr = WsSendMessage( NULL, msg, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ hr = WsSendMessage( channel, NULL, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ hr = WsSendMessage( channel, msg, NULL, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ hr = WsSendMessage( channel, msg, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCloseChannel( channel, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ WsFreeChannel( channel );
+ WsFreeMessage( msg );
+}
+
+static const struct
+{
+ const char *req_action;
+ const char *req_data;
+ unsigned int req_len;
+ const char *resp_action;
+ const char *resp_data;
+ unsigned int resp_len;
+}
+tests[] =
+{
+ { "req_test1", req_test1, sizeof(req_test1)-1, "resp_test1", resp_test1, sizeof(resp_test1)-1 },
+};
+
+static void send_response( int c, const char *action, const char *data, unsigned int len )
+{
+ static const char headers[] =
+ "HTTP/1.1 200 OK\r\nContent-Type: text/xml; charset=utf-8\r\nConnection: close\r\n";
+ static const char fmt[] =
+ "SOAPAction: \"%s\"\r\nContent-Length: %u\r\n\r\n";
+ char buf[128];
+
+ send( c, headers, sizeof(headers) - 1, 0 );
+ sprintf( buf, fmt, action, len );
+ send( c, buf, strlen(buf), 0 );
+ send( c, data, len, 0 );
+}
+
+struct server_info
+{
+ HANDLE event;
+ int port;
+};
+
+static DWORD CALLBACK server_proc( void *arg )
+{
+ struct server_info *info = arg;
+ int len, res, c = -1, i, j, on = 1, quit;
+ WSADATA wsa;
+ SOCKET s;
+ struct sockaddr_in sa;
+ char buf[1024];
+ const char *p;
+
+ WSAStartup( MAKEWORD(1,1), &wsa );
+ if ((s = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET) return 1;
+ setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on) );
+
+ memset( &sa, 0, sizeof(sa) );
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons( info->port );
+ sa.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );
+ if (bind( s, (struct sockaddr *)&sa, sizeof(sa) ) < 0) return 1;
+
+ listen( s, 0 );
+ SetEvent( info->event );
+ for (;;)
+ {
+ c = accept( s, NULL, NULL );
+
+ buf[0] = 0;
+ for (i = 0; i < sizeof(buf) - 1; i++)
+ {
+ if ((res = recv( c, &buf[i], 1, 0 )) != 1) break;
+ if (i < 4) continue;
+ if (buf[i - 2] == '\n' && buf[i] == '\n' && buf[i - 3] == '\r' && buf[i - 1] == '\r')
+ break;
+ }
+ buf[i] = 0;
+ quit = strstr( buf, "SOAPAction: \"quit\"" ) != NULL;
+
+ len = 0;
+ if ((p = strstr( buf, "Content-Length: " )))
+ {
+ p += strlen( "Content-Length: " );
+ while (isdigit( *p ))
+ {
+ len *= 10;
+ len += *p++ - '0';
+ }
+ }
+ for (i = 0; i < len; i++)
+ {
+ if ((res = recv( c, &buf[i], 1, 0 )) != 1) break;
+ }
+ buf[i] = 0;
+
+ for (j = 0; j < sizeof(tests)/sizeof(tests[0]); j++)
+ {
+ if (strstr( buf, tests[j].req_action ))
+ {
+ if (tests[j].req_data)
+ {
+ int data_len = strlen( buf );
+ ok( tests[j].req_len == data_len, "%u: unexpected data length %u %u\n",
+ j, data_len, tests[j].req_len );
+ if (tests[j].req_len == data_len)
+ ok( !memcmp( tests[j].req_data, buf, tests[j].req_len ), "%u: unexpected data\n", j );
+ }
+ send_response( c, tests[j].resp_action, tests[j].resp_data, tests[j].resp_len );
+ }
+ }
+
+ shutdown( c, 2 );
+ closesocket( c );
+ if (quit) break;
+ }
+
+ return 0;
+}
+
START_TEST(proxy)
{
+ WS_XML_STRING test1 = {9, (BYTE *)"req_test1"};
+ WS_XML_STRING quit = {4, (BYTE *)"quit"};
+ struct server_info info;
+ HANDLE thread;
+ DWORD ret;
+
test_WsCreateServiceProxy();
test_WsCreateServiceProxyFromTemplate();
test_WsOpenServiceProxy();
+
+ info.port = 7533;
+ info.event = CreateEventW( NULL, 0, 0, NULL );
+ thread = CreateThread( NULL, 0, server_proc, &info, 0, NULL );
+ ok( thread != NULL, "failed to create server thread %u\n", GetLastError() );
+
+ ret = WaitForSingleObject( info.event, 3000 );
+ ok(ret == WAIT_OBJECT_0, "failed to start test server %u\n", GetLastError());
+ if (ret != WAIT_OBJECT_0) return;
+
+ test_WsSendMessage( info.port, &test1 );
+ test_WsSendMessage( info.port, &quit );
+ WaitForSingleObject( thread, 3000 );
}
--
2.1.4
More information about the wine-patches
mailing list