aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLei Zhang <antiagainst@google.com>2016-09-09 10:46:23 -0400
committerLei Zhang <antiagainst@google.com>2016-09-16 16:37:27 -0400
commit8654caa5657ef0e12367d9e705e6c31e70f68668 (patch)
tree117e7dca92497367c424025d8fda4d3f28c1eef9 /test
parentb54686d0170cc72b889e9bdc45f9c173f26e3467 (diff)
downloadspirv-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.cpp118
-rw-r--r--test/opt/pass_fixture.h4
-rw-r--r--test/opt/test_ir_loader.cpp4
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);
}