diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk index 4a5ca4f66f..7b2400fdf7 100644 --- a/memtrack/1.0/vts/Android.mk +++ b/memtrack/1.0/vts/Android.mk @@ -48,3 +48,4 @@ LOCAL_PROTOC_OPTIMIZE_TYPE := full include $(BUILD_SHARED_LIBRARY) +include $(LOCAL_PATH)/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp new file mode 100644 index 0000000000..b3e560ac95 --- /dev/null +++ b/memtrack/1.0/vts/functional/Android.bp @@ -0,0 +1,40 @@ +// +// Copyright (C) 2016 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. +// + +cc_test { + name: "memtrack_hidl_hal_test", + gtest: true, + srcs: ["memtrack_hidl_hal_test.cpp"], + shared_libs: [ + "libbase", + "liblog", + "libcutils", + "libhardware", + "libhidlbase", + "libhwbinder", + "libutils", + "android.hardware.memtrack@1.0", + ], + static_libs: ["libgtest"], + cflags: [ + "--coverage", + "-O0", + "-g", + ], + ldflags: [ + "--coverage" + ] +} diff --git a/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp new file mode 100644 index 0000000000..597b5da9e6 --- /dev/null +++ b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2016 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. + */ + +#define LOG_TAG "memtrack_hidl_hal_test" +#include +#include + +#include + +#include +#include + +using ::android::hardware::memtrack::V1_0::IMemtrack; +using ::android::hardware::memtrack::V1_0::MemtrackRecord; +using ::android::hardware::memtrack::V1_0::MemtrackFlag; +using ::android::hardware::memtrack::V1_0::MemtrackType; +using ::android::hardware::memtrack::V1_0::MemtrackStatus; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::sp; +using std::vector; +using std::count_if; + +class MemtrackHidlTest : public ::testing::Test { + public: + virtual void SetUp() override { + memtrack = IMemtrack::getService("memtrack"); + ASSERT_NE(memtrack, nullptr); + } + + virtual void TearDown() override {} + + sp memtrack; +}; + +/* Returns true if flags contains at least min, and no more than max, + * of the flags in flagSet. Returns false otherwise. + */ +bool rightFlagCount(uint32_t flags, vector flagSet, uint32_t min, + uint32_t max) { + uint32_t count = + count_if(flagSet.begin(), flagSet.end(), + [&](MemtrackFlag f) { return flags & (uint32_t)f; }); + return (min <= count && count <= max); +} + +/* Returns true when passed a valid, defined status, false otherwise. + */ +bool validStatus(MemtrackStatus s) { + vector statusVec = { + MemtrackStatus::SUCCESS, MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED, + MemtrackStatus::TYPE_NOT_SUPPORTED}; + return std::find(statusVec.begin(), statusVec.end(), s) != statusVec.end(); +} + +/* Returns a pid found in /proc for which the string read from + * /proc/[pid]/cmdline matches cmd, or -1 if no such pid exists. + */ +pid_t getPidFromCmd(const char cmd[], uint32_t len) { + const char procs[] = "/proc/"; + DIR *dir = opendir(procs); + if (!dir) { + return -1; + } + + struct dirent *proc; + while ((proc = readdir(dir)) != NULL) { + if (!isdigit(proc->d_name[0])) { + continue; + } + char line[len]; + char fname[PATH_MAX]; + snprintf(fname, PATH_MAX, "/proc/%s/cmdline", proc->d_name); + + FILE *file = fopen(fname, "r"); + if (!file) { + continue; + } + char *str = fgets(line, len, file); + fclose(file); + if (!str || strcmp(str, cmd)) { + continue; + } else { + closedir(dir); + return atoi(proc->d_name); + } + } + closedir(dir); + return -1; +} + +auto generate_cb(MemtrackStatus *s, hidl_vec *v) { + return [=](MemtrackStatus status, hidl_vec vec) { + *s = status; + *v = vec; + }; +} + +/* Sanity check results when getMemory() is passed a negative PID + */ +TEST_F(MemtrackHidlTest, BadPidTest) { + MemtrackStatus s; + hidl_vec v; + auto cb = generate_cb(&s, &v); + for (uint32_t i = 0; i < static_cast(MemtrackType::NUM_TYPES); + i++) { + Return ret = + memtrack->getMemory(-1, static_cast(i), cb); + ASSERT_TRUE(ret.isOk()); + ASSERT_TRUE(validStatus(s)); + } +} + +/* Sanity check results when getMemory() is passed a bad memory usage type + */ +TEST_F(MemtrackHidlTest, BadTypeTest) { + MemtrackStatus s; + hidl_vec v; + auto cb = generate_cb(&s, &v); + Return ret = memtrack->getMemory(getpid(), MemtrackType::NUM_TYPES, cb); + ASSERT_TRUE(ret.isOk()); + ASSERT_TRUE(validStatus(s)); +} + +/* Call memtrack on the surfaceflinger process and check that the results are + * reasonable for all memory types, including valid flag combinations for + * every MemtrackRecord returned. + */ +TEST_F(MemtrackHidlTest, SurfaceflingerTest) { + const char cmd[] = "/system/bin/surfaceflinger"; + const uint32_t len = sizeof(cmd); + pid_t pid = getPidFromCmd(cmd, len); + ASSERT_LE(0, pid) << "Surfaceflinger process not found"; + + MemtrackStatus s; + hidl_vec v; + auto cb = generate_cb(&s, &v); + uint32_t unsupportedCount = 0; + for (uint32_t i = 0; i < static_cast(MemtrackType::NUM_TYPES); + i++) { + Return ret = + memtrack->getMemory(pid, static_cast(i), cb); + ASSERT_TRUE(ret.isOk()); + + switch (s) { + case MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED: + unsupportedCount++; + break; + case MemtrackStatus::TYPE_NOT_SUPPORTED: + break; + case MemtrackStatus::SUCCESS: { + for (uint32_t j = 0; j < v.size(); j++) { + // Enforce flag constraints + vector smapFlags = {MemtrackFlag::SMAPS_ACCOUNTED, + MemtrackFlag::SMAPS_UNACCOUNTED}; + EXPECT_TRUE(rightFlagCount(v[j].flags, smapFlags, 1, 1)); + vector shareFlags = {MemtrackFlag::SHARED, + MemtrackFlag::SHARED_PSS, + MemtrackFlag::PRIVATE}; + EXPECT_TRUE(rightFlagCount(v[j].flags, shareFlags, 0, 1)); + vector systemFlags = {MemtrackFlag::SYSTEM, + MemtrackFlag::DEDICATED}; + EXPECT_TRUE(rightFlagCount(v[j].flags, systemFlags, 0, 1)); + vector secureFlags = {MemtrackFlag::SECURE, + MemtrackFlag::NONSECURE}; + EXPECT_TRUE(rightFlagCount(v[j].flags, secureFlags, 0, 1)); + } + break; + } + default: + FAIL(); + } + } + // If tracking is not supported this should be returned for all types. + ASSERT_TRUE(unsupportedCount == 0 || + unsupportedCount == + static_cast(MemtrackType::NUM_TYPES)); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + return status; +} diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk new file mode 100644 index 0000000000..8dcaabb66c --- /dev/null +++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2016 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(call all-subdir-makefiles) + +include $(CLEAR_VARS) + +LOCAL_MODULE := HalMemtrackHidlTargetTest +VTS_CONFIG_SRC_DIR := testcases/hal/memtrack/hidl/target +include test/vts/tools/build/Android.host_config.mk diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml new file mode 100644 index 0000000000..7fb286b9d4 --- /dev/null +++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config new file mode 100644 index 0000000000..d2597a2037 --- /dev/null +++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config @@ -0,0 +1,20 @@ +{ + "use_gae_db": true, + "coverage": true, + "modules": [ + { + "module_name": "system/lib64/hw/memtrack.msm8992", + "git_project": { + "name": "platform/hardware/qcom/display", + "path": "hardware/qcom/display" + } + }, + { + "module_name": "system/lib64/hw/android.hardware.memtrack@1.0-impl", + "git_project": { + "name": "platform/hardware/interfaces", + "path": "hardware/interfaces" + } + } + ] +} diff --git a/memtrack/Android.bp b/memtrack/Android.bp index ba90f2c9d1..ed19a37034 100644 --- a/memtrack/Android.bp +++ b/memtrack/Android.bp @@ -2,4 +2,5 @@ subdirs = [ "1.0", "1.0/default", + "1.0/vts/functional", ]