1 // Copyright (C) 2016 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "aemu/base/memory/SharedMemory.h"
16 
17 #include <gtest/gtest.h>
18 
19 #include <type_traits>
20 #include <utility>
21 
22 namespace android {
23 namespace base {
24 
TEST(SharedMemory,ShareVisibileWithinSameProc)25 TEST(SharedMemory, ShareVisibileWithinSameProc) {
26     const mode_t user_read_only = 0600;
27     std::string unique_name = "tst_21654869810548";
28     std::string message = "Hello World!";
29     base::SharedMemory mWriter(unique_name, message.size());
30     base::SharedMemory mReader(unique_name, message.size());
31 
32     ASSERT_FALSE(mWriter.isOpen());
33     ASSERT_FALSE(mReader.isOpen());
34 
35     int err = mWriter.create(user_read_only);
36     ASSERT_EQ(0, err);
37     err = mReader.open(SharedMemory::AccessMode::READ_ONLY);
38     ASSERT_EQ(0, err);
39 
40     ASSERT_TRUE(mWriter.isOpen());
41     ASSERT_TRUE(mReader.isOpen());
42 
43     memcpy(*mWriter, message.c_str(), message.size());
44     std::string read(static_cast<const char*>(*mReader));
45     ASSERT_TRUE(message == read);
46 
47     mWriter.close();
48     mReader.close();
49     ASSERT_FALSE(mWriter.isOpen());
50     ASSERT_FALSE(mReader.isOpen());
51 }
52 
53 // TODO: Provide support for TestSystem.
54 // TEST(SharedMemory, ShareFileBackedVisibileWithinSameProc) {
55 //     android::base::TestSystem ts("/home", 64);
56 //     // Note the unicode character in the filename below!!
57 //     std::string unique_name = android::base::PathUtils::join(
58 //             ts.getTempRoot()->path(), "shāred.mem");
59 //     const mode_t user_read_only = 0600;
60 //     std::string message = "Hello World!";
61 //     base::SharedMemory mWriter("file:///" + unique_name, message.size());
62 //     base::SharedMemory mReader("file:///" + unique_name, message.size());
63 //
64 //     ASSERT_FALSE(mWriter.isOpen());
65 //     ASSERT_FALSE(mReader.isOpen());
66 //
67 //     int err = mWriter.create(user_read_only);
68 //     ASSERT_EQ(0, err);
69 //     err = mReader.open(SharedMemory::AccessMode::READ_ONLY);
70 //     ASSERT_EQ(0, err);
71 //
72 //     ASSERT_TRUE(mWriter.isOpen());
73 //     ASSERT_TRUE(mReader.isOpen());
74 //
75 //     memcpy(*mWriter, message.c_str(), message.size());
76 //     std::string read(static_cast<const char*>(*mReader));
77 //
78 //     EXPECT_EQ(message, read);
79 //
80 //     mWriter.close();
81 //     mReader.close();
82 //     ASSERT_FALSE(mWriter.isOpen());
83 //     ASSERT_FALSE(mReader.isOpen());
84 // }
85 
86 // TEST(SharedMemory, ShareFileCanReadAfterDelete) {
87 //     // Make sure you can still read the memory, even if the server has marked
88 //     // the file for deletion.
89 //     android::base::TestSystem ts("/home", 64);
90 //     // Note the unicode character in the filename below!!
91 //     std::string unique_name = android::base::PathUtils::join(
92 //             ts.getTempRoot()->path(), "shāred.mem");
93 //     const mode_t user_read_only = 0600;
94 //     std::string message = "Hello World!";
95 //     base::SharedMemory mWriter("file://" + unique_name, message.size());
96 //     base::SharedMemory mReader("file://" + unique_name, message.size());
97 //
98 //     ASSERT_FALSE(mWriter.isOpen());
99 //     ASSERT_FALSE(mReader.isOpen());
100 //
101 //     mWriter.create(user_read_only);
102 //     memcpy(*mWriter, message.c_str(), message.size());
103 //
104 //     mReader.open(SharedMemory::AccessMode::READ_ONLY);
105 //     mWriter.close();
106 //
107 //     std::string read(static_cast<const char*>(*mReader));
108 //     ASSERT_TRUE(message == read);
109 //
110 //     mReader.close();
111 // }
112 
113 // TEST(SharedMemory, ShareFileDoesCleanedUp) {
114 //     // Make sure that the file gets removed after the server closes down.
115 //     android::base::TestSystem ts("/home", 64);
116 //     std::string unique_name = android::base::PathUtils::join(
117 //             ts.getTempRoot()->path(), "shared.mem");
118 //     const mode_t user_read_only = 0600;
119 //     std::string message = "Hello World!";
120 //     base::SharedMemory mWriter("file://" + unique_name, message.size());
121 //
122 //     ASSERT_FALSE(mWriter.isOpen());
123 //     mWriter.create(user_read_only);
124 //     memcpy(*mWriter, message.c_str(), message.size());
125 //     ASSERT_TRUE(ts.host()->pathExists(unique_name));
126 //     mWriter.close();
127 //     ASSERT_FALSE(ts.host()->pathExists(unique_name));
128 // }
129 
130 // TEST(SharedMemory, CanShare4KVideo) {
131 //     // Make sure we can use this for sharing video, for now 4K ought to be
132 //     // enough for anybody.
133 //     // This test will likely segfault/fail on a default MacOS config when using
134 //     // shared memory.
135 //     //
136 //     // See:  sysctl -A | grep shm
137 //     // which should produce something like:
138 //     // kern.sysv.shmmax: 4194304
139 //     // kern.sysv.shmmin: 1
140 //     // kern.sysv.shmmni: 32
141 //     // kern.sysv.shmseg: 8
142 //     // kern.sysv.shmall: 1024
143 //
144 //     const int FourK = 3840 * 2160 * 4; // 4k resolution with 4 bytes per pixel.
145 //     android::base::TestSystem ts("/home", FourK);
146 //     std::string unique_name = android::base::PathUtils::join(
147 //             ts.getTempRoot()->path(), "shared.mem");
148 //     const mode_t user_read_only = 0600;
149 //     std::string message = "Hello World!";
150 //     base::SharedMemory mWriter("file://" + unique_name, message.size());
151 //
152 //     ASSERT_FALSE(mWriter.isOpen());
153 //     mWriter.create(user_read_only);
154 //     memcpy(*mWriter, message.c_str(), message.size());
155 //     ASSERT_TRUE(ts.host()->pathExists(unique_name));
156 //     mWriter.close();
157 //     ASSERT_FALSE(ts.host()->pathExists(unique_name));
158 // }
159 
TEST(SharedMemory,CannotOpenTwice)160 TEST(SharedMemory, CannotOpenTwice) {
161     const mode_t user_read_only = 0600;
162     std::string unique_name = "tst_21654869810548";
163     std::string message = "Hello World!";
164     base::SharedMemory mWriter(unique_name, message.size());
165     base::SharedMemory mReader(unique_name, message.size());
166     int err = mWriter.create(user_read_only);
167     ASSERT_EQ(0, err);
168     err = mReader.open(SharedMemory::AccessMode::READ_ONLY);
169     ASSERT_EQ(0, err);
170 
171     // Second create should fail..
172     err = mWriter.create(user_read_only);
173     ASSERT_NE(0, err);
174 
175     // Second open should fail..
176     err = mReader.open(SharedMemory::AccessMode::READ_ONLY);
177     ASSERT_NE(0, err);
178 }
179 
TEST(SharedMemory,CreateNoMapping)180 TEST(SharedMemory, CreateNoMapping) {
181     const mode_t user_read_write = 0755;
182     std::string name = "tst_21654869810548";
183     base::SharedMemory mem(name, 256);
184 
185     ASSERT_FALSE(mem.isOpen());
186 
187     int err = mem.createNoMapping(user_read_write);
188     ASSERT_EQ(0, err);
189 
190     ASSERT_FALSE(mem.isMapped());
191 
192     mem.close();
193     ASSERT_FALSE(mem.isOpen());
194 }
195 
196 }  // namespace base
197 }  // namespace android
198