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