diff --git a/libprocessgroup/profiles/Android.bp b/libprocessgroup/profiles/Android.bp index 15d017290..e05a69096 100644 --- a/libprocessgroup/profiles/Android.bp +++ b/libprocessgroup/profiles/Android.bp @@ -29,9 +29,21 @@ prebuilt_etc { src: "task_profiles.json", } +cc_defaults { + name: "libprocessgroup_test_defaults", + cflags: [ + "-Wall", + "-Werror", + + // Needed for headers from libprotobuf. + "-Wno-unused-parameter", + ], +} + cc_library_static { name: "libprocessgroup_proto", host_supported: true, + defaults: ["libprocessgroup_test_defaults"], srcs: [ "cgroups.proto", "task_profiles.proto", @@ -40,15 +52,11 @@ cc_library_static { type: "full", export_proto_headers: true, }, - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - ], } cc_test_host { name: "libprocessgroup_proto_test", + defaults: ["libprocessgroup_test_defaults"], srcs: [ "test.cpp", ], @@ -64,11 +72,6 @@ cc_test_host { shared_libs: [ "libprotobuf-cpp-full", ], - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - ], data: [ "cgroups.json", "cgroups.recovery.json", @@ -78,3 +81,28 @@ cc_test_host { "general-tests", ], } + +cc_test { + name: "vts_processgroup_validate_test", + defaults: ["libprocessgroup_test_defaults"], + srcs: [ + "test_vendor.cpp", + ], + static_libs: [ + "libgmock", + "libjsonpbverify", + "libjsonpbparse", + "libprocessgroup_proto", + ], + shared_libs: [ + "libbase", + "liblog", + "libjsoncpp", + "libprotobuf-cpp-full", + ], + target: { + android: { + test_config: "vts_processgroup_validate_test.xml", + }, + }, +} diff --git a/libprocessgroup/profiles/Android.mk b/libprocessgroup/profiles/Android.mk new file mode 100644 index 000000000..eab96d431 --- /dev/null +++ b/libprocessgroup/profiles/Android.mk @@ -0,0 +1,21 @@ +# +# Copyright (C) 2019 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 $(CLEAR_VARS) +LOCAL_MODULE := VtsProcessgroupValidateTest +-include test/vts/tools/build/Android.host_config.mk diff --git a/libprocessgroup/profiles/cgroups_test.h b/libprocessgroup/profiles/cgroups_test.h new file mode 100644 index 000000000..13099573c --- /dev/null +++ b/libprocessgroup/profiles/cgroups_test.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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. + */ + +#pragma once + +#include + +#include +#include + +#include "cgroups.pb.h" + +using ::testing::MatchesRegex; + +namespace android { +namespace profiles { + +class CgroupsTest : public jsonpb::JsonSchemaTest { + public: + void SetUp() override { + JsonSchemaTest::SetUp(); + cgroups_ = static_cast(message()); + } + Cgroups* cgroups_; +}; + +TEST_P(CgroupsTest, CgroupRequiredFields) { + for (int i = 0; i < cgroups_->cgroups_size(); ++i) { + auto&& cgroup = cgroups_->cgroups(i); + EXPECT_FALSE(cgroup.controller().empty()) + << "No controller name for cgroup #" << i << " in " << file_path_; + EXPECT_FALSE(cgroup.path().empty()) << "No path for cgroup #" << i << " in " << file_path_; + } +} + +TEST_P(CgroupsTest, Cgroup2RequiredFields) { + if (cgroups_->has_cgroups2()) { + EXPECT_FALSE(cgroups_->cgroups2().path().empty()) + << "No path for cgroup2 in " << file_path_; + } +} + +// "Mode" field must be in the format of "0xxx". +static inline constexpr const char* REGEX_MODE = "(0[0-7]{3})?"; +TEST_P(CgroupsTest, CgroupMode) { + for (int i = 0; i < cgroups_->cgroups_size(); ++i) { + EXPECT_THAT(cgroups_->cgroups(i).mode(), MatchesRegex(REGEX_MODE)) + << "For cgroup controller #" << i << " in " << file_path_; + } +} + +TEST_P(CgroupsTest, Cgroup2Mode) { + EXPECT_THAT(cgroups_->cgroups2().mode(), MatchesRegex(REGEX_MODE)) + << "For cgroups2 in " << file_path_; +} + +} // namespace profiles +} // namespace android diff --git a/libprocessgroup/profiles/task_profiles_test.h b/libprocessgroup/profiles/task_profiles_test.h new file mode 100644 index 000000000..32f122d96 --- /dev/null +++ b/libprocessgroup/profiles/task_profiles_test.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 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. + */ + +#pragma once + +#include + +#include +#include + +#include "task_profiles.pb.h" + +namespace android { +namespace profiles { + +class TaskProfilesTest : public jsonpb::JsonSchemaTest { + public: + void SetUp() override { + JsonSchemaTest::SetUp(); + task_profiles_ = static_cast(message()); + } + TaskProfiles* task_profiles_; +}; + +TEST_P(TaskProfilesTest, AttributeRequiredFields) { + for (int i = 0; i < task_profiles_->attributes_size(); ++i) { + auto&& attribute = task_profiles_->attributes(i); + EXPECT_FALSE(attribute.name().empty()) + << "No name for attribute #" << i << " in " << file_path_; + EXPECT_FALSE(attribute.controller().empty()) + << "No controller for attribute #" << i << " in " << file_path_; + EXPECT_FALSE(attribute.file().empty()) + << "No file for attribute #" << i << " in " << file_path_; + } +} + +TEST_P(TaskProfilesTest, ProfileRequiredFields) { + for (int profile_idx = 0; profile_idx < task_profiles_->profiles_size(); ++profile_idx) { + auto&& profile = task_profiles_->profiles(profile_idx); + EXPECT_FALSE(profile.name().empty()) + << "No name for profile #" << profile_idx << " in " << file_path_; + for (int action_idx = 0; action_idx < profile.actions_size(); ++action_idx) { + auto&& action = profile.actions(action_idx); + EXPECT_FALSE(action.name().empty()) + << "No name for profiles[" << profile_idx << "].actions[" << action_idx + << "] in " << file_path_; + } + } +} + +} // namespace profiles +} // namespace android diff --git a/libprocessgroup/profiles/test.cpp b/libprocessgroup/profiles/test.cpp index 8ba14d603..bc9aade88 100644 --- a/libprocessgroup/profiles/test.cpp +++ b/libprocessgroup/profiles/test.cpp @@ -14,18 +14,15 @@ * limitations under the License. */ -#include - #include -#include +#include #include -#include "cgroups.pb.h" -#include "task_profiles.pb.h" +#include "cgroups_test.h" +#include "task_profiles_test.h" using namespace ::android::jsonpb; using ::android::base::GetExecutableDirectory; -using ::testing::MatchesRegex; namespace android { namespace profiles { @@ -35,87 +32,7 @@ JsonSchemaTestConfigFactory MakeTestParam(const std::string& path) { return jsonpb::MakeTestParam(GetExecutableDirectory() + path); } -TEST(LibProcessgroupProto, EmptyMode) { - EXPECT_EQ(0, strtoul("", nullptr, 8)) - << "Empty mode string cannot be silently converted to 0; this should not happen"; -} - -class CgroupsTest : public JsonSchemaTest { - public: - void SetUp() override { - JsonSchemaTest::SetUp(); - cgroups_ = static_cast(message()); - } - Cgroups* cgroups_; -}; - -TEST_P(CgroupsTest, CgroupRequiredFields) { - for (int i = 0; i < cgroups_->cgroups_size(); ++i) { - auto&& cgroup = cgroups_->cgroups(i); - EXPECT_FALSE(cgroup.controller().empty()) - << "No controller name for cgroup #" << i << " in " << file_path_; - EXPECT_FALSE(cgroup.path().empty()) << "No path for cgroup #" << i << " in " << file_path_; - } -} - -TEST_P(CgroupsTest, Cgroup2RequiredFields) { - if (cgroups_->has_cgroups2()) { - EXPECT_FALSE(cgroups_->cgroups2().path().empty()) - << "No path for cgroup2 in " << file_path_; - } -} - -// "Mode" field must be in the format of "0xxx". -static constexpr const char* REGEX_MODE = "(0[0-7]{3})?"; -TEST_P(CgroupsTest, CgroupMode) { - for (int i = 0; i < cgroups_->cgroups_size(); ++i) { - EXPECT_THAT(cgroups_->cgroups(i).mode(), MatchesRegex(REGEX_MODE)) - << "For cgroup controller #" << i << " in " << file_path_; - } -} - -TEST_P(CgroupsTest, Cgroup2Mode) { - EXPECT_THAT(cgroups_->cgroups2().mode(), MatchesRegex(REGEX_MODE)) - << "For cgroups2 in " << file_path_; -} - -class TaskProfilesTest : public JsonSchemaTest { - public: - void SetUp() override { - JsonSchemaTest::SetUp(); - task_profiles_ = static_cast(message()); - } - TaskProfiles* task_profiles_; -}; - -TEST_P(TaskProfilesTest, AttributeRequiredFields) { - for (int i = 0; i < task_profiles_->attributes_size(); ++i) { - auto&& attribute = task_profiles_->attributes(i); - EXPECT_FALSE(attribute.name().empty()) - << "No name for attribute #" << i << " in " << file_path_; - EXPECT_FALSE(attribute.controller().empty()) - << "No controller for attribute #" << i << " in " << file_path_; - EXPECT_FALSE(attribute.file().empty()) - << "No file for attribute #" << i << " in " << file_path_; - } -} - -TEST_P(TaskProfilesTest, ProfileRequiredFields) { - for (int profile_idx = 0; profile_idx < task_profiles_->profiles_size(); ++profile_idx) { - auto&& profile = task_profiles_->profiles(profile_idx); - EXPECT_FALSE(profile.name().empty()) - << "No name for profile #" << profile_idx << " in " << file_path_; - for (int action_idx = 0; action_idx < profile.actions_size(); ++action_idx) { - auto&& action = profile.actions(action_idx); - EXPECT_FALSE(action.name().empty()) - << "No name for profiles[" << profile_idx << "].actions[" << action_idx - << "] in " << file_path_; - } - } -} - // Test suite instantiations - INSTANTIATE_TEST_SUITE_P(, JsonSchemaTest, ::testing::Values(MakeTestParam("/cgroups.json"), MakeTestParam("/cgroups.recovery.json"), diff --git a/libprocessgroup/profiles/test_vendor.cpp b/libprocessgroup/profiles/test_vendor.cpp new file mode 100644 index 000000000..3ec7fcfb5 --- /dev/null +++ b/libprocessgroup/profiles/test_vendor.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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 +#include +#include + +#include "cgroups_test.h" +#include "task_profiles_test.h" + +using ::android::base::GetExecutableDirectory; +using namespace ::android::jsonpb; + +namespace android { +namespace profiles { + +static constexpr const char* kVendorCgroups = "/vendor/etc/cgroups.json"; +static constexpr const char* kVendorTaskProfiles = "/vendor/etc/task_profiles.json"; + +template +class TestConfig : public JsonSchemaTestConfig { + public: + TestConfig(const std::string& path) : file_path_(path){}; + std::unique_ptr CreateMessage() const override { + return std::make_unique(); + } + std::string file_path() const override { return file_path_; } + bool optional() const override { + // Ignore when vendor JSON files are missing. + return true; + } + + private: + std::string file_path_; +}; + +template +JsonSchemaTestConfigFactory MakeTestParam(const std::string& path) { + return [path]() { return std::make_unique>(path); }; +} + +INSTANTIATE_TEST_SUITE_P(VendorCgroups, JsonSchemaTest, + ::testing::Values(MakeTestParam(kVendorCgroups))); +INSTANTIATE_TEST_SUITE_P(VendorCgroups, CgroupsTest, + ::testing::Values(MakeTestParam(kVendorCgroups))); + +INSTANTIATE_TEST_SUITE_P(VendorTaskProfiles, JsonSchemaTest, + ::testing::Values(MakeTestParam(kVendorTaskProfiles))); +INSTANTIATE_TEST_SUITE_P(VendorTaskProfiles, TaskProfilesTest, + ::testing::Values(MakeTestParam(kVendorTaskProfiles))); + +} // namespace profiles +} // namespace android + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/libprocessgroup/profiles/vts_processgroup_validate_test.xml b/libprocessgroup/profiles/vts_processgroup_validate_test.xml new file mode 100644 index 000000000..21d29cdbb --- /dev/null +++ b/libprocessgroup/profiles/vts_processgroup_validate_test.xml @@ -0,0 +1,29 @@ + + + +