android_system_bpf/libbpf_android/BpfLoadTest.cpp
Connor O'Brien 509131481d libbpf_load_test: use "data" instead of "required" for test progs
atest appears not to know how to push dependencies listed with the
"required" property, but it will push "data" modules to the same
folder as the test itself. Update Android.bp to use data instead, and
change BpfLoadTest.cpp to reflect the new location of the test
programs.

Test: atest libbpf_load_test
Bug: 203823368
Signed-off-by: Connor O'Brien <connoro@google.com>
Change-Id: Iabec3662e2c03f4ab19e5cdce859e4238767519d
2022-01-28 12:26:16 -08:00

126 lines
3.8 KiB
C++

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/file.h>
#include <android-base/macros.h>
#include <gtest/gtest.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include "bpf/BpfMap.h"
#include "bpf/BpfUtils.h"
#include "include/libbpf_android.h"
using ::testing::TestWithParam;
namespace android {
namespace bpf {
class BpfLoadTest : public TestWithParam<std::string> {
protected:
BpfLoadTest() {}
int mProgFd;
std::string mTpProgPath;
std::string mTpNeverLoadProgPath;
std::string mTpMapPath;;
void SetUp() {
mTpProgPath = "/sys/fs/bpf/prog_" + GetParam() + "_tracepoint_sched_sched_switch";
unlink(mTpProgPath.c_str());
mTpNeverLoadProgPath = "/sys/fs/bpf/prog_" + GetParam() + "_tracepoint_sched_sched_wakeup";
unlink(mTpNeverLoadProgPath.c_str());
mTpMapPath = "/sys/fs/bpf/map_" + GetParam() + "_cpu_pid_map";
unlink(mTpMapPath.c_str());
auto progPath = android::base::GetExecutableDirectory() + "/" + GetParam() + ".o";
bool critical = true;
EXPECT_EQ(android::bpf::loadProg(progPath.c_str(), &critical), 0);
EXPECT_EQ(false, critical);
mProgFd = bpf_obj_get(mTpProgPath.c_str());
EXPECT_GT(mProgFd, 0);
int ret = bpf_attach_tracepoint(mProgFd, "sched", "sched_switch");
EXPECT_NE(ret, 0);
}
void TearDown() {
close(mProgFd);
unlink(mTpProgPath.c_str());
unlink(mTpMapPath.c_str());
}
void checkMapNonZero() {
// The test program installs a tracepoint on sched:sched_switch
// and expects the kernel to populate a PID corresponding to CPU
android::bpf::BpfMap<uint32_t, uint32_t> m(mTpMapPath.c_str());
// Wait for program to run a little
sleep(1);
int non_zero = 0;
const auto iterFunc = [&non_zero](const uint32_t& key, const uint32_t& val,
BpfMap<uint32_t, uint32_t>& map) {
if (val && !non_zero) {
non_zero = 1;
}
UNUSED(key);
UNUSED(map);
return base::Result<void>();
};
EXPECT_RESULT_OK(m.iterateWithValue(iterFunc));
EXPECT_EQ(non_zero, 1);
}
void checkMapBtf() {
// Earlier kernels lack BPF_BTF_LOAD support
if (!isAtLeastKernelVersion(4, 19, 0)) GTEST_SKIP() << "pre-4.19 kernel does not support BTF";
const bool haveBtf = GetParam().find("btf") != std::string::npos;
std::string str;
EXPECT_EQ(android::base::ReadFileToString(mTpMapPath, &str), haveBtf);
if (haveBtf) EXPECT_FALSE(str.empty());
}
void checkKernelVersionEnforced() {
EXPECT_EQ(bpf_obj_get(mTpNeverLoadProgPath.c_str()), -1);
EXPECT_EQ(errno, ENOENT);
}
};
INSTANTIATE_TEST_SUITE_P(BpfLoadTests, BpfLoadTest,
::testing::Values("bpf_load_tp_prog",
"bpf_load_tp_prog_btf"));
TEST_P(BpfLoadTest, bpfCheckMap) {
checkMapNonZero();
}
TEST_P(BpfLoadTest, bpfCheckBtf) {
checkMapBtf();
}
TEST_P(BpfLoadTest, bpfCheckMinKernelVersionEnforced) {
checkKernelVersionEnforced();
}
} // namespace bpf
} // namespace android