Skip to content

Commit 9cba46e

Browse files
Improve code coverage of MultiCommand class
This change introduces ULTs for untested parts of MultiCommand class. Furthermore, it contains MockMultiCommand class, which allows white-box testing. Related-To: NEO-6834 Signed-off-by: Patryk Wrobel <patryk.wrobel@intel.com>
1 parent f2a1837 commit 9cba46e

File tree

7 files changed

+208
-4
lines changed

7 files changed

+208
-4
lines changed

opencl/test/unit_test/offline_compiler/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ set(IGDRCL_SRCS_offline_compiler_mock
1919
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_encoder.h
2020
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_iga_wrapper.h
2121
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_argument_helper.h
22+
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_multi_command.h
2223
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h
2324
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_linker.h
2425
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_sip_ocloc_tests.cpp

opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class MockOclocArgHelper : public OclocArgHelper {
3131
bool callBaseReadBinaryFile = false;
3232
bool callBaseLoadDataFromFile = false;
3333
bool callBaseSaveOutput = false;
34+
bool callBaseReadFileToVectorOfStrings = false;
35+
bool shouldReturnEmptyVectorOfStrings = false;
3436

3537
MockOclocArgHelper(FilesMap &filesMap) : OclocArgHelper(0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr),
3638
filesMap(filesMap){};
@@ -44,6 +46,7 @@ class MockOclocArgHelper : public OclocArgHelper {
4446
callBaseReadBinaryFile = value;
4547
callBaseLoadDataFromFile = value;
4648
callBaseSaveOutput = value;
49+
callBaseReadFileToVectorOfStrings = value;
4750
}
4851

4952
protected:
@@ -54,6 +57,16 @@ class MockOclocArgHelper : public OclocArgHelper {
5457
return filesMap.find(filename) != filesMap.end();
5558
}
5659

60+
void readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines) override {
61+
if (callBaseReadFileToVectorOfStrings) {
62+
return OclocArgHelper::readFileToVectorOfStrings(filename, lines);
63+
}
64+
65+
if (shouldReturnEmptyVectorOfStrings) {
66+
lines.clear();
67+
}
68+
}
69+
5770
std::vector<char> readBinaryFile(const std::string &filename) override {
5871
if (callBaseReadBinaryFile) {
5972
return OclocArgHelper::readBinaryFile(filename);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
10+
#include "shared/offline_compiler/source/multi_command.h"
11+
12+
#include "opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h"
13+
14+
#include <optional>
15+
#include <string>
16+
17+
namespace NEO {
18+
19+
class MockMultiCommand : public MultiCommand {
20+
public:
21+
using MultiCommand::argHelper;
22+
using MultiCommand::quiet;
23+
using MultiCommand::retValues;
24+
25+
using MultiCommand::addAdditionalOptionsToSingleCommandLine;
26+
using MultiCommand::initialize;
27+
using MultiCommand::printHelp;
28+
using MultiCommand::runBuilds;
29+
using MultiCommand::showResults;
30+
using MultiCommand::singleBuild;
31+
using MultiCommand::splitLineInSeparateArgs;
32+
33+
MockMultiCommand() : MultiCommand{} {
34+
uniqueHelper = std::make_unique<MockOclocArgHelper>(filesMap);
35+
uniqueHelper->setAllCallBase(true);
36+
argHelper = uniqueHelper.get();
37+
}
38+
39+
~MockMultiCommand() override = default;
40+
41+
std::map<std::string, std::string> filesMap{};
42+
std::unique_ptr<MockOclocArgHelper> uniqueHelper{};
43+
};
44+
45+
} // namespace NEO

opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "gtest/gtest.h"
2828
#include "hw_cmds.h"
2929
#include "mock/mock_argument_helper.h"
30+
#include "mock/mock_multi_command.h"
3031
#include "mock/mock_offline_compiler.h"
3132

3233
#include <algorithm>
@@ -315,6 +316,148 @@ TEST_F(MultiCommandTests, GivenOutputFileListFlagWhenBuildingMultiCommandThenSuc
315316
delete pMultiCommand;
316317
}
317318

319+
TEST(MultiCommandWhiteboxTest, GivenVerboseModeWhenShowingResultsThenLogsArePrintedForEachBuild) {
320+
MockMultiCommand mockMultiCommand{};
321+
mockMultiCommand.retValues = {OclocErrorCode::SUCCESS, OclocErrorCode::INVALID_FILE};
322+
mockMultiCommand.quiet = false;
323+
324+
::testing::internal::CaptureStdout();
325+
const auto result = mockMultiCommand.showResults();
326+
const auto output = testing::internal::GetCapturedStdout();
327+
328+
const auto maskedResult = result | OclocErrorCode::INVALID_FILE;
329+
EXPECT_NE(OclocErrorCode::SUCCESS, result);
330+
EXPECT_EQ(OclocErrorCode::INVALID_FILE, maskedResult);
331+
332+
const auto expectedOutput{"Build command 0: successful\n"
333+
"Build command 1: failed. Error code: -5151\n"};
334+
EXPECT_EQ(expectedOutput, output);
335+
}
336+
337+
TEST(MultiCommandWhiteboxTest, GivenVerboseModeAndDefinedOutputFilenameAndDirectoryWhenAddingAdditionalOptionsToSingleCommandLineThenNothingIsDone) {
338+
MockMultiCommand mockMultiCommand{};
339+
mockMultiCommand.quiet = false;
340+
341+
std::vector<std::string> singleArgs = {
342+
"-file",
343+
"test_files/copybuffer.cl",
344+
"-output",
345+
"SpecialOutputFilename",
346+
"-out_dir",
347+
"SomeOutputDirectory",
348+
"-device",
349+
gEnvironment->devicePrefix.c_str()};
350+
351+
const auto singleArgsCopy{singleArgs};
352+
const size_t buildId{0};
353+
354+
::testing::internal::CaptureStdout();
355+
mockMultiCommand.addAdditionalOptionsToSingleCommandLine(singleArgs, buildId);
356+
const auto output = testing::internal::GetCapturedStdout();
357+
358+
EXPECT_EQ(singleArgsCopy, singleArgs);
359+
}
360+
361+
TEST(MultiCommandWhiteboxTest, GivenHelpArgumentsWhenInitializingThenHelpIsPrinted) {
362+
MockMultiCommand mockMultiCommand{};
363+
mockMultiCommand.quiet = false;
364+
365+
std::vector<std::string> singleArgs = {
366+
"--help"};
367+
368+
const auto args{singleArgs};
369+
370+
::testing::internal::CaptureStdout();
371+
const auto result = mockMultiCommand.initialize(args);
372+
const auto output = testing::internal::GetCapturedStdout();
373+
374+
const auto expectedOutput = R"===(Compiles multiple files using a config file.
375+
376+
Usage: ocloc multi <file_name>
377+
<file_name> Input file containing a list of arguments for subsequent
378+
ocloc invocations.
379+
Expected format of each line inside such file is:
380+
'-file <filename> -device <device_type> [compile_options]'.
381+
See 'ocloc compile --help' for available compile_options.
382+
Results of subsequent compilations will be dumped into
383+
a directory with name indentical file_name's base name.
384+
385+
-output_file_list Name of optional file containing
386+
paths to outputs .bin files
387+
388+
)===";
389+
390+
EXPECT_EQ(expectedOutput, output);
391+
EXPECT_EQ(-1, result);
392+
}
393+
394+
TEST(MultiCommandWhiteboxTest, GivenCommandLineWithApostrophesWhenSplittingLineInSeparateArgsThenTextBetweenApostrophesIsReadAsSingleArg) {
395+
MockMultiCommand mockMultiCommand{};
396+
mockMultiCommand.quiet = false;
397+
398+
const std::string commandLine{" -out_dir \"Some Directory\" -output \'Some Filename\'"};
399+
std::vector<std::string> outputArgs{};
400+
const std::size_t numberOfBuild{0};
401+
402+
::testing::internal::CaptureStdout();
403+
const auto result = mockMultiCommand.splitLineInSeparateArgs(outputArgs, commandLine, numberOfBuild);
404+
const auto output = testing::internal::GetCapturedStdout();
405+
406+
EXPECT_EQ(OclocErrorCode::SUCCESS, result);
407+
EXPECT_TRUE(output.empty()) << output;
408+
409+
ASSERT_EQ(4u, outputArgs.size());
410+
411+
EXPECT_EQ("-out_dir", outputArgs[0]);
412+
EXPECT_EQ("Some Directory", outputArgs[1]);
413+
414+
EXPECT_EQ("-output", outputArgs[2]);
415+
EXPECT_EQ("Some Filename", outputArgs[3]);
416+
}
417+
418+
TEST(MultiCommandWhiteboxTest, GivenCommandLineWithMissingApostropheWhenSplittingLineInSeparateArgsThenErrorIsReturned) {
419+
MockMultiCommand mockMultiCommand{};
420+
mockMultiCommand.quiet = false;
421+
422+
const std::string commandLine{"-out_dir \"Some Directory"};
423+
std::vector<std::string> outputArgs{};
424+
const std::size_t numberOfBuild{0};
425+
426+
::testing::internal::CaptureStdout();
427+
const auto result = mockMultiCommand.splitLineInSeparateArgs(outputArgs, commandLine, numberOfBuild);
428+
const auto output = testing::internal::GetCapturedStdout();
429+
430+
EXPECT_EQ(OclocErrorCode::INVALID_FILE, result);
431+
432+
const auto expectedOutput = "One of the quotes is open in build number 1\n";
433+
EXPECT_EQ(expectedOutput, output);
434+
}
435+
436+
TEST(MultiCommandWhiteboxTest, GivenArgsWithQuietModeAndEmptyMulticomandFileWhenInitializingThenQuietFlagIsSetAndErrorIsReturned) {
437+
MockMultiCommand mockMultiCommand{};
438+
mockMultiCommand.quiet = false;
439+
440+
mockMultiCommand.uniqueHelper->callBaseFileExists = false;
441+
mockMultiCommand.uniqueHelper->callBaseReadFileToVectorOfStrings = false;
442+
mockMultiCommand.uniqueHelper->shouldReturnEmptyVectorOfStrings = true;
443+
mockMultiCommand.filesMap["commands.txt"] = "";
444+
445+
const std::vector<std::string> args = {
446+
"ocloc",
447+
"multi",
448+
"commands.txt",
449+
"-q"};
450+
451+
::testing::internal::CaptureStdout();
452+
const auto result = mockMultiCommand.initialize(args);
453+
const auto output = testing::internal::GetCapturedStdout();
454+
455+
EXPECT_EQ(OclocErrorCode::INVALID_FILE, result);
456+
457+
const auto expectedOutput = "Command file was empty.\n";
458+
EXPECT_EQ(expectedOutput, output);
459+
}
460+
318461
TEST(MockOfflineCompilerTests, givenProductConfigValueWhenInitHwInfoThenResetGtSystemInfo) {
319462
MockOfflineCompiler mockOfflineCompiler;
320463
auto allEnabledDeviceConfigs = mockOfflineCompiler.argHelper->getAllSupportedDeviceConfigs();

shared/offline_compiler/source/multi_command.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Usage: ocloc multi <file_name>
159159
<file_name> Input file containing a list of arguments for subsequent
160160
ocloc invocations.
161161
Expected format of each line inside such file is:
162-
'-file <filename> -device <device_type> [compile_options].
162+
'-file <filename> -device <device_type> [compile_options]'.
163163
See 'ocloc compile --help' for available compile_options.
164164
Results of subsequent compilations will be dumped into
165165
a directory with name indentical file_name's base name.

shared/offline_compiler/source/multi_command.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
/*
2-
* Copyright (C) 2020-2021 Intel Corporation
2+
* Copyright (C) 2020-2022 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
66
*/
77

8+
#pragma once
9+
810
#include "shared/offline_compiler/source/decoder/binary_decoder.h"
911
#include "shared/offline_compiler/source/decoder/binary_encoder.h"
1012
#include "shared/offline_compiler/source/offline_compiler.h"
@@ -23,7 +25,7 @@ class MultiCommand {
2325
public:
2426
MultiCommand &operator=(const MultiCommand &) = delete;
2527
MultiCommand(const MultiCommand &) = delete;
26-
~MultiCommand() = default;
28+
MOCKABLE_VIRTUAL ~MultiCommand() = default;
2729

2830
static MultiCommand *create(const std::vector<std::string> &args, int &retVal, OclocArgHelper *helper);
2931

shared/offline_compiler/source/ocloc_arg_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class OclocArgHelper {
118118
PRODUCT_CONFIG findConfigMatch(const std::string &device, bool firstAppearance);
119119
void insertGenNames(GFXCORE_FAMILY family);
120120
std::vector<std::string> headersToVectorOfStrings();
121-
void readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines);
121+
MOCKABLE_VIRTUAL void readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines);
122122
MOCKABLE_VIRTUAL std::vector<char> readBinaryFile(const std::string &filename);
123123
MOCKABLE_VIRTUAL std::unique_ptr<char[]> loadDataFromFile(const std::string &filename, size_t &retSize);
124124

0 commit comments

Comments
 (0)