Skip to content

Commit 151eabb

Browse files
committed
Add OS memory provider config tests
Testing a single NUMA node: - tests for protection flags except the UMF_PROTECTION_EXEC flag, - tests for numa modes except unsupported values, - tests for visibility.
1 parent c1c55b6 commit 151eabb

File tree

2 files changed

+206
-1
lines changed

2 files changed

+206
-1
lines changed

test/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2022-2023 Intel Corporation
1+
# Copyright (C) 2022-2024 Intel Corporation
22
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

@@ -105,4 +105,7 @@ if(UMF_BUILD_OS_MEMORY_PROVIDER AND LINUX) # OS-specific functions are implement
105105
add_umf_test(NAME memspace_numa
106106
SRCS memspace_numa.cpp
107107
LIBS numa)
108+
add_umf_test(NAME provider_os_memory_config
109+
SRCS provider_os_memory_config.cpp
110+
LIBS umf_utils numa)
108111
endif()

test/provider_os_memory_config.cpp

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
*
3+
* Copyright (C) 2024 Intel Corporation
4+
*
5+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
6+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
*
8+
*/
9+
10+
#include "base.hpp"
11+
#include "provider_os_memory_internal.h"
12+
13+
#include <numa.h>
14+
#include <numaif.h>
15+
16+
struct providerConfigTest : testing::Test {
17+
umf_memory_provider_handle_t provider = nullptr;
18+
umf_os_memory_provider_params_t params = {
19+
/* .protection = */ UMF_PROTECTION_READ | UMF_PROTECTION_WRITE,
20+
/* .visibility = */ UMF_VISIBILITY_PRIVATE,
21+
22+
// NUMA config
23+
/* .nodemask = */ NULL,
24+
/* .maxnode = */ 0,
25+
/* .numa_mode = */ UMF_NUMA_MODE_DEFAULT,
26+
/* .numa_flags = */ 0,
27+
28+
// others
29+
/* .traces = */ 1,
30+
};
31+
const size_t size = 128;
32+
void *ptr = nullptr;
33+
std::string dest = "destination";
34+
35+
void SetUp() override {
36+
int ret = numa_available();
37+
if (ret) {
38+
GTEST_SKIP() << "Test skipped, NUMA not available";
39+
}
40+
}
41+
42+
void TearDown() override {
43+
if (ptr) {
44+
umfMemoryProviderFree(provider, ptr, size);
45+
}
46+
if (provider) {
47+
umfMemoryProviderDestroy(provider);
48+
}
49+
}
50+
51+
void create_provider(umf_os_memory_provider_params_t *params) {
52+
auto res = umfMemoryProviderCreate(&UMF_OS_MEMORY_PROVIDER_OPS, params,
53+
&provider);
54+
ASSERT_EQ(res, UMF_RESULT_SUCCESS);
55+
ASSERT_NE(provider, nullptr);
56+
}
57+
58+
void allocate_memory() {
59+
auto res =
60+
umfMemoryProviderAlloc(provider, size, os_get_page_size(), &ptr);
61+
ASSERT_EQ(res, UMF_RESULT_SUCCESS);
62+
ASSERT_NE(ptr, nullptr);
63+
}
64+
65+
void read_memory() {
66+
dest.reserve(size);
67+
memcpy(dest.data(), ptr, size);
68+
for (int i = 0; i < size; ++i) {
69+
EXPECT_EQ(*(static_cast<char *>(ptr) + i), *(dest.data() + i));
70+
}
71+
}
72+
73+
void write_memory(std::string_view str) {
74+
memset(ptr, '\0', size);
75+
str.copy((char *)ptr, str.size());
76+
EXPECT_EQ(std::string_view((char *)ptr), str);
77+
}
78+
};
79+
80+
TEST_F(providerConfigTest, protection_flag_none) {
81+
// pages may not be accessed - PROT_NONE
82+
params.protection = UMF_PROTECTION_NONE;
83+
create_provider(&params);
84+
allocate_memory();
85+
86+
// read failure
87+
EXPECT_DEATH(read_memory(), "");
88+
89+
// write failure
90+
EXPECT_DEATH(write_memory("write string"), "");
91+
}
92+
93+
TEST_F(providerConfigTest, protection_flag_read) {
94+
// pages may be read - PROT_READ
95+
params.protection = UMF_PROTECTION_READ;
96+
create_provider(&params);
97+
allocate_memory();
98+
99+
// read success
100+
read_memory();
101+
102+
// write failure
103+
EXPECT_DEATH(write_memory("write string"), "");
104+
}
105+
106+
TEST_F(providerConfigTest, protection_flag_write) {
107+
// pages may be written to - PROT_WRITE
108+
params.protection = UMF_PROTECTION_WRITE;
109+
create_provider(&params);
110+
allocate_memory();
111+
112+
// write success
113+
write_memory("write string");
114+
}
115+
116+
TEST_F(providerConfigTest, protection_flag_read_write) {
117+
// pages may be read and written to - PROT_READ | PROT_WRITE
118+
params.protection = UMF_PROTECTION_READ | UMF_PROTECTION_WRITE;
119+
create_provider(&params);
120+
allocate_memory();
121+
122+
// read success
123+
read_memory();
124+
125+
// write success
126+
write_memory("write string");
127+
}
128+
129+
struct providerConfigTestNumaMode
130+
: providerConfigTest,
131+
testing::WithParamInterface<umf_numa_mode_t> {
132+
void SetUp() override {
133+
providerConfigTest::SetUp();
134+
params.numa_mode = GetParam();
135+
}
136+
};
137+
138+
INSTANTIATE_TEST_SUITE_P(numa_modes, providerConfigTestNumaMode,
139+
testing::Values(UMF_NUMA_MODE_DEFAULT,
140+
UMF_NUMA_MODE_BIND,
141+
UMF_NUMA_MODE_INTERLEAVE,
142+
UMF_NUMA_MODE_PREFERRED,
143+
UMF_NUMA_MODE_LOCAL));
144+
145+
TEST_P(providerConfigTestNumaMode, numa_modes) {
146+
if (params.numa_mode != UMF_NUMA_MODE_DEFAULT &&
147+
params.numa_mode != UMF_NUMA_MODE_LOCAL) {
148+
struct bitmask *allowed_nodes = numa_get_mems_allowed();
149+
params.nodemask = allowed_nodes->maskp;
150+
params.maxnode = allowed_nodes->size;
151+
}
152+
153+
create_provider(&params);
154+
allocate_memory();
155+
write_memory("write string");
156+
157+
int actual_mode = -1;
158+
long ret = get_mempolicy(&actual_mode, nullptr, 0, ptr, MPOL_F_ADDR);
159+
ASSERT_EQ(ret, 0);
160+
ASSERT_EQ(os_translate_numa_mode(params.numa_mode), actual_mode);
161+
}
162+
163+
struct providerConfigTestVisibility
164+
: providerConfigTest,
165+
testing::WithParamInterface<umf_mem_visibility_t> {
166+
std::string primary_str = "primary";
167+
std::string new_str = "new";
168+
std::string expected_str;
169+
170+
void SetUp() override {
171+
providerConfigTest::SetUp();
172+
params.visibility = GetParam();
173+
if (params.visibility == UMF_VISIBILITY_PRIVATE) {
174+
expected_str = primary_str;
175+
} else if (params.visibility == UMF_VISIBILITY_SHARED) {
176+
expected_str = new_str;
177+
}
178+
}
179+
};
180+
181+
INSTANTIATE_TEST_SUITE_P(visibility, providerConfigTestVisibility,
182+
testing::Values(UMF_VISIBILITY_PRIVATE,
183+
UMF_VISIBILITY_SHARED));
184+
185+
TEST_P(providerConfigTestVisibility, visibility) {
186+
create_provider(&params);
187+
allocate_memory();
188+
write_memory(primary_str);
189+
190+
int pid = fork();
191+
if (pid == 0) {
192+
// child process
193+
write_memory(new_str);
194+
} else if (pid > 0) {
195+
// main process
196+
int status;
197+
while (-1 == waitpid(0, &status, 0)) {
198+
// wait for the child process to complete
199+
}
200+
EXPECT_EQ(static_cast<char *>(ptr), expected_str);
201+
}
202+
}

0 commit comments

Comments
 (0)