1 : // Copyright 2012 Google Inc.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/grinder/grinder_app.h"
16 :
17 : #include "gtest/gtest.h"
18 : #include "syzygy/common/application.h"
19 : #include "syzygy/core/unittest_util.h"
20 : #include "syzygy/pe/unittest_util.h"
21 :
22 : namespace grinder {
23 :
24 : namespace {
25 :
26 : class TestGrinderApp : public GrinderApp {
27 : public:
28 : // Expose for testing.
29 : using GrinderApp::trace_files_;
30 : using GrinderApp::output_file_;
31 : };
32 :
33 : class GrinderAppTest : public testing::PELibUnitTest {
34 : public:
35 : typedef testing::PELibUnitTest Super;
36 : typedef common::Application<TestGrinderApp> TestApplication;
37 :
38 : GrinderAppTest()
39 : : cmd_line_(FilePath(L"grinder.exe")),
40 E : impl_(app_.implementation()) {
41 E : }
42 :
43 E : virtual void SetUp() OVERRIDE {
44 E : Super::SetUp();
45 :
46 : // Setup the IO streams.
47 E : CreateTemporaryDir(&temp_dir_);
48 E : stdin_path_ = temp_dir_.Append(L"NUL");
49 E : stdout_path_ = temp_dir_.Append(L"stdout.txt");
50 E : stderr_path_ = temp_dir_.Append(L"stderr.txt");
51 E : InitStreams(stdin_path_, stdout_path_, stderr_path_);
52 :
53 : // Point the application at the test's command-line and IO streams.
54 E : app_.set_command_line(&cmd_line_);
55 E : app_.set_in(in());
56 E : app_.set_out(out());
57 E : app_.set_err(err());
58 E : }
59 :
60 : protected:
61 : // The command line to be given to the application under test.
62 : CommandLine cmd_line_;
63 :
64 : // The application object under test.
65 : TestApplication app_;
66 :
67 : // A reference to the underlying application implementation for convenience.
68 : TestGrinderApp& impl_;
69 :
70 : // A temporary folder where all IO will be stored.
71 : FilePath temp_dir_;
72 :
73 : // @name File paths used for the standard IO streams.
74 : // @{
75 : FilePath stdin_path_;
76 : FilePath stdout_path_;
77 : FilePath stderr_path_;
78 : // @}
79 : };
80 :
81 : } // namespace
82 :
83 E : TEST_F(GrinderAppTest, ParseCommandLineFailsWithNoMode) {
84 E : cmd_line_.AppendArgPath(FilePath(L"foo.dat"));
85 E : ASSERT_FALSE(impl_.ParseCommandLine(&cmd_line_));
86 E : }
87 :
88 E : TEST_F(GrinderAppTest, ParseCommandLineFailsWithNoFiles) {
89 E : cmd_line_.AppendSwitchASCII("mode", "profile");
90 E : ASSERT_FALSE(impl_.ParseCommandLine(&cmd_line_));
91 E : }
92 :
93 E : TEST_F(GrinderAppTest, ParseCommandLineTraceFiles) {
94 E : std::vector<FilePath> temp_files;
95 E : cmd_line_.AppendSwitchASCII("mode", "profile");
96 E : for (size_t i = 0; i < 10; ++i) {
97 E : FilePath temp_file;
98 E : ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_, &temp_file));
99 E : cmd_line_.AppendArgPath(temp_file);
100 E : temp_files.push_back(temp_file);
101 E : }
102 :
103 E : ASSERT_TRUE(impl_.ParseCommandLine(&cmd_line_));
104 E : ASSERT_EQ(temp_files, impl_.trace_files_);
105 E : }
106 :
107 E : TEST_F(GrinderAppTest, ParseCommandLineOutputFile) {
108 E : ASSERT_TRUE(impl_.output_file_.empty());
109 E : cmd_line_.AppendSwitchASCII("mode", "profile");
110 E : cmd_line_.AppendSwitchPath("output-file", FilePath(L"output.txt"));
111 : cmd_line_.AppendArgPath(
112 E : testing::GetExeTestDataRelativePath(L"profile_traces/trace-1.bin"));
113 :
114 E : ASSERT_TRUE(impl_.ParseCommandLine(&cmd_line_));
115 E : ASSERT_EQ(L"output.txt", impl_.output_file_.value());
116 E : }
117 :
118 E : TEST_F(GrinderAppTest, ProfileEndToEnd) {
119 E : cmd_line_.AppendSwitchASCII("mode", "profile");
120 : cmd_line_.AppendArgPath(
121 E : testing::GetExeTestDataRelativePath(L"profile_traces/trace-1.bin"));
122 :
123 E : FilePath output_file;
124 E : ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_, &output_file));
125 E : ASSERT_TRUE(file_util::Delete(output_file, false));
126 E : cmd_line_.AppendSwitchPath("output-file", output_file);
127 :
128 E : ASSERT_TRUE(!file_util::PathExists(output_file));
129 :
130 E : EXPECT_EQ(0, app_.Run());
131 :
132 : // Verify that the output file was created.
133 E : EXPECT_TRUE(file_util::PathExists(output_file));
134 E : }
135 :
136 E : TEST_F(GrinderAppTest, CoverageEndToEnd) {
137 E : cmd_line_.AppendSwitchASCII("mode", "coverage");
138 : cmd_line_.AppendArgPath(
139 E : testing::GetExeTestDataRelativePath(L"coverage_traces/trace-1.bin"));
140 :
141 E : FilePath output_file;
142 E : ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_, &output_file));
143 E : ASSERT_TRUE(file_util::Delete(output_file, false));
144 E : cmd_line_.AppendSwitchPath("output-file", output_file);
145 :
146 E : ASSERT_TRUE(!file_util::PathExists(output_file));
147 :
148 E : EXPECT_EQ(0, app_.Run());
149 :
150 : // Verify that the output file was created.
151 E : EXPECT_TRUE(file_util::PathExists(output_file));
152 E : }
153 :
154 : } // namespace grinder
|