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 <assert.h> 6#include <stdbool.h> 7 8#include <zircon/syscalls.h> 9#include <zircon/syscalls/object.h> 10#include <zircon/process.h> 11 12#include <unittest/unittest.h> 13 14// Test that VMO handles support user signals 15static bool vmo_signal_sanity_test(void) { 16 BEGIN_TEST; 17 18 zx_handle_t vmo = ZX_HANDLE_INVALID; 19 ASSERT_EQ(zx_vmo_create(4096, 0, &vmo), ZX_OK, ""); 20 ASSERT_NE(vmo, ZX_HANDLE_INVALID, "zx_vmo_create() failed"); 21 22 zx_signals_t out_signals = 0; 23 24 // This is not timing dependent, if this fails is not a flake. 25 ASSERT_EQ(zx_object_wait_one( 26 vmo, ZX_USER_SIGNAL_0, zx_deadline_after(2), &out_signals), ZX_ERR_TIMED_OUT, ""); 27 28 ASSERT_EQ(out_signals, ZX_VMO_ZERO_CHILDREN, "unexpected initial signal set"); 29 ASSERT_EQ(zx_object_signal(vmo, 0, ZX_USER_SIGNAL_0), ZX_OK, ""); 30 ASSERT_EQ(zx_object_wait_one( 31 vmo, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, &out_signals), ZX_OK, ""); 32 ASSERT_EQ( 33 out_signals, ZX_USER_SIGNAL_0 | ZX_VMO_ZERO_CHILDREN, 34 "ZX_USER_SIGNAL_0 not set after successful wait"); 35 36 ASSERT_EQ(zx_handle_close(vmo), ZX_OK, ""); 37 38 END_TEST; 39} 40 41static zx_status_t vmo_has_no_children(zx_handle_t vmo) { 42 zx_signals_t signals; 43 return zx_object_wait_one(vmo, ZX_VMO_ZERO_CHILDREN, ZX_TIME_INFINITE, &signals); 44} 45 46static zx_status_t vmo_has_children(zx_handle_t vmo) { 47 zx_signals_t signals; 48 zx_status_t res = zx_object_wait_one( 49 vmo, ZX_VMO_ZERO_CHILDREN, zx_deadline_after(2), &signals); 50 return (res == ZX_ERR_TIMED_OUT) ? ZX_OK : res; 51} 52 53static bool vmo_child_signal_clone_test(void) { 54 BEGIN_TEST; 55 56 zx_handle_t vmo = ZX_HANDLE_INVALID; 57 ASSERT_EQ(zx_vmo_create(4096u * 2, 0, &vmo), ZX_OK, ""); 58 ASSERT_NE(vmo, ZX_HANDLE_INVALID, ""); 59 60 zx_handle_t clone = ZX_HANDLE_INVALID; 61 zx_handle_t clone2 = ZX_HANDLE_INVALID; 62 63 // The waits below with timeout are not timing dependent, if this fails is not a flake. 64 65 for (int ix = 0; ix != 10; ++ix) { 66 ASSERT_EQ(vmo_has_no_children(vmo), ZX_OK, ""); 67 68 ASSERT_EQ(zx_vmo_clone( 69 vmo, ZX_VMO_CLONE_COPY_ON_WRITE, 0u, 4096u, &clone), ZX_OK, ""); 70 71 ASSERT_EQ(vmo_has_no_children(clone), ZX_OK, ""); 72 ASSERT_EQ(vmo_has_children(vmo), ZX_OK, ""); 73 74 ASSERT_EQ(zx_vmo_clone( 75 clone, ZX_VMO_CLONE_COPY_ON_WRITE, 0u, 4096u, &clone2), ZX_OK, ""); 76 77 ASSERT_EQ(vmo_has_no_children(clone2), ZX_OK, ""); 78 ASSERT_EQ(vmo_has_children(clone), ZX_OK, ""); 79 ASSERT_EQ(vmo_has_children(vmo), ZX_OK, ""); 80 81 ASSERT_EQ(zx_handle_close(clone), ZX_OK, ""); 82 ASSERT_EQ(vmo_has_children(vmo), ZX_OK, ""); 83 ASSERT_EQ(vmo_has_no_children(clone2), ZX_OK, ""); 84 85 ASSERT_EQ(zx_handle_close(clone2), ZX_OK, ""); 86 } 87 88 ASSERT_EQ(zx_handle_close(vmo), ZX_OK, ""); 89 90 END_TEST; 91} 92 93static bool vmo_child_signal_map_test(void) { 94 BEGIN_TEST; 95 96 zx_handle_t vmo = ZX_HANDLE_INVALID; 97 ASSERT_EQ(zx_vmo_create(4096u * 2, 0, &vmo), ZX_OK, ""); 98 ASSERT_NE(vmo, ZX_HANDLE_INVALID, ""); 99 100 zx_handle_t clone = ZX_HANDLE_INVALID; 101 102 zx_vm_option_t options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE; 103 104 for (int ix = 0; ix != 10; ++ix) { 105 ASSERT_EQ(vmo_has_no_children(vmo), ZX_OK, ""); 106 107 ASSERT_EQ(zx_vmo_clone( 108 vmo, ZX_VMO_CLONE_COPY_ON_WRITE, 0u, 4096u, &clone), ZX_OK, ""); 109 110 uintptr_t addr = 0; 111 ASSERT_EQ(zx_vmar_map( 112 zx_vmar_root_self(), options, 0u, clone, 0, 4096u, &addr), ZX_OK, ""); 113 114 ASSERT_EQ(vmo_has_children(vmo), ZX_OK, ""); 115 116 ASSERT_EQ(zx_handle_close(clone), ZX_OK, ""); 117 118 ASSERT_EQ(vmo_has_children(vmo), ZX_OK, ""); 119 120 ASSERT_EQ(zx_vmar_unmap(zx_vmar_root_self(), addr, 4096u), ZX_OK, ""); 121 } 122 123 ASSERT_EQ(zx_handle_close(vmo), ZX_OK, ""); 124 125 END_TEST; 126} 127 128BEGIN_TEST_CASE(vmo_signal_tests) 129RUN_TEST(vmo_signal_sanity_test) 130RUN_TEST(vmo_child_signal_clone_test) 131RUN_TEST(vmo_child_signal_map_test) 132END_TEST_CASE(vmo_signal_tests) 133 134#ifndef BUILD_COMBINED_TESTS 135int main(int argc, char** argv) { 136 return unittest_run_all_tests(argc, argv) ? 0 : -1; 137} 138#endif 139