xref: /openbmc/linux/tools/perf/tests/dso-data.c (revision b6bec26c)
1 #include "util.h"
2 
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <string.h>
8 
9 #include "machine.h"
10 #include "symbol.h"
11 #include "tests.h"
12 
13 #define TEST_ASSERT_VAL(text, cond) \
14 do { \
15 	if (!(cond)) { \
16 		pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
17 		return -1; \
18 	} \
19 } while (0)
20 
21 static char *test_file(int size)
22 {
23 	static char buf_templ[] = "/tmp/test-XXXXXX";
24 	char *templ = buf_templ;
25 	int fd, i;
26 	unsigned char *buf;
27 
28 	fd = mkstemp(templ);
29 	if (fd < 0) {
30 		perror("mkstemp failed");
31 		return NULL;
32 	}
33 
34 	buf = malloc(size);
35 	if (!buf) {
36 		close(fd);
37 		return NULL;
38 	}
39 
40 	for (i = 0; i < size; i++)
41 		buf[i] = (unsigned char) ((int) i % 10);
42 
43 	if (size != write(fd, buf, size))
44 		templ = NULL;
45 
46 	close(fd);
47 	return templ;
48 }
49 
50 #define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20)
51 
52 struct test_data_offset {
53 	off_t offset;
54 	u8 data[10];
55 	int size;
56 };
57 
58 struct test_data_offset offsets[] = {
59 	/* Fill first cache page. */
60 	{
61 		.offset = 10,
62 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
63 		.size   = 10,
64 	},
65 	/* Read first cache page. */
66 	{
67 		.offset = 10,
68 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
69 		.size   = 10,
70 	},
71 	/* Fill cache boundary pages. */
72 	{
73 		.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
74 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
75 		.size   = 10,
76 	},
77 	/* Read cache boundary pages. */
78 	{
79 		.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
80 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
81 		.size   = 10,
82 	},
83 	/* Fill final cache page. */
84 	{
85 		.offset = TEST_FILE_SIZE - 10,
86 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
87 		.size   = 10,
88 	},
89 	/* Read final cache page. */
90 	{
91 		.offset = TEST_FILE_SIZE - 10,
92 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
93 		.size   = 10,
94 	},
95 	/* Read final cache page. */
96 	{
97 		.offset = TEST_FILE_SIZE - 3,
98 		.data   = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 },
99 		.size   = 3,
100 	},
101 };
102 
103 int test__dso_data(void)
104 {
105 	struct machine machine;
106 	struct dso *dso;
107 	char *file = test_file(TEST_FILE_SIZE);
108 	size_t i;
109 
110 	TEST_ASSERT_VAL("No test file", file);
111 
112 	memset(&machine, 0, sizeof(machine));
113 
114 	dso = dso__new((const char *)file);
115 
116 	/* Basic 10 bytes tests. */
117 	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
118 		struct test_data_offset *data = &offsets[i];
119 		ssize_t size;
120 		u8 buf[10];
121 
122 		memset(buf, 0, 10);
123 		size = dso__data_read_offset(dso, &machine, data->offset,
124 				     buf, 10);
125 
126 		TEST_ASSERT_VAL("Wrong size", size == data->size);
127 		TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10));
128 	}
129 
130 	/* Read cross multiple cache pages. */
131 	{
132 		ssize_t size;
133 		int c;
134 		u8 *buf;
135 
136 		buf = malloc(TEST_FILE_SIZE);
137 		TEST_ASSERT_VAL("ENOMEM\n", buf);
138 
139 		/* First iteration to fill caches, second one to read them. */
140 		for (c = 0; c < 2; c++) {
141 			memset(buf, 0, TEST_FILE_SIZE);
142 			size = dso__data_read_offset(dso, &machine, 10,
143 						     buf, TEST_FILE_SIZE);
144 
145 			TEST_ASSERT_VAL("Wrong size",
146 				size == (TEST_FILE_SIZE - 10));
147 
148 			for (i = 0; i < (size_t)size; i++)
149 				TEST_ASSERT_VAL("Wrong data",
150 					buf[i] == (i % 10));
151 		}
152 
153 		free(buf);
154 	}
155 
156 	dso__delete(dso);
157 	unlink(file);
158 	return 0;
159 }
160