1 /*
2 * Copyright © 2012-2020 Inria. All rights reserved.
3 * See COPYING in top-level directory.
4 */
5
6 #include "private/autogen/config.h" /* for HWLOC_WIN_SYS */
7 #include "hwloc.h"
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #ifdef HAVE_UNISTD_H
12 #include <unistd.h>
13 #endif
14 #include <string.h>
15 #include <errno.h>
16 #include <assert.h>
17
18 #ifndef HAVE_MKSTEMP
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include "private/misc.h" /* for S_IRWXU */
mkstemp(char * name)23 static inline int mkstemp(char *name)
24 {
25 mktemp(name);
26 return open(name, O_RDWR|O_CREAT, S_IRWXU);
27 }
28 #endif
29
30 /* mostly useful with valgrind, to check if backend cleanup properly */
31
get_backend_name(hwloc_topology_t topo)32 static const char *get_backend_name(hwloc_topology_t topo)
33 {
34 hwloc_obj_t root = hwloc_get_root_obj(topo);
35 return hwloc_obj_get_info_by_name(root, "Backend");
36 }
37
assert_backend_name(hwloc_topology_t topo,const char * wanted)38 static void assert_backend_name(hwloc_topology_t topo, const char *wanted)
39 {
40 const char *found = get_backend_name(topo);
41 int diff;
42 assert(found);
43 diff = strcmp(found, wanted);
44 assert(!diff);
45 }
46
assert_foo_bar(hwloc_topology_t topo,int setornot)47 static void assert_foo_bar(hwloc_topology_t topo, int setornot)
48 {
49 hwloc_obj_t root = hwloc_get_root_obj(topo);
50 const char *found = hwloc_obj_get_info_by_name(root, "Foo");
51 if (!setornot) {
52 assert(!found);
53 } else {
54 int diff;
55 assert(found);
56 diff = strcmp(found, "Bar");
57 assert(!diff);
58 }
59 }
60
main(void)61 int main(void)
62 {
63 hwloc_topology_t topology1, topology2;
64 char *xmlbuf;
65 int xmlbuflen;
66 char xmlfile[] = "hwloc_backends.tmpxml.XXXXXX";
67 char env[64];
68 int xmlbufok = 0, xmlfileok = 0, xmlfilefd;
69 const char *orig_backend_name;
70 int err;
71
72 putenv((char *) "HWLOC_LIBXML_CLEANUP=1");
73
74 printf("trying to export topology to XML buffer and file for later...\n");
75 hwloc_topology_init(&topology1);
76 hwloc_topology_load(topology1);
77 orig_backend_name = get_backend_name(topology1);
78 hwloc_obj_add_info(hwloc_get_root_obj(topology1), "Foo", "Bar");
79 assert(hwloc_topology_is_thissystem(topology1));
80 if (hwloc_topology_export_xmlbuffer(topology1, &xmlbuf, &xmlbuflen, 0) < 0)
81 printf("XML buffer export failed (%s), ignoring\n", strerror(errno));
82 else
83 xmlbufok = 1;
84 xmlfilefd = mkstemp(xmlfile);
85 if (xmlfilefd < 0 || hwloc_topology_export_xml(topology1, xmlfile, 0) < 0)
86 printf("XML file export failed (%s), ignoring\n", strerror(errno));
87 else
88 xmlfileok = 1;
89
90
91 /* init+config+destroy without loading */
92 printf("init...\n");
93 hwloc_topology_init(&topology2);
94 if (xmlfileok) {
95 printf("switching to xml...\n");
96 assert(!hwloc_topology_set_xml(topology2, xmlfile));
97 }
98 if (xmlbufok) {
99 printf("switching to xmlbuffer...\n");
100 assert(!hwloc_topology_set_xmlbuffer(topology2, xmlbuf, xmlbuflen));
101 }
102 printf("switching to synthetic...\n");
103 hwloc_topology_set_synthetic(topology2, "pack:2 node:3 l1:2 pu:4");
104 hwloc_topology_destroy(topology2);
105
106 /* init+xml+load+destroy */
107 if (xmlfileok) {
108 printf("switching to xml and loading...\n");
109 hwloc_topology_init(&topology2);
110 assert(!hwloc_topology_set_xml(topology2, xmlfile));
111 hwloc_topology_load(topology2);
112 assert_backend_name(topology2, orig_backend_name);
113 assert_foo_bar(topology2, 1);
114 hwloc_topology_check(topology2);
115 assert(!hwloc_topology_is_thissystem(topology2));
116 hwloc_topology_destroy(topology2);
117 }
118
119 /* init+xmlbuf+load+destroy */
120 if (xmlbufok) {
121 printf("switching to xmlbuffer and loading...\n");
122 hwloc_topology_init(&topology2);
123 assert(!hwloc_topology_set_xmlbuffer(topology2, xmlbuf, xmlbuflen));
124 hwloc_topology_load(topology2);
125 assert_backend_name(topology2, orig_backend_name);
126 assert_foo_bar(topology2, 1);
127 hwloc_topology_check(topology2);
128 assert(!hwloc_topology_is_thissystem(topology2));
129 hwloc_topology_destroy(topology2);
130 }
131
132 /* init+synthetic+load+destroy */
133 printf("switching to synthetic and loading...\n");
134 hwloc_topology_init(&topology2);
135 hwloc_topology_set_synthetic(topology2, "pack:2 node:3 l3i:2 pu:4");
136 hwloc_topology_load(topology2);
137 assert_backend_name(topology2, "Synthetic");
138 assert_foo_bar(topology2, 0);
139 assert(hwloc_get_nbobjs_by_type(topology2, HWLOC_OBJ_PU) == 2*3*2*4);
140 hwloc_topology_check(topology2);
141 assert(!hwloc_topology_is_thissystem(topology2));
142 hwloc_topology_destroy(topology2);
143
144 /* xmlenv+init+load+destroy */
145 if (xmlfileok) {
146 printf("switching to xml by env and loading...\n");
147 snprintf(env, sizeof(env), "HWLOC_XMLFILE=%s", xmlfile);
148 putenv(env);
149 hwloc_topology_init(&topology2);
150 hwloc_topology_load(topology2);
151 assert_backend_name(topology2, orig_backend_name);
152 assert_foo_bar(topology2, 1);
153 hwloc_topology_check(topology2);
154 assert(!hwloc_topology_is_thissystem(topology2));
155 hwloc_topology_destroy(topology2);
156 }
157
158 /* syntheticenv+init+load+destroy, synthetic env overrides xml */
159 printf("switching to synthetic by env and loading...\n");
160 putenv((char *) "HWLOC_SYNTHETIC=node:3 pu:3");
161 hwloc_topology_init(&topology2);
162 hwloc_topology_load(topology2);
163 assert_backend_name(topology2, "Synthetic");
164 assert_foo_bar(topology2, 0);
165 assert(hwloc_get_nbobjs_by_type(topology2, HWLOC_OBJ_PU) == 3*3);
166 hwloc_topology_check(topology2);
167 assert(!hwloc_topology_is_thissystem(topology2));
168 hwloc_topology_destroy(topology2);
169
170 /* componentsenv+init+load+destroy for testing defaults, overrides synthetic/xml/fsroot envs */
171 printf("switching to default components by env and loading...\n");
172 putenv((char *) "HWLOC_COMPONENTS=,"); /* don't set to empty since it means 'unset' on windows */
173 hwloc_topology_init(&topology2);
174 hwloc_topology_load(topology2);
175 assert_backend_name(topology2, orig_backend_name);
176 assert_foo_bar(topology2, 0);
177 hwloc_topology_check(topology2);
178 assert(hwloc_topology_is_thissystem(topology2));
179 hwloc_topology_destroy(topology2);
180
181 if (xmlbufok)
182 hwloc_free_xmlbuffer(topology1, xmlbuf);
183 if (xmlfilefd >= 0) {
184 unlink(xmlfile);
185 close(xmlfilefd);
186 }
187 hwloc_topology_destroy(topology1);
188
189 /* blacklist everything but noos with hwloc_topology_set_components() */
190 printf("disabling everything but noos with hwloc_topology_set_components()\n");
191 putenv((char *) "HWLOC_COMPONENTS="); /* means 'unset' on windows, which means HWLOC_XMLFILE and HWLOC_SYNTHETIC
192 * would be processed if not empty, so clear them too. */
193 putenv((char *) "HWLOC_XMLFILE=");
194 putenv((char *) "HWLOC_SYNTHETIC=");
195 hwloc_topology_init(&topology1);
196 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "foobar");
197 assert(err == -1);
198 assert(errno == EINVAL);
199 err = hwloc_topology_set_components(topology1, ~HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "synthetic");
200 assert(err == -1);
201 assert(errno == EINVAL);
202 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "synthetic");
203 assert(!err);
204 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "xml");
205 assert(!err);
206 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "x86");
207 #ifdef HWLOC_HAVE_X86_CPUID
208 assert(!err);
209 #else
210 assert(err == -1);
211 assert(errno == EINVAL);
212 #endif
213 #ifdef HWLOC_LINUX_SYS
214 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "linux:0xf");
215 assert(!err);
216 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "linux:0xfffffff0");
217 assert(!err);
218 #endif
219 #ifdef HWLOC_BGQ_SYS
220 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "bgq");
221 assert(!err);
222 #endif
223 #ifdef HWLOC_DARWIN_SYS
224 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "darwin");
225 assert(!err);
226 #endif
227 #ifdef HWLOC_SOLARIS_SYS
228 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "solaris");
229 assert(!err);
230 #endif
231 #ifdef HWLOC_AIX_SYS
232 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "aix");
233 assert(!err);
234 #endif
235 #ifdef HWLOC_HPUX_SYS
236 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "hpux");
237 assert(!err);
238 #endif
239 #ifdef HWLOC_WIN_SYS
240 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "windows");
241 assert(!err);
242 #endif
243 #ifdef HWLOC_FREEBSD_SYS
244 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "freebsd");
245 assert(!err);
246 #endif
247 #ifdef HWLOC_NETBSD_SYS
248 err = hwloc_topology_set_components(topology1, HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST, "netbsd");
249 assert(!err);
250 #endif
251 hwloc_topology_load(topology1);
252 assert(!get_backend_name(topology1)); /* noos doesn't put any Backend info attr */
253 hwloc_topology_check(topology1);
254 assert(hwloc_topology_is_thissystem(topology1));
255 hwloc_topology_destroy(topology1);
256
257 return 0;
258 }
259