blob: 14579c8cdf287a4c0e0c42788ecc84441237bf6c [file] [log] [blame]
Roger Meier213a6642010-10-27 12:30:11 +00001#include <assert.h>
2#include <netdb.h>
3
4#include "transport/thrift_transport.h"
5#include "transport/thrift_server_transport.h"
6#include "transport/thrift_server_socket.h"
7
8#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
9
10/* substituted functions to test failures of system and library calls */
11static int socket_error = 0;
12int
13my_socket(int domain, int type, int protocol)
14{
15 if (socket_error == 0)
16 {
17 return socket (domain, type, protocol);
18 }
19 return -1;
20}
21
22static int recv_error = 0;
23ssize_t
24my_recv(int socket, void *buffer, size_t length, int flags)
25{
26 if (recv_error == 0)
27 {
28 return recv (socket, buffer, length, flags);
29 }
30 return -1;
31}
32
33static int send_error = 0;
34ssize_t
35my_send(int socket, const void *buffer, size_t length, int flags)
36{
37 if (send_error == 0)
38 {
39 return send (socket, buffer, length, flags);
40 }
41 return -1;
42}
43
44#define socket my_socket
45#define recv my_recv
46#define send my_send
47#include "../src/transport/thrift_socket.c"
48#undef socket
49#undef recv
50#undef send
51
52static const char TEST_ADDRESS[] = "localhost";
53static const short TEST_PORT = 64444;
54
55static void thrift_socket_server (const int port);
56
57/* test object creation and destruction */
58static void
59test_create_and_destroy(void)
60{
61 gchar *hostname = NULL;
62 guint port = 0;
63
64 GObject *object = NULL;
65 object = g_object_new (THRIFT_TYPE_SOCKET, NULL);
66 assert (object != NULL);
67 g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL);
68 g_free (hostname);
69
70 g_object_unref (object);
71}
72
73static void
74test_open_and_close(void)
75{
76 ThriftSocket *tsocket = NULL;
77 ThriftTransport *transport = NULL;
78 GError *err = NULL;
79
80 /* open a connection and close it */
81 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
82 "port", 51188, NULL);
83 transport = THRIFT_TRANSPORT (tsocket);
84 thrift_socket_open (transport, NULL);
85 assert (thrift_socket_is_open (transport) == TRUE);
86 thrift_socket_close (transport, NULL);
87 assert (thrift_socket_is_open (transport) == FALSE);
88
89 /* test close failure */
90 tsocket->sd = -1;
91 thrift_socket_close (transport, NULL);
92 g_object_unref (tsocket);
93
94 /* try a hostname lookup failure */
95 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
96 NULL);
97 transport = THRIFT_TRANSPORT (tsocket);
98 assert (thrift_socket_open (transport, &err) == FALSE);
99 g_object_unref (tsocket);
100 g_error_free (err);
101 err = NULL;
102
103 /* try an error call to socket() */
104 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", NULL);
105 transport = THRIFT_TRANSPORT (tsocket);
106 socket_error = 1;
107 assert (thrift_socket_open (transport, &err) == FALSE);
108 socket_error = 0;
109 g_object_unref (tsocket);
110 g_error_free (err);
111}
112
113static void
114test_read_and_write(void)
115{
116 int status;
117 pid_t pid;
118 ThriftSocket *tsocket = NULL;
119 ThriftTransport *transport = NULL;
120 int port = 51199;
121 guchar buf[10] = TEST_DATA; /* a buffer */
122
123 pid = fork ();
124 assert ( pid >= 0 );
125
126 if ( pid == 0 )
127 {
128 /* child listens */
129 thrift_socket_server (port);
130 exit (0);
131 } else {
132 /* parent connects, wait a bit for the socket to be created */
133 sleep (1);
134
135 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
136 "port", port, NULL);
137 transport = THRIFT_TRANSPORT (tsocket);
138 assert (thrift_socket_open (transport, NULL) == TRUE);
139 assert (thrift_socket_is_open (transport));
140 thrift_socket_write (transport, buf, 10, NULL);
141
142 /* write fail */
143 send_error = 1;
144 thrift_socket_write (transport, buf, 1, NULL);
145 send_error = 0;
146
147 thrift_socket_write_end (transport, NULL);
148 thrift_socket_flush (transport, NULL);
149 thrift_socket_close (transport, NULL);
150 g_object_unref (tsocket);
151
152 assert ( wait (&status) == pid );
153 assert ( status == 0 );
154 }
155}
156
157static void
158thrift_socket_server (const int port)
159{
160 int bytes = 0;
161 ThriftServerTransport *transport = NULL;
162 ThriftTransport *client = NULL;
163 guchar buf[10]; /* a buffer */
164 guchar match[10] = TEST_DATA;
165
166 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
167 "port", port, NULL);
168
169 transport = THRIFT_SERVER_TRANSPORT (tsocket);
170 thrift_server_transport_listen (transport, NULL);
171 client = thrift_server_transport_accept (transport, NULL);
172 assert (client != NULL);
173
174 /* read 10 bytes */
175 bytes = thrift_socket_read (client, buf, 10, NULL);
176 assert (bytes == 10); /* make sure we've read 10 bytes */
177 assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */
178
179 /* failed read */
180 recv_error = 1;
181 thrift_socket_read (client, buf, 1, NULL);
182 recv_error = 0;
183
184 thrift_socket_read_end (client, NULL);
185 thrift_socket_close (client, NULL);
186 g_object_unref (tsocket);
187 g_object_unref (client);
188}
189
190int
191main(void)
192{
193 g_type_init();
194 test_create_and_destroy();
195 test_open_and_close();
196 test_read_and_write();
197
198 return 0;
199}
200