blob: 312b2d9704d3b635797c061f4184594f3da6f1fb [file] [log] [blame]
Vitaly Buka00b61072016-10-19 16:22:51 -07001// Copyright 2016 Google Inc. All rights reserved.
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
Vitaly Bukaf90698f2017-03-01 15:46:58 -080015#include "src/mutator.h"
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080016
Vitaly Bukaf047a002017-01-12 23:57:00 -080017#include <algorithm>
18#include <set>
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080019#include <string>
Vitaly Bukafb193372017-03-04 19:25:29 -080020#include <tuple>
Vitaly Bukaf047a002017-01-12 23:57:00 -080021#include <utility>
22#include <vector>
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080023
Vitaly Buka35df2e42017-02-25 01:17:25 -080024#include "port/gtest.h"
Vitaly Bukaaf8136f2017-06-09 16:40:12 -070025#include "src/binary_format.h"
Vitaly Bukaf90698f2017-03-01 15:46:58 -080026#include "src/mutator_test_proto2.pb.h"
27#include "src/mutator_test_proto3.pb.h"
Vitaly Buka829ad002017-03-01 16:26:00 -080028#include "src/text_format.h"
Vitaly Buka1109c002016-10-20 17:25:19 -070029
Vitaly Bukaf86815c2017-02-27 14:19:19 -080030namespace protobuf_mutator {
31
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080032using protobuf::util::MessageDifferencer;
Vitaly Buka4af611d2016-12-03 18:57:32 -080033using testing::TestWithParam;
34using testing::ValuesIn;
Vitaly Buka0e17fd72016-11-18 10:02:46 -080035
Vitaly Buka4af611d2016-12-03 18:57:32 -080036const char kMessages[] = R"(
37 required_msg {}
38 optional_msg {}
39 repeated_msg {}
40 repeated_msg {required_sint32: 56}
41 repeated_msg {}
42 repeated_msg {
43 required_msg {}
44 optional_msg {}
45 repeated_msg {}
46 repeated_msg { required_int32: 67 }
47 repeated_msg {}
48 }
Vitaly Bukaa268b672020-01-27 18:49:40 -080049 any {
50 [type.googleapis.com/protobuf_mutator.Msg] {
51 optional_msg {}
52 repeated_msg {}
53 any {
54 [type.googleapis.com/protobuf_mutator.Msg3.SubMsg] {
55 optional_int64: -5
56 }
57 }
58 }
59 }
Vitaly Buka4af611d2016-12-03 18:57:32 -080060)";
Vitaly Buka0e17fd72016-11-18 10:02:46 -080061
Vitaly Buka28ca0ee2017-03-04 21:35:42 -080062const char kMessagesProto3[] = R"(
63 optional_msg {}
64 repeated_msg {}
65 repeated_msg {optional_sint32: 56}
66 repeated_msg {}
67 repeated_msg {
68 optional_msg {}
69 repeated_msg {}
70 repeated_msg { optional_int32: 67 }
71 repeated_msg {}
72 }
Vitaly Bukaa268b672020-01-27 18:49:40 -080073 any {
74 [type.googleapis.com/protobuf_mutator.Msg] {
75 optional_msg {}
76 repeated_msg {}
77 any {
78 [type.googleapis.com/protobuf_mutator.Msg3.SubMsg] {
79 optional_int64: -5
80 }
81 }
82 }
83 }
Vitaly Buka28ca0ee2017-03-04 21:35:42 -080084)";
85
Vitaly Buka4af611d2016-12-03 18:57:32 -080086const char kRequiredFields[] = R"(
87 required_double: 1.26685288449177e-313
88 required_float: 5.9808638e-39
89 required_int32: 67
90 required_int64: 5285068
91 required_uint32: 14486213
92 required_uint64: 520229415
93 required_sint32: 56
94 required_sint64: -6057486163525532641
95 required_fixed32: 8812173
96 required_fixed64: 273731277756
97 required_sfixed32: 43142
98 required_sfixed64: 132
99 required_bool: false
100 required_string: "qwert"
101 required_bytes: "asdf"
102)";
103
104const char kOptionalFields[] = R"(
105 optional_double: 1.93177850152856e-314
106 optional_float: 4.7397519e-41
107 optional_int32: 40020
108 optional_int64: 10
109 optional_uint32: 40
110 optional_uint64: 159
111 optional_sint32: 44015
112 optional_sint64: 17493625000076
113 optional_fixed32: 193
114 optional_fixed64: 8542688694448488723
115 optional_sfixed32: 4926
116 optional_sfixed64: 60
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800117 optional_bool: true
Vitaly Buka4af611d2016-12-03 18:57:32 -0800118 optional_string: "QWERT"
119 optional_bytes: "ASDF"
120 optional_enum: ENUM_5
121)";
122
123const char kRepeatedFields[] = R"(
124 repeated_double: 1.93177850152856e-314
125 repeated_double: 1.26685288449177e-313
126 repeated_float: 4.7397519e-41
127 repeated_float: 5.9808638e-39
128 repeated_int32: 40020
129 repeated_int32: 67
130 repeated_int64: 10
131 repeated_int64: 5285068
132 repeated_uint32: 40
133 repeated_uint32: 14486213
134 repeated_uint64: 159
135 repeated_uint64: 520229415
136 repeated_sint32: 44015
137 repeated_sint32: 56
138 repeated_sint64: 17493625000076
139 repeated_sint64: -6057486163525532641
140 repeated_fixed32: 193
141 repeated_fixed32: 8812173
142 repeated_fixed64: 8542688694448488723
143 repeated_fixed64: 273731277756
144 repeated_sfixed32: 4926
145 repeated_sfixed32: 43142
146 repeated_sfixed64: 60
147 repeated_sfixed64: 132
148 repeated_bool: false
149 repeated_bool: true
150 repeated_string: "QWERT"
151 repeated_string: "qwert"
152 repeated_bytes: "ASDF"
153 repeated_bytes: "asdf"
154 repeated_enum: ENUM_5
155 repeated_enum: ENUM_4
156)";
157
158const char kRequiredNestedFields[] = R"(
159 required_int32: 123
160 optional_msg {
161 required_double: 1.26685288449177e-313
162 required_float: 5.9808638e-39
163 required_int32: 67
164 required_int64: 5285068
165 required_uint32: 14486213
166 required_uint64: 520229415
167 required_sint32: 56
168 required_sint64: -6057486163525532641
169 required_fixed32: 8812173
170 required_fixed64: 273731277756
171 required_sfixed32: 43142
172 required_sfixed64: 132
173 required_bool: false
174 required_string: "qwert"
175 required_bytes: "asdf"
176 }
177)";
178
Vitaly Bukaa268b672020-01-27 18:49:40 -0800179const char kRequiredInAnyFields[] = R"(
180 any {
181 [type.googleapis.com/protobuf_mutator.Msg] {
182 required_uint32: 14486213
183 required_uint64: 520229415
184 required_sint64: -6057486163525532641
185 required_string: "qwert"
186 required_bytes: "asdf"
187 }
188 }
189)";
190
Vitaly Buka4af611d2016-12-03 18:57:32 -0800191const char kOptionalNestedFields[] = R"(
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800192 optional_int32: 123
Vitaly Buka4af611d2016-12-03 18:57:32 -0800193 optional_msg {
194 optional_double: 1.93177850152856e-314
195 optional_float: 4.7397519e-41
196 optional_int32: 40020
197 optional_int64: 10
198 optional_uint32: 40
199 optional_uint64: 159
200 optional_sint32: 44015
201 optional_sint64: 17493625000076
202 optional_fixed32: 193
203 optional_fixed64: 8542688694448488723
204 optional_sfixed32: 4926
205 optional_sfixed64: 60
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800206 optional_bool: true
Vitaly Buka4af611d2016-12-03 18:57:32 -0800207 optional_string: "QWERT"
208 optional_bytes: "ASDF"
209 optional_enum: ENUM_5
210 }
211)";
212
Vitaly Bukaa268b672020-01-27 18:49:40 -0800213const char kOptionalInAnyFields[] = R"(
214 any {
215 [type.googleapis.com/protobuf_mutator.Msg] {
216 optional_uint32: 440
217 optional_uint64: 1559
218 optional_sint32: 440615
219 optional_string: "XYZ"
220 optional_enum: ENUM_4
221 }
222 }
223)";
224
Vitaly Buka4af611d2016-12-03 18:57:32 -0800225const char kRepeatedNestedFields[] = R"(
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800226 optional_int32: 123
Vitaly Buka4af611d2016-12-03 18:57:32 -0800227 optional_msg {
228 repeated_double: 1.93177850152856e-314
229 repeated_double: 1.26685288449177e-313
230 repeated_float: 4.7397519e-41
231 repeated_float: 5.9808638e-39
232 repeated_int32: 40020
233 repeated_int32: 67
234 repeated_int64: 10
235 repeated_int64: 5285068
236 repeated_uint32: 40
237 repeated_uint32: 14486213
238 repeated_uint64: 159
239 repeated_uint64: 520229415
240 repeated_sint32: 44015
241 repeated_sint32: 56
242 repeated_sint64: 17493625000076
243 repeated_sint64: -6057486163525532641
244 repeated_fixed32: 193
245 repeated_fixed32: 8812173
246 repeated_fixed64: 8542688694448488723
247 repeated_fixed64: 273731277756
248 repeated_sfixed32: 4926
249 repeated_sfixed32: 43142
250 repeated_sfixed64: 60
251 repeated_sfixed64: 132
252 repeated_bool: false
253 repeated_bool: true
254 repeated_string: "QWERT"
255 repeated_string: "qwert"
256 repeated_bytes: "ASDF"
257 repeated_bytes: "asdf"
258 repeated_enum: ENUM_5
259 repeated_enum: ENUM_4
260 }
261)";
262
Vitaly Bukaa268b672020-01-27 18:49:40 -0800263const char kRepeatedInAnyFields[] = R"(
264 any {
265 [type.googleapis.com/protobuf_mutator.Msg] {
266 repeated_double: 1.931778501556e-31
267 repeated_double: 1.26685288449177e-31
268 repeated_float: 4.739759e-41
269 repeated_float: 5.98038e-39
270 repeated_int32: 400201
271 repeated_int32: 673
272 repeated_int64: 104
273 repeated_int64: 52850685
274 }
275 }
276)";
277
278const char kOptionalInDeepAnyFields[] = R"(
279 any {
280 [type.googleapis.com/protobuf_mutator.Msg] {
281 any {
282 [type.googleapis.com/protobuf_mutator.Msg] {
283 any {
284 [type.googleapis.com/protobuf_mutator.Msg] {
285 optional_double: 1.9317850152856e-314
286 optional_sint64: 1743625000076
287 optional_string: "XYZ"
288 }
289 }
290 }
291 }
292 }
293 }
294)";
295
Teju Nareddy4aeed372020-04-20 09:52:45 -0700296const char kUnknownFieldInput[] = R"(
Teju Nareddy45d4dae2020-04-17 16:20:08 -0700297 optional_bool: true
298 unknown_field: "test unknown field"
299)";
300
Teju Nareddy4aeed372020-04-20 09:52:45 -0700301const char kUnknownFieldExpected[] = R"(optional_bool: true
302)";
303
Vitaly Bukae79e0182017-03-01 16:02:14 -0800304class TestMutator : public Mutator {
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800305 public:
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800306 explicit TestMutator(bool keep_initialized,
Vitaly Buka379f5ab2019-08-31 16:11:59 -0700307 size_t random_to_default_ratio = 0) {
308 Seed(17);
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800309 if (random_to_default_ratio)
310 random_to_default_ratio_ = random_to_default_ratio;
Vitaly Bukaba129722016-12-14 17:29:15 -0800311 keep_initialized_ = keep_initialized;
312 }
Vitaly Buka142e08b2017-03-05 16:26:15 -0800313
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800314 private:
315 RandomEngine random_;
Vitaly Buka2256ad72017-03-04 17:38:15 -0800316};
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800317
Vitaly Bukae79e0182017-03-01 16:02:14 -0800318class ReducedTestMutator : public TestMutator {
Vitaly Buka2256ad72017-03-04 17:38:15 -0800319 public:
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800320 ReducedTestMutator() : TestMutator(false, 4) {
Vitaly Buka2256ad72017-03-04 17:38:15 -0800321 for (float i = 1000; i > 0.1; i /= 7) {
322 values_.push_back(i);
323 values_.push_back(-i);
324 }
325 values_.push_back(-1.0);
326 values_.push_back(0.0);
327 values_.push_back(1.0);
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800328 }
329
Vitaly Buka2256ad72017-03-04 17:38:15 -0800330 protected:
331 int32_t MutateInt32(int32_t value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800332 int64_t MutateInt64(int64_t value) override { return GetRandomValue(); }
Vitaly Buka0fa21bd2017-03-08 17:02:45 -0800333 uint32_t MutateUInt32(uint32_t value) override {
334 return fabs(GetRandomValue());
335 }
336 uint64_t MutateUInt64(uint64_t value) override {
337 return fabs(GetRandomValue());
338 }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800339 float MutateFloat(float value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800340 double MutateDouble(double value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800341 std::string MutateString(const std::string& value,
Vitaly Buka1c91e722020-01-25 21:56:22 -0800342 int size_increase_hint) override {
Toshi Piazzaade13bd2019-06-01 23:49:57 -0700343 return strings_[std::uniform_int_distribution<>(
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800344 0, strings_.size() - 1)(*random())];
Vitaly Buka2256ad72017-03-04 17:38:15 -0800345 }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800346
347 private:
Vitaly Buka2256ad72017-03-04 17:38:15 -0800348 float GetRandomValue() {
Toshi Piazzaade13bd2019-06-01 23:49:57 -0700349 return values_[std::uniform_int_distribution<>(
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800350 0, values_.size() - 1)(*random())];
Vitaly Buka2256ad72017-03-04 17:38:15 -0800351 }
352
Vitaly Buka2256ad72017-03-04 17:38:15 -0800353 std::vector<float> values_;
354 std::vector<std::string> strings_ = {
355 "", "\001", "\000", "a", "b", "ab",
356 };
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800357};
358
Vitaly Buka4af611d2016-12-03 18:57:32 -0800359std::vector<std::string> Split(const std::string& str) {
360 std::istringstream iss(str);
361 std::vector<std::string> result;
362 for (std::string line; std::getline(iss, line, '\n');) result.push_back(line);
363 return result;
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800364}
365
Vitaly Bukabe8416c2020-01-27 18:14:36 -0800366using TestParams =
367 std::tuple<const protobuf::Message*, const char*, size_t, std::string>;
Vitaly Bukafb193372017-03-04 19:25:29 -0800368
369template <class T>
370std::vector<TestParams> GetFieldTestParams(
Vitaly Buka4af611d2016-12-03 18:57:32 -0800371 const std::vector<const char*>& tests) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800372 std::vector<TestParams> results;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800373 for (auto t : tests) {
374 auto lines = Split(t);
375 for (size_t i = 0; i != lines.size(); ++i) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800376 if (lines[i].find(':') != std::string::npos)
Vitaly Bukabe8416c2020-01-27 18:14:36 -0800377 results.push_back(
378 std::make_tuple(&T::default_instance(), t, i, lines[i]));
Vitaly Buka781853c2016-11-21 23:09:35 -0800379 }
Vitaly Buka781853c2016-11-21 23:09:35 -0800380 }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800381 return results;
Vitaly Buka00b61072016-10-19 16:22:51 -0700382}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800383
Vitaly Bukafb193372017-03-04 19:25:29 -0800384template <class T>
385std::vector<TestParams> GetMessageTestParams(
Vitaly Buka4af611d2016-12-03 18:57:32 -0800386 const std::vector<const char*>& tests) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800387 std::vector<TestParams> results;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800388 for (auto t : tests) {
389 auto lines = Split(t);
390 for (size_t i = 0; i != lines.size(); ++i) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800391 if (lines[i].find("{}") != std::string::npos)
Vitaly Bukabe8416c2020-01-27 18:14:36 -0800392 results.push_back(
393 std::make_tuple(&T::default_instance(), t, i, lines[i]));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800394 }
395 }
396 return results;
397}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800398
Vitaly Bukabbb27cc2020-01-27 18:37:11 -0800399bool Mutate(const protobuf::Message& from, const protobuf::Message& to,
Vitaly Bukaa268b672020-01-27 18:49:40 -0800400 int iterations = 100000) {
Vitaly Buka43f748f2017-01-05 20:59:32 -0800401 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
Vitaly Bukae79e0182017-03-01 16:02:14 -0800402 ReducedTestMutator mutator;
Vitaly Bukafb193372017-03-04 19:25:29 -0800403 std::unique_ptr<protobuf::Message> message(from.New());
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800404 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
Vitaly Bukabbb27cc2020-01-27 18:37:11 -0800405 for (int j = 0; j < iterations; ++j) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800406 message->CopyFrom(from);
Vitaly Bukadbc4c0f2020-01-29 01:22:21 -0800407 mutator.Mutate(message.get(), 1500);
Vitaly Bukafb193372017-03-04 19:25:29 -0800408 if (MessageDifferencer::Equals(*message, to)) return true;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800409 }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800410
411 ADD_FAILURE() << "Failed to get from:\n"
Vitaly Bukaa268b672020-01-27 18:49:40 -0800412 << from.DebugString() << "\nto:\n"
413 << to.DebugString();
Vitaly Buka4af611d2016-12-03 18:57:32 -0800414 return false;
415}
416
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800417bool CrossOver(const protobuf::Message& from, const protobuf::Message& with,
Vitaly Bukaa268b672020-01-27 18:49:40 -0800418 const protobuf::Message& to, int iterations = 100000) {
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800419 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
420 ReducedTestMutator mutator;
421 std::unique_ptr<protobuf::Message> message(from.New());
422 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
Vitaly Bukabbb27cc2020-01-27 18:37:11 -0800423 for (int j = 0; j < iterations; ++j) {
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800424 message->CopyFrom(from);
425 mutator.CrossOver(with, message.get(), 1000);
426 if (MessageDifferencer::Equals(*message, to)) return true;
427 }
428 return false;
429}
430
Vitaly Bukae79e0182017-03-01 16:02:14 -0800431class MutatorTest : public TestWithParam<TestParams> {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800432 protected:
433 void SetUp() override {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800434 m1_.reset(std::get<0>(GetParam())->New());
435 m2_.reset(std::get<0>(GetParam())->New());
436 text_ = std::get<1>(GetParam());
437 line_ = std::get<2>(GetParam());
Vitaly Buka4af611d2016-12-03 18:57:32 -0800438 }
Vitaly Bukafb193372017-03-04 19:25:29 -0800439
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800440 void LoadMessage(protobuf::Message* message) {
Vitaly Bukabe54a442017-03-01 16:39:33 -0800441 EXPECT_TRUE(ParseTextMessage(text_, message));
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800442 }
443
Vitaly Buka6e957512019-01-23 15:48:23 -0800444 void LoadWithoutLine(protobuf::Message* message) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800445 std::ostringstream oss;
446 auto lines = Split(text_);
447 for (size_t i = 0; i != lines.size(); ++i) {
448 if (i != line_) oss << lines[i] << '\n';
449 }
Vitaly Buka6e957512019-01-23 15:48:23 -0800450 EXPECT_TRUE(ParseTextMessage(oss.str(), message));
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800451 }
452
Vitaly Buka6e957512019-01-23 15:48:23 -0800453 void LoadWithChangedLine(protobuf::Message* message, int value) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800454 auto lines = Split(text_);
455 std::ostringstream oss;
456 for (size_t i = 0; i != lines.size(); ++i) {
457 if (i != line_) {
458 oss << lines[i] << '\n';
459 } else {
460 std::string s = lines[i];
461 s.resize(s.find(':') + 2);
462
463 if (lines[i].back() == '\"') {
464 // strings
465 s += value ? "\"\\" + std::to_string(value) + "\"" : "\"\"";
466 } else if (lines[i].back() == 'e') {
467 // bools
468 s += value ? "true" : "false";
469 } else {
470 s += std::to_string(value);
471 }
472 oss << s << '\n';
473 }
474 }
Vitaly Buka6e957512019-01-23 15:48:23 -0800475 EXPECT_TRUE(ParseTextMessage(oss.str(), message));
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800476 }
477
478 std::string text_;
479 size_t line_;
480 std::unique_ptr<protobuf::Message> m1_;
481 std::unique_ptr<protobuf::Message> m2_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800482};
483
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800484// These tests are irrelevant for Proto3 as it has no required fields and
485// insertion/deletion.
Vitaly Bukafb193372017-03-04 19:25:29 -0800486
Vitaly Bukae79e0182017-03-01 16:02:14 -0800487class MutatorFieldInsDelTest : public MutatorTest {};
Vitaly Bukaf0a8ca02019-01-23 21:37:13 -0800488INSTANTIATE_TEST_SUITE_P(Proto2, MutatorFieldInsDelTest,
489 ValuesIn(GetFieldTestParams<Msg>(
490 {kRequiredFields, kOptionalFields, kRepeatedFields,
Vitaly Bukaa268b672020-01-27 18:49:40 -0800491 kRequiredNestedFields, kRequiredInAnyFields,
492 kOptionalNestedFields, kOptionalInAnyFields,
493 kRepeatedNestedFields, kRepeatedInAnyFields,
494 kOptionalInDeepAnyFields})));
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800495
Vitaly Bukae79e0182017-03-01 16:02:14 -0800496TEST_P(MutatorFieldInsDelTest, DeleteField) {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800497 LoadMessage(m1_.get());
498 LoadWithoutLine(m2_.get());
499 EXPECT_TRUE(Mutate(*m1_, *m2_));
500}
501
Vitaly Buka7c375c02020-02-04 13:01:10 -0800502INSTANTIATE_TEST_SUITE_P(Proto2, MutatorTest,
Vitaly Bukaf0a8ca02019-01-23 21:37:13 -0800503 ValuesIn(GetFieldTestParams<Msg>(
504 {kRequiredFields, kOptionalFields, kRepeatedFields,
Vitaly Bukaa268b672020-01-27 18:49:40 -0800505 kRequiredNestedFields, kRequiredInAnyFields,
506 kOptionalNestedFields, kOptionalInAnyFields,
507 kRepeatedNestedFields, kRepeatedInAnyFields,
508 kOptionalInDeepAnyFields})));
Vitaly Buka7c375c02020-02-04 13:01:10 -0800509INSTANTIATE_TEST_SUITE_P(Proto3, MutatorTest,
Vitaly Bukaf0a8ca02019-01-23 21:37:13 -0800510 ValuesIn(GetFieldTestParams<Msg3>(
511 {kOptionalFields, kRepeatedFields,
Vitaly Bukaa268b672020-01-27 18:49:40 -0800512 kOptionalNestedFields, kOptionalInAnyFields,
513 kRepeatedNestedFields, kRepeatedInAnyFields,
514 kOptionalInDeepAnyFields})));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800515
Vitaly Buka7c375c02020-02-04 13:01:10 -0800516TEST_P(MutatorTest, Initialized) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800517 LoadWithoutLine(m1_.get());
Vitaly Bukae79e0182017-03-01 16:02:14 -0800518 TestMutator mutator(true);
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800519 mutator.Mutate(m1_.get(), 1000);
520 EXPECT_TRUE(m1_->IsInitialized());
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800521}
522
Vitaly Buka7c375c02020-02-04 13:01:10 -0800523TEST_P(MutatorTest, InsertField) {
Vitaly Buka439d4de2020-01-29 00:40:43 -0800524 LoadWithoutLine(m1_.get());
525 LoadWithChangedLine(m2_.get(), 1);
526 EXPECT_TRUE(Mutate(*m1_, *m2_));
527}
528
Vitaly Buka7c375c02020-02-04 13:01:10 -0800529TEST_P(MutatorTest, ChangeField) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800530 LoadWithChangedLine(m1_.get(), 0);
531 LoadWithChangedLine(m2_.get(), 1);
Vitaly Bukabbb27cc2020-01-27 18:37:11 -0800532 EXPECT_TRUE(Mutate(*m1_, *m2_, 1000000));
533 EXPECT_TRUE(Mutate(*m2_, *m1_, 1000000));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800534}
535
Vitaly Buka7c375c02020-02-04 13:01:10 -0800536TEST_P(MutatorTest, CrossOver) {
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800537 LoadWithoutLine(m1_.get());
538 LoadMessage(m2_.get());
539
540 EXPECT_FALSE(MessageDifferencer::Equals(*m1_, *m2_));
541 TestMutator mutator(false);
542
543 EXPECT_TRUE(CrossOver(*m1_, *m2_, *m2_));
544}
545
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800546template <class Msg>
Vitaly Buka7c375c02020-02-04 13:01:10 -0800547void RunCrossOver(const protobuf::Message& m1, const protobuf::Message& m2) {
548 Msg from;
549 from.add_repeated_msg()->CopyFrom(m1);
550 from.add_repeated_msg()->CopyFrom(m2);
551 from.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
552
553 Msg to;
554 to.add_repeated_msg()->CopyFrom(m1);
555 to.add_repeated_msg()->CopyFrom(m1);
556 to.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
557 EXPECT_TRUE(CrossOver(from, from, to));
558}
559
560TEST_P(MutatorTest, CopyField) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800561 LoadWithChangedLine(m1_.get(), 7);
562 LoadWithChangedLine(m2_.get(), 0);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800563
Vitaly Buka7c375c02020-02-04 13:01:10 -0800564 if (m1_->GetDescriptor() == Msg::descriptor())
565 RunCrossOver<Msg>(*m1_, *m2_);
566 else
567 RunCrossOver<Msg3>(*m1_, *m2_);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800568}
569
Vitaly Buka7c375c02020-02-04 13:01:10 -0800570TEST_P(MutatorTest, CloneField) {
571 LoadWithChangedLine(m1_.get(), 7);
572 LoadWithoutLine(m2_.get());
573
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800574 if (m1_->GetDescriptor() == Msg::descriptor())
Vitaly Buka7c375c02020-02-04 13:01:10 -0800575 RunCrossOver<Msg>(*m1_, *m2_);
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800576 else
Vitaly Buka7c375c02020-02-04 13:01:10 -0800577 RunCrossOver<Msg3>(*m1_, *m2_);
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800578}
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800579
Vitaly Bukae79e0182017-03-01 16:02:14 -0800580class MutatorSingleFieldTest : public MutatorTest {};
Vitaly Buka89098ff2017-03-03 14:48:04 -0800581template <typename T>
Vitaly Bukae79e0182017-03-01 16:02:14 -0800582class MutatorTypedTest : public ::testing::Test {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800583 public:
584 using Message = T;
585};
586
Vitaly Bukae79e0182017-03-01 16:02:14 -0800587using MutatorTypedTestTypes = testing::Types<Msg, Msg3>;
Vitaly Buka62c5c912019-09-06 15:08:16 -0700588TYPED_TEST_SUITE(MutatorTypedTest, MutatorTypedTestTypes);
Vitaly Buka89098ff2017-03-03 14:48:04 -0800589
Vitaly Bukae79e0182017-03-01 16:02:14 -0800590TYPED_TEST(MutatorTypedTest, FailedMutations) {
591 TestMutator mutator(false);
Vitaly Buka2d609df2017-03-06 23:29:47 -0800592 size_t crossovers = 0;
Vitaly Bukad7f943f2019-01-31 14:05:33 -0800593 for (int i = 0; i < 1000; ++i) {
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800594 typename TestFixture::Message messages[2];
595 typename TestFixture::Message tmp;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800596 for (int j = 0; j < 20; ++j) {
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800597 for (auto& m : messages) {
598 tmp.CopyFrom(m);
599 mutator.Mutate(&m, 1000);
600 // Mutate must not produce the same result.
601 EXPECT_FALSE(MessageDifferencer::Equals(m, tmp));
602 }
Vitaly Buka8aa75102016-12-09 20:01:15 -0800603 }
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800604
605 tmp.CopyFrom(messages[1]);
Vitaly Buka9f357ae2020-01-26 23:17:11 -0800606 mutator.CrossOver(messages[0], &tmp, 1000);
Vitaly Buka2d609df2017-03-06 23:29:47 -0800607 if (MessageDifferencer::Equals(tmp, messages[1]) ||
608 MessageDifferencer::Equals(tmp, messages[0]))
609 ++crossovers;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800610 }
Vitaly Buka2d609df2017-03-06 23:29:47 -0800611
612 // CrossOver may fail but very rare.
Vitaly Buka1989ccb2020-02-04 15:40:30 -0800613 EXPECT_LT(crossovers, 100u);
Vitaly Buka8aa75102016-12-09 20:01:15 -0800614}
615
Vitaly Buka67387f72019-08-31 19:34:10 -0700616TYPED_TEST(MutatorTypedTest, RegisterPostProcessor) {
Vitaly Bukaad520b32020-01-08 14:39:55 -0800617 std::set<std::string> top_mutations = {"0123456789abcdef",
618 "abcdef0123456789"};
Allen-Webbc4fa5912018-09-07 15:53:30 -0700619 TestMutator mutator(false);
Vitaly Bukaad520b32020-01-08 14:39:55 -0800620 for (auto& v : top_mutations) {
621 mutator.RegisterPostProcessor(
622 TestFixture::Message::descriptor(),
623 [=](protobuf::Message* message, unsigned int seed) {
624 auto test_message =
625 static_cast<typename TestFixture::Message*>(message);
626 if (seed % 2) test_message->set_optional_string(v);
627 });
628 }
629
630 std::set<int64_t> nested_mutations = {1234567, 567890};
631 for (auto& v : nested_mutations) {
632 mutator.RegisterPostProcessor(
633 TestFixture::Message::SubMsg::descriptor(),
634 [=](protobuf::Message* message, unsigned int seed) {
635 auto test_message =
636 static_cast<typename TestFixture::Message::SubMsg*>(message);
637 if (seed % 2) test_message->set_optional_int64(v);
638 });
639 }
640
641 bool regular_mutation = false;
Allen-Webbc4fa5912018-09-07 15:53:30 -0700642
643 for (int j = 0; j < 100000; ++j) {
644 // Include this field to increase the probability of mutation.
645 typename TestFixture::Message message;
Vitaly Bukaad520b32020-01-08 14:39:55 -0800646 message.set_optional_string("a");
Allen-Webbc4fa5912018-09-07 15:53:30 -0700647 mutator.Mutate(&message, 1000);
648
Vitaly Bukaad520b32020-01-08 14:39:55 -0800649 top_mutations.erase(message.optional_string());
650 nested_mutations.erase(message.mutable_sub_message()->optional_int64());
651 if (message.optional_string().empty()) regular_mutation = true;
Allen-Webbc4fa5912018-09-07 15:53:30 -0700652
Vitaly Bukaad520b32020-01-08 14:39:55 -0800653 if (top_mutations.empty() && nested_mutations.empty() && regular_mutation)
654 break;
Allen-Webbc4fa5912018-09-07 15:53:30 -0700655 }
656
Vitaly Bukaad520b32020-01-08 14:39:55 -0800657 EXPECT_TRUE(top_mutations.empty());
658 EXPECT_TRUE(nested_mutations.empty());
Allen-Webbc4fa5912018-09-07 15:53:30 -0700659 EXPECT_TRUE(regular_mutation);
660}
661
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700662TYPED_TEST(MutatorTypedTest, Serialization) {
663 TestMutator mutator(false);
664 for (int i = 0; i < 10000; ++i) {
665 typename TestFixture::Message message;
666 for (int j = 0; j < 5; ++j) {
667 mutator.Mutate(&message, 1000);
668 typename TestFixture::Message parsed;
669
670 EXPECT_TRUE(ParseTextMessage(SaveMessageAsText(message), &parsed));
671 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
672
673 EXPECT_TRUE(ParseBinaryMessage(SaveMessageAsBinary(message), &parsed));
674 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
675 }
676 }
677}
678
Teju Nareddy4aeed372020-04-20 09:52:45 -0700679TYPED_TEST(MutatorTypedTest, UnknownFieldTextFormat) {
Teju Nareddy45d4dae2020-04-17 16:20:08 -0700680 typename TestFixture::Message parsed;
Teju Nareddy93a38b52020-05-05 16:00:26 -0700681 EXPECT_TRUE(ParseTextMessage(kUnknownFieldInput, &parsed));
Teju Nareddyefda25d2020-05-05 16:00:36 -0700682 EXPECT_EQ(SaveMessageAsText(parsed), kUnknownFieldExpected);
Teju Nareddy45d4dae2020-04-17 16:20:08 -0700683}
684
Vitaly Buka6e552e32019-01-31 15:54:09 -0800685TYPED_TEST(MutatorTypedTest, DeepRecursion) {
686 typename TestFixture::Message message;
687 typename TestFixture::Message* last = &message;
688 for (int i = 0; i < 150; ++i) {
689 last = last->mutable_optional_msg();
690 std::string text = SaveMessageAsText(message);
691 std::string binary = SaveMessageAsBinary(message);
692 typename TestFixture::Message parsed;
693 EXPECT_EQ(i < 100, ParseTextMessage(SaveMessageAsText(message), &parsed));
694 EXPECT_EQ(i < 100,
695 ParseBinaryMessage(SaveMessageAsBinary(message), &parsed));
696 }
697}
698
Vitaly Buka384a0e62019-07-29 15:10:17 -0700699TYPED_TEST(MutatorTypedTest, EmptyMessage) {
700 typename TestFixture::Message::EmptyMessage message;
701 TestMutator mutator(false);
702 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
703}
704
705TYPED_TEST(MutatorTypedTest, Regressions) {
706 typename TestFixture::Message::RegressionMessage message;
707 TestMutator mutator(false);
708 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
709}
710
711TYPED_TEST(MutatorTypedTest, UsageExample) {
712 typename TestFixture::Message::SmallMessage message;
713 TestMutator mutator(false);
714
715 // Test that we can generate all variation of the message.
716 std::set<std::string> mutations;
717 for (int j = 0; j < 1000; ++j) {
718 mutator.Mutate(&message, 1000);
719 std::string str = SaveMessageAsText(message);
720 mutations.insert(str);
721 }
722
723 if (std::is_same<typename TestFixture::Message, Msg>::value) {
724 // 3 states for boolean and 5 for enum, including missing fields.
725 EXPECT_EQ(3u * 5u, mutations.size());
726 } else {
727 // 2 states for boolean and 4 for enum.
728 EXPECT_EQ(2u * 4u, mutations.size());
729 }
730}
731
Vitaly Buka4200a1e2019-07-29 15:19:59 -0700732TYPED_TEST(MutatorTypedTest, Maps) {
733 TestMutator mutator(true);
734
735 typename TestFixture::Message::MapMessage message;
736 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
737}
738
Vitaly Bukae79e0182017-03-01 16:02:14 -0800739class MutatorMessagesTest : public MutatorTest {};
Vitaly Bukaf0a8ca02019-01-23 21:37:13 -0800740INSTANTIATE_TEST_SUITE_P(Proto2, MutatorMessagesTest,
741 ValuesIn(GetMessageTestParams<Msg>({kMessages})));
742INSTANTIATE_TEST_SUITE_P(
Vitaly Bukae79e0182017-03-01 16:02:14 -0800743 Proto3, MutatorMessagesTest,
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800744 ValuesIn(GetMessageTestParams<Msg3>({kMessagesProto3})));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800745
Vitaly Bukae79e0182017-03-01 16:02:14 -0800746TEST_P(MutatorMessagesTest, DeletedMessage) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800747 LoadMessage(m1_.get());
748 LoadWithoutLine(m2_.get());
749 EXPECT_TRUE(Mutate(*m1_, *m2_));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800750}
751
Vitaly Bukae79e0182017-03-01 16:02:14 -0800752TEST_P(MutatorMessagesTest, InsertMessage) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800753 LoadWithoutLine(m1_.get());
754 LoadMessage(m2_.get());
755 EXPECT_TRUE(Mutate(*m1_, *m2_));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800756}
757
Vitaly Buka40b4d892020-01-25 22:03:58 -0800758class MutatorMessagesSizeTest : public TestWithParam<size_t> {};
Vitaly Bukabaa13292020-01-25 19:39:28 -0800759
760static const size_t kMaxSizes[] = {100, 256, 777, 10101};
761INSTANTIATE_TEST_SUITE_P(Proto, MutatorMessagesSizeTest, ValuesIn(kMaxSizes));
762
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800763TEST_P(MutatorMessagesSizeTest, MaxSize) {
Vitaly Bukabaa13292020-01-25 19:39:28 -0800764 TestMutator mutator(false);
765 size_t over_sized_count = 0;
766 Msg message;
767 const size_t kMaxSize = GetParam();
768 const int kIterations = 10000;
769 for (int i = 0; i < kIterations; ++i) {
770 mutator.Mutate(&message, kMaxSize);
771 if (message.ByteSizeLong() > kMaxSize) ++over_sized_count;
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800772 EXPECT_LT(message.ByteSizeLong(), 1.1 * kMaxSize);
Vitaly Bukabaa13292020-01-25 19:39:28 -0800773 }
Vitaly Buka5cd166e2020-01-25 22:33:05 -0800774 EXPECT_LT(over_sized_count, kIterations * .1);
Vitaly Bukabaa13292020-01-25 19:39:28 -0800775}
776
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800777// TODO(vitalybuka): Special tests for oneof.
778
Vitaly Bukaf281d172019-01-23 18:21:51 -0800779TEST(MutatorMessagesTest, NeverCopyUnknownEnum) {
780 TestMutator mutator(false);
781 for (int j = 0; j < 10000; ++j) {
782 Msg3 message;
783 message.set_optional_enum(Msg3::ENUM_5);
784 message.add_repeated_enum(static_cast<Msg3::Enum>(100));
785 mutator.Mutate(&message, 100);
786 EXPECT_NE(message.optional_enum(), 100);
787 }
788}
789
Vitaly Buka432b5452016-12-09 14:42:09 -0800790} // namespace protobuf_mutator