1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 #include <test_progs.h> 4 #include <string.h> 5 #include <stdio.h> 6 7 #define __CHECK_STR(str, name) \ 8 do { \ 9 if (!ASSERT_HAS_SUBSTR(fix->output, (str), (name))) \ 10 goto out; \ 11 } while (0) 12 13 struct fixture { 14 char tmpfile[80]; 15 int fd; 16 char *output; 17 size_t sz; 18 char veristat[80]; 19 }; 20 21 static struct fixture *init_fixture(void) 22 { 23 struct fixture *fix = malloc(sizeof(struct fixture)); 24 25 /* for no_alu32 and cpuv4 veristat is in parent folder */ 26 if (access("./veristat", F_OK) == 0) 27 strcpy(fix->veristat, "./veristat"); 28 else if (access("../veristat", F_OK) == 0) 29 strcpy(fix->veristat, "../veristat"); 30 else 31 PRINT_FAIL("Can't find veristat binary"); 32 33 snprintf(fix->tmpfile, sizeof(fix->tmpfile), "/tmp/test_veristat.XXXXXX"); 34 fix->fd = mkstemp(fix->tmpfile); 35 fix->sz = 1000000; 36 fix->output = malloc(fix->sz); 37 return fix; 38 } 39 40 static void teardown_fixture(struct fixture *fix) 41 { 42 free(fix->output); 43 close(fix->fd); 44 remove(fix->tmpfile); 45 free(fix); 46 } 47 48 static void test_set_global_vars_succeeds(void) 49 { 50 struct fixture *fix = init_fixture(); 51 52 SYS(out, 53 "%s set_global_vars.bpf.o"\ 54 " -G \"var_s64 = 0xf000000000000001\" "\ 55 " -G \"var_u64 = 0xfedcba9876543210\" "\ 56 " -G \"var_s32 = -0x80000000\" "\ 57 " -G \"var_u32 = 0x76543210\" "\ 58 " -G \"var_s16 = -32768\" "\ 59 " -G \"var_u16 = 60652\" "\ 60 " -G \"var_s8 = -128\" "\ 61 " -G \"var_u8 = 255\" "\ 62 " -G \"var_ea = EA2\" "\ 63 " -G \"var_eb = EB2\" "\ 64 " -G \"var_ec = EC2\" "\ 65 " -G \"var_b = 1\" "\ 66 " -G \"struct1.struct2.u.var_u8 = 170\" "\ 67 " -G \"union1.struct3.var_u8_l = 0xaa\" "\ 68 " -G \"union1.struct3.var_u8_h = 0xaa\" "\ 69 "-vl2 > %s", fix->veristat, fix->tmpfile); 70 71 read(fix->fd, fix->output, fix->sz); 72 __CHECK_STR("_w=0xf000000000000001 ", "var_s64 = 0xf000000000000001"); 73 __CHECK_STR("_w=0xfedcba9876543210 ", "var_u64 = 0xfedcba9876543210"); 74 __CHECK_STR("_w=0x80000000 ", "var_s32 = -0x80000000"); 75 __CHECK_STR("_w=0x76543210 ", "var_u32 = 0x76543210"); 76 __CHECK_STR("_w=0x8000 ", "var_s16 = -32768"); 77 __CHECK_STR("_w=0xecec ", "var_u16 = 60652"); 78 __CHECK_STR("_w=128 ", "var_s8 = -128"); 79 __CHECK_STR("_w=255 ", "var_u8 = 255"); 80 __CHECK_STR("_w=11 ", "var_ea = EA2"); 81 __CHECK_STR("_w=12 ", "var_eb = EB2"); 82 __CHECK_STR("_w=13 ", "var_ec = EC2"); 83 __CHECK_STR("_w=1 ", "var_b = 1"); 84 __CHECK_STR("_w=170 ", "struct1.struct2.u.var_u8 = 170"); 85 __CHECK_STR("_w=0xaaaa ", "union1.var_u16 = 0xaaaa"); 86 87 out: 88 teardown_fixture(fix); 89 } 90 91 static void test_set_global_vars_from_file_succeeds(void) 92 { 93 struct fixture *fix = init_fixture(); 94 char input_file[80]; 95 const char *vars = "var_s16 = -32768\nvar_u16 = 60652"; 96 int fd; 97 98 snprintf(input_file, sizeof(input_file), "/tmp/veristat_input.XXXXXX"); 99 fd = mkstemp(input_file); 100 if (!ASSERT_GE(fd, 0, "valid fd")) 101 goto out; 102 103 write(fd, vars, strlen(vars)); 104 syncfs(fd); 105 SYS(out, "%s set_global_vars.bpf.o -G \"@%s\" -vl2 > %s", 106 fix->veristat, input_file, fix->tmpfile); 107 read(fix->fd, fix->output, fix->sz); 108 __CHECK_STR("_w=0x8000 ", "var_s16 = -32768"); 109 __CHECK_STR("_w=0xecec ", "var_u16 = 60652"); 110 111 out: 112 close(fd); 113 remove(input_file); 114 teardown_fixture(fix); 115 } 116 117 static void test_set_global_vars_out_of_range(void) 118 { 119 struct fixture *fix = init_fixture(); 120 121 SYS_FAIL(out, 122 "%s set_global_vars.bpf.o -G \"var_s32 = 2147483648\" -vl2 2> %s", 123 fix->veristat, fix->tmpfile); 124 125 read(fix->fd, fix->output, fix->sz); 126 __CHECK_STR("is out of range [-2147483648; 2147483647]", "out of range"); 127 128 out: 129 teardown_fixture(fix); 130 } 131 132 void test_veristat(void) 133 { 134 if (test__start_subtest("set_global_vars_succeeds")) 135 test_set_global_vars_succeeds(); 136 137 if (test__start_subtest("set_global_vars_out_of_range")) 138 test_set_global_vars_out_of_range(); 139 140 if (test__start_subtest("set_global_vars_from_file_succeeds")) 141 test_set_global_vars_from_file_succeeds(); 142 } 143 144 #undef __CHECK_STR 145