Skip to content

Commit

Permalink
Merge pull request #706 from aya-rs/reloc-tests
Browse files Browse the repository at this point in the history
integration-test: Remove runtime toolchain deps
  • Loading branch information
tamird authored Aug 1, 2023
2 parents afacfdd + dca5e6c commit 3692e53
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 467 deletions.
85 changes: 69 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:

- name: Run miri
run: |
set -euxo pipefail
cargo hack miri test --all-targets --feature-powerset \
--exclude aya-bpf \
--exclude aya-bpf-bindings \
Expand Down Expand Up @@ -79,6 +80,7 @@ jobs:

- name: Build
run: |
set -euxo pipefail
cargo hack build --all-targets --feature-powerset \
--exclude aya-bpf \
--exclude aya-bpf-bindings \
Expand All @@ -90,6 +92,7 @@ jobs:
env:
RUST_BACKTRACE: full
run: |
set -euxo pipefail
cargo hack test --all-targets --feature-powerset \
--exclude aya-bpf \
--exclude aya-bpf-bindings \
Expand Down Expand Up @@ -122,34 +125,79 @@ jobs:

- uses: Swatinem/rust-cache@v2

- name: Prereqs
- name: bpf-linker
run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git

- uses: taiki-e/install-action@cargo-hack
- name: Build
env:
CARGO_CFG_BPF_TARGET_ARCH: ${{ matrix.arch }}
run: |
set -euxo pipefail
cargo hack build --package aya-bpf --package aya-log-ebpf \
--feature-powerset \
--target ${{ matrix.target }} \
-Z build-std=core
integration-test:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
# See https://doc.rust-lang.org/cargo/reference/profiles.html for the names
# of the builtin profiles. Note that dev builds "debug" targets.
profile:
- release
- dev
build-integration-test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: rust-src

- uses: Swatinem/rust-cache@v2

- name: bpf-linker
run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git

- name: Install dependencies
# ubuntu-22.04 comes with clang 14[0] which doesn't include support for signed and 64bit
# enum values which was added in clang 15[1].
#
# gcc-multilib provides at least <asm/types.h> which is referenced by libbpf.
#
# llvm provides llvm-objcopy which is used to build the BTF relocation tests.
#
# [0] https://github.com/actions/runner-images/blob/ubuntu22/20230724.1/images/linux/Ubuntu2204-Readme.md
#
# [1] https://github.com/llvm/llvm-project/commit/dc1c43d
run: |
set -euxo pipefail
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy main | sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt-get update
sudo apt-get -y install clang gcc-multilib llvm
- name: Build
run: |
set -euxo pipefail
mkdir -p integration-test-binaries
# See https://doc.rust-lang.org/cargo/reference/profiles.html for the
# names of the builtin profiles. Note that dev builds "debug" targets.
cargo xtask build-integration-test --cargo-arg=--profile=dev | xargs -I % cp % integration-test-binaries/dev
cargo xtask build-integration-test --cargo-arg=--profile=release | xargs -I % cp % integration-test-binaries/release
- uses: actions/upload-artifact@v3
with:
name: integration-test-binaries
path: integration-test-binaries

run-integration-test:
runs-on: macos-latest
needs: ["build-integration-test"]
steps:
- uses: actions/checkout@v3
with:
sparse-checkout: |
test/run.sh
test/cloud-localds
- name: Install Pre-requisites
run: |
brew install qemu gnu-getopt coreutils cdrtools
Expand All @@ -161,20 +209,25 @@ jobs:
.tmp/*.qcow2
.tmp/test_rsa
.tmp/test_rsa.pub
# FIXME: we should invalidate the cache on new bpf-linker releases.
# For now we must manually delete the cache when we release a new
# bpf-linker version.
key: tmp-files-${{ hashFiles('test/run.sh') }}

- uses: actions/download-artifact@v3
with:
name: integration-test-binaries
path: integration-test-binaries

- name: Run integration tests
run: test/run.sh --cargo-arg=--profile=${{ matrix.profile }}
run: |
set -euxo pipefail
find integration-test-binaries -type f -exec chmod +x {} \;
test/run.sh integration-test-binaries
# Provides a single status check for the entire build workflow.
# This is used for merge automation, like Mergify, since GH actions
# has no concept of "when all status checks pass".
# https://docs.mergify.com/conditions/#validating-all-status-checks
build-workflow-complete:
needs: ["lint", "build-test-aya", "build-test-aya-bpf", "integration-test"]
needs: ["lint", "build-test-aya", "build-test-aya-bpf", "run-integration-test"]
runs-on: ubuntu-latest
steps:
- name: Build Complete
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ netns-rs = { version = "0.1", default-features = false }
num_enum = { version = "0.6", default-features = false }
object = { version = "0.31", default-features = false }
parking_lot = { version = "0.12.0", default-features = false }
proc-macro2 = { version = "1", default-features = false }
proc-macro-error = { version = "1.0", default-features = false }
proc-macro2 = { version = "1", default-features = false }
public-api = { version = "0.31.2", default-features = false }
quote = { version = "1", default-features = false }
rbpf = { version = "0.2.0", default-features = false }
Expand All @@ -85,6 +85,7 @@ rustup-toolchain = { version = "0.1.5", default-features = false }
rustversion = { version = "1.0.0", default-features = false }
syn = { version = "2", default-features = false }
tempfile = { version = "3", default-features = false }
test-case = { version = "3.1.0", default-features = false }
testing_logger = { version = "0.1.1", default-features = false }
thiserror = { version = "1", default-features = false }
tokio = { version = "1.24.0", default-features = false }
Expand Down
32 changes: 16 additions & 16 deletions aya/src/programs/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,16 +403,16 @@ mod tests {
let id1 = links.insert(l1).unwrap();
let id2 = links.insert(l2).unwrap();

assert!(*l1_detached.borrow() == 0);
assert!(*l2_detached.borrow() == 0);
assert_eq!(*l1_detached.borrow(), 0);
assert_eq!(*l2_detached.borrow(), 0);

assert!(links.remove(id1).is_ok());
assert!(*l1_detached.borrow() == 1);
assert!(*l2_detached.borrow() == 0);
assert_eq!(*l1_detached.borrow(), 1);
assert_eq!(*l2_detached.borrow(), 0);

assert!(links.remove(id2).is_ok());
assert!(*l1_detached.borrow() == 1);
assert!(*l2_detached.borrow() == 1);
assert_eq!(*l1_detached.borrow(), 1);
assert_eq!(*l2_detached.borrow(), 1);
}

#[test]
Expand Down Expand Up @@ -451,12 +451,12 @@ mod tests {
links.insert(l2).unwrap();
// manually remove one link
assert!(links.remove(id1).is_ok());
assert!(*l1_detached.borrow() == 1);
assert!(*l2_detached.borrow() == 0);
assert_eq!(*l1_detached.borrow(), 1);
assert_eq!(*l2_detached.borrow(), 0);
}
// remove the other on drop
assert!(*l1_detached.borrow() == 1);
assert!(*l2_detached.borrow() == 1);
assert_eq!(*l1_detached.borrow(), 1);
assert_eq!(*l2_detached.borrow(), 1);
}

#[test]
Expand All @@ -472,19 +472,19 @@ mod tests {
links.insert(l2).unwrap();
// manually forget one link
let owned_l1 = links.forget(id1);
assert!(*l1_detached.borrow() == 0);
assert!(*l2_detached.borrow() == 0);
assert_eq!(*l1_detached.borrow(), 0);
assert_eq!(*l2_detached.borrow(), 0);
owned_l1.unwrap()
};

// l2 is detached on `Drop`, but l1 is still alive
assert!(*l1_detached.borrow() == 0);
assert!(*l2_detached.borrow() == 1);
assert_eq!(*l1_detached.borrow(), 0);
assert_eq!(*l2_detached.borrow(), 1);

// manually detach l1
assert!(owned_l1.detach().is_ok());
assert!(*l1_detached.borrow() == 1);
assert!(*l2_detached.borrow() == 1);
assert_eq!(*l1_detached.borrow(), 1);
assert_eq!(*l2_detached.borrow(), 1);
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ cargo xtask integration-test
### Virtualized

```
./test/run.sh
mkdir -p integration-test-binaries
cargo xtask build-integration-test | xargs -I % cp % integration-test-binaries
./test/run.sh integration-test-binaries
```

### Writing an integration test
Expand Down
1 change: 1 addition & 0 deletions test/integration-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ log = { workspace = true }
netns-rs = { workspace = true }
object = { workspace = true }
rbpf = { workspace = true }
test-case = { workspace = true }
tokio = { workspace = true, default-features = false, features = [
"macros",
"time",
Expand Down
106 changes: 106 additions & 0 deletions test/integration-test/bpf/reloc.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// clang-format off
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
// clang-format on

char _license[] __attribute__((section("license"), used)) = "GPL";

struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__type(key, __u32);
__type(value, __u64);
__uint(max_entries, 1);
} output_map SEC(".maps");

long set_output(__u64 value) {
__u32 key = 0;
return bpf_map_update_elem(&output_map, &key, &value, BPF_ANY);
}

struct relocated_struct_with_scalars {
__u8 a;
__u8 b;
__u8 c;
};

__attribute__((noinline)) int field_global() {
struct relocated_struct_with_scalars s = {1, 2, 3};
return set_output(__builtin_preserve_access_index(s.b));
}

SEC("uprobe/field") int field(void *ctx) {
return field_global();
}

struct relocated_struct_with_pointer {
struct relocated_struct_with_pointer *first;
struct relocated_struct_with_pointer *second;
};

__attribute__((noinline)) int pointer_global() {
struct relocated_struct_with_pointer s = {
(struct relocated_struct_with_pointer *)42,
(struct relocated_struct_with_pointer *)21,
};
return set_output((__u64)__builtin_preserve_access_index(s.first));
}

SEC("uprobe/pointer") int pointer(void *ctx) {
return pointer_global();
}

__attribute__((noinline)) int struct_flavors_global() {
struct relocated_struct_with_scalars s = {1, 2, 3};
if (bpf_core_field_exists(s.a)) {
return set_output(__builtin_preserve_access_index(s.a));
} else {
return set_output(__builtin_preserve_access_index(s.b));
}
}

SEC("uprobe/struct_flavors") int struct_flavors(void *ctx) {
return struct_flavors_global();
}

enum relocated_enum_unsigned_32 { U32 = 0xAAAAAAAA };

__attribute__((noinline)) int enum_unsigned_32_global() {
return set_output(bpf_core_enum_value(enum relocated_enum_unsigned_32, U32));
}

SEC("uprobe/enum_unsigned_32")
int enum_unsigned_32(void *ctx) {
return enum_unsigned_32_global();
}

enum relocated_enum_signed_32 { S32 = -0x7AAAAAAA };

__attribute__((noinline)) int enum_signed_32_global() {
return set_output(bpf_core_enum_value(enum relocated_enum_signed_32, S32));
}

SEC("uprobe/enum_signed_32") int enum_signed_32(void *ctx) {
return enum_signed_32_global();
}

enum relocated_enum_unsigned_64 { U64 = 0xAAAAAAAABBBBBBBB };

__attribute__((noinline)) int enum_unsigned_64_global() {
return set_output(bpf_core_enum_value(enum relocated_enum_unsigned_64, U64));
}

SEC("uprobe/enum_unsigned_64")
int enum_unsigned_64(void *ctx) {
return enum_unsigned_64_global();
}

enum relocated_enum_signed_64 { u64 = -0xAAAAAAABBBBBBBB };

__attribute__((noinline)) int enum_signed_64_global() {
return set_output(bpf_core_enum_value(enum relocated_enum_signed_64, u64));
}

SEC("uprobe/enum_signed_64") int enum_signed_64(void *ctx) {
return enum_signed_64_global();
}
Loading

0 comments on commit 3692e53

Please sign in to comment.