Edit

kc3-lang/angle/src/tests/test_utils/compiler_test.cpp

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2016-06-30 12:24:09
    Hash : 10fcd9be
    Message : Add a helper class for compiler string matching tests The MatchOutputCodeTest class makes it easier to implement tests that do string matching on compiler output. Inheriting test classes set the compiler settings, tests then call compile() with the shader string and can call foundInCode() to check if the output code contains a given string. Various compiler unit tests that already did string matching are refactored to make use of this new helper class. Some tests now use SH_GLES3_SPEC instead of SH_GLES2_SPEC - this should not have a significant impact on test coverage. Some compileTestShader function variants that are now unused can be removed from the code. BUG=angleproject:1430 TEST=angle_unittests Change-Id: I1fd3529d5a1c6ab192f95ace800cf162604e68e7 Reviewed-on: https://chromium-review.googlesource.com/357800 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/tests/test_utils/compiler_test.cpp
  • //
    // Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // compiler_test.cpp:
    //     utilities for compiler unit tests.
    
    #include "tests/test_utils/compiler_test.h"
    
    #include "angle_gl.h"
    #include "compiler/translator/Compiler.h"
    
    bool compileTestShader(GLenum type,
                           ShShaderSpec spec,
                           ShShaderOutput output,
                           const std::string &shaderString,
                           ShBuiltInResources *resources,
                           int compileOptions,
                           std::string *translatedCode,
                           std::string *infoLog)
    {
        TCompiler *translator = ConstructCompiler(type, spec, output);
        if (!translator->Init(*resources))
        {
            SafeDelete(translator);
            return false;
        }
    
        const char *shaderStrings[] = { shaderString.c_str() };
    
        bool compilationSuccess = translator->compile(shaderStrings, 1, SH_OBJECT_CODE | compileOptions);
        TInfoSink &infoSink = translator->getInfoSink();
        if (translatedCode)
            *translatedCode = infoSink.obj.c_str();
        if (infoLog)
            *infoLog = infoSink.info.c_str();
        SafeDelete(translator);
        return compilationSuccess;
    }
    
    bool compileTestShader(GLenum type,
                           ShShaderSpec spec,
                           ShShaderOutput output,
                           const std::string &shaderString,
                           int compileOptions,
                           std::string *translatedCode,
                           std::string *infoLog)
    {
        ShBuiltInResources resources;
        ShInitBuiltInResources(&resources);
        return compileTestShader(type, spec, output, shaderString, &resources, compileOptions, translatedCode, infoLog);
    }
    
    MatchOutputCodeTest::MatchOutputCodeTest(GLenum shaderType,
                                             int defaultCompileOptions,
                                             ShShaderOutput outputType)
        : mShaderType(shaderType), mDefaultCompileOptions(defaultCompileOptions)
    {
        ShInitBuiltInResources(&mResources);
        mOutputCode[outputType] = std::string();
    }
    
    void MatchOutputCodeTest::addOutputType(const ShShaderOutput outputType)
    {
        mOutputCode[outputType] = std::string();
    }
    
    ShBuiltInResources *MatchOutputCodeTest::getResources()
    {
        return &mResources;
    }
    
    void MatchOutputCodeTest::compile(const std::string &shaderString)
    {
        compile(shaderString, mDefaultCompileOptions);
    }
    
    void MatchOutputCodeTest::compile(const std::string &shaderString, const int compileOptions)
    {
        std::string infoLog;
        for (auto &code : mOutputCode)
        {
            bool compilationSuccess =
                compileWithSettings(code.first, shaderString, compileOptions, &code.second, &infoLog);
            if (!compilationSuccess)
            {
                FAIL() << "Shader compilation failed:\n" << infoLog;
            }
        }
    }
    
    bool MatchOutputCodeTest::compileWithSettings(ShShaderOutput output,
                                                  const std::string &shaderString,
                                                  const int compileOptions,
                                                  std::string *translatedCode,
                                                  std::string *infoLog)
    {
        return compileTestShader(mShaderType, SH_GLES3_SPEC, output, shaderString, &mResources,
                                 compileOptions, translatedCode, infoLog);
    }
    
    bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringToFind) const
    {
        const auto code = mOutputCode.find(output);
        EXPECT_NE(mOutputCode.end(), code);
        return code->second.find(stringToFind) != std::string::npos;
    }
    
    bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
                                          const char *stringToFind,
                                          const int expectedOccurrences) const
    {
        const auto code = mOutputCode.find(output);
        EXPECT_NE(mOutputCode.end(), code);
        size_t currentPos  = 0;
        int occurencesLeft = expectedOccurrences;
        while (occurencesLeft-- > 0)
        {
            auto position = code->second.find(stringToFind, currentPos);
            if (position == std::string::npos)
            {
                return false;
            }
            currentPos = position + 1;
        }
        return code->second.find(stringToFind, currentPos) == std::string::npos;
    }
    
    bool MatchOutputCodeTest::foundInCode(const char *stringToFind) const
    {
        for (auto &code : mOutputCode)
        {
            if (!foundInCode(code.first, stringToFind))
            {
                return false;
            }
        }
        return true;
    }
    
    bool MatchOutputCodeTest::foundInCode(const char *stringToFind, const int expectedOccurrences) const
    {
        for (auto &code : mOutputCode)
        {
            if (!foundInCode(code.first, stringToFind, expectedOccurrences))
            {
                return false;
            }
        }
        return true;
    }
    
    bool MatchOutputCodeTest::notFoundInCode(const char *stringToFind) const
    {
        for (auto &code : mOutputCode)
        {
            if (foundInCode(code.first, stringToFind))
            {
                return false;
            }
        }
        return true;
    }