NAME printf
PROG i:ms:1 { printf("hi!\n"); exit();}
EXPECT hi!
TIMEOUT 5

NAME printf_long_fmt
PROG i:ms:1 { printf("hi abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyz!\n"); exit();}
EXPECT ^hi abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyz!
TIMEOUT 5

NAME printf_argument
PROG i:ms:1 { printf("value: %dms100\n", 100); exit();}
EXPECT value: 100ms100
TIMEOUT 5

NAME printf_llu
PROG BEGIN { @start = nsecs; } i:s:1 { printf("Elapsed time: %llus\n", (nsecs - @start)/1000000000); clear(@start); exit();}
EXPECT Elapsed time: 1s
TIMEOUT 5

NAME printf_argument_alignment
RUN {{BPFTRACE}} -e 'struct Foo { int a; char b[10]; } uprobe:testprogs/uprobe_test:uprobeFunction2 { $foo = (struct Foo *)arg0; $foo2 = (struct Foo *)arg1; printf("%d %s %d %s\n", $foo->a, $foo->b, $foo2->a, $foo2->b) }' -c ./testprogs/uprobe_test
EXPECT 123 hello 456 world
TIMEOUT 5

NAME printf_more_arguments
PROG BEGIN { printf("%dst: %sa; %dnd: %sb;; %drd: %sc;;; %dth: %sd;;;;\\n", 1, "a", 2, "ab", 3, "abc", 4, "abcd"); exit(); }
EXPECT 1st: aa; 2nd: abb;; 3rd: abcc;;; 4th: abcdd;;;;
TIMEOUT 5

NAME printf_length_modifiers
PROG BEGIN { $x = 0x12345678abcdef; printf("%hhx %hx %x %jx\n", $x, $x, $x, $x); exit(); }
EXPECT ef cdef 78abcdef 12345678abcdef
TIMEOUT 5

NAME printf_char
PROG BEGIN { printf("%c%c%c%c\n", 0x41, 0x42, 0x43, 0x44); exit(); }
EXPECT ABCD
TIMEOUT 5

NAME time
PROG i:ms:1 { time("%H:%M:%S\n"); exit();}
EXPECT [0-9]*:[0-9]*:[0-9]*
TIMEOUT 5

NAME time_short
PROG i:ms:1 { time("%H-%M:%S\n"); exit();}
EXPECT [0-9]*-[0-9]*
TIMEOUT 5

NAME join
RUN {{BPFTRACE}} --unsafe -e 'i:ms:1 { system("echo '_A_'"); } t:syscalls:sys_enter_execve { join(args.argv); exit();}'
EXPECT _A_
TIMEOUT 5

NAME join_delim
RUN {{BPFTRACE}} --unsafe -e 'i:ms:1 { system("echo '_A_'"); } t:syscalls:sys_enter_execve { join(args.argv, ","); exit();}'
EXPECT _A_
TIMEOUT 5

NAME str
PROG t:syscalls:sys_enter_execve { printf("P: %s\n", str(args.filename)); exit();}
AFTER ./testprogs/syscall execve /bin/ls
EXPECT P: /*.
TIMEOUT 5

NAME str_truncated
PROG t:syscalls:sys_enter_execve { printf("P: %s\n", str(args.filename)); exit();}
ENV BPFTRACE_MAX_STRLEN=5
AFTER ./testprogs/syscall execve /bin/ls &>/dev/null
EXPECT P: /...\.\.
TIMEOUT 5

NAME str_truncated_custom
PROG t:syscalls:sys_enter_execve { printf("P: %s\n", str(args.filename)); exit();}
ENV BPFTRACE_MAX_STRLEN=5 BPFTRACE_STR_TRUNC_TRAILER=_xxx
AFTER ./testprogs/syscall execve /bin/ls &>/dev/null
EXPECT P: /..._xxx
TIMEOUT 5

NAME buf
RUN {{BPFTRACE}} -e 'struct MyStruct { const char* a; char b[4]; uint8_t c[4]; int d[4]; uint16_t e[4]; uint64_t f[4] }; u:./testprogs/complex_struct:func { $s = (struct MyStruct *)arg0; printf("P: %r-%r-%r-%r-%r-%r\n", buf($s->a, 4), buf($s->b, 4), buf($s->c), buf($s->d), buf($s->e), buf($s->f)); exit(); }' -c ./testprogs/complex_struct
EXPECT P: \\x09\\x08\\x07\\x06-\\x05\\x04\\x03\\x02-\\x01\\x02\\x03\\x04-\\x05\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x08\\x00\\x00\\x00-\\x09\\x00\\x0a\\x00\\x0b\\x00\\x0c\\x00-\\x0d\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0e\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0f\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00
TIMEOUT 5
ARCH x86_64|ppc64le|aarch64|armv7l

NAME buf
RUN {{BPFTRACE}} -e 'struct MyStruct { const char* a; char b[4]; uint8_t c[4]; int d[4]; uint16_t e[4]; uint64_t f[4] }; u:./testprogs/complex_struct:func { $s = (struct MyStruct *)arg0; printf("P: %r-%r-%r-%r-%r-%r\n", buf($s->a, 4), buf($s->b, 4), buf($s->c), buf($s->d), buf($s->e), buf($s->f)); exit(); }' -c ./testprogs/complex_struct
EXPECT P: \\x09\\x08\\x07\\x06-\\x05\\x04\\x03\\x02-\\x01\\x02\\x03\\x04-\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x08-\\x00\\x09\\x00\\x0a\\x00\\x0b\\x00\\x0c-\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0d\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0e\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0f\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10
TIMEOUT 5
ARCH s390x|ppc64

NAME buf_map_key
PROG i:ms:100 { @[buf("ok_key", 6)] = 1; exit(); }
EXPECT @\[ok_key\]: 1
TIMEOUT 5

NAME buf_map_multikey
PROG BEGIN { @[buf("ok_key", 8), 1] = hist(1); exit(); }
EXPECT @\[ok_key\\x00\\x00\, 1]
TIMEOUT 5

NAME buf_hist_map_key
PROG BEGIN { @[buf("ok_key", 8)] = hist(1); exit(); }
EXPECT @\[ok_key\\x00\\x00\]
TIMEOUT 5

NAME buf_map_value
PROG i:ms:100 { @ = buf("ok_value", 8); exit(); }
EXPECT @: ok_value
TIMEOUT 5

NAME buf_no_ascii
PROG BEGIN { printf("%rx", buf("Hello\0", 6)); exit(); }
EXPECT \\x48\\x65\\x6c\\x6c\\x6f\\x00
TIMEOUT 5

NAME buf_no_ascii_no_escaping
PROG BEGIN { printf("%rh", buf("Hello\0", 6)); exit(); }
EXPECT 48 65 6c 6c 6f 00
TIMEOUT 5

NAME ksym
PROG kprobe:do_nanosleep { printf("%s\n", ksym(reg("ip"))); exit();}
EXPECT do_nanosleep
TIMEOUT 5
ARCH x86_64
AFTER ./testprogs/syscall nanosleep 1e8

NAME ksym
PROG kprobe:do_nanosleep { printf("%s\n", ksym(reg("pswaddr"))); exit();}
EXPECT do_nanosleep
TIMEOUT 5
ARCH s390x
AFTER ./testprogs/syscall nanosleep 1e8

NAME ksym
PROG kprobe:do_nanosleep { printf("%s\n", ksym(reg("pc"))); exit();}
EXPECT do_nanosleep
TIMEOUT 5
ARCH aarch64|armv7l
AFTER ./testprogs/syscall nanosleep 1e8

NAME ksym
PROG kprobe:do_nanosleep { printf("%s\n", ksym(reg("nip"))); exit();}
EXPECT do_nanosleep
TIMEOUT 5
ARCH ppc64|ppc64le
AFTER ./testprogs/syscall nanosleep 1e8

NAME system
RUN {{BPFTRACE}} --unsafe -e 'i:ms:100 { system("echo 'ok_system'"); exit();}'
EXPECT ok_system
TIMEOUT 5

NAME system_more_args
RUN {{BPFTRACE}} --unsafe -e 'i:ms:100 { system("echo %d %d %d %d %d %d %d", 1, 2, 3, 4, 5, 6, 7); exit();}'
EXPECT 1 2 3 4 5 6 7
TIMEOUT 5

NAME count
PROG i:ms:100 { @ = count(); exit();}
EXPECT @:\s[0-9]+
TIMEOUT 5

NAME sum
PROG kprobe:vfs_read { @bytes[comm] = sum(arg2); exit();}
EXPECT @.*\[.*\]\:\s[0-9]*
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME avg
PROG kprobe:vfs_read { @bytes[comm] = avg(arg2); exit();}
EXPECT @.*\[.*\]\:\s[0-9]*
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME min
PROG kprobe:vfs_read { @bytes[comm] = min(arg2); exit();}
EXPECT @.*\[.*\]\:\s[0-9]*
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME max
PROG kprobe:vfs_read { @bytes[comm] = max(arg2); exit();}
EXPECT @.*\[.*\]\:\s[0-9]*
AFTER ./testprogs/syscall read
TIMEOUT 5

NAME stats
PROG kprobe:vfs_read { @bytes[comm] = stats(arg2); exit();}
EXPECT @.*\[.*\]\:\scount\s[0-9]*\,\saverage\s[0-9]*\,\stotal\s[0-9]*
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME hist
PROG kretprobe:vfs_read { @bytes = hist(retval); exit();}
EXPECT @bytes: *\n[\[(].*
AFTER ./testprogs/syscall read
TIMEOUT 5

NAME hist_2_values
PROG BEGIN { @=hist(3);@=hist(20);exit();}
EXPECT_FILE runtime/outputs/hist_2_values.txt
TIMEOUT 1

NAME hist_10g
PROG BEGIN { @ = hist(10 * 1024 * 1024 * 1024); exit(); }
EXPECT_JSON runtime/outputs/hist_10g.json
TIMEOUT 1

NAME lhist
PROG kretprobe:vfs_read { @bytes = lhist(retval, 0, 10000, 1000); exit()}
EXPECT @bytes: *\n[\[(].*
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME kstack
PROG k:do_nanosleep { printf("%s\n%s\n", kstack(), kstack(1)); exit(); }
EXPECT Attaching 1 probe
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME kstack perf mode
PROG k:do_nanosleep { printf("%s\n", kstack(perf, 1)); exit(); }
EXPECT Attaching 1 probe
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack
PROG k:do_nanosleep { printf("%s\n%s\n", ustack(), ustack(1)); exit(); }
EXPECT Attaching 1 probe
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack_stack_mode_env_bpftrace
PROG k:do_nanosleep { printf("%s", ustack(1)); exit(); }
ENV BPFTRACE_STACK_MODE=bpftrace
EXPECT ^\s+[a-zA-Z0-9_]+
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack_stack_mode_env_perf
PROG k:do_nanosleep { printf("%s", ustack(1)); exit(); }
ENV BPFTRACE_STACK_MODE=perf
EXPECT ^\s+[0-9a-f]+ [a-zA-Z0-9_]+
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack_stack_mode_env_raw
PROG k:do_nanosleep { printf("%s", ustack(1)); exit(); }
ENV BPFTRACE_STACK_MODE=raw
EXPECT ^\s+[0-9a-f]+$
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack_stack_mode_env_override
PROG k:do_nanosleep { printf("%s", ustack(raw, 1)); exit(); }
ENV BPFTRACE_STACK_MODE=perf
EXPECT ^\s+[0-9a-f]+$
TIMEOUT 5
AFTER ./testprogs/syscall nanosleep  1e8

NAME ustack_elf_symtable
ENV BPFTRACE_CACHE_USER_SYMBOLS=PER_PROGRAM
PROG uprobe:./testprogs/uprobe_symres_exited_process:test { print(ustack); exit(); }
EXPECT ^\s+test\+0\s+main\+[1-9][0-9]*
AFTER ./testprogs/disable_aslr ./testprogs/uprobe_symres_exited_process
ARCH x86_64
TIMEOUT 5

NAME ustack_elf_symtable
ENV BPFTRACE_CACHE_USER_SYMBOLS=PER_PROGRAM
PROG uprobe:./testprogs/uprobe_symres_exited_process:test { print(ustack); exit(); }
EXPECT ^\s+test\+0\s+test2\+[1-9][0-9]*\s+main\+[1-9][0-9]*
AFTER ./testprogs/disable_aslr ./testprogs/uprobe_symres_exited_process
ARCH ppc64le
TIMEOUT 5

NAME cat
PROG i:ms:1 { cat("/proc/uptime"); exit();}
EXPECT [0-9]*.[0-9]* [0-9]*.[0-9]*
TIMEOUT 5

NAME cat_more_args
PROG i:ms:1 { cat("/%s%s%s%s/%s%s%s", "p", "r", "o", "c", "u", "p", "time"); exit();}
EXPECT [0-9]*.[0-9]* [0-9]*.[0-9]*
TIMEOUT 5

NAME uaddr
RUN {{BPFTRACE}} -e 'uprobe:testprogs/uprobe_test:uprobeFunction1 { printf("0x%lx -- 0x%lx\n", *uaddr("GLOBAL_A"), *uaddr("GLOBAL_C")); exit(); }' -c ./testprogs/uprobe_test
EXPECT 0x55555555 -- 0x33333333
TIMEOUT 5

NAME ntop static ip
PROG i:ms:100 { printf("IP: %s, %s, %s, %s\n", ntop(1), ntop(0x0100007f), ntop(0xffff0000), ntop(0x0000ffff)); exit() }
EXPECT IP: 1.0.0.0, 127.0.0.1, 0.0.255.255, 255.255.0.0
ARCH x86_64|aarch64|ppc64le|armv7l
TIMEOUT 5

NAME ntop static ip
PROG i:ms:100 { printf("IP: %s, %s, %s, %s\n", ntop(0x01000000), ntop(0x7f000001), ntop(0x0000ffff), ntop(0xffff0000)); exit() }
EXPECT IP: 1.0.0.0, 127.0.0.1, 0.0.255.255, 255.255.0.0
ARCH s390x|ppc64
TIMEOUT 5

NAME pton ipv4
PROG i:ms:100 { printf("IP: %s\n", ntop(2, pton("127.0.0.1"))); exit(); }
EXPECT IP: 127.0.0.1
TIMEOUT 5

NAME pton ipv6
PROG i:ms:100 { printf("IP: %s\n", ntop(10, pton("::1"))); exit(); }
EXPECT IP: ::1
TIMEOUT 5

NAME usym
PROG i:ms:100 { @=usym(1); @a=@; exit(); }
EXPECT ^@a: 0x1$
TIMEOUT 5

NAME print_non_map
PROG BEGIN { $x = 5; print($x); exit() }
EXPECT 5
TIMEOUT 1

NAME print_non_map_builtin
PROG BEGIN { print(comm); exit() }
EXPECT bpftrace
TIMEOUT 1

NAME print_non_map_tuple
PROG BEGIN { $t = (1, 2, "string"); print($t); exit() }
EXPECT (1, 2, string)
TIMEOUT 1

NAME print_non_map_array
PROG struct A { int x[4]; } uprobe:./testprogs/array_access:test_struct { $a = ((struct A *) arg0)->x; print($a); exit(); }
EXPECT \[1,2,3,4\]
TIMEOUT 5
AFTER ./testprogs/array_access

NAME print_non_map_multi_dimensional_array
PROG struct B { int y[2][2]; } uprobe:./testprogs/array_access:test_struct { $b = ((struct B *) arg1)->y; print($b); exit(); }
EXPECT \[\[5,6\],\[7,8\]\]
TIMEOUT 5
AFTER ./testprogs/array_access

NAME print_non_map_struct
PROG struct Foo { int m; int n; } uprobe:./testprogs/simple_struct:func { $f = *((struct Foo *) arg0); print($f); exit(); }
EXPECT { .m = 2, .n = 3 }
TIMEOUT 5
AFTER ./testprogs/simple_struct

NAME print_non_map_struct_kfunc
PROG kfunc:vfs_open { print(*args.path); exit(); }
EXPECT { .mnt = 0x[0-9a-f]+, .dentry = 0x[0-9a-f]+ }
REQUIRES_FEATURE kfunc
TIMEOUT 5
AFTER ./testprogs/syscall open

NAME strftime
PROG BEGIN { $ts = strftime("%m/%d/%y", nsecs); printf("%s\n", $ts); exit(); }
EXPECT [0-9]{2}\/[0-9]{2}\/[0-9]{2}
TIMEOUT 5

NAME strftime_as_map_key
PROG BEGIN { @[strftime("%m/%d/%y", nsecs)] = 1; exit();}
EXPECT \[[0-9]{2}\/[0-9]{2}\/[0-9]{2}\]: 1
TIMEOUT 5

NAME strftime_as_map_value
PROG BEGIN { @[nsecs] = strftime("%m/%d/%y", nsecs); exit();}
EXPECT @\[[0-9]*\]: [0-9]{2}\/[0-9]{2}\/[0-9]{2}
TIMEOUT 5

# Output two microsecond timestamps, 123000 nsecs apart. Use python to evaluate and verify there's a 123us delta
#
# Note we add a `1` before the timestamp b/c leading zeros (eg `0123`) is invalid integer in python.
NAME strftime_microsecond_extension
RUN {{BPFTRACE}} -e 'BEGIN { printf("%s - %s\n", strftime("1%f", 1000123000), strftime("1%f", 0)); exit(); }' | tail -n +2 | xargs -I{} python -c "print({})"
EXPECT 123
TIMEOUT 1

# Similar to above test but test that rolling over past 1s works as expected
NAME strftime_microsecond_extension_rollover
RUN {{BPFTRACE}} -e 'BEGIN { printf("%s - %s\n", strftime("1%f", 1000000123000), strftime("1%f", 0)); exit(); }' | tail -n +2 | xargs -I{} python -c "print({})"
EXPECT 123
TIMEOUT 1

NAME print_avg_map_args
PROG BEGIN { print("BEGIN"); @["a"] = avg(10); @["b"] = avg(20); @["c"] = avg(30); @["d"] = avg(40); print(@, 2, 10); print("END"); clear(@); exit(); }
EXPECT BEGIN\n@\[c\]: 3\n@\[d\]: 4\n\nEND
TIMEOUT 1

NAME print_avg_map_with_large_top
PROG BEGIN { print("BEGIN"); @["a"] = avg(10); @["b"] = avg(20); @["c"] = avg(30); @["d"] = avg(40); print(@, 10, 10); print("END"); clear(@); exit(); }
EXPECT BEGIN\n@\[a\]: 1\n@\[b\]: 2\n@\[c\]: 3\n@\[d\]: 4\n\nEND
TIMEOUT 1

NAME print_hist_with_top_arg
PROG BEGIN { print("BEGIN"); @[1] = hist(10); @[2] = hist(20); @[3] = hist(30); print(@, 2); print("END"); clear(@); exit(); }
EXPECT BEGIN\n@\[2\]:(.*\n)+@\[3\]:(.*\n)+END
TIMEOUT 1

NAME print_hist_with_large_top_arg
PROG BEGIN { print("BEGIN"); @[1] = hist(10); @[2] = hist(20); @[3] = hist(30); print(@, 10); print("END"); clear(@); exit(); }
EXPECT BEGIN\n@\[1\]:(.*\n)+@\[2\]:(.*\n)+@\[3\]:(.*\n)+END
TIMEOUT 1

NAME path
RUN {{BPFTRACE}} -ve 'kfunc:filp_close { $f = path(args.filp->f_path); if (!strncmp($f, "/tmp/bpftrace_runtime_test_syscall_gen_read_temp", 49)) { printf("OK\n"); exit(); } }'
EXPECT OK
REQUIRES_FEATURE dpath kfunc
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME strcontains
RUN {{BPFTRACE}} -ve 'kfunc:filp_close { $f = path(args.filp->f_path); if (strcontains($f, "tmp")) { printf("OK\n"); exit(); } }'
EXPECT OK
REQUIRES_FEATURE dpath kfunc
TIMEOUT 5
AFTER ./testprogs/syscall read

NAME strcontains literals
RUN {{BPFTRACE}} -e 'BEGIN { if (strcontains("abc", "a")) { printf("OK\n"); exit(); } }'
EXPECT OK
TIMEOUT 1

NAME path_in_unsupported_kfunc
PROG kfunc:vfs_read { print(path(args.file->f_path)); }
EXPECT \nstdin:1:18-47: ERROR: helper bpf_d_path not supported in probe\n
REQUIRES_FEATURE dpath
REQUIRES_FEATURE kfunc
TIMEOUT 5
WILL_FAIL
AFTER ./testprogs/syscall read

NAME macaddr
RUN {{BPFTRACE}} -e 'struct MyStruct { const char* ignore; char mac[6]; }; u:./testprogs/complex_struct:func { $s = ((struct MyStruct *)arg0); printf("P: %s\n", macaddr($s->mac)); exit(); }' -c ./testprogs/complex_struct
EXPECT P: 05:04:03:02:01:02
TIMEOUT 5

NAME macaddr as map key
RUN {{BPFTRACE}} -e 'struct MyStruct { const char* ignore; char mac[6]; }; u:./testprogs/complex_struct:func { $s = ((struct MyStruct *)arg0); @[macaddr($s->mac)] = 1; exit(); }' -c ./testprogs/complex_struct
EXPECT @\[05:04:03:02:01:02\]: 1
TIMEOUT 5

NAME macaddr as map value
RUN {{BPFTRACE}} -e 'struct MyStruct { const char* ignore; char mac[6]; }; u:./testprogs/complex_struct:func { $s = ((struct MyStruct *)arg0); @[1] = macaddr($s->mac); exit(); }' -c ./testprogs/complex_struct
EXPECT \[1\]: 05:04:03:02:01:02
TIMEOUT 5

NAME iter:task
PROG iter:task { printf("OK"); }
EXPECT OK
REQUIRES_FEATURE iter:task
TIMEOUT 5

NAME iter:task_file
PROG iter:task_file { printf("OK"); }
EXPECT OK
REQUIRES_FEATURE iter:task_file
TIMEOUT 5

NAME iter:task_vma
PROG iter:task_vma { printf("OK"); }
EXPECT OK
REQUIRES_FEATURE iter:task_vma
TIMEOUT 5

NAME cgroup_path
PROG BEGIN { print(cgroup_path(cgroup & ((1 << 32) - 1))); exit(); }
EXPECT ([a-z]*:\/.*;)*[a-z]*:\/.*
REQUIRES grep -q '^cgroup2' /proc/mounts
TIMEOUT 5
MIN_KERNEL 4.18

NAME cgroup_path printf
PROG BEGIN { printf("path: %s", cgroup_path(cgroup & ((1 << 32) - 1))); exit(); }
EXPECT path: ([a-z]*:\/.*;)*[a-z]*:\/.*
REQUIRES grep -q '^cgroup2' /proc/mounts
TIMEOUT 5
MIN_KERNEL 4.18

NAME strerror
RUN {{BPFTRACE}} --include "errno.h" -e 'BEGIN { print(strerror(EPERM)); exit(); }'
EXPECT Operation not permitted
TIMEOUT 5

NAME bswap_int64
RUN {{BPFTRACE}} -e 'BEGIN { printf("%llx", bswap(0x1122334455667788)); exit(); }'
EXPECT 8877665544332211
TIMEOUT 1

NAME bswap_int32
RUN {{BPFTRACE}} -e 'BEGIN { printf("%x", bswap((int32)0x12345678)); exit(); }'
EXPECT 78563412
TIMEOUT 1

NAME bswap_int16
RUN {{BPFTRACE}} -e 'BEGIN { printf("%x", bswap((int16)0x1234)); exit(); }'
EXPECT 3412
TIMEOUT 1

NAME bswap_int8
RUN {{BPFTRACE}} -e 'BEGIN { printf("%x", bswap((int8)0x12)); exit(); }'
EXPECT 12
TIMEOUT 1

NAME bswap_int64_op
RUN {{BPFTRACE}} -e 'BEGIN { printf("%llx", bswap(0x12340000 + 0x5678)); exit(); }'
EXPECT 7856341200000000
TIMEOUT 1

NAME bswap_twice
RUN {{BPFTRACE}} -e 'BEGIN { printf("%x", bswap(bswap(0x1234))); exit(); }'
EXPECT 1234
TIMEOUT 1

NAME skboutput
RUN {{BPFTRACE}} -e 'kfunc:__dev_queue_xmit { $ret = skboutput("skb.pcap", args.skb, args.skb->len, 14); if ($ret == 0) { printf("OK\n"); exit(); } }'
AFTER ./testprogs/syscall connect 127.0.0.1 80
EXPECT OK
REQUIRES_FEATURE kfunc
REQUIRES_FEATURE skboutput
TIMEOUT 5
MIN_KERNEL 5.5

NAME debugf
RUN echo > /sys/kernel/debug/tracing/trace; {{BPFTRACE}} -e 'i:ms:1 { debugf("debugf"); exit();}'; cat /sys/kernel/debug/tracing/trace
EXPECT bpf_trace_printk: debugf
TIMEOUT 3

NAME debugf_with_arguments
RUN echo > /sys/kernel/debug/tracing/trace; {{BPFTRACE}} -e 'i:ms:1 { debugf("debugf %s %d %x", "a", 1, 16); exit();}'; cat /sys/kernel/debug/tracing/trace
EXPECT bpf_trace_printk: debugf a 1 10
TIMEOUT 3

NAME debugf_with_seq_printf
RUN echo > /sys/kernel/debug/tracing/trace; {{BPFTRACE}} -e 'i:ms:1 { printf("printf %d", 0); debugf("debugf %d", 1); exit();}'; cat /sys/kernel/debug/tracing/trace
EXPECT bpf_trace_printk: debugf 1
TIMEOUT 3

NAME nsecs
PROG i:ms:1 { printf("SUCCESS %llu\n", nsecs()); exit(); }
EXPECT SUCCESS [0-9]+
TIMEOUT 5

NAME nsecs_monotonic
PROG i:ms:1 { printf("SUCCESS %llu\n", nsecs(monotonic)); exit(); }
EXPECT SUCCESS [0-9]+
TIMEOUT 5

NAME nsecs_boot
PROG i:ms:1 { printf("SUCCESS %llu\n", nsecs(boot)); exit(); }
EXPECT SUCCESS [0-9]+
TIMEOUT 5

NAME nsecs_tai
PROG i:ms:1 { printf("SUCCESS %llu\n", nsecs(tai)); exit(); }
EXPECT SUCCESS [0-9]+
TIMEOUT 5
REQUIRES_FEATURE get_tai_ns
MIN_KERNEL 6.1

NAME nsecs_sw_tai
PROG i:ms:1 { printf("SUCCESS %llu\n", nsecs(sw_tai)); exit(); }
EXPECT SUCCESS [0-9]+
TIMEOUT 5

NAME map len
PROG BEGIN { @[0] = 0; @[1] = 1; printf("map len: %d\n", len(@)); exit(); }
EXPECT map len: 2
TIMEOUT 3
