From 4186e7b02f5129d1474ae9347c3f58f16b5ee49c Mon Sep 17 00:00:00 2001
From: Dave Tucker <dave@dtucker.co.uk>
Date: Fri, 31 Jan 2025 14:46:52 +0000
Subject: [PATCH] wip: Add prog_array test

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
---
 test/integration-test/bpf/progarray.bpf.c     | 26 +++++++++++++++++++
 test/integration-test/build.rs                |  1 +
 test/integration-test/src/lib.rs              |  1 +
 test/integration-test/src/tests/load.rs       | 19 ++++++++++++++
 test/integration-test/src/tests/prog_array.rs |  0
 5 files changed, 47 insertions(+)
 create mode 100644 test/integration-test/bpf/progarray.bpf.c
 create mode 100644 test/integration-test/src/tests/prog_array.rs

diff --git a/test/integration-test/bpf/progarray.bpf.c b/test/integration-test/bpf/progarray.bpf.c
new file mode 100644
index 00000000..fe8d80b1
--- /dev/null
+++ b/test/integration-test/bpf/progarray.bpf.c
@@ -0,0 +1,26 @@
+// clang-format off
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+// clang-format on
+
+struct {
+  __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
+  __uint(key_size, sizeof(uint32_t));
+  __uint(value_size, sizeof(uint32_t));
+  __uint(max_entries, 2);
+  __array(values, int());
+} jump_table SEC(".maps") = {
+    .values =
+        {
+            [1] = &xdp_pass,
+        },
+};
+
+SEC("xdp")
+int prog_array_test(struct xdp_md *ctx) {
+  bpf_tail_call(ctx, &jump_table, 1);
+  return XDP_ABORTED;
+}
+
+SEC("xdp")
+int xdp_pass(struct xdp_md *ctx) { return XDP_PASS; }
diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs
index aec4a2ab..6bd6cfff 100644
--- a/test/integration-test/build.rs
+++ b/test/integration-test/build.rs
@@ -70,6 +70,7 @@ fn main() -> Result<()> {
         ("reloc.bpf.c", true),
         ("text_64_64_reloc.c", false),
         ("variables_reloc.bpf.c", false),
+        ("prog_array.bpf.c", false),
     ];
 
     if build_integration_bpf {
diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs
index 49b99300..ca13b2f2 100644
--- a/test/integration-test/src/lib.rs
+++ b/test/integration-test/src/lib.rs
@@ -13,6 +13,7 @@ pub const TEXT_64_64_RELOC: &[u8] =
     include_bytes_aligned!(concat!(env!("OUT_DIR"), "/text_64_64_reloc.o"));
 pub const VARIABLES_RELOC: &[u8] =
     include_bytes_aligned!(concat!(env!("OUT_DIR"), "/variables_reloc.bpf.o"));
+pub const PROG_ARRAY: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/prog_array.bpf.o"));
 
 pub const BPF_PROBE_READ: &[u8] =
     include_bytes_aligned!(concat!(env!("OUT_DIR"), "/bpf_probe_read"));
diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs
index e5c44d19..bb324f9a 100644
--- a/test/integration-test/src/tests/load.rs
+++ b/test/integration-test/src/tests/load.rs
@@ -630,6 +630,25 @@ fn test_ofmaps_rust() {
     assert_eq!(m.get(&0, 0).unwrap(), 24);
 }
 
+#[test]
+fn test_prog_array() {
+    let mut bpf = EbpfLoader::new().load(crate::PROG_ARRAY).unwrap();
+    let prog: &mut UProbe = bpf
+        .program_mut("prog_array_test")
+        .unwrap()
+        .try_into()
+        .unwrap();
+    prog.load().unwrap();
+    prog.attach("trigger_mim_test_program", "/proc/self/exe", None, None)
+        .unwrap();
+
+    assert_loaded("mim_test_array");
+
+    // prog test run
+
+    assert_eq!(m.get(&0, 0).unwrap(), 24);
+}
+
 #[no_mangle]
 #[inline(never)]
 pub extern "C" fn trigger_mim_test_program() {
diff --git a/test/integration-test/src/tests/prog_array.rs b/test/integration-test/src/tests/prog_array.rs
new file mode 100644
index 00000000..e69de29b