1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20
21 #include <string.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <unistd.h>
25
26 #include <glib.h>
27 #include <glib/gstdio.h>
28
29 #include <thrift/c_glib/transport/thrift_transport.h>
30 #include <thrift/c_glib/transport/thrift_fd_transport.h>
31
32 #define MAX_MESSAGE_SIZE 2
33
34 static const gchar TEST_DATA[12] = "abcde01234!";
35
36 static void
test_open_and_close(void)37 test_open_and_close (void)
38 {
39 ThriftConfiguration *configuration;
40 ThriftTransport *transport;
41 ThriftTransportClass *klass;
42 GError *error;
43 gint fd;
44 gchar *filename;
45
46 error = NULL;
47 filename = NULL;
48
49 fd = g_file_open_tmp (NULL, &filename, &error);
50 g_assert (fd >= 0);
51
52 configuration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE,
53 "max_frame_size", MAX_MESSAGE_SIZE, NULL);
54
55 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
56 "configuration", configuration, "fd", fd,
57 NULL));
58 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
59
60 /* open is no-op */
61 g_assert (klass->is_open (transport));
62 g_assert (klass->peek (transport, &error));
63 g_assert (klass->open (transport, &error));
64 g_assert (klass->is_open (transport));
65 g_assert (klass->peek (transport, &error));
66
67 g_assert (klass->close (transport, &error));
68 g_assert (! klass->open (transport, &error));
69 g_assert (! klass->is_open (transport));
70 g_assert (! klass->peek (transport, &error));
71
72 /* already closed */
73 g_assert (close (fd) != 0);
74 g_assert (errno == EBADF);
75
76 g_object_unref (transport);
77 g_object_unref (configuration);
78
79 g_remove (filename);
80 g_free (filename);
81
82 /* test bad fd */
83 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
84 "fd", -1,
85 NULL));
86 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
87
88 g_assert (! klass->is_open (transport));
89 error = NULL;
90 g_assert (! klass->peek (transport, &error));
91 error = NULL;
92 g_assert (! klass->open (transport, &error));
93 error = NULL;
94 g_assert (! klass->close (transport, &error));
95
96 g_object_unref (transport);
97 }
98
99 static void
test_read_and_write(void)100 test_read_and_write (void)
101 {
102 gchar out_buf[8];
103 gchar *b;
104 gint want, got;
105 ThriftConfiguration *configuration;
106 ThriftTransport *transport;
107 ThriftTransportClass *klass;
108 GError *error;
109 gint fd;
110 gchar *filename;
111
112 error = NULL;
113 filename = NULL;
114
115 fd = g_file_open_tmp (NULL, &filename, &error);
116 g_assert (fd >= 0);
117
118 configuration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE,
119 "max_frame_size", MAX_MESSAGE_SIZE, NULL);
120 /* write */
121 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
122 "configuration", configuration, "fd", fd,
123 NULL));
124 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
125 g_assert (klass->is_open (transport));
126 g_assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error));
127 g_assert (klass->flush (transport, &error));
128 g_assert (klass->close (transport, &error));
129 g_object_unref (transport);
130
131 /* read */
132 fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR);
133 g_assert (fd >= 0);
134
135 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
136 "configuration", configuration,
137 "remainingmessagesize", MAX_MESSAGE_SIZE,
138 "fd", fd,
139 NULL));
140 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
141
142 memset(out_buf, 0, 8);
143 b = out_buf;
144 want = 2;
145 while (want > 0) {
146 got = klass->read (transport, (gpointer) b, want, &error);
147 g_assert (got > 0 && got <= want);
148 b += got;
149 want -= got;
150 }
151 g_assert (memcmp (out_buf, TEST_DATA, 2) == 0);
152
153 memset(out_buf, 0, 8);
154 b = out_buf;
155 want = 4;
156 got = klass->read (transport, (gpointer) b, want, &error);
157 g_assert (got < 0);
158
159 g_assert (klass->close (transport, &error));
160 g_object_unref (transport);
161 g_object_unref (configuration);
162
163 /* clean up */
164
165 g_remove (filename);
166 g_free (filename);
167 }
168
169 int
main(int argc,char * argv[])170 main (int argc, char *argv[])
171 {
172 #if (!GLIB_CHECK_VERSION (2, 36, 0))
173 g_type_init ();
174 #endif
175
176 g_test_init (&argc, &argv, NULL);
177
178 g_test_add_func ("/testfdtransport/OpenAndClose", test_open_and_close);
179 g_test_add_func ("/testfdtransport/ReadAndWrite", test_read_and_write);
180
181 return g_test_run ();
182 }
183