util: Add a "writefile" unit test to the m5 utility.
[gem5.git] / util / m5 / src / call_type.test.cc
1 /*
2 * Copyright 2020 Google Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <gtest/gtest.h>
29
30 // For EXPECT_THAT and HasSubstr
31 #include <gmock/gmock.h>
32
33 #include "call_type.hh"
34
35 // Simple substitute definitions for Args and DispatchTable, with an int so
36 // we can tell instances apart.
37 class Args { public: int i; };
38 class DispatchTable { public: int i; };
39
40 class TestCallType : public CallType
41 {
42 protected:
43 bool isDefault() const override { return testIsDefault; }
44 bool checkArgs(Args &args) override { return args.i == testAcceptArgs; }
45 void
46 init() override
47 {
48 testInitHappened = true;
49 CallType::init();
50 }
51
52 void printBrief(std::ostream &os) const override { os << testBrief; }
53 void printDesc(std::ostream &os) const override { os << testDesc; }
54 public:
55 static std::vector<CallType *> &testGetAllTypes() { return allTypes(); }
56
57 // Usage strings to return.
58 std::string testBrief;
59 std::string testDesc;
60
61 // Return this dispatch table when requested.
62 DispatchTable testDt = { 0 };
63 const DispatchTable &getDispatch() const override { return testDt; }
64
65 // If an Args has this value, accept it.
66 int testAcceptArgs = 0;
67
68 // Whether this call type should be considered default.
69 bool testIsDefault = false;
70
71 // Whether init has been called.
72 bool testInitHappened = false;
73 };
74
75 TEST(CallTypeTest, Constructor)
76 {
77 auto &all_types = TestCallType::testGetAllTypes();
78
79 // There should be no call types yet.
80 EXPECT_EQ(all_types.size(), 0);
81
82 // Create one.
83 TestCallType test_ct;
84
85 // Set the dispatch table to something we'll recognize.
86 test_ct.testDt.i = 0xaa55;
87
88 // Verify that the list of all call types has one in it now.
89 EXPECT_EQ(all_types.size(), 1);
90
91 // Verify that that was our call type by verifying that the dispatch table
92 // has our signature.
93 EXPECT_EQ(all_types[0]->getDispatch().i, 0xaa55);
94
95 // Clear all_types, since call types don't clean up after themselves as
96 // they go away.
97 all_types.clear();
98 }
99
100 TEST(CallTypeTest, DetectOne)
101 {
102 auto &all_types = TestCallType::testGetAllTypes();
103
104 // One option selected.
105 TestCallType option1;
106 option1.testAcceptArgs = 1;
107 option1.testIsDefault = true;
108 option1.testDt.i = 1;
109
110 EXPECT_EQ(all_types.size(), 1);
111
112 Args args;
113 args.i = 1;
114
115 EXPECT_FALSE(option1.testInitHappened);
116
117 auto &ct = CallType::detect(args);
118
119 // Verify that we selected the only option.
120 EXPECT_TRUE(option1.testInitHappened);
121 EXPECT_EQ(ct.getDispatch().i, 1);
122
123 // One option, selecting the default.
124 option1.testInitHappened = false;
125
126 // Args will not match.
127 args.i = 2;
128
129 auto &def_ct = CallType::detect(args);
130
131 // Verify that the one option was defaulted to.
132 EXPECT_TRUE(option1.testInitHappened);
133 EXPECT_EQ(def_ct.getDispatch().i, 1);
134
135 // Reset all_types.
136 all_types.clear();
137 }
138
139 TEST(CallTypeTest, DetectTwo)
140 {
141 auto &all_types = TestCallType::testGetAllTypes();
142
143 // One of two options selected.
144 TestCallType option1;
145 option1.testAcceptArgs = 1;
146 option1.testIsDefault = true;
147 option1.testDt.i = 1;
148
149 TestCallType option2;
150 option2.testAcceptArgs = 2;
151 option2.testIsDefault = false;
152 option2.testDt.i = 2;
153
154 EXPECT_EQ(all_types.size(), 2);
155
156 // Select the first option.
157 Args args;
158 args.i = 1;
159
160 EXPECT_FALSE(option1.testInitHappened);
161 EXPECT_FALSE(option2.testInitHappened);
162
163 auto &ct1 = CallType::detect(args);
164
165 // Verify that we selected the first option.
166 EXPECT_TRUE(option1.testInitHappened);
167 EXPECT_FALSE(option2.testInitHappened);
168 EXPECT_EQ(ct1.getDispatch().i, 1);
169
170 option1.testInitHappened = false;
171 option2.testInitHappened = false;
172
173 // Select the second option.
174 args.i = 2;
175
176 auto &ct2 = CallType::detect(args);
177
178 // Verify that we selected the second option.
179 EXPECT_FALSE(option1.testInitHappened);
180 EXPECT_TRUE(option2.testInitHappened);
181 EXPECT_EQ(ct2.getDispatch().i, 2);
182
183 option1.testInitHappened = false;
184 option2.testInitHappened = false;
185
186 // Default to the first option.
187 args.i = 3;
188
189 auto &def_ct1 = CallType::detect(args);
190
191 // Verify that we selected the first option.
192 EXPECT_TRUE(option1.testInitHappened);
193 EXPECT_FALSE(option2.testInitHappened);
194 EXPECT_EQ(ct1.getDispatch().i, 1);
195
196 option1.testInitHappened = false;
197 option2.testInitHappened = false;
198
199 // Default to the second option.
200 option1.testIsDefault = false;
201 option2.testIsDefault = true;
202
203 auto &def_ct2 = CallType::detect(args);
204
205 // Verify that we selected the second option.
206 EXPECT_FALSE(option1.testInitHappened);
207 EXPECT_TRUE(option2.testInitHappened);
208 EXPECT_EQ(ct2.getDispatch().i, 2);
209
210 option1.testInitHappened = false;
211 option2.testInitHappened = false;
212
213 // Reset all_types.
214 all_types.clear();
215 }
216
217 TEST(CallTypeTest, Usage)
218 {
219 auto &all_types = TestCallType::testGetAllTypes();
220
221 TestCallType ct1;
222 ct1.testBrief = "brief 1";
223 ct1.testDesc = "A longer description of call type 1, which is long.";
224
225 TestCallType ct2;
226 ct2.testBrief = "short 2";
227 ct2.testDesc = "Very verbose text saying what call type 2 is, "
228 "and is different from 1.";
229
230 EXPECT_EQ(all_types.size(), 2);
231
232 auto summary = CallType::usageSummary();
233
234 // For now, just expect that the brief and full descriptive text shows up
235 // in the summary somewhere.
236 //
237 // More strict checks might test that things were placed in the right
238 // order, were on their own lines when appropriate, etc.
239 EXPECT_THAT(summary, testing::HasSubstr(ct1.testBrief));
240 EXPECT_THAT(summary, testing::HasSubstr(ct1.testDesc));
241 EXPECT_THAT(summary, testing::HasSubstr(ct2.testBrief));
242 EXPECT_THAT(summary, testing::HasSubstr(ct2.testDesc));
243 EXPECT_THAT(summary, testing::HasSubstr(ct2.testDesc));
244
245 // Reset all_types.
246 all_types.clear();
247 }