docs: Reword virDomainGetEmulatorPinInfo description
[libvirt.git] / tests / virhostcputest.c
blobcf310cb4cec4c69376036ba230deccc5d8842aaf
1 #include <config.h>
3 #include <unistd.h>
4 #include <fcntl.h>
6 #include "testutils.h"
7 #include "internal.h"
8 #define LIBVIRT_VIRHOSTCPUPRIV_H_ALLOW
9 #include "virhostcpupriv.h"
10 #include "virfile.h"
11 #include "virfilewrapper.h"
13 #define VIR_FROM_THIS VIR_FROM_NONE
15 #define SYSFS_SYSTEM_PATH "/sys/devices/system"
17 #if !(defined __linux__)
19 int
20 main(void)
22 return EXIT_AM_SKIP;
25 #else
27 static int
28 linuxTestCompareFiles(const char *cpuinfofile,
29 virArch arch,
30 const char *outputfile)
32 g_autofree char *actualData = NULL;
33 virNodeInfo nodeinfo = { 0 };
34 g_autoptr(FILE) cpuinfo = NULL;
36 cpuinfo = fopen(cpuinfofile, "r");
37 if (!cpuinfo) {
38 fprintf(stderr, "unable to open: %s : %s\n",
39 cpuinfofile, g_strerror(errno));
40 return -1;
43 if (virHostCPUGetInfoPopulateLinux(cpuinfo, arch,
44 &nodeinfo.cpus, &nodeinfo.mhz,
45 &nodeinfo.nodes, &nodeinfo.sockets,
46 &nodeinfo.cores, &nodeinfo.threads) < 0) {
47 if (virTestGetDebug()) {
48 if (virGetLastErrorCode())
49 VIR_TEST_DEBUG("\n%s", virGetLastErrorMessage());
51 return -1;
54 actualData = g_strdup_printf("CPUs: %u/%u, MHz: %u, Nodes: %u, Sockets: %u, "
55 "Cores: %u, Threads: %u\n",
56 nodeinfo.cpus, VIR_NODEINFO_MAXCPUS(nodeinfo),
57 nodeinfo.mhz, nodeinfo.nodes, nodeinfo.sockets,
58 nodeinfo.cores, nodeinfo.threads);
60 if (virTestCompareToFile(actualData, outputfile) < 0)
61 return -1;
63 return 0;
67 static int
68 linuxCPUStatsToBuf(virBuffer *buf,
69 int cpu,
70 virNodeCPUStatsPtr param,
71 size_t nparams)
73 size_t i = 0;
74 unsigned long long tick_to_nsec;
75 long long sc_clk_tck;
77 if ((sc_clk_tck = sysconf(_SC_CLK_TCK)) < 0) {
78 fprintf(stderr, "sysconf(_SC_CLK_TCK) fails : %s\n",
79 g_strerror(errno));
80 return -1;
82 tick_to_nsec = (1000ull * 1000ull * 1000ull) / sc_clk_tck;
84 if (cpu < 0)
85 virBufferAddLit(buf, "cpu:\n");
86 else
87 virBufferAsprintf(buf, "cpu%d:\n", cpu);
89 for (i = 0; i < nparams; i++)
90 virBufferAsprintf(buf, "%s: %llu\n", param[i].field,
91 param[i].value / tick_to_nsec);
93 virBufferAddChar(buf, '\n');
94 return 0;
97 static int
98 linuxCPUStatsCompareFiles(const char *cpustatfile,
99 size_t ncpus,
100 const char *outfile)
102 int ret = -1;
103 g_autofree char *actualData = NULL;
104 g_autoptr(FILE) cpustat = NULL;
105 virNodeCPUStatsPtr params = NULL;
106 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
107 size_t i;
108 int nparams = 0;
110 if (!(cpustat = fopen(cpustatfile, "r"))) {
111 virReportSystemError(errno, "failed to open '%s': ", cpustatfile);
112 goto fail;
115 if (virHostCPUGetStatsLinux(NULL, 0, NULL, &nparams) < 0)
116 goto fail;
118 params = g_new0(virNodeCPUStats, nparams);
120 if (virHostCPUGetStatsLinux(cpustat, VIR_NODE_CPU_STATS_ALL_CPUS, params,
121 &nparams) < 0)
122 goto fail;
124 if (linuxCPUStatsToBuf(&buf, VIR_NODE_CPU_STATS_ALL_CPUS,
125 params, nparams) < 0)
126 goto fail;
128 for (i = 0; i < ncpus; i++) {
129 if (virHostCPUGetStatsLinux(cpustat, i, params, &nparams) < 0)
130 goto fail;
131 if (linuxCPUStatsToBuf(&buf, i, params, nparams) < 0)
132 goto fail;
135 actualData = virBufferContentAndReset(&buf);
137 if (virTestCompareToFile(actualData, outfile) < 0)
138 goto fail;
140 ret = 0;
142 fail:
143 VIR_FREE(params);
144 return ret;
148 struct linuxTestHostCPUData {
149 const char *testName;
150 virArch arch;
153 static int
154 linuxTestHostCPU(const void *opaque)
156 int result = -1;
157 g_autofree char *cpuinfo = NULL;
158 g_autofree char *sysfs_prefix = NULL;
159 g_autofree char *output = NULL;
160 struct linuxTestHostCPUData *data = (struct linuxTestHostCPUData *) opaque;
161 const char *archStr = virArchToString(data->arch);
163 sysfs_prefix = g_strdup_printf("%s/virhostcpudata/linux-%s",
164 abs_srcdir, data->testName);
165 cpuinfo = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.cpuinfo",
166 abs_srcdir, archStr, data->testName);
167 output = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.expected",
168 abs_srcdir, archStr, data->testName);
170 virFileWrapperAddPrefix(SYSFS_SYSTEM_PATH, sysfs_prefix);
171 result = linuxTestCompareFiles(cpuinfo, data->arch, output);
172 virFileWrapperRemovePrefix(SYSFS_SYSTEM_PATH);
174 return result;
178 static int
179 hostCPUSignature(const void *opaque)
181 const struct linuxTestHostCPUData *data = opaque;
182 const char *arch = virArchToString(data->arch);
183 g_autofree char *cpuinfo = NULL;
184 g_autofree char *expected = NULL;
185 g_autofree char *signature = NULL;
186 g_autoptr(FILE) f = NULL;
188 cpuinfo = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.cpuinfo",
189 abs_srcdir, arch, data->testName);
190 expected = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.signature",
191 abs_srcdir, arch, data->testName);
193 if (!(f = fopen(cpuinfo, "r"))) {
194 virReportSystemError(errno,
195 "Failed to open cpuinfo file '%s'", cpuinfo);
196 return -1;
199 if (virHostCPUReadSignature(data->arch, f, &signature) < 0)
200 return -1;
202 if (!signature && !virFileExists(expected))
203 return 0;
205 return virTestCompareToFile(signature, expected);
209 struct nodeCPUStatsData {
210 const char *name;
211 int ncpus;
212 bool shouldFail;
215 static int
216 linuxTestNodeCPUStats(const void *data)
218 const struct nodeCPUStatsData *testData = data;
219 int result = -1;
220 g_autofree char *cpustatfile = NULL;
221 g_autofree g_autofree char *outfile = NULL;
223 cpustatfile = g_strdup_printf("%s/virhostcpudata/linux-cpustat-%s.stat",
224 abs_srcdir, testData->name);
225 outfile = g_strdup_printf("%s/virhostcpudata/linux-cpustat-%s.out",
226 abs_srcdir, testData->name);
228 result = linuxCPUStatsCompareFiles(cpustatfile,
229 testData->ncpus,
230 outfile);
231 if (result < 0) {
232 if (testData->shouldFail) {
233 /* Expected error */
234 result = 0;
236 } else {
237 if (testData->shouldFail) {
238 fprintf(stderr, "Expected a failure, got success");
239 result = -1;
243 return result;
247 static int
248 mymain(void)
250 int ret = 0;
251 size_t i;
252 const struct linuxTestHostCPUData nodeData[] = {
253 {"test1", VIR_ARCH_X86_64},
254 {"test1", VIR_ARCH_PPC},
255 {"test2", VIR_ARCH_X86_64},
256 {"test3", VIR_ARCH_X86_64},
257 {"test4", VIR_ARCH_X86_64},
258 {"test5", VIR_ARCH_X86_64},
259 {"test6", VIR_ARCH_X86_64},
260 {"test7", VIR_ARCH_X86_64},
261 {"test8", VIR_ARCH_X86_64},
262 {"raspberrypi", VIR_ARCH_ARMV6L},
263 {"f21-mustang", VIR_ARCH_AARCH64},
264 {"rhelsa-3.19.0-mustang", VIR_ARCH_AARCH64},
265 {"rhel74-moonshot", VIR_ARCH_AARCH64},
266 {"high-ids", VIR_ARCH_AARCH64},
267 {"deconf-cpus", VIR_ARCH_PPC64},
268 /* subcores, default configuration */
269 {"subcores1", VIR_ARCH_PPC64},
270 /* subcores, some of the cores are offline */
271 {"subcores2", VIR_ARCH_PPC64},
272 /* subcores, invalid configuration */
273 {"subcores3", VIR_ARCH_PPC64},
274 {"with-frequency", VIR_ARCH_S390X},
275 {"with-die", VIR_ARCH_X86_64},
276 {"with-clusters", VIR_ARCH_AARCH64},
279 if (virInitialize() < 0)
280 return EXIT_FAILURE;
282 for (i = 0; i < G_N_ELEMENTS(nodeData); i++) {
283 g_autofree char *sigTest = NULL;
285 if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0)
286 ret = -1;
288 sigTest = g_strdup_printf("%s CPU signature", nodeData[i].testName);
289 if (virTestRun(sigTest, hostCPUSignature, &nodeData[i]) != 0)
290 ret = -1;
293 # define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \
294 do { \
295 static struct nodeCPUStatsData data = { name, ncpus, shouldFail}; \
296 if (virTestRun("CPU stats " name, linuxTestNodeCPUStats, &data) < 0) \
297 ret = -1; \
298 } while (0)
300 DO_TEST_CPU_STATS("24cpu", 24, false);
301 DO_TEST_CPU_STATS("24cpu", 25, true);
303 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
306 VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virhostcpu"))
308 #endif /* __linux__ */