From affbc3184900322de6dd71057e258296d585666b Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 23 Jan 2017 18:31:14 -0500 Subject: [PATCH] Making the unit tests more robust. It is best to check the error messages of unit tests that fail validation. This will ensure that a validation failure is due to what we expect and not due to some secondary reason. Updating SPIR-V Validator unit tests with error message checks. --- test/val/val_id_test.cpp | 226 ++++++++++++++++++++++++++++++++++++++---- test/val/val_layout_test.cpp | 14 +++ test/val/val_storage_test.cpp | 11 ++ 3 files changed, 234 insertions(+), 17 deletions(-) diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index 8855394..c8c72cf 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -120,6 +120,8 @@ TEST_F(ValidateIdWithMessage, OpMemberNameTypeBad) { %1 = OpTypeInt 32 0)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpMemberName Type '1' is not a struct type.")); } TEST_F(ValidateIdWithMessage, OpMemberNameMemberBad) { string spirv = kGLSL450MemoryModel + R"( @@ -128,6 +130,9 @@ TEST_F(ValidateIdWithMessage, OpMemberNameMemberBad) { %2 = OpTypeStruct %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpMemberName Member '1' index is larger than " + "Type '1's member count.")); } TEST_F(ValidateIdWithMessage, OpLineGood) { @@ -142,12 +147,13 @@ TEST_F(ValidateIdWithMessage, OpLineGood) { } TEST_F(ValidateIdWithMessage, OpLineFileBad) { string spirv = kGLSL450MemoryModel + R"( - OpLine %2 0 0 -%2 = OpTypeInt 32 0 -%3 = OpTypePointer Input %2 -%4 = OpVariable %3 Input)"; + %1 = OpTypeInt 32 0 + OpLine %1 0 0 + )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpLine Target '1' is not an OpString.")); } TEST_F(ValidateIdWithMessage, OpDecorateGood) { @@ -300,6 +306,9 @@ TEST_F(ValidateIdWithMessage, OpEntryPointFunctionBad) { %1 = OpTypeVoid)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpEntryPoint Entry Point '1' is not a function.")); } TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBad) { string spirv = kGLSL450MemoryModel + R"( @@ -312,6 +321,9 @@ TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpEntryPoint Entry Point '1's function parameter " + "count is not zero")); } TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -324,6 +336,9 @@ TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpEntryPoint Entry Point '1's function return " + "type is not void.")); } TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceIsNotVariableTypeBad) { @@ -402,6 +417,9 @@ TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointMissing) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpExecutionMode Entry Point '1' is not the Entry " + "Point operand of an OpEntryPoint.")); } TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointBad) { @@ -418,6 +436,9 @@ TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpExecutionMode Entry Point '2' is not the Entry " + "Point operand of an OpEntryPoint.")); } TEST_F(ValidateIdWithMessage, OpTypeVectorFloat) { @@ -459,6 +480,9 @@ TEST_F(ValidateIdWithMessage, OpTypeVectorComponentTypeBad) { %3 = OpTypeVector %2 4)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpTypeVector Component Type '2' is not a scalar type.")); } TEST_F(ValidateIdWithMessage, OpTypeMatrixGood) { @@ -475,6 +499,8 @@ TEST_F(ValidateIdWithMessage, OpTypeMatrixColumnTypeBad) { %2 = OpTypeMatrix %1 3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Columns in a matrix must be of type vector.")); } TEST_F(ValidateIdWithMessage, OpTypeSamplerGood) { @@ -501,6 +527,8 @@ TEST_F(ValidateIdWithMessage, OpTypeArrayElementTypeBad) { %3 = OpTypeArray %2 %2)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypeArray Element Type '2' is not a type.")); } // Signed or unsigned. @@ -527,12 +555,13 @@ class OpTypeArrayLengthTest ~OpTypeArrayLengthTest() { spvDiagnosticDestroy(diagnostic_); } // Runs spvValidate() on v, printing any errors via spvDiagnosticPrint(). - spv_result_t Val(const SpirvVector& v) { + spv_result_t Val(const SpirvVector& v, const std::string &expected_err = "") { spv_const_binary_t cbinary{v.data(), v.size()}; const auto status = spvValidate(ScopedContext().context, &cbinary, &diagnostic_); if (status != SPV_SUCCESS) { spvDiagnosticPrint(diagnostic_); + EXPECT_THAT(std::string(diagnostic_->error), HasSubstr(expected_err)); } return status; } @@ -566,23 +595,35 @@ TEST_P(OpTypeArrayLengthTest, LengthPositive) { TEST_P(OpTypeArrayLengthTest, LengthZero) { const int width = GetParam(); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)))); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)))); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); } TEST_P(OpTypeArrayLengthTest, LengthNegative) { const int width = GetParam(); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)))); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)))); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)))); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); const string neg_max = "0x8" + string(width / 4 - 1, '0'); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)))); + EXPECT_EQ( + SPV_ERROR_INVALID_ID, + Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)), + "OpTypeArray Length '2' default value must be at least 1.")); } // The only valid widths for integers are 8, 16, 32, and 64. @@ -596,6 +637,10 @@ TEST_F(ValidateIdWithMessage, OpTypeArrayLengthNull) { %ary = OpTypeArray %i32 %len)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpTypeArray Length '2' default value must be at least 1.")); } TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) { @@ -632,6 +677,9 @@ TEST_F(ValidateIdWithMessage, OpTypeRuntimeArrayBad) { %3 = OpTypeRuntimeArray %2)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpTypeRuntimeArray Element Type '2' is not a type.")); } // TODO: Object of this type can only be created with OpVariable using the // Unifrom Storage Class @@ -653,6 +701,8 @@ TEST_F(ValidateIdWithMessage, OpTypeStructMemberTypeBad) { %4 = OpTypeStruct %1 %2 %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypeStruct Member Type '3' is not a type.")); } TEST_F(ValidateIdWithMessage, OpTypePointerGood) { @@ -669,6 +719,8 @@ TEST_F(ValidateIdWithMessage, OpTypePointerBad) { %3 = OpTypePointer Input %2)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypePointer Type '2' is not a type.")); } TEST_F(ValidateIdWithMessage, OpTypeFunctionGood) { @@ -685,6 +737,8 @@ TEST_F(ValidateIdWithMessage, OpTypeFunctionReturnTypeBad) { %3 = OpTypeFunction %2)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypeFunction Return Type '2' is not a type.")); } TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterBad) { string spirv = kGLSL450MemoryModel + R"( @@ -694,6 +748,9 @@ TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterBad) { %4 = OpTypeFunction %1 %2 %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpTypeFunction Parameter Type '3' is not a type.")); } TEST_F(ValidateIdWithMessage, OpTypePipeGood) { @@ -718,6 +775,9 @@ TEST_F(ValidateIdWithMessage, OpConstantTrueBad) { %2 = OpConstantTrue %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpConstantTrue Result Type '1' is not a boolean type.")); } TEST_F(ValidateIdWithMessage, OpConstantFalseGood) { @@ -733,6 +793,9 @@ TEST_F(ValidateIdWithMessage, OpConstantFalseBad) { %2 = OpConstantFalse %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpConstantFalse Result Type '1' is not a boolean type.")); } TEST_F(ValidateIdWithMessage, OpConstantGood) { @@ -780,6 +843,10 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorResultTypeBad) { %4 = OpConstantComposite %1 %3 %3 %3 %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantComposite Result Type '1' is not a composite type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -791,6 +858,10 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) { %6 = OpConstantComposite %2 %3 %5 %3 %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5's type does not match " + "Result Type '2's vector element type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentUndefTypeBad) { @@ -803,6 +874,10 @@ TEST_F(ValidateIdWithMessage, %6 = OpConstantComposite %2 %3 %5 %3 %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5's type does not match " + "Result Type '2's vector element type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixGood) { string spirv = kGLSL450MemoryModel + R"( @@ -849,6 +924,10 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixConstituentTypeBad) { %10 = OpConstantComposite %3 %6 %7 %8 %9)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '10' vector " + "component count does not match Result Type '4's " + "vector component count.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixConstituentUndefTypeBad) { @@ -866,6 +945,10 @@ TEST_F(ValidateIdWithMessage, %10 = OpConstantComposite %3 %6 %7 %8 %9)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '10' vector " + "component count does not match Result Type '4's " + "vector component count.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixColumnTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -881,6 +964,8 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixColumnTypeBad) { %10 = OpConstantComposite %5 %8 %9)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Columns in a matrix must be of type vector.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayGood) { string spirv = kGLSL450MemoryModel + R"( @@ -909,6 +994,9 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstConstituentBad) { %4 = OpConstantComposite %3 %2 %2 %2 %1)"; // Uses a type as operand CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '1' is not a " + "constant or undef.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -920,6 +1008,9 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) { %4 = OpConstantComposite %3 %2 %2 %2 %6)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5's type does " + "not match Result Type '3's array element type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -931,6 +1022,9 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) { %4 = OpConstantComposite %3 %2 %2 %2 %6)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5's type does " + "not match Result Type '3's array element type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeStructGood) { string spirv = kGLSL450MemoryModel + R"( @@ -964,6 +1058,9 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberTypeBad) { %6 = OpConstantComposite %3 %4 %5 %4)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5' type does " + "not match the Result Type '3's member type.")); } TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) { @@ -976,6 +1073,9 @@ TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) { %6 = OpConstantComposite %3 %4 %5 %4)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpConstantComposite Constituent '5' type does " + "not match the Result Type '3's member type.")); } TEST_F(ValidateIdWithMessage, OpConstantSamplerGood) { @@ -992,6 +1092,10 @@ TEST_F(ValidateIdWithMessage, OpConstantSamplerResultTypeBad) { %2 = OpConstantSampler %1 Clamp 0 Nearest)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantSampler Result Type '1' is not a sampler type.")); } TEST_F(ValidateIdWithMessage, OpConstantNullGood) { @@ -1036,6 +1140,10 @@ TEST_F(ValidateIdWithMessage, OpConstantNullBasicBad) { %2 = OpConstantNull %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantNull Result Type '1' cannot have a null value.")); } TEST_F(ValidateIdWithMessage, OpConstantNullArrayBad) { @@ -1047,6 +1155,10 @@ TEST_F(ValidateIdWithMessage, OpConstantNullArrayBad) { %6 = OpConstantNull %5)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantNull Result Type '4' cannot have a null value.")); } TEST_F(ValidateIdWithMessage, OpConstantNullStructBad) { @@ -1056,6 +1168,10 @@ TEST_F(ValidateIdWithMessage, OpConstantNullStructBad) { %4 = OpConstantNull %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantNull Result Type '2' cannot have a null value.")); } TEST_F(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) { @@ -1065,6 +1181,10 @@ TEST_F(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) { %null = OpConstantNull %array)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpConstantNull Result Type '2' cannot have a null value.")); } TEST_F(ValidateIdWithMessage, OpSpecConstantTrueGood) { @@ -1080,6 +1200,8 @@ TEST_F(ValidateIdWithMessage, OpSpecConstantTrueBad) { %2 = OpSpecConstantTrue %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Specialization constant must be a boolean type.")); } TEST_F(ValidateIdWithMessage, OpSpecConstantFalseGood) { @@ -1095,6 +1217,8 @@ TEST_F(ValidateIdWithMessage, OpSpecConstantFalseBad) { %2 = OpSpecConstantFalse %1)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Specialization constant must be a boolean type.")); } TEST_F(ValidateIdWithMessage, OpSpecConstantGood) { @@ -1113,6 +1237,8 @@ TEST_F(ValidateIdWithMessage, OpSpecConstantBad) { // change over time, but this must always fail. CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Type Id 1 is not a scalar numeric type")); } // Valid: SpecConstantComposite specializes to a vector. @@ -1596,6 +1722,9 @@ TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) { %2 = OpVariable %1 Input)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpVariable Result Type '1' is not a pointer type.")); } TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1679,6 +1808,9 @@ TEST_F(ValidateIdWithMessage, OpLoadResultTypeBad) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpLoad Result Type '3' does not match Pointer " + " '5's type.")); } TEST_F(ValidateIdWithMessage, OpLoadPointerBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1695,6 +1827,8 @@ TEST_F(ValidateIdWithMessage, OpLoadPointerBad) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpLoad Pointer '4' is not a pointer.")); } TEST_F(ValidateIdWithMessage, OpStoreGood) { @@ -1728,6 +1862,8 @@ TEST_F(ValidateIdWithMessage, OpStorePointerBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpStore Pointer '3' is not a pointer.")); } TEST_F(ValidateIdWithMessage, OpStoreObjectGood) { string spirv = kGLSL450MemoryModel + R"( @@ -1744,6 +1880,8 @@ TEST_F(ValidateIdWithMessage, OpStoreObjectGood) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpStore Object '7's type is void.")); } TEST_F(ValidateIdWithMessage, OpStoreTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1761,6 +1899,9 @@ TEST_F(ValidateIdWithMessage, OpStoreTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpStore Pointer '7's type does not match Object " + " '3's type.")); } TEST_F(ValidateIdWithMessage, OpStoreVoid) { @@ -1778,6 +1919,8 @@ TEST_F(ValidateIdWithMessage, OpStoreVoid) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpStore Object '8's type is void.")); } TEST_F(ValidateIdWithMessage, OpStoreLabel) { @@ -1794,6 +1937,8 @@ TEST_F(ValidateIdWithMessage, OpStoreLabel) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpStore Object '7' is not an object.")); } // TODO: enable when this bug is fixed: @@ -1852,6 +1997,9 @@ TEST_F(ValidateIdWithMessage, OpCopyMemoryBad) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpCopyMemory Target '5's type does not match " + "Source '2's type.")); } // TODO: OpCopyMemorySized @@ -1889,6 +2037,8 @@ TEST_F(ValidateIdWithMessage, OpCopyMemorySizedTargetBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpCopyMemorySized Target '9' is not a pointer.")); } TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1906,6 +2056,8 @@ TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpCopyMemorySized Source '6' is not a pointer.")); } TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1924,6 +2076,9 @@ TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpCopyMemorySized Size '6's variable type is not " + "an integer type.")); } TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -1944,6 +2099,10 @@ TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpCopyMemorySized Size '9's type is not an integer type.")); } const char kDeeplyNestedStructureSetup[] = R"( @@ -2451,6 +2610,9 @@ TEST_F(ValidateIdWithMessage, OpFunctionResultTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpFunction Result Type '2' does not match the " + "Function Type '2's return type.")); } TEST_F(ValidateIdWithMessage, OpFunctionFunctionTypeBad) { string spirv = kGLSL450MemoryModel + R"( @@ -2460,6 +2622,9 @@ TEST_F(ValidateIdWithMessage, OpFunctionFunctionTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpFunction Function Type '2' is not a function type.")); } TEST_F(ValidateIdWithMessage, OpFunctionParameterGood) { @@ -2501,6 +2666,10 @@ TEST_F(ValidateIdWithMessage, OpFunctionParameterResultTypeBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpFunctionParameter Result Type '1' does not match the " + "OpTypeFunction parameter type of the same index.")); } TEST_F(ValidateIdWithMessage, OpFunctionCallGood) { @@ -3234,6 +3403,9 @@ TEST_F(ValidateIdWithMessage, OpReturnValueIsType) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpReturnValue Value '1' does not represent a value.")); } TEST_F(ValidateIdWithMessage, OpReturnValueIsLabel) { @@ -3247,6 +3419,9 @@ TEST_F(ValidateIdWithMessage, OpReturnValueIsLabel) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpReturnValue Value '5' does not represent a value.")); } TEST_F(ValidateIdWithMessage, OpReturnValueIsVoid) { @@ -3261,6 +3436,9 @@ TEST_F(ValidateIdWithMessage, OpReturnValueIsVoid) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpReturnValue value's type '1' is missing or void.")); } TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInPhysical) { @@ -3295,6 +3473,9 @@ TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInLogical) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpReturnValue value's type '3' is a pointer, " + "which is invalid in the Logical addressing model.")); } // TODO: enable when this bug is fixed: @@ -3318,6 +3499,9 @@ TEST_F(ValidateIdWithMessage, UndefinedTypeId) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Forward reference operands in an OpTypeStruct must " + "first be declared using OpTypeForwardPointer.")); } TEST_F(ValidateIdWithMessage, UndefinedIdScope) { @@ -3334,6 +3518,7 @@ TEST_F(ValidateIdWithMessage, UndefinedIdScope) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7 has not been defined")); } TEST_F(ValidateIdWithMessage, UndefinedIdMemSem) { @@ -3350,6 +3535,7 @@ TEST_F(ValidateIdWithMessage, UndefinedIdMemSem) { )"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7 has not been defined")); } TEST_F(ValidateIdWithMessage, @@ -3455,6 +3641,9 @@ TEST_F(ValidateIdWithMessage, OpLoadBitcastNonPointerBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpLoad type for pointer '11' is not a pointer type.")); } TEST_F(ValidateIdWithMessage, OpStoreBitcastPointerGood) { string spirv = kOpenCLMemoryModel64 + R"( @@ -3492,6 +3681,9 @@ TEST_F(ValidateIdWithMessage, OpStoreBitcastNonPointerBad) { OpFunctionEnd)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpStore type for pointer '11' is not a pointer type.")); } // Result resulting from an instruction within a function may not be used diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp index e8b4247..172f14a 100644 --- a/test/val/val_layout_test.cpp +++ b/test/val/val_layout_test.cpp @@ -225,6 +225,10 @@ TEST_F(ValidateLayout, MemoryModelMissing) { CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "EntryPoint cannot appear before the memory model instruction")); } TEST_F(ValidateLayout, FunctionDefinitionBeforeDeclarationBad) { @@ -249,6 +253,10 @@ TEST_F(ValidateLayout, FunctionDefinitionBeforeDeclarationBad) { CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "Function declarations must appear before function definitions.")); } // TODO(umar): Passes but gives incorrect error message. Should be fixed after @@ -273,6 +281,9 @@ TEST_F(ValidateLayout, LabelBeforeFunctionParameterBad) { CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Function parameters must only appear immediately " + "after the function definition")); } TEST_F(ValidateLayout, FuncParameterNotImmediatlyAfterFuncBad) { @@ -298,6 +309,9 @@ TEST_F(ValidateLayout, FuncParameterNotImmediatlyAfterFuncBad) { CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Function parameters must only appear immediately " + "after the function definition")); } TEST_F(ValidateLayout, OpUndefCanAppearInTypeDeclarationSection) { diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp index d26a860..5c7a4e3 100644 --- a/test/val/val_storage_test.cpp +++ b/test/val/val_storage_test.cpp @@ -21,6 +21,8 @@ #include "gmock/gmock.h" #include "val_fixtures.h" +using ::testing::HasSubstr; + using ValidateStorage = spvtest::ValidateBase; namespace { @@ -63,6 +65,9 @@ TEST_F(ValidateStorage, FunctionStorageOutsideFunction) { CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Variables can not have a function[7] storage class " + "outside of a function")); } TEST_F(ValidateStorage, OtherStorageOutsideFunction) { @@ -118,6 +123,8 @@ TEST_P(ValidateStorage, OtherStorageInsideFunction) { CompileSuccessfully(ss.str()); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr( + "Variables must have a function[7] storage class inside of a function")); } INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateStorage, @@ -144,6 +151,8 @@ TEST_F(ValidateStorage, GenericVariableOutsideFunction) { )"; CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpVariable storage class cannot be Generic")); } TEST_F(ValidateStorage, GenericVariableInsideFunction) { @@ -163,5 +172,7 @@ TEST_F(ValidateStorage, GenericVariableInsideFunction) { )"; CompileSuccessfully(str); ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpVariable storage class cannot be Generic")); } } -- 2.7.4