• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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