Path: blob/main_old/src/tests/test_utils/runner/TestSuite.h
1694 views
//1// Copyright 2019 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// TestSuite:6// Basic implementation of a test harness in ANGLE.78#ifndef ANGLE_TESTS_TEST_UTILS_TEST_SUITE_H_9#define ANGLE_TESTS_TEST_UTILS_TEST_SUITE_H_1011#include <map>12#include <memory>13#include <mutex>14#include <queue>15#include <string>16#include <thread>1718#include "HistogramWriter.h"19#include "tests/test_expectations/GPUTestExpectationsParser.h"20#include "util/test_utils.h"2122namespace angle23{24struct TestIdentifier25{26TestIdentifier();27TestIdentifier(const std::string &suiteNameIn, const std::string &nameIn);28TestIdentifier(const TestIdentifier &other);29~TestIdentifier();3031TestIdentifier &operator=(const TestIdentifier &other);3233static bool ParseFromString(const std::string &str, TestIdentifier *idOut);3435bool valid() const { return !testName.empty(); }36void sprintfName(char *outBuffer) const;3738std::string testSuiteName;39std::string testName;40};4142inline bool operator<(const TestIdentifier &a, const TestIdentifier &b)43{44return std::tie(a.testSuiteName, a.testName) < std::tie(b.testSuiteName, b.testName);45}4647inline bool operator==(const TestIdentifier &a, const TestIdentifier &b)48{49return std::tie(a.testSuiteName, a.testName) == std::tie(b.testSuiteName, b.testName);50}5152inline std::ostream &operator<<(std::ostream &os, const TestIdentifier &id)53{54return os << id.testSuiteName << "." << id.testName;55}5657enum class TestResultType58{59Crash,60Fail,61NoResult,62Pass,63Skip,64Timeout,65Unknown,66};6768const char *TestResultTypeToString(TestResultType type);6970struct TestResult71{72TestResultType type = TestResultType::NoResult;73double elapsedTimeSeconds = 0.0;74uint32_t flakyFailures = 0;75};7677inline bool operator==(const TestResult &a, const TestResult &b)78{79return a.type == b.type;80}8182inline std::ostream &operator<<(std::ostream &os, const TestResult &result)83{84return os << TestResultTypeToString(result.type);85}8687struct TestResults88{89TestResults();90~TestResults();9192std::map<TestIdentifier, TestResult> results;93std::mutex currentTestMutex;94TestIdentifier currentTest;95Timer currentTestTimer;96double currentTestTimeout = 0.0;97bool allDone = false;98std::string testArtifactsFakeTestName;99std::vector<std::string> testArtifactPaths;100};101102struct FileLine103{104const char *file;105int line;106};107108struct ProcessInfo : angle::NonCopyable109{110ProcessInfo();111~ProcessInfo();112ProcessInfo(ProcessInfo &&other);113ProcessInfo &operator=(ProcessInfo &&rhs);114115ProcessHandle process;116std::vector<TestIdentifier> testsInBatch;117std::string resultsFileName;118std::string filterFileName;119std::string commandLine;120std::string filterString;121};122123using TestQueue = std::queue<std::vector<TestIdentifier>>;124125class TestSuite126{127public:128TestSuite(int *argc, char **argv);129~TestSuite();130131int run();132void onCrashOrTimeout(TestResultType crashOrTimeout);133void addHistogramSample(const std::string &measurement,134const std::string &story,135double value,136const std::string &units);137138static TestSuite *GetInstance() { return mInstance; }139140// Returns the path to the artifact in the output directory.141std::string addTestArtifact(const std::string &artifactName);142143int getShardIndex() const { return mShardIndex; }144int getBatchId() const { return mBatchId; }145146// Test expectation processing.147bool loadTestExpectationsFromFileWithConfig(const GPUTestConfig &config,148const std::string &fileName);149bool loadAllTestExpectationsFromFile(const std::string &fileName);150int32_t getTestExpectation(const std::string &testName);151void maybeUpdateTestTimeout(uint32_t testExpectation);152int32_t getTestExpectationWithConfigAndUpdateTimeout(const GPUTestConfig &config,153const std::string &testName);154bool logAnyUnusedTestExpectations();155void setTestExpectationsAllowMask(uint32_t mask)156{157mTestExpectationsParser.setTestExpectationsAllowMask(mask);158}159160private:161bool parseSingleArg(const char *argument);162bool launchChildTestProcess(uint32_t batchId, const std::vector<TestIdentifier> &testsInBatch);163bool finishProcess(ProcessInfo *processInfo);164int printFailuresAndReturnCount() const;165void startWatchdog();166void dumpTestExpectationsErrorMessages();167int getSlowTestTimeout() const;168169static TestSuite *mInstance;170171std::string mTestExecutableName;172std::string mTestSuiteName;173TestQueue mTestQueue;174std::string mFilterString;175std::string mFilterFile;176std::string mResultsDirectory;177std::string mResultsFile;178std::string mHistogramJsonFile;179int mShardCount;180int mShardIndex;181angle::CrashCallback mCrashCallback;182TestResults mTestResults;183bool mBotMode;184bool mDebugTestGroups;185bool mGTestListTests;186bool mListTests;187bool mPrintTestStdout;188bool mDisableCrashHandler;189int mBatchSize;190int mCurrentResultCount;191int mTotalResultCount;192int mMaxProcesses;193int mTestTimeout;194int mBatchTimeout;195int mBatchId;196int mFlakyRetries;197int mMaxFailures;198int mFailureCount;199std::vector<std::string> mChildProcessArgs;200std::map<TestIdentifier, FileLine> mTestFileLines;201std::vector<ProcessInfo> mCurrentProcesses;202std::thread mWatchdogThread;203HistogramWriter mHistogramWriter;204std::string mTestArtifactDirectory;205GPUTestExpectationsParser mTestExpectationsParser;206};207208bool GetTestResultsFromFile(const char *fileName, TestResults *resultsOut);209} // namespace angle210211#endif // ANGLE_TESTS_TEST_UTILS_TEST_SUITE_H_212213214