Check that __system_property_set() doesn't leak FDs

Bug: 143936364
Test: fail when b/143936364 repros
Test: pass when b/143936364 is fixed
Change-Id: I01d061c4fb4f37b0300ef418a19c88003038092c
This commit is contained in:
Tom Cherry 2019-11-05 11:31:42 -08:00
parent ef18d440d9
commit fd7216cc19
2 changed files with 57 additions and 5 deletions

View File

@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
#include <gtest/gtest.h>
#include <errno.h> #include <errno.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
@ -24,6 +22,10 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <gtest/gtest.h>
#include "utils.h"
#if defined(__BIONIC__) #if defined(__BIONIC__)
#include <sys/system_properties.h> #include <sys/system_properties.h>
int64_t NanoTime() { int64_t NanoTime() {
@ -128,6 +130,29 @@ TEST(properties, smoke) {
#endif // __BIONIC__ #endif // __BIONIC__
} }
TEST(properties, no_fd_leaks) {
#if defined(__BIONIC__)
FdLeakChecker leak_checker;
std::stringstream ss;
ss << "debug.test." << getpid() << "." << NanoTime() << ".";
const std::string property_prefix = ss.str();
const std::string property_name = property_prefix + "property1";
for (size_t i = 0; i < 100; ++i) {
char propvalue[PROP_VALUE_MAX];
ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1"));
ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue));
ASSERT_STREQ("value1", propvalue);
ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value2"));
ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue));
ASSERT_STREQ("value2", propvalue);
}
#else // __BIONIC__
GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
TEST(properties, empty_value) { TEST(properties, empty_value) {
#if defined(__BIONIC__) #if defined(__BIONIC__)
char propvalue[PROP_VALUE_MAX]; char propvalue[PROP_VALUE_MAX];
@ -136,7 +161,7 @@ TEST(properties, empty_value) {
ss << "debug.test." << getpid() << "." << NanoTime() << "." << "property_empty"; ss << "debug.test." << getpid() << "." << NanoTime() << "." << "property_empty";
const std::string property_name = ss.str(); const std::string property_name = ss.str();
for (size_t i=0; i<1000; ++i) { for (size_t i = 0; i < 1000; ++i) {
ASSERT_EQ(0, __system_property_set(property_name.c_str(), "")); ASSERT_EQ(0, __system_property_set(property_name.c_str(), ""));
ASSERT_EQ(0, __system_property_get(property_name.c_str(), propvalue)); ASSERT_EQ(0, __system_property_get(property_name.c_str(), propvalue));
ASSERT_STREQ("", propvalue); ASSERT_STREQ("", propvalue);

View File

@ -16,6 +16,7 @@
#pragma once #pragma once
#include <dirent.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
@ -253,3 +254,29 @@ class ExecTestHelper {
std::string output_; std::string output_;
}; };
#endif #endif
class FdLeakChecker {
public:
FdLeakChecker() {
}
~FdLeakChecker() {
size_t end_count = CountOpenFds();
EXPECT_EQ(start_count_, end_count);
}
private:
static size_t CountOpenFds() {
auto fd_dir = std::unique_ptr<DIR, decltype(&closedir)>{ opendir("/proc/self/fd"), closedir };
size_t count = 0;
dirent* de = nullptr;
while ((de = readdir(fd_dir.get())) != nullptr) {
if (de->d_type == DT_LNK) {
++count;
}
}
return count;
}
size_t start_count_ = CountOpenFds();
};