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..db08dde117 --- /dev/null +++ b/audio/2.0/vts/functional/Android.mk @@ -0,0 +1,42 @@ +# 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 \ + ValidateAudioConfiguration.cpp \ + utility/ValidateXml.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/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 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",