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 static const gchar TEST_DATA[12] = "abcde01234!";
33
34 static void
test_create_and_destroy(void)35 test_create_and_destroy (void)
36 {
37 GObject *object;
38 object = g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", -1, NULL);
39 g_assert (object != NULL);
40 g_object_unref (object);
41 }
42
43 static void
test_open_and_close(void)44 test_open_and_close (void)
45 {
46 ThriftTransport *transport;
47 ThriftTransportClass *klass;
48 GError *error;
49 gint fd;
50 gchar *filename;
51
52 error = NULL;
53 filename = NULL;
54
55 fd = g_file_open_tmp (NULL, &filename, &error);
56 g_assert (fd >= 0);
57
58 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
59 "fd", fd,
60 NULL));
61 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
62
63 /* open is no-op */
64 g_assert (klass->is_open (transport));
65 g_assert (klass->peek (transport, &error));
66 g_assert (klass->open (transport, &error));
67 g_assert (klass->is_open (transport));
68 g_assert (klass->peek (transport, &error));
69
70 g_assert (klass->close (transport, &error));
71 g_assert (! klass->open (transport, &error));
72 g_assert (! klass->is_open (transport));
73 g_assert (! klass->peek (transport, &error));
74
75 /* already closed */
76 g_assert (close (fd) != 0);
77 g_assert (errno == EBADF);
78
79 g_object_unref (transport);
80
81 g_remove (filename);
82 g_free (filename);
83
84 /* test bad fd */
85 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
86 "fd", -1,
87 NULL));
88 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
89
90 g_assert (! klass->is_open (transport));
91 error = NULL;
92 g_assert (! klass->peek (transport, &error));
93 error = NULL;
94 g_assert (! klass->open (transport, &error));
95 error = NULL;
96 g_assert (! klass->close (transport, &error));
97
98 g_object_unref (transport);
99 }
100
101 static void
test_read_and_write(void)102 test_read_and_write (void)
103 {
104 gchar out_buf[8];
105 gchar *b;
106 gint want, got;
107 ThriftTransport *transport;
108 ThriftTransportClass *klass;
109 GError *error;
110 gint fd;
111 gchar *filename;
112
113 error = NULL;
114 filename = NULL;
115
116 fd = g_file_open_tmp (NULL, &filename, &error);
117 g_assert (fd >= 0);
118
119 /* write */
120 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
121 "fd", fd,
122 NULL));
123 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
124 g_assert (klass->is_open (transport));
125 g_assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error));
126 g_assert (klass->flush (transport, &error));
127 g_assert (klass->close (transport, &error));
128 g_object_unref (transport);
129
130 /* read */
131 fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR);
132 g_assert (fd >= 0);
133
134 transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT,
135 "fd", fd,
136 NULL));
137 klass = THRIFT_TRANSPORT_GET_CLASS (transport);
138
139 memset(out_buf, 0, 8);
140 b = out_buf;
141 want = 7;
142 while (want > 0) {
143 got = klass->read (transport, (gpointer) b, want, &error);
144 g_assert (got > 0 && got <= want);
145 b += got;
146 want -= got;
147 }
148 g_assert (memcmp (out_buf, TEST_DATA, 7) == 0);
149
150 memset(out_buf, 0, 8);
151 b = out_buf;
152 want = 4;
153 while (want > 0) {
154 got = klass->read (transport, (gpointer) b, want, &error);
155 g_assert (got > 0 && got <= want);
156 b += got;
157 want -= got;
158 }
159 g_assert (memcmp (out_buf, TEST_DATA + 7, 4) == 0);
160
161 g_assert (klass->close (transport, &error));
162 g_object_unref (transport);
163
164 /* clean up */
165
166 g_remove (filename);
167 g_free (filename);
168 }
169
170 int
main(int argc,char * argv[])171 main (int argc, char *argv[])
172 {
173 #if (!GLIB_CHECK_VERSION (2, 36, 0))
174 g_type_init ();
175 #endif
176
177 g_test_init (&argc, &argv, NULL);
178
179 g_test_add_func ("/testfdtransport/CreateAndDestroy", test_create_and_destroy);
180 g_test_add_func ("/testfdtransport/OpenAndClose", test_open_and_close);
181 g_test_add_func ("/testfdtransport/ReadAndWrite", test_read_and_write);
182
183 return g_test_run ();
184 }
185