blob: e2277232f4c148590bc5ea067b624dcdd0392ecf [file] [log] [blame]
Vitaly Buka00b61072016-10-19 16:22:51 -07001// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Vitaly Buka9dd2f8e2017-01-13 00:48:31 -080015#include "src/protobuf_mutator.h"
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080016
Vitaly Bukaf047a002017-01-12 23:57:00 -080017#include <algorithm>
18#include <set>
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080019#include <string>
Vitaly Bukaf047a002017-01-12 23:57:00 -080020#include <utility>
21#include <vector>
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080022
Vitaly Buka35df2e42017-02-25 01:17:25 -080023#include "port/gtest.h"
Vitaly Buka5b1a0032017-02-17 00:06:06 -080024#include "src/protobuf_mutator.pb.h"
Vitaly Buka1109c002016-10-20 17:25:19 -070025
Vitaly Bukaf86815c2017-02-27 14:19:19 -080026namespace protobuf_mutator {
27
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080028using protobuf::TextFormat;
29using protobuf::util::MessageDifferencer;
Vitaly Buka4af611d2016-12-03 18:57:32 -080030using testing::TestWithParam;
31using testing::ValuesIn;
32using testing::WithParamInterface;
Vitaly Buka0e17fd72016-11-18 10:02:46 -080033
Vitaly Buka4af611d2016-12-03 18:57:32 -080034const char kMessages[] = R"(
35 required_msg {}
36 optional_msg {}
37 repeated_msg {}
38 repeated_msg {required_sint32: 56}
39 repeated_msg {}
40 repeated_msg {
41 required_msg {}
42 optional_msg {}
43 repeated_msg {}
44 repeated_msg { required_int32: 67 }
45 repeated_msg {}
46 }
47)";
Vitaly Buka0e17fd72016-11-18 10:02:46 -080048
Vitaly Buka4af611d2016-12-03 18:57:32 -080049const char kRequiredFields[] = R"(
50 required_double: 1.26685288449177e-313
51 required_float: 5.9808638e-39
52 required_int32: 67
53 required_int64: 5285068
54 required_uint32: 14486213
55 required_uint64: 520229415
56 required_sint32: 56
57 required_sint64: -6057486163525532641
58 required_fixed32: 8812173
59 required_fixed64: 273731277756
60 required_sfixed32: 43142
61 required_sfixed64: 132
62 required_bool: false
63 required_string: "qwert"
64 required_bytes: "asdf"
65)";
66
67const char kOptionalFields[] = R"(
68 optional_double: 1.93177850152856e-314
69 optional_float: 4.7397519e-41
70 optional_int32: 40020
71 optional_int64: 10
72 optional_uint32: 40
73 optional_uint64: 159
74 optional_sint32: 44015
75 optional_sint64: 17493625000076
76 optional_fixed32: 193
77 optional_fixed64: 8542688694448488723
78 optional_sfixed32: 4926
79 optional_sfixed64: 60
80 optional_bool: false
81 optional_string: "QWERT"
82 optional_bytes: "ASDF"
83 optional_enum: ENUM_5
84)";
85
86const char kRepeatedFields[] = R"(
87 repeated_double: 1.93177850152856e-314
88 repeated_double: 1.26685288449177e-313
89 repeated_float: 4.7397519e-41
90 repeated_float: 5.9808638e-39
91 repeated_int32: 40020
92 repeated_int32: 67
93 repeated_int64: 10
94 repeated_int64: 5285068
95 repeated_uint32: 40
96 repeated_uint32: 14486213
97 repeated_uint64: 159
98 repeated_uint64: 520229415
99 repeated_sint32: 44015
100 repeated_sint32: 56
101 repeated_sint64: 17493625000076
102 repeated_sint64: -6057486163525532641
103 repeated_fixed32: 193
104 repeated_fixed32: 8812173
105 repeated_fixed64: 8542688694448488723
106 repeated_fixed64: 273731277756
107 repeated_sfixed32: 4926
108 repeated_sfixed32: 43142
109 repeated_sfixed64: 60
110 repeated_sfixed64: 132
111 repeated_bool: false
112 repeated_bool: true
113 repeated_string: "QWERT"
114 repeated_string: "qwert"
115 repeated_bytes: "ASDF"
116 repeated_bytes: "asdf"
117 repeated_enum: ENUM_5
118 repeated_enum: ENUM_4
119)";
120
121const char kRequiredNestedFields[] = R"(
122 required_int32: 123
123 optional_msg {
124 required_double: 1.26685288449177e-313
125 required_float: 5.9808638e-39
126 required_int32: 67
127 required_int64: 5285068
128 required_uint32: 14486213
129 required_uint64: 520229415
130 required_sint32: 56
131 required_sint64: -6057486163525532641
132 required_fixed32: 8812173
133 required_fixed64: 273731277756
134 required_sfixed32: 43142
135 required_sfixed64: 132
136 required_bool: false
137 required_string: "qwert"
138 required_bytes: "asdf"
139 }
140)";
141
142const char kOptionalNestedFields[] = R"(
143 required_int32: 123
144 optional_msg {
145 optional_double: 1.93177850152856e-314
146 optional_float: 4.7397519e-41
147 optional_int32: 40020
148 optional_int64: 10
149 optional_uint32: 40
150 optional_uint64: 159
151 optional_sint32: 44015
152 optional_sint64: 17493625000076
153 optional_fixed32: 193
154 optional_fixed64: 8542688694448488723
155 optional_sfixed32: 4926
156 optional_sfixed64: 60
157 optional_bool: false
158 optional_string: "QWERT"
159 optional_bytes: "ASDF"
160 optional_enum: ENUM_5
161 }
162)";
163
164const char kRepeatedNestedFields[] = R"(
165 required_int32: 123
166 optional_msg {
167 repeated_double: 1.93177850152856e-314
168 repeated_double: 1.26685288449177e-313
169 repeated_float: 4.7397519e-41
170 repeated_float: 5.9808638e-39
171 repeated_int32: 40020
172 repeated_int32: 67
173 repeated_int64: 10
174 repeated_int64: 5285068
175 repeated_uint32: 40
176 repeated_uint32: 14486213
177 repeated_uint64: 159
178 repeated_uint64: 520229415
179 repeated_sint32: 44015
180 repeated_sint32: 56
181 repeated_sint64: 17493625000076
182 repeated_sint64: -6057486163525532641
183 repeated_fixed32: 193
184 repeated_fixed32: 8812173
185 repeated_fixed64: 8542688694448488723
186 repeated_fixed64: 273731277756
187 repeated_sfixed32: 4926
188 repeated_sfixed32: 43142
189 repeated_sfixed64: 60
190 repeated_sfixed64: 132
191 repeated_bool: false
192 repeated_bool: true
193 repeated_string: "QWERT"
194 repeated_string: "qwert"
195 repeated_bytes: "ASDF"
196 repeated_bytes: "asdf"
197 repeated_enum: ENUM_5
198 repeated_enum: ENUM_4
199 }
200)";
201
202class TestProtobufMutator : public ProtobufMutator {
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800203 public:
Vitaly Buka4af611d2016-12-03 18:57:32 -0800204 explicit TestProtobufMutator(bool keep_initialized)
Vitaly Bukaba129722016-12-14 17:29:15 -0800205 : ProtobufMutator(17), random_(13) {
206 keep_initialized_ = keep_initialized;
207 }
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800208
Vitaly Buka4af611d2016-12-03 18:57:32 -0800209 float MutateFloat(float value) override {
210 // Hack for tests. It's hard compare reals generated using random mutations.
211 return std::uniform_int_distribution<uint8_t>(-10, 10)(random_);
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800212 }
213
Vitaly Buka4af611d2016-12-03 18:57:32 -0800214 double MutateDouble(double value) override { return MutateFloat(value); }
215
216 private:
217 RandomEngine random_;
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800218};
219
Vitaly Buka4af611d2016-12-03 18:57:32 -0800220std::vector<std::string> Split(const std::string& str) {
221 std::istringstream iss(str);
222 std::vector<std::string> result;
223 for (std::string line; std::getline(iss, line, '\n');) result.push_back(line);
224 return result;
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800225}
226
Vitaly Buka4af611d2016-12-03 18:57:32 -0800227std::vector<std::pair<const char*, size_t>> GetFieldTestParams(
228 const std::vector<const char*>& tests) {
229 std::vector<std::pair<const char*, size_t>> results;
230 for (auto t : tests) {
231 auto lines = Split(t);
232 for (size_t i = 0; i != lines.size(); ++i) {
233 if (lines[i].find(':') != std::string::npos) results.push_back({t, i});
Vitaly Buka781853c2016-11-21 23:09:35 -0800234 }
Vitaly Buka781853c2016-11-21 23:09:35 -0800235 }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800236 return results;
Vitaly Buka00b61072016-10-19 16:22:51 -0700237}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800238
Vitaly Buka4af611d2016-12-03 18:57:32 -0800239std::vector<std::pair<const char*, size_t>> GetMessageTestParams(
240 const std::vector<const char*>& tests) {
241 std::vector<std::pair<const char*, size_t>> results;
242 for (auto t : tests) {
243 auto lines = Split(t);
244 for (size_t i = 0; i != lines.size(); ++i) {
245 if (lines[i].find("{}") != std::string::npos) results.push_back({t, i});
246 }
247 }
248 return results;
249}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800250
Vitaly Buka89098ff2017-03-03 14:48:04 -0800251void LoadMessage(const std::string& text_message, protobuf::Message* message) {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800252 message->Clear();
253 TextFormat::Parser parser;
254 parser.AllowPartialMessage(true);
255 EXPECT_TRUE(parser.ParseFromString(text_message, message));
256}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800257
Vitaly Buka4af611d2016-12-03 18:57:32 -0800258bool LoadWithoutLine(const std::string& text_message, size_t line,
Vitaly Buka89098ff2017-03-03 14:48:04 -0800259 protobuf::Message* message) {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800260 std::ostringstream oss;
261 auto lines = Split(text_message);
262 for (size_t i = 0; i != lines.size(); ++i) {
263 if (i != line) oss << lines[i] << '\n';
264 }
265 message->Clear();
266 TextFormat::Parser parser;
267 parser.AllowPartialMessage(true);
268 return parser.ParseFromString(oss.str(), message);
269}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800270
Vitaly Buka4af611d2016-12-03 18:57:32 -0800271bool LoadWithChangedLine(const std::string& text_message, size_t line,
Vitaly Buka89098ff2017-03-03 14:48:04 -0800272 protobuf::Message* message, int value) {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800273 auto lines = Split(text_message);
274 std::ostringstream oss;
275 for (size_t i = 0; i != lines.size(); ++i) {
276 if (i != line) {
277 oss << lines[i] << '\n';
278 } else {
279 std::string s = lines[i];
280 s.resize(s.find(':') + 2);
Vitaly Buka781853c2016-11-21 23:09:35 -0800281
Vitaly Buka4af611d2016-12-03 18:57:32 -0800282 if (lines[i].back() == '\"') {
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800283 // strings
284 s += value ? "\"\\" + std::to_string(value) + "\"" : "\"\"";
285 } else if (lines[i].back() == 'e') {
286 // bools
287 s += value ? "true" : "false";
Vitaly Buka4af611d2016-12-03 18:57:32 -0800288 } else {
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800289 s += std::to_string(value);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800290 }
291 oss << s << '\n';
292 }
293 }
294 message->Clear();
295 TextFormat::Parser parser;
296 parser.AllowPartialMessage(true);
297 return parser.ParseFromString(oss.str(), message);
298}
Vitaly Buka781853c2016-11-21 23:09:35 -0800299
Vitaly Buka89098ff2017-03-03 14:48:04 -0800300template <class Message>
301bool Mutate(const Message& from, const Message& to) {
Vitaly Buka43f748f2017-01-05 20:59:32 -0800302 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800303
304 TestProtobufMutator mutator(false);
305
306 for (int j = 0; j < 1000000; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800307 Message message;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800308 message.CopyFrom(from);
Vitaly Buka72019dc2016-12-14 19:17:24 -0800309 mutator.Mutate(&message, 1000);
Vitaly Buka43f748f2017-01-05 20:59:32 -0800310 if (MessageDifferencer::Equals(message, to)) return true;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800311 }
312 return false;
313}
314
315class ProtobufMutatorTest {
316 protected:
317 std::string test_message_;
318 size_t field_;
319 Msg from_;
320 Msg to_;
321};
322
323class ProtobufMutatorFieldTest
324 : public ProtobufMutatorTest,
325 public TestWithParam<std::pair<const char*, size_t>> {
326 protected:
327 void SetUp() override {
328 test_message_ = GetParam().first;
329 field_ = GetParam().second;
330 }
331};
332
333INSTANTIATE_TEST_CASE_P(AllTest, ProtobufMutatorFieldTest,
334 ValuesIn(GetFieldTestParams(
335 {kRequiredFields, kOptionalFields, kRepeatedFields,
336 kRequiredNestedFields, kOptionalNestedFields,
337 kRepeatedNestedFields})));
338
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800339TEST_P(ProtobufMutatorFieldTest, Initialized) {
340 LoadWithoutLine(test_message_, field_, &from_);
341 TestProtobufMutator mutator(true);
Vitaly Buka72019dc2016-12-14 19:17:24 -0800342 mutator.Mutate(&from_, 1000);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800343 EXPECT_TRUE(from_.IsInitialized());
344}
345
346TEST_P(ProtobufMutatorFieldTest, DeleteField) {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800347 LoadMessage(test_message_, &from_);
348 LoadWithoutLine(test_message_, field_, &to_);
349 EXPECT_TRUE(Mutate(from_, to_));
350}
351
352TEST_P(ProtobufMutatorFieldTest, InsertField) {
353 LoadWithoutLine(test_message_, field_, &from_);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800354 LoadWithChangedLine(test_message_, field_, &to_, 0);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800355 EXPECT_TRUE(Mutate(from_, to_));
356}
357
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800358TEST_P(ProtobufMutatorFieldTest, ChangeField) {
359 LoadWithChangedLine(test_message_, field_, &from_, 0);
360 LoadWithChangedLine(test_message_, field_, &to_, 1);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800361 EXPECT_TRUE(Mutate(from_, to_));
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800362 EXPECT_TRUE(Mutate(to_, from_));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800363}
364
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800365TEST_P(ProtobufMutatorFieldTest, CopyField) {
366 Msg msg1;
367 LoadWithChangedLine(test_message_, field_, &msg1, 7);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800368
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800369 Msg msg2;
370 LoadWithChangedLine(test_message_, field_, &msg2, 0);
371
372 from_.add_repeated_msg()->CopyFrom(msg1);
373 from_.add_repeated_msg()->CopyFrom(msg2);
374
375 to_.add_repeated_msg()->CopyFrom(msg1);
376 to_.add_repeated_msg()->CopyFrom(msg1);
377 EXPECT_TRUE(Mutate(from_, to_));
378
379 to_.Clear();
380 to_.add_repeated_msg()->CopyFrom(msg2);
381 to_.add_repeated_msg()->CopyFrom(msg2);
382 EXPECT_TRUE(Mutate(from_, to_));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800383}
384
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800385class ProtobufMutatorSingleFieldTest : public ProtobufMutatorFieldTest {};
386
387INSTANTIATE_TEST_CASE_P(AllTest, ProtobufMutatorSingleFieldTest,
388 ValuesIn(GetFieldTestParams({
389 kRequiredFields, kOptionalFields,
390 kRequiredNestedFields, kOptionalNestedFields,
391 })));
392
393TEST_P(ProtobufMutatorSingleFieldTest, CrossOver) {
394 LoadWithoutLine(test_message_, field_, &from_);
395 LoadMessage(test_message_, &to_);
396
397 EXPECT_FALSE(MessageDifferencer::Equals(from_, to_));
398 TestProtobufMutator mutator(false);
399
400 int match_from_ = 0;
401 int match_to_ = 0;
402 int iterations = 1000;
403 for (int j = 0; j < iterations; ++j) {
404 Msg message;
405 message.CopyFrom(from_);
406 mutator.CrossOver(to_, &message);
407 if (MessageDifferencer::Equals(message, to_)) ++match_to_;
408 if (MessageDifferencer::Equals(message, from_)) ++match_from_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800409 }
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800410
411 EXPECT_LT(iterations * .4, match_from_);
412 EXPECT_GE(iterations * .6, match_from_);
413 EXPECT_LT(iterations * .4, match_to_);
414 EXPECT_GE(iterations * .6, match_to_);
415}
416
Vitaly Buka89098ff2017-03-03 14:48:04 -0800417template <typename T>
418class ProtobufMutatorTypedTest : public ::testing::Test {
419 public:
420 using Message = T;
421};
422
423using ProtobufMutatorTypedTestTypes = testing::Types<Msg>;
424TYPED_TEST_CASE(ProtobufMutatorTypedTest, ProtobufMutatorTypedTestTypes);
425
426TYPED_TEST(ProtobufMutatorTypedTest, CrossOverRepeated) {
427 typename TestFixture::Message m1;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800428 m1.add_repeated_int32(1);
429 m1.add_repeated_int32(2);
430 m1.add_repeated_int32(3);
431
Vitaly Buka89098ff2017-03-03 14:48:04 -0800432 typename TestFixture::Message m2;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800433 m2.add_repeated_int32(4);
434 m2.add_repeated_int32(5);
435 m2.add_repeated_int32(6);
436
437 int iterations = 10000;
438 std::set<std::set<int>> sets;
439 TestProtobufMutator mutator(false);
440 for (int j = 0; j < iterations; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800441 typename TestFixture::Message message;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800442 message.CopyFrom(m1);
443 mutator.CrossOver(m2, &message);
444 sets.insert(
445 {message.repeated_int32().begin(), message.repeated_int32().end()});
446 }
447
448 EXPECT_EQ(1 << 6, sets.size());
449}
450
Vitaly Buka89098ff2017-03-03 14:48:04 -0800451TYPED_TEST(ProtobufMutatorTypedTest, CrossOverRepeatedMessages) {
452 typename TestFixture::Message m1;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800453 auto* rm1 = m1.add_repeated_msg();
454 rm1->add_repeated_int32(1);
455 rm1->add_repeated_int32(2);
456
Vitaly Buka89098ff2017-03-03 14:48:04 -0800457 typename TestFixture::Message m2;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800458 auto* rm2 = m2.add_repeated_msg();
459 rm2->add_repeated_int32(3);
460 rm2->add_repeated_int32(4);
461 rm2->add_repeated_int32(5);
462 rm2->add_repeated_int32(6);
463
464 int iterations = 10000;
465 std::set<std::set<int>> sets;
466 TestProtobufMutator mutator(false);
467 for (int j = 0; j < iterations; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800468 typename TestFixture::Message message;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800469 message.CopyFrom(m1);
470 mutator.CrossOver(m2, &message);
471 for (const auto& msg : message.repeated_msg())
472 sets.insert({msg.repeated_int32().begin(), msg.repeated_int32().end()});
473 }
474
475 EXPECT_EQ(1 << 6, sets.size());
476}
477
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800478TYPED_TEST(ProtobufMutatorTypedTest, FailedMutations) {
Vitaly Buka8aa75102016-12-09 20:01:15 -0800479 TestProtobufMutator mutator(false);
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800480 size_t crossovers = 0;
481 for (int i = 0; i < 10000; ++i) {
482 typename TestFixture::Message messages[2];
483 typename TestFixture::Message tmp;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800484 for (int j = 0; j < 20; ++j) {
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800485 for (auto& m : messages) {
486 tmp.CopyFrom(m);
487 mutator.Mutate(&m, 1000);
488 // Mutate must not produce the same result.
489 EXPECT_FALSE(MessageDifferencer::Equals(m, tmp));
490 }
Vitaly Buka8aa75102016-12-09 20:01:15 -0800491 }
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800492
493 tmp.CopyFrom(messages[1]);
494 mutator.CrossOver(messages[0], &tmp);
495 if (MessageDifferencer::Equals(tmp, messages[1])) ++crossovers;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800496 }
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800497
498 // CrossOver may fail but very rare.
499 EXPECT_LT(crossovers, 100);
Vitaly Buka8aa75102016-12-09 20:01:15 -0800500}
501
Vitaly Buka89098ff2017-03-03 14:48:04 -0800502TYPED_TEST(ProtobufMutatorTypedTest, Size) {
Vitaly Buka72019dc2016-12-14 19:17:24 -0800503 const size_t kIterations = 10000;
Vitaly Buka72019dc2016-12-14 19:17:24 -0800504 auto loop = [&](bool control) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800505 typename TestFixture::Message message;
Vitaly Buka72019dc2016-12-14 19:17:24 -0800506 std::string str;
507 TestProtobufMutator mutator(false);
508 const size_t kTargetSize = 1000;
509 size_t overflows = 0;
510 for (size_t j = 0; j < kIterations; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800511 typename TestFixture::Message message2;
Vitaly Buka72019dc2016-12-14 19:17:24 -0800512 message2.CopyFrom(message);
513 mutator.Mutate(&message2,
514 control ? kTargetSize - std::min(str.size(), kTargetSize)
515 : kTargetSize);
Vitaly Bukaf86815c2017-02-27 14:19:19 -0800516 std::string str2 = MessageToTextString(message2);
Vitaly Buka72019dc2016-12-14 19:17:24 -0800517 if (str2.size() > kTargetSize) {
518 ++overflows;
519 } else if (str2.size() > kTargetSize - 150 || str2.size() > str.size()) {
520 message.CopyFrom(message2);
521 str = str2;
522 }
523 }
524 return overflows;
525 };
526
Vitaly Buka4782c142017-03-04 00:12:32 -0800527 EXPECT_GT(loop(false), kIterations * 0.1);
528 EXPECT_LE(loop(true), kIterations * 0.1);
Vitaly Buka72019dc2016-12-14 19:17:24 -0800529}
530
Vitaly Buka89098ff2017-03-03 14:48:04 -0800531class ProtobufMutatorMessagesTest : public ProtobufMutatorFieldTest {};
532
533INSTANTIATE_TEST_CASE_P(AllTest, ProtobufMutatorMessagesTest,
534 ValuesIn(GetMessageTestParams({kMessages})));
535
536TEST_P(ProtobufMutatorMessagesTest, DeletedMessage) {
537 LoadMessage(test_message_, &from_);
538 LoadWithoutLine(test_message_, field_, &to_);
539 EXPECT_TRUE(Mutate(from_, to_));
540}
541
542TEST_P(ProtobufMutatorMessagesTest, InsertMessage) {
543 LoadWithoutLine(test_message_, field_, &from_);
544 LoadMessage(test_message_, &to_);
545 EXPECT_TRUE(Mutate(from_, to_));
546}
547
Vitaly Buka432b5452016-12-09 14:42:09 -0800548// TODO(vitalybuka): Special tests for oneof.
549
Vitaly Buka482c1722016-12-14 14:48:32 -0800550TEST(ProtobufMutatorMessagesTest, UsageExample) {
551 SmallMessage message;
552 TestProtobufMutator mutator(false);
553
554 // Test that we can generate all variation of the message.
555 std::set<std::string> mutations;
556 for (int j = 0; j < 1000; ++j) {
Vitaly Buka72019dc2016-12-14 19:17:24 -0800557 mutator.Mutate(&message, 1000);
Vitaly Bukaf86815c2017-02-27 14:19:19 -0800558 std::string str = MessageToTextString(message);
Vitaly Buka482c1722016-12-14 14:48:32 -0800559 mutations.insert(str);
560 }
561
562 // 3 states for boolean and 5 for enum, including missing fields.
Vitaly Buka0e1e46b2017-01-12 21:54:25 -0800563 EXPECT_EQ(3u * 5u, mutations.size());
Vitaly Buka482c1722016-12-14 14:48:32 -0800564}
Vitaly Bukae8c86432016-12-09 19:49:43 -0800565
Vitaly Buka432b5452016-12-09 14:42:09 -0800566} // namespace protobuf_mutator