1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdio.h>
6 #include <unistd.h>
7 
8 #include <zircon/syscalls.h>
9 #include <zircon/types.h>
10 #include <unittest/unittest.h>
11 
12 static const char* msg = "This is a test message, please discard.";
13 
cleanup_test(void)14 bool cleanup_test(void) {
15     BEGIN_TEST;
16     zx_handle_t p0[2], p1[2];
17     zx_signals_t pending;
18     zx_status_t r;
19 
20     // TEST1
21     // Create a channel, close one end, try to wait on the other.
22     r = zx_channel_create(0, p1, p1 + 1);
23     ASSERT_EQ(r, ZX_OK, "cleanup-test: channel create 1 failed");
24 
25     zx_handle_close(p1[1]);
26     unittest_printf("cleanup-test: about to wait, should return with PEER_CLOSED\n");
27     r = zx_object_wait_one(p1[0], ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
28                                  ZX_TIME_INFINITE, &pending);
29     ASSERT_EQ(r, ZX_OK, "cleanup-test: FAILED");
30 
31     ASSERT_EQ(pending, ZX_CHANNEL_PEER_CLOSED, "cleanup-test: FAILED");
32     unittest_printf("cleanup-test: SUCCESS, observed PEER_CLOSED signal\n\n");
33     zx_handle_close(p1[0]);
34 
35     // TEST2
36     // Create a channel, close one end. Then create an event and write a
37     // message on the channel sending the event along. See that the write
38     // fails (because the other end is closed) and that the event is
39     // consumed (because the write failed).
40     r = zx_channel_create(0, p1, p1 + 1);
41     ASSERT_EQ(r, ZX_OK, "cleanup-test: channel create 1 failed");
42     zx_handle_close(p1[1]);
43 
44     zx_handle_t event = ZX_HANDLE_INVALID;
45     r = zx_event_create(0u, &event);
46     ASSERT_EQ(r, ZX_OK, "");
47     ASSERT_NE(event, ZX_HANDLE_INVALID, "cleanup-test: event create failed");
48     r = zx_channel_write(p1[0], 0, &msg, sizeof(msg), &event, 1);
49     ASSERT_EQ(r, ZX_ERR_PEER_CLOSED, "cleanup-test: unexpected message_write return code");
50 
51     r = zx_object_signal(event, 0u, ZX_EVENT_SIGNALED);
52     ASSERT_EQ(r, ZX_ERR_BAD_HANDLE, "cleanup-test: able to signal event!");
53     unittest_printf("cleanup-test: SUCCESS, event is closed\n\n");
54 
55     zx_handle_close(p1[0]);
56 
57     // TEST3
58     // Simulates the case where we prepare a message channel with a
59     // message+channelhandle already in it and the far end closed,
60     // like we pass to newly created processes, but then (say
61     // process creation fails), we delete the other end of the
62     // channel we were going to send.  At this point we expect
63     // that the channel handle bundled with the message should
64     // be closed and waiting on the opposing handle should
65     // signal PEER_CLOSED.
66     r = zx_channel_create(0, p0, p0 + 1);
67     ASSERT_EQ(r, ZX_OK, "cleanup-test: channel create 0 failed");
68 
69     r = zx_channel_create(0, p1, p1 + 1);
70     ASSERT_EQ(r, ZX_OK, "cleanup-test: channel create 1 failed");
71 
72     r = zx_channel_write(p0[0], 0, &msg, sizeof(msg), &p1[1], 1);
73     ASSERT_EQ(r, ZX_OK, "cleanup-test: channel write failed");
74 
75     zx_handle_close(p0[0]);
76     zx_handle_close(p0[1]);
77 
78     unittest_printf("cleanup-test: about to wait, should return with PEER_CLOSED\n");
79     r = zx_object_wait_one(p1[0], ZX_CHANNEL_PEER_CLOSED, ZX_TIME_INFINITE, NULL);
80     ASSERT_EQ(r, ZX_OK, "cleanup-test: FAILED");
81 
82     unittest_printf("cleanup-test: PASSED\n");
83     zx_handle_close(p1[0]);
84     END_TEST;
85 }
86 
87 BEGIN_TEST_CASE(cleanup_tests)
RUN_TEST(cleanup_test)88 RUN_TEST(cleanup_test)
89 END_TEST_CASE(cleanup_tests)
90 
91 int main(int argc, char** argv) {
92     return unittest_run_all_tests(argc, argv) ? 0 : -1;
93 }
94