diff options
author | Lei Zhang <antiagainst@google.com> | 2016-09-09 10:46:23 -0400 |
---|---|---|
committer | Lei Zhang <antiagainst@google.com> | 2016-09-16 16:37:27 -0400 |
commit | 8654caa5657ef0e12367d9e705e6c31e70f68668 (patch) | |
tree | 117e7dca92497367c424025d8fda4d3f28c1eef9 /test | |
parent | b54686d0170cc72b889e9bdc45f9c173f26e3467 (diff) | |
download | spirv-tools-8654caa5657ef0e12367d9e705e6c31e70f68668.tar.gz |
Prepare the C++ interface for publication.
* Use PIMPL idiom in the C++ interface.
* Clean up interface for assembling and disassembling.
* Add validation into C++ interface.
* Add more tests for the C++ interface.
Diffstat (limited to 'test')
-rw-r--r-- | test/cpp_interface.cpp | 118 | ||||
-rw-r--r-- | test/opt/pass_fixture.h | 4 | ||||
-rw-r--r-- | test/opt/test_ir_loader.cpp | 4 |
3 files changed, 115 insertions, 11 deletions
diff --git a/test/cpp_interface.cpp b/test/cpp_interface.cpp index 104958d3..a585951a 100644 --- a/test/cpp_interface.cpp +++ b/test/cpp_interface.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <gmock/gmock.h> #include <gtest/gtest.h> #include "opt/libspirv.hpp" @@ -20,40 +21,143 @@ namespace { using namespace spvtools; +using ::testing::ContainerEq; TEST(CppInterface, SuccessfulRoundTrip) { const std::string input_text = "%2 = OpSizeOf %1 %3\n"; SpvTools t(SPV_ENV_UNIVERSAL_1_1); std::vector<uint32_t> binary; - EXPECT_EQ(SPV_SUCCESS, t.Assemble(input_text, &binary)); + EXPECT_TRUE(t.Assemble(input_text, &binary)); EXPECT_TRUE(binary.size() > 5u); EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(SpvVersion, binary[1]); + // This cannot pass validation since %1 is not defined. + t.SetMessageConsumer([](MessageLevel level, const char* source, + const spv_position_t& position, const char* message) { + EXPECT_EQ(MessageLevel::Error, level); + EXPECT_STREQ("", source); + EXPECT_EQ(0u, position.line); + EXPECT_EQ(0u, position.column); + EXPECT_EQ(1u, position.index); + EXPECT_STREQ("ID 1 has not been defined", message); + }); + EXPECT_FALSE(t.Validate(binary)); + std::string output_text; - EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &output_text)); + EXPECT_TRUE(t.Disassemble(binary, &output_text)); EXPECT_EQ(input_text, output_text); } +TEST(CppInterface, AssembleEmptyModule) { + std::vector<uint32_t> binary(10, 42); + SpvTools t(SPV_ENV_UNIVERSAL_1_1); + EXPECT_TRUE(t.Assemble("", &binary)); + // We only have the header. + EXPECT_EQ(5u, binary.size()); + EXPECT_EQ(SpvMagicNumber, binary[0]); + EXPECT_EQ(SpvVersion, binary[1]); +} + TEST(CppInterface, AssembleWithWrongTargetEnv) { const std::string input_text = "%r = OpSizeOf %type %pointer"; SpvTools t(SPV_ENV_UNIVERSAL_1_0); + int invocation_count = 0; + t.SetMessageConsumer( + [&invocation_count](MessageLevel level, const char* source, + const spv_position_t& position, const char* message) { + ++invocation_count; + EXPECT_EQ(MessageLevel::Error, level); + EXPECT_STREQ("", source); + EXPECT_EQ(0u, position.line); + EXPECT_EQ(5u, position.column); + EXPECT_EQ(5u, position.index); + EXPECT_STREQ("Invalid Opcode name 'OpSizeOf'", message); + }); - std::vector<uint32_t> binary; - EXPECT_EQ(SPV_ERROR_INVALID_TEXT, t.Assemble(input_text, &binary)); + std::vector<uint32_t> binary = {42, 42}; + EXPECT_FALSE(t.Assemble(input_text, &binary)); + EXPECT_THAT(binary, ContainerEq(std::vector<uint32_t>{42, 42})); + EXPECT_EQ(1, invocation_count); +} + +TEST(CppInterface, DisassembleEmptyModule) { + std::string text(10, 'x'); + SpvTools t(SPV_ENV_UNIVERSAL_1_1); + int invocation_count = 0; + t.SetMessageConsumer( + [&invocation_count](MessageLevel level, const char* source, + const spv_position_t& position, const char* message) { + ++invocation_count; + EXPECT_EQ(MessageLevel::Error, level); + EXPECT_STREQ("", source); + EXPECT_EQ(0u, position.line); + EXPECT_EQ(0u, position.column); + EXPECT_EQ(0u, position.index); + EXPECT_STREQ("Missing module.", message); + }); + EXPECT_FALSE(t.Disassemble({}, &text)); + EXPECT_EQ("xxxxxxxxxx", text); // The original string is unmodified. + EXPECT_EQ(1, invocation_count); } TEST(CppInterface, DisassembleWithWrongTargetEnv) { const std::string input_text = "%r = OpSizeOf %type %pointer"; SpvTools t11(SPV_ENV_UNIVERSAL_1_1); SpvTools t10(SPV_ENV_UNIVERSAL_1_0); + int invocation_count = 0; + t10.SetMessageConsumer( + [&invocation_count](MessageLevel level, const char* source, + const spv_position_t& position, const char* message) { + ++invocation_count; + EXPECT_EQ(MessageLevel::Error, level); + EXPECT_STREQ("", source); + EXPECT_EQ(0u, position.line); + EXPECT_EQ(0u, position.column); + EXPECT_EQ(5u, position.index); + EXPECT_STREQ("Invalid opcode: 321", message); + }); std::vector<uint32_t> binary; - EXPECT_EQ(SPV_SUCCESS, t11.Assemble(input_text, &binary)); + EXPECT_TRUE(t11.Assemble(input_text, &binary)); - std::string output_text; - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, t10.Disassemble(binary, &output_text)); + std::string output_text(10, 'x'); + EXPECT_FALSE(t10.Disassemble(binary, &output_text)); + EXPECT_EQ("xxxxxxxxxx", output_text); // The original string is unmodified. +} + +TEST(CppInterface, SuccessfulValidation) { + const std::string input_text = + "OpCapability Shader\nOpMemoryModel Logical GLSL450"; + SpvTools t(SPV_ENV_UNIVERSAL_1_1); + int invocation_count = 0; + t.SetMessageConsumer( + [&invocation_count](MessageLevel, const char*, const spv_position_t&, + const char*) { ++invocation_count; }); + + std::vector<uint32_t> binary; + EXPECT_TRUE(t.Assemble(input_text, &binary)); + EXPECT_TRUE(t.Validate(binary)); + EXPECT_EQ(0, invocation_count); +} + +TEST(CppInterface, ValidateEmptyModule) { + SpvTools t(SPV_ENV_UNIVERSAL_1_1); + int invocation_count = 0; + t.SetMessageConsumer( + [&invocation_count](MessageLevel level, const char* source, + const spv_position_t& position, const char* message) { + ++invocation_count; + EXPECT_EQ(MessageLevel::Error, level); + EXPECT_STREQ("", source); + EXPECT_EQ(0u, position.line); + EXPECT_EQ(0u, position.column); + EXPECT_EQ(0u, position.index); + EXPECT_STREQ("Invalid SPIR-V magic number.", message); + }); + EXPECT_FALSE(t.Validate({})); + EXPECT_EQ(1, invocation_count); } } // anonymous namespace diff --git a/test/opt/pass_fixture.h b/test/opt/pass_fixture.h index df41ad50..9cc831cf 100644 --- a/test/opt/pass_fixture.h +++ b/test/opt/pass_fixture.h @@ -63,7 +63,7 @@ class PassTest : public TestT { std::vector<uint32_t> binary; module->ToBinary(&binary, skip_nop); std::string optimized; - EXPECT_EQ(SPV_SUCCESS, tools_.Disassemble(binary, &optimized)) + EXPECT_TRUE(tools_.Disassemble(binary, &optimized)) << "Disassembling failed for shader:\n" << original << std::endl; return std::make_tuple(optimized, modified); @@ -122,7 +122,7 @@ class PassTest : public TestT { module->ToBinary(&binary, /* skip_nop = */ false); std::string optimized; - EXPECT_EQ(SPV_SUCCESS, tools_.Disassemble(binary, &optimized)); + EXPECT_TRUE(tools_.Disassemble(binary, &optimized)); EXPECT_EQ(expected, optimized); } diff --git a/test/opt/test_ir_loader.cpp b/test/opt/test_ir_loader.cpp index 27860c7b..b9893809 100644 --- a/test/opt/test_ir_loader.cpp +++ b/test/opt/test_ir_loader.cpp @@ -32,7 +32,7 @@ void DoRoundTripCheck(const std::string& text) { module->ToBinary(&binary, /* skip_nop = */ false); std::string disassembled_text; - EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &disassembled_text)); + EXPECT_TRUE(t.Disassemble(binary, &disassembled_text)); EXPECT_EQ(text, disassembled_text); } @@ -224,7 +224,7 @@ TEST(IrBuilder, OpUndefOutsideFunction) { module->ToBinary(&binary, /* skip_nop = */ false); std::string disassembled_text; - EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &disassembled_text)); + EXPECT_TRUE(t.Disassemble(binary, &disassembled_text)); EXPECT_EQ(text, disassembled_text); } |