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 const char kUnknownFieldInput[] = R"(
297   optional_bool: true
298   unknown_field: "test unknown field"
299 )";
300 
301 const char kUnknownFieldExpected[] = R"(optional_bool: true
302 )";
303 
304 class TestMutator : public Mutator {
305  public:
TestMutator(bool keep_initialized,size_t random_to_default_ratio=0)306   explicit TestMutator(bool keep_initialized,
307                        size_t random_to_default_ratio = 0) {
308     Seed(17);
309     if (random_to_default_ratio)
310       random_to_default_ratio_ = random_to_default_ratio;
311     keep_initialized_ = keep_initialized;
312   }
313 
314  private:
315   RandomEngine random_;
316 };
317 
318 class ReducedTestMutator : public TestMutator {
319  public:
ReducedTestMutator()320   ReducedTestMutator() : TestMutator(false, 4) {
321     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);
328   }
329 
330  protected:
MutateInt32(int32_t value)331   int32_t MutateInt32(int32_t value) override { return GetRandomValue(); }
MutateInt64(int64_t value)332   int64_t MutateInt64(int64_t value) override { return GetRandomValue(); }
MutateUInt32(uint32_t value)333   uint32_t MutateUInt32(uint32_t value) override {
334     return fabs(GetRandomValue());
335   }
MutateUInt64(uint64_t value)336   uint64_t MutateUInt64(uint64_t value) override {
337     return fabs(GetRandomValue());
338   }
MutateFloat(float value)339   float MutateFloat(float value) override { return GetRandomValue(); }
MutateDouble(double value)340   double MutateDouble(double value) override { return GetRandomValue(); }
MutateString(const std::string & value,int size_increase_hint)341   std::string MutateString(const std::string& value,
342                            int size_increase_hint) override {
343     return strings_[std::uniform_int_distribution<>(
344         0, strings_.size() - 1)(*random())];
345   }
346 
347  private:
GetRandomValue()348   float GetRandomValue() {
349     return values_[std::uniform_int_distribution<>(
350         0, values_.size() - 1)(*random())];
351   }
352 
353   std::vector<float> values_;
354   std::vector<std::string> strings_ = {
355       "", "\001", "\000", "a", "b", "ab",
356   };
357 };
358 
Split(const std::string & str)359 std::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;
364 }
365 
366 using TestParams =
367     std::tuple<const protobuf::Message*, const char*, size_t, std::string>;
368 
369 template <class T>
GetFieldTestParams(const std::vector<const char * > & tests)370 std::vector<TestParams> GetFieldTestParams(
371     const std::vector<const char*>& tests) {
372   std::vector<TestParams> results;
373   for (auto t : tests) {
374     auto lines = Split(t);
375     for (size_t i = 0; i != lines.size(); ++i) {
376       if (lines[i].find(':') != std::string::npos)
377         results.push_back(
378             std::make_tuple(&T::default_instance(), t, i, lines[i]));
379     }
380   }
381   return results;
382 }
383 
384 template <class T>
GetMessageTestParams(const std::vector<const char * > & tests)385 std::vector<TestParams> GetMessageTestParams(
386     const std::vector<const char*>& tests) {
387   std::vector<TestParams> results;
388   for (auto t : tests) {
389     auto lines = Split(t);
390     for (size_t i = 0; i != lines.size(); ++i) {
391       if (lines[i].find("{}") != std::string::npos)
392         results.push_back(
393             std::make_tuple(&T::default_instance(), t, i, lines[i]));
394     }
395   }
396   return results;
397 }
398 
Mutate(const protobuf::Message & from,const protobuf::Message & to,int iterations=100000)399 bool Mutate(const protobuf::Message& from, const protobuf::Message& to,
400             int iterations = 100000) {
401   EXPECT_FALSE(MessageDifferencer::Equals(from, to));
402   ReducedTestMutator mutator;
403   std::unique_ptr<protobuf::Message> message(from.New());
404   EXPECT_FALSE(MessageDifferencer::Equals(from, to));
405   for (int j = 0; j < iterations; ++j) {
406     message->CopyFrom(from);
407     mutator.Mutate(message.get(), 1500);
408     if (MessageDifferencer::Equals(*message, to)) return true;
409   }
410 
411   ADD_FAILURE() << "Failed to get from:\n"
412                 << from.DebugString() << "\nto:\n"
413                 << to.DebugString();
414   return false;
415 }
416 
CrossOver(const protobuf::Message & from,const protobuf::Message & with,const protobuf::Message & to,int iterations=100000)417 bool CrossOver(const protobuf::Message& from, const protobuf::Message& with,
418                const protobuf::Message& to, int iterations = 100000) {
419   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));
423   for (int j = 0; j < iterations; ++j) {
424     message->CopyFrom(from);
425     mutator.CrossOver(with, message.get(), 1000);
426     if (MessageDifferencer::Equals(*message, to)) return true;
427   }
428   return false;
429 }
430 
431 class MutatorTest : public TestWithParam<TestParams> {
432  protected:
SetUp()433   void SetUp() override {
434     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());
438   }
439 
LoadMessage(protobuf::Message * message)440   void LoadMessage(protobuf::Message* message) {
441     EXPECT_TRUE(ParseTextMessage(text_, message));
442   }
443 
LoadWithoutLine(protobuf::Message * message)444   void LoadWithoutLine(protobuf::Message* message) {
445     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     }
450     EXPECT_TRUE(ParseTextMessage(oss.str(), message));
451   }
452 
LoadWithChangedLine(protobuf::Message * message,int value)453   void LoadWithChangedLine(protobuf::Message* message, int value) {
454     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     }
475     EXPECT_TRUE(ParseTextMessage(oss.str(), message));
476   }
477 
478   std::string text_;
479   size_t line_;
480   std::unique_ptr<protobuf::Message> m1_;
481   std::unique_ptr<protobuf::Message> m2_;
482 };
483 
484 // These tests are irrelevant for Proto3 as it has no required fields and
485 // insertion/deletion.
486 
487 class MutatorFieldInsDelTest : public MutatorTest {};
488 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorFieldInsDelTest,
489                          ValuesIn(GetFieldTestParams<Msg>(
490                              {kRequiredFields, kOptionalFields, kRepeatedFields,
491                               kRequiredNestedFields, kRequiredInAnyFields,
492                               kOptionalNestedFields, kOptionalInAnyFields,
493                               kRepeatedNestedFields, kRepeatedInAnyFields,
494                               kOptionalInDeepAnyFields})));
495 
TEST_P(MutatorFieldInsDelTest,DeleteField)496 TEST_P(MutatorFieldInsDelTest, DeleteField) {
497   LoadMessage(m1_.get());
498   LoadWithoutLine(m2_.get());
499   EXPECT_TRUE(Mutate(*m1_, *m2_));
500 }
501 
502 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorTest,
503                          ValuesIn(GetFieldTestParams<Msg>(
504                              {kRequiredFields, kOptionalFields, kRepeatedFields,
505                               kRequiredNestedFields, kRequiredInAnyFields,
506                               kOptionalNestedFields, kOptionalInAnyFields,
507                               kRepeatedNestedFields, kRepeatedInAnyFields,
508                               kOptionalInDeepAnyFields})));
509 INSTANTIATE_TEST_SUITE_P(Proto3, MutatorTest,
510                          ValuesIn(GetFieldTestParams<Msg3>(
511                              {kOptionalFields, kRepeatedFields,
512                               kOptionalNestedFields, kOptionalInAnyFields,
513                               kRepeatedNestedFields, kRepeatedInAnyFields,
514                               kOptionalInDeepAnyFields})));
515 
TEST_P(MutatorTest,Initialized)516 TEST_P(MutatorTest, Initialized) {
517   LoadWithoutLine(m1_.get());
518   TestMutator mutator(true);
519   mutator.Mutate(m1_.get(), 1000);
520   EXPECT_TRUE(m1_->IsInitialized());
521 }
522 
TEST_P(MutatorTest,InsertField)523 TEST_P(MutatorTest, InsertField) {
524   LoadWithoutLine(m1_.get());
525   LoadWithChangedLine(m2_.get(), 1);
526   EXPECT_TRUE(Mutate(*m1_, *m2_));
527 }
528 
TEST_P(MutatorTest,ChangeField)529 TEST_P(MutatorTest, ChangeField) {
530   LoadWithChangedLine(m1_.get(), 0);
531   LoadWithChangedLine(m2_.get(), 1);
532   EXPECT_TRUE(Mutate(*m1_, *m2_, 1000000));
533   EXPECT_TRUE(Mutate(*m2_, *m1_, 1000000));
534 }
535 
TEST_P(MutatorTest,CrossOver)536 TEST_P(MutatorTest, CrossOver) {
537   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 
546 template <class Msg>
RunCrossOver(const protobuf::Message & m1,const protobuf::Message & m2)547 void 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 
TEST_P(MutatorTest,CopyField)560 TEST_P(MutatorTest, CopyField) {
561   LoadWithChangedLine(m1_.get(), 7);
562   LoadWithChangedLine(m2_.get(), 0);
563 
564   if (m1_->GetDescriptor() == Msg::descriptor())
565     RunCrossOver<Msg>(*m1_, *m2_);
566   else
567     RunCrossOver<Msg3>(*m1_, *m2_);
568 }
569 
TEST_P(MutatorTest,CloneField)570 TEST_P(MutatorTest, CloneField) {
571   LoadWithChangedLine(m1_.get(), 7);
572   LoadWithoutLine(m2_.get());
573 
574   if (m1_->GetDescriptor() == Msg::descriptor())
575     RunCrossOver<Msg>(*m1_, *m2_);
576   else
577     RunCrossOver<Msg3>(*m1_, *m2_);
578 }
579 
580 class MutatorSingleFieldTest : public MutatorTest {};
581 template <typename T>
582 class MutatorTypedTest : public ::testing::Test {
583  public:
584   using Message = T;
585 };
586 
587 using MutatorTypedTestTypes = testing::Types<Msg, Msg3>;
588 TYPED_TEST_SUITE(MutatorTypedTest, MutatorTypedTestTypes);
589 
TYPED_TEST(MutatorTypedTest,FailedMutations)590 TYPED_TEST(MutatorTypedTest, FailedMutations) {
591   TestMutator mutator(false);
592   size_t crossovers = 0;
593   for (int i = 0; i < 1000; ++i) {
594     typename TestFixture::Message messages[2];
595     typename TestFixture::Message tmp;
596     for (int j = 0; j < 20; ++j) {
597       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       }
603     }
604 
605     tmp.CopyFrom(messages[1]);
606     mutator.CrossOver(messages[0], &tmp, 1000);
607     if (MessageDifferencer::Equals(tmp, messages[1]) ||
608         MessageDifferencer::Equals(tmp, messages[0]))
609       ++crossovers;
610   }
611 
612   // CrossOver may fail but very rare.
613   EXPECT_LT(crossovers, 100u);
614 }
615 
TYPED_TEST(MutatorTypedTest,RegisterPostProcessor)616 TYPED_TEST(MutatorTypedTest, RegisterPostProcessor) {
617   std::set<std::string> top_mutations = {"0123456789abcdef",
618                                          "abcdef0123456789"};
619   TestMutator mutator(false);
620   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;
642 
643   for (int j = 0; j < 100000; ++j) {
644     // Include this field to increase the probability of mutation.
645     typename TestFixture::Message message;
646     message.set_optional_string("a");
647     mutator.Mutate(&message, 1000);
648 
649     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;
652 
653     if (top_mutations.empty() && nested_mutations.empty() && regular_mutation)
654       break;
655   }
656 
657   EXPECT_TRUE(top_mutations.empty());
658   EXPECT_TRUE(nested_mutations.empty());
659   EXPECT_TRUE(regular_mutation);
660 }
661 
TYPED_TEST(MutatorTypedTest,Serialization)662 TYPED_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 
TYPED_TEST(MutatorTypedTest,UnknownFieldTextFormat)679 TYPED_TEST(MutatorTypedTest, UnknownFieldTextFormat) {
680   typename TestFixture::Message parsed;
681   EXPECT_TRUE(ParseTextMessage(kUnknownFieldInput, &parsed));
682   EXPECT_EQ(SaveMessageAsText(parsed), kUnknownFieldExpected);
683 }
684 
TYPED_TEST(MutatorTypedTest,DeepRecursion)685 TYPED_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 
TYPED_TEST(MutatorTypedTest,EmptyMessage)699 TYPED_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 
TYPED_TEST(MutatorTypedTest,Regressions)705 TYPED_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 
TYPED_TEST(MutatorTypedTest,UsageExample)711 TYPED_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 
TYPED_TEST(MutatorTypedTest,Maps)732 TYPED_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 
739 class MutatorMessagesTest : public MutatorTest {};
740 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorMessagesTest,
741                          ValuesIn(GetMessageTestParams<Msg>({kMessages})));
742 INSTANTIATE_TEST_SUITE_P(
743     Proto3, MutatorMessagesTest,
744     ValuesIn(GetMessageTestParams<Msg3>({kMessagesProto3})));
745 
TEST_P(MutatorMessagesTest,DeletedMessage)746 TEST_P(MutatorMessagesTest, DeletedMessage) {
747   LoadMessage(m1_.get());
748   LoadWithoutLine(m2_.get());
749   EXPECT_TRUE(Mutate(*m1_, *m2_));
750 }
751 
TEST_P(MutatorMessagesTest,InsertMessage)752 TEST_P(MutatorMessagesTest, InsertMessage) {
753   LoadWithoutLine(m1_.get());
754   LoadMessage(m2_.get());
755   EXPECT_TRUE(Mutate(*m1_, *m2_));
756 }
757 
758 class MutatorMessagesSizeTest : public TestWithParam<size_t> {};
759 
760 static const size_t kMaxSizes[] = {100, 256, 777, 10101};
761 INSTANTIATE_TEST_SUITE_P(Proto, MutatorMessagesSizeTest, ValuesIn(kMaxSizes));
762 
TEST_P(MutatorMessagesSizeTest,MaxSize)763 TEST_P(MutatorMessagesSizeTest, MaxSize) {
764   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;
772     EXPECT_LT(message.ByteSizeLong(), 1.1 * kMaxSize);
773   }
774   EXPECT_LT(over_sized_count, kIterations * .1);
775 }
776 
777 // TODO(vitalybuka): Special tests for oneof.
778 
TEST(MutatorMessagesTest,NeverCopyUnknownEnum)779 TEST(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 
790 }  // namespace protobuf_mutator
791