blob: 41aa445fc113ec3bfbc4ece47e3b71c3636e11bf [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <assert.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/process.h>
#include <zxtest/zxtest.h>
namespace {
// Test that VMO handles support user signals
TEST(VmoSignalTestCase, SignalSanity) {
zx_handle_t vmo = ZX_HANDLE_INVALID;
ASSERT_OK(zx_vmo_create(4096, 0, &vmo), "");
ASSERT_NE(vmo, ZX_HANDLE_INVALID, "zx_vmo_create() failed");
zx_signals_t out_signals = 0;
// This is not timing dependent, if this fails is not a flake.
ASSERT_EQ(zx_object_wait_one(vmo, ZX_USER_SIGNAL_0, zx_deadline_after(2), &out_signals),
ZX_ERR_TIMED_OUT, "");
ASSERT_EQ(out_signals, ZX_VMO_ZERO_CHILDREN, "unexpected initial signal set");
ASSERT_OK(zx_object_signal(vmo, 0, ZX_USER_SIGNAL_0), "");
ASSERT_OK(zx_object_wait_one(vmo, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, &out_signals), "");
ASSERT_EQ(out_signals, ZX_USER_SIGNAL_0 | ZX_VMO_ZERO_CHILDREN,
"ZX_USER_SIGNAL_0 not set after successful wait");
ASSERT_OK(zx_handle_close(vmo), "");
}
zx_status_t VmoHasNoChildren(zx_handle_t vmo) {
zx_signals_t signals;
return zx_object_wait_one(vmo, ZX_VMO_ZERO_CHILDREN, ZX_TIME_INFINITE, &signals);
}
zx_status_t VmoHasChildren(zx_handle_t vmo) {
zx_signals_t signals;
zx_status_t res = zx_object_wait_one(vmo, ZX_VMO_ZERO_CHILDREN, zx_deadline_after(2), &signals);
return (res == ZX_ERR_TIMED_OUT) ? ZX_OK : res;
}
TEST(VmoSignalTestCase, ChildSignalClone) {
zx_handle_t vmo = ZX_HANDLE_INVALID;
ASSERT_OK(zx_vmo_create(4096u * 2, 0, &vmo), "");
ASSERT_NE(vmo, ZX_HANDLE_INVALID, "");
zx_handle_t clone = ZX_HANDLE_INVALID;
zx_handle_t clone2 = ZX_HANDLE_INVALID;
// The waits below with timeout are not timing dependent, if this fails is not a flake.
for (int ix = 0; ix != 10; ++ix) {
ASSERT_OK(VmoHasNoChildren(vmo), "");
ASSERT_OK(zx_vmo_create_child(vmo, ZX_VMO_CHILD_SNAPSHOT, 0u, 4096u, &clone), "");
ASSERT_OK(VmoHasNoChildren(clone), "");
ASSERT_OK(VmoHasChildren(vmo), "");
ASSERT_OK(zx_vmo_create_child(clone, ZX_VMO_CHILD_SNAPSHOT, 0u, 4096u, &clone2), "");
ASSERT_OK(VmoHasNoChildren(clone2), "");
ASSERT_OK(VmoHasChildren(clone), "");
ASSERT_OK(VmoHasChildren(vmo), "");
ASSERT_OK(zx_handle_close(clone), "");
ASSERT_OK(VmoHasChildren(vmo), "");
ASSERT_OK(VmoHasNoChildren(clone2), "");
ASSERT_OK(zx_handle_close(clone2), "");
}
ASSERT_OK(zx_handle_close(vmo), "");
}
TEST(VmoSignalTestCase, ChildSignalMap) {
zx_handle_t vmo = ZX_HANDLE_INVALID;
ASSERT_OK(zx_vmo_create(4096u * 2, 0, &vmo), "");
ASSERT_NE(vmo, ZX_HANDLE_INVALID, "");
zx_handle_t clone = ZX_HANDLE_INVALID;
zx_vm_option_t options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
for (int ix = 0; ix != 10; ++ix) {
ASSERT_OK(VmoHasNoChildren(vmo), "");
ASSERT_OK(zx_vmo_create_child(vmo, ZX_VMO_CHILD_SNAPSHOT, 0u, 4096u, &clone), "");
uintptr_t addr = 0;
ASSERT_OK(zx_vmar_map(zx_vmar_root_self(), options, 0u, clone, 0, 4096u, &addr), "");
ASSERT_OK(VmoHasChildren(vmo), "");
ASSERT_OK(zx_handle_close(clone), "");
ASSERT_OK(VmoHasChildren(vmo), "");
ASSERT_OK(zx_vmar_unmap(zx_vmar_root_self(), addr, 4096u), "");
}
ASSERT_OK(zx_handle_close(vmo), "");
}
} // namespace