| // Copyright (c) 2015-2016 The Khronos Group Inc. |
| // |
| // 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. |
| |
| // Common validation fixtures for unit tests |
| |
| #ifndef TEST_VAL_VAL_FIXTURES_H_ |
| #define TEST_VAL_VAL_FIXTURES_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "source/val/validation_state.h" |
| #include "spirv-tools/libspirv.h" |
| #include "test/test_fixture.h" |
| #include "test/unit_spirv.h" |
| |
| namespace spvtest { |
| |
| template <typename T> |
| class ValidateBase : public ::testing::Test, |
| public ::testing::WithParamInterface<T> { |
| public: |
| ValidateBase(); |
| |
| virtual void TearDown(); |
| |
| // Returns the a spv_const_binary struct |
| spv_const_binary get_const_binary(); |
| |
| // Assembles the given SPIR-V text, checks that it fails to assemble, |
| // and returns resulting diagnostic. No internal state is updated. |
| std::string CompileFailure(std::string code, |
| spv_target_env env = SPV_ENV_UNIVERSAL_1_0); |
| |
| // Checks that 'code' is valid SPIR-V text representation and stores the |
| // binary version for further method calls. |
| void CompileSuccessfully(std::string code, |
| spv_target_env env = SPV_ENV_UNIVERSAL_1_0); |
| |
| // Overwrites the word at index 'index' with the given word. |
| // For testing purposes, it is often useful to be able to manipulate the |
| // assembled binary before running the validator on it. |
| // This function overwrites the word at the given index with a new word. |
| void OverwriteAssembledBinary(uint32_t index, uint32_t word); |
| |
| // Performs validation on the SPIR-V code. |
| spv_result_t ValidateInstructions(spv_target_env env = SPV_ENV_UNIVERSAL_1_0); |
| |
| // Performs validation. Returns the status and stores validation state into |
| // the vstate_ member. |
| spv_result_t ValidateAndRetrieveValidationState( |
| spv_target_env env = SPV_ENV_UNIVERSAL_1_0); |
| |
| // Destroys the stored binary. |
| void DestroyBinary() { |
| spvBinaryDestroy(binary_); |
| binary_ = nullptr; |
| } |
| |
| // Destroys the stored diagnostic. |
| void DestroyDiagnostic() { |
| spvDiagnosticDestroy(diagnostic_); |
| diagnostic_ = nullptr; |
| } |
| |
| std::string getDiagnosticString(); |
| spv_position_t getErrorPosition(); |
| spv_validator_options getValidatorOptions(); |
| |
| spv_binary binary_; |
| spv_diagnostic diagnostic_; |
| spv_validator_options options_; |
| std::unique_ptr<spvtools::val::ValidationState_t> vstate_; |
| }; |
| |
| template <typename T> |
| ValidateBase<T>::ValidateBase() : binary_(nullptr), diagnostic_(nullptr) { |
| // Initialize to default command line options. Different tests can then |
| // specialize specific options as necessary. |
| options_ = spvValidatorOptionsCreate(); |
| } |
| |
| template <typename T> |
| spv_const_binary ValidateBase<T>::get_const_binary() { |
| return spv_const_binary(binary_); |
| } |
| |
| template <typename T> |
| void ValidateBase<T>::TearDown() { |
| if (diagnostic_) { |
| spvDiagnosticPrint(diagnostic_); |
| } |
| DestroyBinary(); |
| DestroyDiagnostic(); |
| spvValidatorOptionsDestroy(options_); |
| } |
| |
| template <typename T> |
| std::string ValidateBase<T>::CompileFailure(std::string code, |
| spv_target_env env) { |
| spv_diagnostic diagnostic = nullptr; |
| EXPECT_NE(SPV_SUCCESS, |
| spvTextToBinary(ScopedContext(env).context, code.c_str(), |
| code.size(), &binary_, &diagnostic)); |
| std::string result(diagnostic->error); |
| spvDiagnosticDestroy(diagnostic); |
| return result; |
| } |
| |
| template <typename T> |
| void ValidateBase<T>::CompileSuccessfully(std::string code, |
| spv_target_env env) { |
| DestroyBinary(); |
| spv_diagnostic diagnostic = nullptr; |
| ScopedContext context(env); |
| auto status = spvTextToBinary(context.context, code.c_str(), code.size(), |
| &binary_, &diagnostic); |
| EXPECT_EQ(SPV_SUCCESS, status) |
| << "ERROR: " << diagnostic->error |
| << "\nSPIR-V could not be compiled into binary:\n" |
| << code; |
| ASSERT_EQ(SPV_SUCCESS, status); |
| spvDiagnosticDestroy(diagnostic); |
| } |
| |
| template <typename T> |
| void ValidateBase<T>::OverwriteAssembledBinary(uint32_t index, uint32_t word) { |
| ASSERT_TRUE(index < binary_->wordCount) |
| << "OverwriteAssembledBinary: The given index is larger than the binary " |
| "word count."; |
| binary_->code[index] = word; |
| } |
| |
| template <typename T> |
| spv_result_t ValidateBase<T>::ValidateInstructions(spv_target_env env) { |
| DestroyDiagnostic(); |
| if (binary_ == nullptr) { |
| fprintf(stderr, |
| "ERROR: Attempting to validate a null binary, did you forget to " |
| "call CompileSuccessfully?"); |
| fflush(stderr); |
| } |
| assert(binary_ != nullptr); |
| return spvValidateWithOptions(ScopedContext(env).context, options_, |
| get_const_binary(), &diagnostic_); |
| } |
| |
| template <typename T> |
| spv_result_t ValidateBase<T>::ValidateAndRetrieveValidationState( |
| spv_target_env env) { |
| DestroyDiagnostic(); |
| return spvtools::val::ValidateBinaryAndKeepValidationState( |
| ScopedContext(env).context, options_, get_const_binary()->code, |
| get_const_binary()->wordCount, &diagnostic_, &vstate_); |
| } |
| |
| template <typename T> |
| std::string ValidateBase<T>::getDiagnosticString() { |
| return diagnostic_ == nullptr ? std::string() |
| : std::string(diagnostic_->error); |
| } |
| |
| template <typename T> |
| spv_validator_options ValidateBase<T>::getValidatorOptions() { |
| return options_; |
| } |
| |
| template <typename T> |
| spv_position_t ValidateBase<T>::getErrorPosition() { |
| return diagnostic_ == nullptr ? spv_position_t() : diagnostic_->position; |
| } |
| |
| } // namespace spvtest |
| |
| #endif // TEST_VAL_VAL_FIXTURES_H_ |