Files
o3de/Gems/Atom/Asset/Shader/Code/Tests/McppBinderTests.cpp
T
galibzon 2b5f77683c [ATOM-13679] ShaderAssetBuilder: Create UnitTest To Validate (#3096)
* [ATOM-13679] ShaderAssetBuilder: Create UnitTest To Validate
 STDOUT Data Capture From MCPP

azvsnprintf was being used improperly, in particular
in windows if the data to print was larger than the
local buffer in the stack, then azvsnprintf returns -1.

Also azvsnprintf needs a +1 in buffer size to accomodate for
the '\0' character at the end and that was not done.

Added UnitTest to validate all cases:
1. Data to print is smaller than the local buffer.
2. Data to print is the same size as the local buffer.
3. Data to print is bigger than the local buffer.

Signed-off-by: garrieta <garrieta@amazon.com>

* Fix for MacOS & Linux,
they require va_start to be called each time azvsnprintf is called

Signed-off-by: garrieta <garrieta@amazon.com>
2021-08-17 11:53:22 -05:00

93 lines
3.6 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include "Common/ShaderBuilderTestFixture.h"
#include <CommonFiles/Preprocessor.h>
namespace UnitTest
{
using namespace AZ;
// The main purpose of this class is to test ShaderBuilder::McppBinder::Fprintf_StaticHinge()
// Which has three common scenarios to validate.
// 1- The formatted string is expected to yield less bytes than McppBinder::DefaultFprintfBufferSize.
// 2- The formatted string is expected to yield exactly McppBinder::DefaultFprintfBufferSize number of bytes.
// 3- The formatted string is expectedc to yield more bytes than McppBinder::DefaultFprintfBufferSize.
class McppBinderTests : public ShaderBuilderTestFixture
{
public:
// Fills @buffer with 'a' to 'z' for up to @bufferSize number of bytes.
// This function will null('\0') char terminate @buffer.
void FillBufferWithAlphabet(char* buffer, int bufferSize)
{
for (int bufferPos = 0, rollback = 0; bufferPos < (bufferSize - 1); ++bufferPos)
{
const char value = 'a' + rollback++;
buffer[bufferPos] = value;
if (value == 'z')
{
rollback = 0;
}
}
buffer[bufferSize - 1] = '\0';
}
// Pushes the null terminated string, @inputString, into McppBinder capture stream
// using McppBinder::Fprintf_StaticHinge().
// Returns the content of the McppBinder capture stream as a string.
AZStd::string PrintStringThroughStaticHinge(const char* inputString)
{
ShaderBuilder::PreprocessorData preprocessorData;
ShaderBuilder::McppBinder mcppBinder(preprocessorData, false);
ShaderBuilder::McppBinder::Fprintf_StaticHinge(MCPP_OUTDEST::MCPP_OUT, "%s", inputString);
// convert from std::ostringstring to AZStd::string
return AZStd::string(mcppBinder.m_outStream.str().c_str());
}
}; // class McppBinderTests
TEST_F(McppBinderTests, ShouldPrintLessBytesThanDefaultSize)
{
constexpr int bufferSize = (ShaderBuilder::McppBinder::DefaultFprintfBufferSize / 2) + 1;
EXPECT_TRUE(bufferSize > 0);
char buffer[bufferSize] = "";
FillBufferWithAlphabet(buffer, bufferSize);
auto printedString = PrintStringThroughStaticHinge(buffer);
EXPECT_EQ(AZStd::string(buffer), printedString);
}
TEST_F(McppBinderTests, ShouldPrintSameBytesAsDefaultSize)
{
constexpr int bufferSize = ShaderBuilder::McppBinder::DefaultFprintfBufferSize + 1;
EXPECT_TRUE(bufferSize > 0);
char buffer[bufferSize] = "";
FillBufferWithAlphabet(buffer, bufferSize);
auto printedString = PrintStringThroughStaticHinge(buffer);
EXPECT_EQ(AZStd::string(buffer), printedString);
}
TEST_F(McppBinderTests, ShouldPrintMoreBytesThanDefaultSize)
{
constexpr int bufferSize = (ShaderBuilder::McppBinder::DefaultFprintfBufferSize * 2) + 1;
EXPECT_TRUE(bufferSize > 0);
char buffer[bufferSize] = "";
FillBufferWithAlphabet(buffer, bufferSize);
auto printedString = PrintStringThroughStaticHinge(buffer);
EXPECT_EQ(AZStd::string(buffer), printedString);
}
} //namespace UnitTest
//AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);