From 88e8f90e7f7f133130a41e5ac542adb20f4e679c Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 30 May 2017 17:15:28 -0700 Subject: [PATCH 1/2] Audio VTS: Test now use Android.mk To validate the audio_policy_configuration.xml against a schema, libxml2 is used. Unfortunately, libxml2 uses Android.mk in oc-dev thus can not be used from the tests which uses Android.bp. It has been deemed safer to transform the tests to use Android.mk rather than backporting the Android.bp patch from master. Test: Compile Bug: 35700978 Merged-In: I800e692a6ff4f64655007c33af7e34d879ee1132 Change-Id: Ie3f2069d60be369b4c37c27e9c1cf9372323a19c Signed-off-by: Kevin Rocard --- audio/2.0/vts/Android.mk | 3 +++ audio/2.0/vts/functional/Android.bp | 39 ---------------------------- audio/2.0/vts/functional/Android.mk | 40 +++++++++++++++++++++++++++++ audio/Android.bp | 1 - 4 files changed, 43 insertions(+), 40 deletions(-) create mode 100644 audio/2.0/vts/Android.mk delete mode 100644 audio/2.0/vts/functional/Android.bp create mode 100644 audio/2.0/vts/functional/Android.mk diff --git a/audio/2.0/vts/Android.mk b/audio/2.0/vts/Android.mk new file mode 100644 index 0000000000..7a16792d14 --- /dev/null +++ b/audio/2.0/vts/Android.mk @@ -0,0 +1,3 @@ +LOCAL_PATH := $(call my-dir) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/audio/2.0/vts/functional/Android.bp b/audio/2.0/vts/functional/Android.bp deleted file mode 100644 index f5ab76f2bd..0000000000 --- a/audio/2.0/vts/functional/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) 2017 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: "VtsHalAudioV2_0TargetTest", - defaults: ["hidl_defaults"], - srcs: ["AudioPrimaryHidlHalTest.cpp"], - shared_libs: [ - "libbase", - "liblog", - "libhidlbase", - "libhidltransport", - "libutils", - "libcutils", - "android.hardware.audio@2.0", - "android.hardware.audio.common@2.0", - ], - static_libs: ["VtsHalHidlTargetTestBase"], - cflags: [ - "-O0", - "-g", - "-Wall", - "-Wextra", - "-Werror", - ], -} diff --git a/audio/2.0/vts/functional/Android.mk b/audio/2.0/vts/functional/Android.mk new file mode 100644 index 0000000000..8af18bea0e --- /dev/null +++ b/audio/2.0/vts/functional/Android.mk @@ -0,0 +1,40 @@ +# Copyright (C) 2017 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_CLANG := true +LOCAL_MODULE := VtsHalAudioV2_0TargetTest +LOCAL_CPPFLAGS := -O0 -g -Wall -Wextra -Werror +LOCAL_SRC_FILES := \ + AudioPrimaryHidlHalTest.cpp \ + +LOCAL_C_INCLUDES := external/libxml2/include + +LOCAL_STATIC_LIBRARIES := VtsHalHidlTargetTestBase +LOCAL_SHARED_LIBRARIES := \ + libbase \ + liblog \ + libhidlbase \ + libhidltransport \ + libutils \ + libcutils \ + libxml2 \ + libicuuc \ + android.hardware.audio@2.0 \ + android.hardware.audio.common@2.0 \ + +include $(BUILD_NATIVE_TEST) diff --git a/audio/Android.bp b/audio/Android.bp index c3c2be1dbd..abb2bbba03 100644 --- a/audio/Android.bp +++ b/audio/Android.bp @@ -1,7 +1,6 @@ // This is an autogenerated file, do not edit. subdirs = [ "2.0", - "2.0/vts/functional", "common/2.0", "common/2.0/default", "effect/2.0", From 19b3e43fb4e639985fde0219bb1bb491abf88537 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Wed, 24 May 2017 11:01:34 -0700 Subject: [PATCH 2/2] Audio VTS: Enforce policy configuration format Validate the audio_policy_configuration.xml supplied in /vendor against the format schema. Test: Run the VTS test on target Test: vts-tradefed run commandAndExit vts --skip-all-system-status-check --primary-abi-only --skip-preconditions --module VtsHalAudioV2_0Target -t CheckConfig.audioPolicyConfigurationValidation Bug: 35700978 Change-Id: I800e692a6ff4f64655007c33af7e34d879ee1132 Signed-off-by: Kevin Rocard --- audio/2.0/vts/functional/Android.mk | 2 + .../functional/ValidateAudioConfiguration.cpp | 22 +++ .../vts/functional/utility/ValidateXml.cpp | 141 ++++++++++++++++++ .../2.0/vts/functional/utility/ValidateXml.h | 47 ++++++ 4 files changed, 212 insertions(+) create mode 100644 audio/2.0/vts/functional/ValidateAudioConfiguration.cpp create mode 100644 audio/2.0/vts/functional/utility/ValidateXml.cpp create mode 100644 audio/2.0/vts/functional/utility/ValidateXml.h diff --git a/audio/2.0/vts/functional/Android.mk b/audio/2.0/vts/functional/Android.mk index 8af18bea0e..db08dde117 100644 --- a/audio/2.0/vts/functional/Android.mk +++ b/audio/2.0/vts/functional/Android.mk @@ -21,6 +21,8 @@ LOCAL_MODULE := VtsHalAudioV2_0TargetTest LOCAL_CPPFLAGS := -O0 -g -Wall -Wextra -Werror LOCAL_SRC_FILES := \ AudioPrimaryHidlHalTest.cpp \ + ValidateAudioConfiguration.cpp \ + utility/ValidateXml.cpp LOCAL_C_INCLUDES := external/libxml2/include diff --git a/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp new file mode 100644 index 0000000000..01324c87d3 --- /dev/null +++ b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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 "utility/ValidateXml.h" + +TEST(CheckConfig, audioPolicyConfigurationValidation) { + ASSERT_VALID_XML("/vendor/etc/audio_policy_configuration.xml", + "/data/local/tmp/audio_policy_configuration.xsd"); +} diff --git a/audio/2.0/vts/functional/utility/ValidateXml.cpp b/audio/2.0/vts/functional/utility/ValidateXml.cpp new file mode 100644 index 0000000000..ff08d2dc5a --- /dev/null +++ b/audio/2.0/vts/functional/utility/ValidateXml.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2017 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 "ValidateAudioConfig" +#include + +#define LIBXML_SCHEMAS_ENABLED +#include +#define LIBXML_XINCLUDE_ENABLED +#include + +#include +#include + +#include "ValidateXml.h" + +namespace android { +namespace hardware { +namespace audio { +namespace test { + +/** Map libxml2 structures to their corresponding deleters. */ +template +constexpr void (*xmlDeleter)(T* t); +template <> +constexpr auto xmlDeleter = xmlSchemaFree; +template <> +constexpr auto xmlDeleter = xmlFreeDoc; +template <> +constexpr auto xmlDeleter = xmlSchemaFreeParserCtxt; +template <> +constexpr auto xmlDeleter = xmlSchemaFreeValidCtxt; + +/** @return a unique_ptr with the correct deleter for the libxml2 object. */ +template +constexpr auto make_xmlUnique(T* t) { + // Wrap deleter in lambda to enable empty base optimization + auto deleter = [](T* t) { xmlDeleter(t); }; + return std::unique_ptr{t, deleter}; +} + +/** Class that handles libxml2 initialization and cleanup. NOT THREAD SAFE*/ +struct Libxml2Global { + Libxml2Global() { + xmlLineNumbersDefault(1); // Better error message + xmlSetGenericErrorFunc(this, errorCb); + } + ~Libxml2Global() { + // TODO: check if all those cleanup are needed + xmlSetGenericErrorFunc(nullptr, nullptr); + xmlSchemaCleanupTypes(); + xmlCleanupParser(); + xmlCleanupThreads(); + } + + const std::string& getErrors() { return errors; } + + private: + static void errorCb(void* ctxt, const char* msg, ...) { + auto* self = static_cast(ctxt); + va_list args; + va_start(args, msg); + + char* formatedMsg; + if (vasprintf(&formatedMsg, msg, args) >= 0) { + LOG_PRI(ANDROID_LOG_ERROR, LOG_TAG, "%s", formatedMsg); + self->errors += "Error: "; + self->errors += formatedMsg; + } + free(formatedMsg); + + va_end(args); + } + std::string errors; +}; + +::testing::AssertionResult validateXml(const char* xmlFilePathExpr, + const char* xsdFilePathExpr, + const char* xmlFilePath, + const char* xsdFilePath) { + Libxml2Global libxml2; + + auto context = [&]() { + return std::string() + " While validating: " + xmlFilePathExpr + + "\n Which is: " + xmlFilePath + + "\nAgainst the schema: " + xsdFilePathExpr + + "\n Which is: " + xsdFilePath + "Libxml2 errors\n" + + libxml2.getErrors(); + }; + + auto schemaParserCtxt = make_xmlUnique(xmlSchemaNewParserCtxt(xsdFilePath)); + auto schema = make_xmlUnique(xmlSchemaParse(schemaParserCtxt.get())); + if (schema == nullptr) { + return ::testing::AssertionFailure() << "Failed to parse schema (xsd)\n" + << context(); + } + + auto doc = make_xmlUnique(xmlReadFile(xmlFilePath, nullptr, 0)); + if (doc == nullptr) { + return ::testing::AssertionFailure() << "Failed to parse xml\n" + << context(); + } + + if (xmlXIncludeProcess(doc.get()) == -1) { + return ::testing::AssertionFailure() + << "Failed to resolve xincludes in xml\n" + << context(); + } + + auto schemaCtxt = make_xmlUnique(xmlSchemaNewValidCtxt(schema.get())); + int ret = xmlSchemaValidateDoc(schemaCtxt.get(), doc.get()); + if (ret > 0) { + return ::testing::AssertionFailure() + << "xml is not valid according to the xsd.\n" + << context(); + } + if (ret < 0) { + return ::testing::AssertionFailure() << "Internal or API error\n" + << context(); + } + + return ::testing::AssertionSuccess(); +} + +} // namespace test +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/2.0/vts/functional/utility/ValidateXml.h b/audio/2.0/vts/functional/utility/ValidateXml.h new file mode 100644 index 0000000000..619dd4061b --- /dev/null +++ b/audio/2.0/vts/functional/utility/ValidateXml.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML +#define ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML + +#include + +namespace android { +namespace hardware { +namespace audio { +namespace test { + +/** Validate the provided XmlFile with the provided xsdFile. + * Intended to use with ASSERT_PRED_FORMAT2 as such: + * ASSERT_PRED_FORMAT2(validateXml, pathToXml, pathToXsd); + * See ASSERT_VALID_XML for a helper macro. + */ +::testing::AssertionResult validateXml(const char* xmlFilePathExpr, + const char* xsdFilePathExpr, + const char* xmlFilePath, + const char* xsdPathName); + +/** Helper gtest ASSERT to test xml validity against an xsd. */ +#define ASSERT_VALID_XML(xmlFilePath, xsdFilePath) \ + ASSERT_PRED_FORMAT2(::android::hardware::audio::test::validateXml, \ + xmlFilePath, xsdFilePath) + +} // namespace test +} // namespace audio +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML