1 #include "parse-events.h" 2 #include "pmu.h" 3 #include "util.h" 4 #include "tests.h" 5 6 /* Simulated format definitions. */ 7 static struct test_format { 8 const char *name; 9 const char *value; 10 } test_formats[] = { 11 { "krava01", "config:0-1,62-63\n", }, 12 { "krava02", "config:10-17\n", }, 13 { "krava03", "config:5\n", }, 14 { "krava11", "config1:0,2,4,6,8,20-28\n", }, 15 { "krava12", "config1:63\n", }, 16 { "krava13", "config1:45-47\n", }, 17 { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", }, 18 { "krava22", "config2:8,18,48,58\n", }, 19 { "krava23", "config2:28-29,38\n", }, 20 }; 21 22 /* Simulated users input. */ 23 static struct parse_events_term test_terms[] = { 24 { 25 .config = (char *) "krava01", 26 .val.num = 15, 27 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 28 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 29 }, 30 { 31 .config = (char *) "krava02", 32 .val.num = 170, 33 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 34 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 35 }, 36 { 37 .config = (char *) "krava03", 38 .val.num = 1, 39 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 40 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 41 }, 42 { 43 .config = (char *) "krava11", 44 .val.num = 27, 45 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 46 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 47 }, 48 { 49 .config = (char *) "krava12", 50 .val.num = 1, 51 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 52 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 53 }, 54 { 55 .config = (char *) "krava13", 56 .val.num = 2, 57 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 58 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 59 }, 60 { 61 .config = (char *) "krava21", 62 .val.num = 119, 63 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 64 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 65 }, 66 { 67 .config = (char *) "krava22", 68 .val.num = 11, 69 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 70 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 71 }, 72 { 73 .config = (char *) "krava23", 74 .val.num = 2, 75 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 76 .type_term = PARSE_EVENTS__TERM_TYPE_USER, 77 }, 78 }; 79 80 /* 81 * Prepare format directory data, exported by kernel 82 * at /sys/bus/event_source/devices/<dev>/format. 83 */ 84 static char *test_format_dir_get(void) 85 { 86 static char dir[PATH_MAX]; 87 unsigned int i; 88 89 snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX"); 90 if (!mkdtemp(dir)) 91 return NULL; 92 93 for (i = 0; i < ARRAY_SIZE(test_formats); i++) { 94 static char name[PATH_MAX]; 95 struct test_format *format = &test_formats[i]; 96 FILE *file; 97 98 snprintf(name, PATH_MAX, "%s/%s", dir, format->name); 99 100 file = fopen(name, "w"); 101 if (!file) 102 return NULL; 103 104 if (1 != fwrite(format->value, strlen(format->value), 1, file)) 105 break; 106 107 fclose(file); 108 } 109 110 return dir; 111 } 112 113 /* Cleanup format directory. */ 114 static int test_format_dir_put(char *dir) 115 { 116 char buf[PATH_MAX]; 117 snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir); 118 if (system(buf)) 119 return -1; 120 121 snprintf(buf, PATH_MAX, "rmdir %s\n", dir); 122 return system(buf); 123 } 124 125 static struct list_head *test_terms_list(void) 126 { 127 static LIST_HEAD(terms); 128 unsigned int i; 129 130 for (i = 0; i < ARRAY_SIZE(test_terms); i++) 131 list_add_tail(&test_terms[i].list, &terms); 132 133 return &terms; 134 } 135 136 int test__pmu(void) 137 { 138 char *format = test_format_dir_get(); 139 LIST_HEAD(formats); 140 struct list_head *terms = test_terms_list(); 141 int ret; 142 143 if (!format) 144 return -EINVAL; 145 146 do { 147 struct perf_event_attr attr; 148 149 memset(&attr, 0, sizeof(attr)); 150 151 ret = perf_pmu__format_parse(format, &formats); 152 if (ret) 153 break; 154 155 ret = perf_pmu__config_terms(&formats, &attr, terms, false); 156 if (ret) 157 break; 158 159 ret = -EINVAL; 160 161 if (attr.config != 0xc00000000002a823) 162 break; 163 if (attr.config1 != 0x8000400000000145) 164 break; 165 if (attr.config2 != 0x0400000020041d07) 166 break; 167 168 ret = 0; 169 } while (0); 170 171 test_format_dir_put(format); 172 return ret; 173 } 174