Idletimer-related commands porting
Test: built, flashed, booted
system/netd/tests/runtests.sh passes
Change-Id: I10eec44acca8e4d5a7c8de64b89590e3cccda597
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 689e2e6..e97d191 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -57,6 +57,8 @@
#define IP6TABLES_PATH "/system/bin/ip6tables"
#define IPTABLES_PATH "/system/bin/iptables"
#define TUN_DEV "/dev/tun"
+#define RAW_TABLE "raw"
+#define MANGLE_TABLE "mangle"
using namespace android;
using namespace android::base;
@@ -150,7 +152,6 @@
static std::vector<std::string> runCommand(const std::string& command) {
std::vector<std::string> lines;
-
FILE *f = popen(command.c_str(), "r"); // NOLINT(cert-env33-c)
if (f == nullptr) {
perror("popen");
@@ -958,3 +959,78 @@
expectNoTestCounterRules();
}
+namespace {
+
+constexpr char chainName_LOCAL_RAW_PREROUTING[] = "idletimer_raw_PREROUTING";
+constexpr char chainName_MANGLE_POSTROUTING[] = "idletimer_mangle_POSTROUTING";
+
+static std::vector<std::string> listIptablesRuleByTable(const char* binary, const char* table,
+ const char* chainName) {
+ std::string command = StringPrintf("%s -t %s -w -n -v -L %s", binary, table, chainName);
+ return runCommand(command);
+}
+
+bool iptablesIdleTimerInterfcaeRuleExists(const char* binary, const char* chainName,
+ const std::string& expectedInterface,
+ const std::string& expectedRule, const char* table) {
+ std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
+ for (const auto& rule : rules) {
+ if (rule.find(expectedInterface) != std::string::npos) {
+ if (rule.find(expectedRule) != std::string::npos) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void expectIdletimerInterfaceRuleExists(const std::string& ifname, int timeout,
+ const std::string& classLable) {
+ std::string IdletimerRule =
+ StringPrintf("timeout:%u label:%s send_nl_msg:1", timeout, classLable.c_str());
+ for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
+ EXPECT_TRUE(iptablesIdleTimerInterfcaeRuleExists(binary, chainName_LOCAL_RAW_PREROUTING,
+ ifname, IdletimerRule, RAW_TABLE));
+ EXPECT_TRUE(iptablesIdleTimerInterfcaeRuleExists(binary, chainName_MANGLE_POSTROUTING,
+ ifname, IdletimerRule, MANGLE_TABLE));
+ }
+}
+
+void expectIdletimerInterfaceRuleNotExists(const std::string& ifname, int timeout,
+ const std::string& classLable) {
+ std::string IdletimerRule =
+ StringPrintf("timeout:%u label:%s send_nl_msg:1", timeout, classLable.c_str());
+ for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
+ EXPECT_FALSE(iptablesIdleTimerInterfcaeRuleExists(binary, chainName_LOCAL_RAW_PREROUTING,
+ ifname, IdletimerRule, RAW_TABLE));
+ EXPECT_FALSE(iptablesIdleTimerInterfcaeRuleExists(binary, chainName_MANGLE_POSTROUTING,
+ ifname, IdletimerRule, MANGLE_TABLE));
+ }
+}
+
+TEST_F(BinderTest, TestIdletimerAddRemoveInterface) {
+ // TODO: We will get error in if expectIdletimerInterfaceRuleNotExists if there are the same
+ // rule in the table. Because we only check the result after calling remove function. We might
+ // check the actual rule which is removed by our function (maybe compare the results between
+ // calling function before and after)
+ binder::Status status;
+ const struct TestData {
+ const std::string ifname;
+ int32_t timeout;
+ const std::string classLabel;
+ } idleTestData[] = {
+ {"wlan0", 1234, "happyday"},
+ {"rmnet_data0", 4567, "friday"},
+ };
+ for (const auto& td : idleTestData) {
+ status = mNetd->idletimerAddInterface(td.ifname, td.timeout, td.classLabel);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectIdletimerInterfaceRuleExists(td.ifname, td.timeout, td.classLabel);
+
+ status = mNetd->idletimerRemoveInterface(td.ifname, td.timeout, td.classLabel);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectIdletimerInterfaceRuleNotExists(td.ifname, td.timeout, td.classLabel);
+ }
+}
+
+} // namespace
\ No newline at end of file