TestShmem.cpp (3911B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * Test sending and receiving Shmem values. 9 */ 10 11 #include "gtest/gtest.h" 12 13 #include "mozilla/_ipdltest/IPDLUnitTest.h" 14 #include "mozilla/_ipdltest/PTestShmemChild.h" 15 #include "mozilla/_ipdltest/PTestShmemParent.h" 16 17 using namespace mozilla::ipc; 18 19 namespace mozilla::_ipdltest { 20 21 class TestShmemParent : public PTestShmemParent { 22 NS_INLINE_DECL_REFCOUNTING(TestShmemParent, override) 23 private: 24 IPCResult RecvTake(Shmem&& mem, Shmem&& unsafe, 25 const uint32_t& expectedSize) final override { 26 EXPECT_EQ(mem.Size<char>(), expectedSize) 27 << "expected shmem size " << expectedSize << ", but it has size " 28 << mem.Size<char>(); 29 EXPECT_EQ(unsafe.Size<char>(), expectedSize) 30 << "expected shmem size " << expectedSize << ", but it has size " 31 << unsafe.Size<char>(); 32 33 EXPECT_FALSE(strcmp(mem.get<char>(), "And yourself!")) 34 << "expected message was not written"; 35 EXPECT_FALSE(strcmp(unsafe.get<char>(), "And yourself!")) 36 << "expected message was not written"; 37 38 EXPECT_TRUE(DeallocShmem(mem)); 39 EXPECT_TRUE(DeallocShmem(unsafe)); 40 41 Close(); 42 43 return IPC_OK(); 44 } 45 46 ~TestShmemParent() = default; 47 }; 48 49 class TestShmemChild : public PTestShmemChild { 50 NS_INLINE_DECL_REFCOUNTING(TestShmemChild, override) 51 private: 52 IPCResult RecvGive(Shmem&& mem, Shmem&& unsafe, 53 const uint32_t& expectedSize) final override { 54 EXPECT_EQ(mem.Size<char>(), expectedSize) 55 << "expected shmem size " << expectedSize << ", but it has size " 56 << mem.Size<char>(); 57 EXPECT_EQ(unsafe.Size<char>(), expectedSize) 58 << "expected shmem size " << expectedSize << ", but it has size " 59 << unsafe.Size<char>(); 60 61 EXPECT_FALSE(strcmp(mem.get<char>(), "Hello!")) 62 << "expected message was not written"; 63 EXPECT_FALSE(strcmp(unsafe.get<char>(), "Hello!")) 64 << "expected message was not written"; 65 66 char* unsafeptr = unsafe.get<char>(); 67 68 memcpy(mem.get<char>(), "And yourself!", sizeof("And yourself!")); 69 memcpy(unsafeptr, "And yourself!", sizeof("And yourself!")); 70 71 Shmem unsafecopy = unsafe; 72 EXPECT_TRUE(SendTake(std::move(mem), std::move(unsafe), expectedSize)); 73 74 // these checks also shouldn't fail in the child 75 char uc1 = *unsafeptr; 76 (void)uc1; 77 char uc2 = *unsafecopy.get<char>(); 78 (void)uc2; 79 80 return IPC_OK(); 81 } 82 83 ~TestShmemChild() = default; 84 }; 85 86 IPDL_TEST(TestShmem) { 87 Shmem mem; 88 Shmem unsafe; 89 90 uint32_t size = 12345; 91 EXPECT_TRUE(mActor->AllocShmem(size, &mem)) << "can't alloc shmem"; 92 EXPECT_TRUE(mActor->AllocUnsafeShmem(size, &unsafe)) << "can't alloc shmem"; 93 94 EXPECT_EQ(mem.Size<char>(), size) << "shmem is wrong size: expected " << size 95 << ", got " << mem.Size<char>(); 96 EXPECT_EQ(unsafe.Size<char>(), size) 97 << "shmem is wrong size: expected " << size << ", got " 98 << unsafe.Size<char>(); 99 100 char* ptr = mem.get<char>(); 101 memcpy(ptr, "Hello!", sizeof("Hello!")); 102 103 char* unsafeptr = unsafe.get<char>(); 104 memcpy(unsafeptr, "Hello!", sizeof("Hello!")); 105 106 Shmem unsafecopy = unsafe; 107 EXPECT_TRUE(mActor->SendGive(std::move(mem), std::move(unsafe), size)); 108 109 // uncomment the following line for a (nondeterministic) surprise! 110 // char c1 = *ptr; (void)c1; 111 112 // uncomment the following line for a deterministic surprise! 113 // char c2 = *mem.get<char>(); (void)c2; 114 115 // unsafe shmem gets rid of those checks 116 char uc1 = *unsafeptr; 117 (void)uc1; 118 char uc2 = *unsafecopy.get<char>(); 119 (void)uc2; 120 } 121 122 } // namespace mozilla::_ipdltest