1 // 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
15 #include "src/mutator.h"
16
17 #include <algorithm>
18 #include <set>
19 #include <string>
20 #include <tuple>
21 #include <utility>
22 #include <vector>
23
24 #include "port/gtest.h"
25 #include "src/binary_format.h"
26 #include "src/mutator_test_proto2.pb.h"
27 #include "src/mutator_test_proto3.pb.h"
28 #include "src/text_format.h"
29
30 namespace protobuf_mutator {
31
32 using protobuf::util::MessageDifferencer;
33 using testing::TestWithParam;
34 using testing::ValuesIn;
35
36 const 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 }
49 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 }
60 )";
61
62 const 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 }
73 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 }
84 )";
85
86 const 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
104 const 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
117 optional_bool: true
118 optional_string: "QWERT"
119 optional_bytes: "ASDF"
120 optional_enum: ENUM_5
121 )";
122
123 const 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
158 const 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
179 const 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
191 const char kOptionalNestedFields[] = R"(
192 optional_int32: 123
193 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
206 optional_bool: true
207 optional_string: "QWERT"
208 optional_bytes: "ASDF"
209 optional_enum: ENUM_5
210 }
211 )";
212
213 const 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
225 const char kRepeatedNestedFields[] = R"(
226 optional_int32: 123
227 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
263 const 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
278 const 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
296 class TestMutator : public Mutator {
297 public:
TestMutator(bool keep_initialized,size_t random_to_default_ratio=0)298 explicit TestMutator(bool keep_initialized,
299 size_t random_to_default_ratio = 0) {
300 Seed(17);
301 if (random_to_default_ratio)
302 random_to_default_ratio_ = random_to_default_ratio;
303 keep_initialized_ = keep_initialized;
304 }
305
306 private:
307 RandomEngine random_;
308 };
309
310 class ReducedTestMutator : public TestMutator {
311 public:
ReducedTestMutator()312 ReducedTestMutator() : TestMutator(false, 4) {
313 for (float i = 1000; i > 0.1; i /= 7) {
314 values_.push_back(i);
315 values_.push_back(-i);
316 }
317 values_.push_back(-1.0);
318 values_.push_back(0.0);
319 values_.push_back(1.0);
320 }
321
322 protected:
MutateInt32(int32_t value)323 int32_t MutateInt32(int32_t value) override { return GetRandomValue(); }
MutateInt64(int64_t value)324 int64_t MutateInt64(int64_t value) override { return GetRandomValue(); }
MutateUInt32(uint32_t value)325 uint32_t MutateUInt32(uint32_t value) override {
326 return fabs(GetRandomValue());
327 }
MutateUInt64(uint64_t value)328 uint64_t MutateUInt64(uint64_t value) override {
329 return fabs(GetRandomValue());
330 }
MutateFloat(float value)331 float MutateFloat(float value) override { return GetRandomValue(); }
MutateDouble(double value)332 double MutateDouble(double value) override { return GetRandomValue(); }
MutateString(const std::string & value,int size_increase_hint)333 std::string MutateString(const std::string& value,
334 int size_increase_hint) override {
335 return strings_[std::uniform_int_distribution<>(
336 0, strings_.size() - 1)(*random())];
337 }
338
339 private:
GetRandomValue()340 float GetRandomValue() {
341 return values_[std::uniform_int_distribution<>(
342 0, values_.size() - 1)(*random())];
343 }
344
345 std::vector<float> values_;
346 std::vector<std::string> strings_ = {
347 "", "\001", "\000", "a", "b", "ab",
348 };
349 };
350
Split(const std::string & str)351 std::vector<std::string> Split(const std::string& str) {
352 std::istringstream iss(str);
353 std::vector<std::string> result;
354 for (std::string line; std::getline(iss, line, '\n');) result.push_back(line);
355 return result;
356 }
357
358 using TestParams =
359 std::tuple<const protobuf::Message*, const char*, size_t, std::string>;
360
361 template <class T>
GetFieldTestParams(const std::vector<const char * > & tests)362 std::vector<TestParams> GetFieldTestParams(
363 const std::vector<const char*>& tests) {
364 std::vector<TestParams> results;
365 for (auto t : tests) {
366 auto lines = Split(t);
367 for (size_t i = 0; i != lines.size(); ++i) {
368 if (lines[i].find(':') != std::string::npos)
369 results.push_back(
370 std::make_tuple(&T::default_instance(), t, i, lines[i]));
371 }
372 }
373 return results;
374 }
375
376 template <class T>
GetMessageTestParams(const std::vector<const char * > & tests)377 std::vector<TestParams> GetMessageTestParams(
378 const std::vector<const char*>& tests) {
379 std::vector<TestParams> results;
380 for (auto t : tests) {
381 auto lines = Split(t);
382 for (size_t i = 0; i != lines.size(); ++i) {
383 if (lines[i].find("{}") != std::string::npos)
384 results.push_back(
385 std::make_tuple(&T::default_instance(), t, i, lines[i]));
386 }
387 }
388 return results;
389 }
390
Mutate(const protobuf::Message & from,const protobuf::Message & to,int iterations=100000)391 bool Mutate(const protobuf::Message& from, const protobuf::Message& to,
392 int iterations = 100000) {
393 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
394 ReducedTestMutator mutator;
395 std::unique_ptr<protobuf::Message> message(from.New());
396 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
397 for (int j = 0; j < iterations; ++j) {
398 message->CopyFrom(from);
399 mutator.Mutate(message.get(), 1500);
400 if (MessageDifferencer::Equals(*message, to)) return true;
401 }
402
403 ADD_FAILURE() << "Failed to get from:\n"
404 << from.DebugString() << "\nto:\n"
405 << to.DebugString();
406 return false;
407 }
408
CrossOver(const protobuf::Message & from,const protobuf::Message & with,const protobuf::Message & to,int iterations=100000)409 bool CrossOver(const protobuf::Message& from, const protobuf::Message& with,
410 const protobuf::Message& to, int iterations = 100000) {
411 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
412 ReducedTestMutator mutator;
413 std::unique_ptr<protobuf::Message> message(from.New());
414 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
415 for (int j = 0; j < iterations; ++j) {
416 message->CopyFrom(from);
417 mutator.CrossOver(with, message.get(), 1000);
418 if (MessageDifferencer::Equals(*message, to)) return true;
419 }
420 return false;
421 }
422
423 class MutatorTest : public TestWithParam<TestParams> {
424 protected:
SetUp()425 void SetUp() override {
426 m1_.reset(std::get<0>(GetParam())->New());
427 m2_.reset(std::get<0>(GetParam())->New());
428 text_ = std::get<1>(GetParam());
429 line_ = std::get<2>(GetParam());
430 }
431
LoadMessage(protobuf::Message * message)432 void LoadMessage(protobuf::Message* message) {
433 EXPECT_TRUE(ParseTextMessage(text_, message));
434 }
435
LoadWithoutLine(protobuf::Message * message)436 void LoadWithoutLine(protobuf::Message* message) {
437 std::ostringstream oss;
438 auto lines = Split(text_);
439 for (size_t i = 0; i != lines.size(); ++i) {
440 if (i != line_) oss << lines[i] << '\n';
441 }
442 EXPECT_TRUE(ParseTextMessage(oss.str(), message));
443 }
444
LoadWithChangedLine(protobuf::Message * message,int value)445 void LoadWithChangedLine(protobuf::Message* message, int value) {
446 auto lines = Split(text_);
447 std::ostringstream oss;
448 for (size_t i = 0; i != lines.size(); ++i) {
449 if (i != line_) {
450 oss << lines[i] << '\n';
451 } else {
452 std::string s = lines[i];
453 s.resize(s.find(':') + 2);
454
455 if (lines[i].back() == '\"') {
456 // strings
457 s += value ? "\"\\" + std::to_string(value) + "\"" : "\"\"";
458 } else if (lines[i].back() == 'e') {
459 // bools
460 s += value ? "true" : "false";
461 } else {
462 s += std::to_string(value);
463 }
464 oss << s << '\n';
465 }
466 }
467 EXPECT_TRUE(ParseTextMessage(oss.str(), message));
468 }
469
470 std::string text_;
471 size_t line_;
472 std::unique_ptr<protobuf::Message> m1_;
473 std::unique_ptr<protobuf::Message> m2_;
474 };
475
476 // These tests are irrelevant for Proto3 as it has no required fields and
477 // insertion/deletion.
478
479 class MutatorFieldInsDelTest : public MutatorTest {};
480 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorFieldInsDelTest,
481 ValuesIn(GetFieldTestParams<Msg>(
482 {kRequiredFields, kOptionalFields, kRepeatedFields,
483 kRequiredNestedFields, kRequiredInAnyFields,
484 kOptionalNestedFields, kOptionalInAnyFields,
485 kRepeatedNestedFields, kRepeatedInAnyFields,
486 kOptionalInDeepAnyFields})));
487
TEST_P(MutatorFieldInsDelTest,DeleteField)488 TEST_P(MutatorFieldInsDelTest, DeleteField) {
489 LoadMessage(m1_.get());
490 LoadWithoutLine(m2_.get());
491 EXPECT_TRUE(Mutate(*m1_, *m2_));
492 }
493
494 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorTest,
495 ValuesIn(GetFieldTestParams<Msg>(
496 {kRequiredFields, kOptionalFields, kRepeatedFields,
497 kRequiredNestedFields, kRequiredInAnyFields,
498 kOptionalNestedFields, kOptionalInAnyFields,
499 kRepeatedNestedFields, kRepeatedInAnyFields,
500 kOptionalInDeepAnyFields})));
501 INSTANTIATE_TEST_SUITE_P(Proto3, MutatorTest,
502 ValuesIn(GetFieldTestParams<Msg3>(
503 {kOptionalFields, kRepeatedFields,
504 kOptionalNestedFields, kOptionalInAnyFields,
505 kRepeatedNestedFields, kRepeatedInAnyFields,
506 kOptionalInDeepAnyFields})));
507
TEST_P(MutatorTest,Initialized)508 TEST_P(MutatorTest, Initialized) {
509 LoadWithoutLine(m1_.get());
510 TestMutator mutator(true);
511 mutator.Mutate(m1_.get(), 1000);
512 EXPECT_TRUE(m1_->IsInitialized());
513 }
514
TEST_P(MutatorTest,InsertField)515 TEST_P(MutatorTest, InsertField) {
516 LoadWithoutLine(m1_.get());
517 LoadWithChangedLine(m2_.get(), 1);
518 EXPECT_TRUE(Mutate(*m1_, *m2_));
519 }
520
TEST_P(MutatorTest,ChangeField)521 TEST_P(MutatorTest, ChangeField) {
522 LoadWithChangedLine(m1_.get(), 0);
523 LoadWithChangedLine(m2_.get(), 1);
524 EXPECT_TRUE(Mutate(*m1_, *m2_, 1000000));
525 EXPECT_TRUE(Mutate(*m2_, *m1_, 1000000));
526 }
527
TEST_P(MutatorTest,CrossOver)528 TEST_P(MutatorTest, CrossOver) {
529 LoadWithoutLine(m1_.get());
530 LoadMessage(m2_.get());
531
532 EXPECT_FALSE(MessageDifferencer::Equals(*m1_, *m2_));
533 TestMutator mutator(false);
534
535 EXPECT_TRUE(CrossOver(*m1_, *m2_, *m2_));
536 }
537
538 template <class Msg>
RunCrossOver(const protobuf::Message & m1,const protobuf::Message & m2)539 void RunCrossOver(const protobuf::Message& m1, const protobuf::Message& m2) {
540 Msg from;
541 from.add_repeated_msg()->CopyFrom(m1);
542 from.add_repeated_msg()->CopyFrom(m2);
543 from.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
544
545 Msg to;
546 to.add_repeated_msg()->CopyFrom(m1);
547 to.add_repeated_msg()->CopyFrom(m1);
548 to.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
549 EXPECT_TRUE(CrossOver(from, from, to));
550 }
551
TEST_P(MutatorTest,CopyField)552 TEST_P(MutatorTest, CopyField) {
553 LoadWithChangedLine(m1_.get(), 7);
554 LoadWithChangedLine(m2_.get(), 0);
555
556 if (m1_->GetDescriptor() == Msg::descriptor())
557 RunCrossOver<Msg>(*m1_, *m2_);
558 else
559 RunCrossOver<Msg3>(*m1_, *m2_);
560 }
561
TEST_P(MutatorTest,CloneField)562 TEST_P(MutatorTest, CloneField) {
563 LoadWithChangedLine(m1_.get(), 7);
564 LoadWithoutLine(m2_.get());
565
566 if (m1_->GetDescriptor() == Msg::descriptor())
567 RunCrossOver<Msg>(*m1_, *m2_);
568 else
569 RunCrossOver<Msg3>(*m1_, *m2_);
570 }
571
572 class MutatorSingleFieldTest : public MutatorTest {};
573 template <typename T>
574 class MutatorTypedTest : public ::testing::Test {
575 public:
576 using Message = T;
577 };
578
579 using MutatorTypedTestTypes = testing::Types<Msg, Msg3>;
580 TYPED_TEST_SUITE(MutatorTypedTest, MutatorTypedTestTypes);
581
TYPED_TEST(MutatorTypedTest,FailedMutations)582 TYPED_TEST(MutatorTypedTest, FailedMutations) {
583 TestMutator mutator(false);
584 size_t crossovers = 0;
585 for (int i = 0; i < 1000; ++i) {
586 typename TestFixture::Message messages[2];
587 typename TestFixture::Message tmp;
588 for (int j = 0; j < 20; ++j) {
589 for (auto& m : messages) {
590 tmp.CopyFrom(m);
591 mutator.Mutate(&m, 1000);
592 // Mutate must not produce the same result.
593 EXPECT_FALSE(MessageDifferencer::Equals(m, tmp));
594 }
595 }
596
597 tmp.CopyFrom(messages[1]);
598 mutator.CrossOver(messages[0], &tmp, 1000);
599 if (MessageDifferencer::Equals(tmp, messages[1]) ||
600 MessageDifferencer::Equals(tmp, messages[0]))
601 ++crossovers;
602 }
603
604 // CrossOver may fail but very rare.
605 EXPECT_LT(crossovers, 100u);
606 }
607
TYPED_TEST(MutatorTypedTest,RegisterPostProcessor)608 TYPED_TEST(MutatorTypedTest, RegisterPostProcessor) {
609 std::set<std::string> top_mutations = {"0123456789abcdef",
610 "abcdef0123456789"};
611 TestMutator mutator(false);
612 for (auto& v : top_mutations) {
613 mutator.RegisterPostProcessor(
614 TestFixture::Message::descriptor(),
615 [=](protobuf::Message* message, unsigned int seed) {
616 auto test_message =
617 static_cast<typename TestFixture::Message*>(message);
618 if (seed % 2) test_message->set_optional_string(v);
619 });
620 }
621
622 std::set<int64_t> nested_mutations = {1234567, 567890};
623 for (auto& v : nested_mutations) {
624 mutator.RegisterPostProcessor(
625 TestFixture::Message::SubMsg::descriptor(),
626 [=](protobuf::Message* message, unsigned int seed) {
627 auto test_message =
628 static_cast<typename TestFixture::Message::SubMsg*>(message);
629 if (seed % 2) test_message->set_optional_int64(v);
630 });
631 }
632
633 bool regular_mutation = false;
634
635 for (int j = 0; j < 100000; ++j) {
636 // Include this field to increase the probability of mutation.
637 typename TestFixture::Message message;
638 message.set_optional_string("a");
639 mutator.Mutate(&message, 1000);
640
641 top_mutations.erase(message.optional_string());
642 nested_mutations.erase(message.mutable_sub_message()->optional_int64());
643 if (message.optional_string().empty()) regular_mutation = true;
644
645 if (top_mutations.empty() && nested_mutations.empty() && regular_mutation)
646 break;
647 }
648
649 EXPECT_TRUE(top_mutations.empty());
650 EXPECT_TRUE(nested_mutations.empty());
651 EXPECT_TRUE(regular_mutation);
652 }
653
TYPED_TEST(MutatorTypedTest,Serialization)654 TYPED_TEST(MutatorTypedTest, Serialization) {
655 TestMutator mutator(false);
656 for (int i = 0; i < 10000; ++i) {
657 typename TestFixture::Message message;
658 for (int j = 0; j < 5; ++j) {
659 mutator.Mutate(&message, 1000);
660 typename TestFixture::Message parsed;
661
662 EXPECT_TRUE(ParseTextMessage(SaveMessageAsText(message), &parsed));
663 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
664
665 EXPECT_TRUE(ParseBinaryMessage(SaveMessageAsBinary(message), &parsed));
666 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
667 }
668 }
669 }
670
TYPED_TEST(MutatorTypedTest,DeepRecursion)671 TYPED_TEST(MutatorTypedTest, DeepRecursion) {
672 typename TestFixture::Message message;
673 typename TestFixture::Message* last = &message;
674 for (int i = 0; i < 150; ++i) {
675 last = last->mutable_optional_msg();
676 std::string text = SaveMessageAsText(message);
677 std::string binary = SaveMessageAsBinary(message);
678 typename TestFixture::Message parsed;
679 EXPECT_EQ(i < 100, ParseTextMessage(SaveMessageAsText(message), &parsed));
680 EXPECT_EQ(i < 100,
681 ParseBinaryMessage(SaveMessageAsBinary(message), &parsed));
682 }
683 }
684
TYPED_TEST(MutatorTypedTest,EmptyMessage)685 TYPED_TEST(MutatorTypedTest, EmptyMessage) {
686 typename TestFixture::Message::EmptyMessage message;
687 TestMutator mutator(false);
688 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
689 }
690
TYPED_TEST(MutatorTypedTest,Regressions)691 TYPED_TEST(MutatorTypedTest, Regressions) {
692 typename TestFixture::Message::RegressionMessage message;
693 TestMutator mutator(false);
694 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
695 }
696
TYPED_TEST(MutatorTypedTest,UsageExample)697 TYPED_TEST(MutatorTypedTest, UsageExample) {
698 typename TestFixture::Message::SmallMessage message;
699 TestMutator mutator(false);
700
701 // Test that we can generate all variation of the message.
702 std::set<std::string> mutations;
703 for (int j = 0; j < 1000; ++j) {
704 mutator.Mutate(&message, 1000);
705 std::string str = SaveMessageAsText(message);
706 mutations.insert(str);
707 }
708
709 if (std::is_same<typename TestFixture::Message, Msg>::value) {
710 // 3 states for boolean and 5 for enum, including missing fields.
711 EXPECT_EQ(3u * 5u, mutations.size());
712 } else {
713 // 2 states for boolean and 4 for enum.
714 EXPECT_EQ(2u * 4u, mutations.size());
715 }
716 }
717
TYPED_TEST(MutatorTypedTest,Maps)718 TYPED_TEST(MutatorTypedTest, Maps) {
719 TestMutator mutator(true);
720
721 typename TestFixture::Message::MapMessage message;
722 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
723 }
724
725 class MutatorMessagesTest : public MutatorTest {};
726 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorMessagesTest,
727 ValuesIn(GetMessageTestParams<Msg>({kMessages})));
728 INSTANTIATE_TEST_SUITE_P(
729 Proto3, MutatorMessagesTest,
730 ValuesIn(GetMessageTestParams<Msg3>({kMessagesProto3})));
731
TEST_P(MutatorMessagesTest,DeletedMessage)732 TEST_P(MutatorMessagesTest, DeletedMessage) {
733 LoadMessage(m1_.get());
734 LoadWithoutLine(m2_.get());
735 EXPECT_TRUE(Mutate(*m1_, *m2_));
736 }
737
TEST_P(MutatorMessagesTest,InsertMessage)738 TEST_P(MutatorMessagesTest, InsertMessage) {
739 LoadWithoutLine(m1_.get());
740 LoadMessage(m2_.get());
741 EXPECT_TRUE(Mutate(*m1_, *m2_));
742 }
743
744 class MutatorMessagesSizeTest : public TestWithParam<size_t> {};
745
746 static const size_t kMaxSizes[] = {100, 256, 777, 10101};
747 INSTANTIATE_TEST_SUITE_P(Proto, MutatorMessagesSizeTest, ValuesIn(kMaxSizes));
748
TEST_P(MutatorMessagesSizeTest,MaxSize)749 TEST_P(MutatorMessagesSizeTest, MaxSize) {
750 TestMutator mutator(false);
751 size_t over_sized_count = 0;
752 Msg message;
753 const size_t kMaxSize = GetParam();
754 const int kIterations = 10000;
755 for (int i = 0; i < kIterations; ++i) {
756 mutator.Mutate(&message, kMaxSize);
757 if (message.ByteSizeLong() > kMaxSize) ++over_sized_count;
758 EXPECT_LT(message.ByteSizeLong(), 1.1 * kMaxSize);
759 }
760 EXPECT_LT(over_sized_count, kIterations * .1);
761 }
762
763 // TODO(vitalybuka): Special tests for oneof.
764
TEST(MutatorMessagesTest,NeverCopyUnknownEnum)765 TEST(MutatorMessagesTest, NeverCopyUnknownEnum) {
766 TestMutator mutator(false);
767 for (int j = 0; j < 10000; ++j) {
768 Msg3 message;
769 message.set_optional_enum(Msg3::ENUM_5);
770 message.add_repeated_enum(static_cast<Msg3::Enum>(100));
771 mutator.Mutate(&message, 100);
772 EXPECT_NE(message.optional_enum(), 100);
773 }
774 }
775
776 } // namespace protobuf_mutator
777