blob: 34766c6305e5de33c068dca014da089cf0376e15 [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 Bukaf90698f2017-03-01 15:46:58 -080015#include "src/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 Bukafb193372017-03-04 19:25:29 -080020#include <tuple>
Vitaly Bukaf047a002017-01-12 23:57:00 -080021#include <utility>
22#include <vector>
Vitaly Bukaa3e59c72016-12-06 16:53:56 -080023
Vitaly Buka35df2e42017-02-25 01:17:25 -080024#include "port/gtest.h"
Vitaly Bukaaf8136f2017-06-09 16:40:12 -070025#include "src/binary_format.h"
Vitaly Bukaf90698f2017-03-01 15:46:58 -080026#include "src/mutator_test_proto2.pb.h"
27#include "src/mutator_test_proto3.pb.h"
Vitaly Buka829ad002017-03-01 16:26:00 -080028#include "src/text_format.h"
Vitaly Buka1109c002016-10-20 17:25:19 -070029
Vitaly Bukaf86815c2017-02-27 14:19:19 -080030namespace protobuf_mutator {
31
Vitaly Buka6c6dbbe2017-02-22 13:58:24 -080032using protobuf::util::MessageDifferencer;
Vitaly Buka4af611d2016-12-03 18:57:32 -080033using testing::TestWithParam;
34using testing::ValuesIn;
Vitaly Buka0e17fd72016-11-18 10:02:46 -080035
Vitaly Buka4af611d2016-12-03 18:57:32 -080036const 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)";
Vitaly Buka0e17fd72016-11-18 10:02:46 -080050
Vitaly Buka28ca0ee2017-03-04 21:35:42 -080051const char kMessagesProto3[] = R"(
52 optional_msg {}
53 repeated_msg {}
54 repeated_msg {optional_sint32: 56}
55 repeated_msg {}
56 repeated_msg {
57 optional_msg {}
58 repeated_msg {}
59 repeated_msg { optional_int32: 67 }
60 repeated_msg {}
61 }
62)";
63
Vitaly Buka4af611d2016-12-03 18:57:32 -080064const char kRequiredFields[] = R"(
65 required_double: 1.26685288449177e-313
66 required_float: 5.9808638e-39
67 required_int32: 67
68 required_int64: 5285068
69 required_uint32: 14486213
70 required_uint64: 520229415
71 required_sint32: 56
72 required_sint64: -6057486163525532641
73 required_fixed32: 8812173
74 required_fixed64: 273731277756
75 required_sfixed32: 43142
76 required_sfixed64: 132
77 required_bool: false
78 required_string: "qwert"
79 required_bytes: "asdf"
80)";
81
82const char kOptionalFields[] = R"(
83 optional_double: 1.93177850152856e-314
84 optional_float: 4.7397519e-41
85 optional_int32: 40020
86 optional_int64: 10
87 optional_uint32: 40
88 optional_uint64: 159
89 optional_sint32: 44015
90 optional_sint64: 17493625000076
91 optional_fixed32: 193
92 optional_fixed64: 8542688694448488723
93 optional_sfixed32: 4926
94 optional_sfixed64: 60
Vitaly Buka28ca0ee2017-03-04 21:35:42 -080095 optional_bool: true
Vitaly Buka4af611d2016-12-03 18:57:32 -080096 optional_string: "QWERT"
97 optional_bytes: "ASDF"
98 optional_enum: ENUM_5
99)";
100
101const char kRepeatedFields[] = R"(
102 repeated_double: 1.93177850152856e-314
103 repeated_double: 1.26685288449177e-313
104 repeated_float: 4.7397519e-41
105 repeated_float: 5.9808638e-39
106 repeated_int32: 40020
107 repeated_int32: 67
108 repeated_int64: 10
109 repeated_int64: 5285068
110 repeated_uint32: 40
111 repeated_uint32: 14486213
112 repeated_uint64: 159
113 repeated_uint64: 520229415
114 repeated_sint32: 44015
115 repeated_sint32: 56
116 repeated_sint64: 17493625000076
117 repeated_sint64: -6057486163525532641
118 repeated_fixed32: 193
119 repeated_fixed32: 8812173
120 repeated_fixed64: 8542688694448488723
121 repeated_fixed64: 273731277756
122 repeated_sfixed32: 4926
123 repeated_sfixed32: 43142
124 repeated_sfixed64: 60
125 repeated_sfixed64: 132
126 repeated_bool: false
127 repeated_bool: true
128 repeated_string: "QWERT"
129 repeated_string: "qwert"
130 repeated_bytes: "ASDF"
131 repeated_bytes: "asdf"
132 repeated_enum: ENUM_5
133 repeated_enum: ENUM_4
134)";
135
136const char kRequiredNestedFields[] = R"(
137 required_int32: 123
138 optional_msg {
139 required_double: 1.26685288449177e-313
140 required_float: 5.9808638e-39
141 required_int32: 67
142 required_int64: 5285068
143 required_uint32: 14486213
144 required_uint64: 520229415
145 required_sint32: 56
146 required_sint64: -6057486163525532641
147 required_fixed32: 8812173
148 required_fixed64: 273731277756
149 required_sfixed32: 43142
150 required_sfixed64: 132
151 required_bool: false
152 required_string: "qwert"
153 required_bytes: "asdf"
154 }
155)";
156
157const char kOptionalNestedFields[] = R"(
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800158 optional_int32: 123
Vitaly Buka4af611d2016-12-03 18:57:32 -0800159 optional_msg {
160 optional_double: 1.93177850152856e-314
161 optional_float: 4.7397519e-41
162 optional_int32: 40020
163 optional_int64: 10
164 optional_uint32: 40
165 optional_uint64: 159
166 optional_sint32: 44015
167 optional_sint64: 17493625000076
168 optional_fixed32: 193
169 optional_fixed64: 8542688694448488723
170 optional_sfixed32: 4926
171 optional_sfixed64: 60
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800172 optional_bool: true
Vitaly Buka4af611d2016-12-03 18:57:32 -0800173 optional_string: "QWERT"
174 optional_bytes: "ASDF"
175 optional_enum: ENUM_5
176 }
177)";
178
179const char kRepeatedNestedFields[] = R"(
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800180 optional_int32: 123
Vitaly Buka4af611d2016-12-03 18:57:32 -0800181 optional_msg {
182 repeated_double: 1.93177850152856e-314
183 repeated_double: 1.26685288449177e-313
184 repeated_float: 4.7397519e-41
185 repeated_float: 5.9808638e-39
186 repeated_int32: 40020
187 repeated_int32: 67
188 repeated_int64: 10
189 repeated_int64: 5285068
190 repeated_uint32: 40
191 repeated_uint32: 14486213
192 repeated_uint64: 159
193 repeated_uint64: 520229415
194 repeated_sint32: 44015
195 repeated_sint32: 56
196 repeated_sint64: 17493625000076
197 repeated_sint64: -6057486163525532641
198 repeated_fixed32: 193
199 repeated_fixed32: 8812173
200 repeated_fixed64: 8542688694448488723
201 repeated_fixed64: 273731277756
202 repeated_sfixed32: 4926
203 repeated_sfixed32: 43142
204 repeated_sfixed64: 60
205 repeated_sfixed64: 132
206 repeated_bool: false
207 repeated_bool: true
208 repeated_string: "QWERT"
209 repeated_string: "qwert"
210 repeated_bytes: "ASDF"
211 repeated_bytes: "asdf"
212 repeated_enum: ENUM_5
213 repeated_enum: ENUM_4
214 }
215)";
216
Vitaly Bukae79e0182017-03-01 16:02:14 -0800217class TestMutator : public Mutator {
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800218 public:
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800219 explicit TestMutator(bool keep_initialized) : Mutator(&random_), random_(17) {
Vitaly Bukaba129722016-12-14 17:29:15 -0800220 keep_initialized_ = keep_initialized;
221 }
Vitaly Buka142e08b2017-03-05 16:26:15 -0800222
223 // Avoids dedup logic for some tests.
224 void NoDeDupCrossOver(const protobuf::Message& message1,
225 protobuf::Message* message2) {
226 CrossOverImpl(message1, message2);
227 }
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800228
229 private:
230 RandomEngine random_;
Vitaly Buka2256ad72017-03-04 17:38:15 -0800231};
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800232
Vitaly Bukae79e0182017-03-01 16:02:14 -0800233class ReducedTestMutator : public TestMutator {
Vitaly Buka2256ad72017-03-04 17:38:15 -0800234 public:
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800235 ReducedTestMutator() : TestMutator(false) {
Vitaly Buka2256ad72017-03-04 17:38:15 -0800236 for (float i = 1000; i > 0.1; i /= 7) {
237 values_.push_back(i);
238 values_.push_back(-i);
239 }
240 values_.push_back(-1.0);
241 values_.push_back(0.0);
242 values_.push_back(1.0);
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800243 }
244
Vitaly Buka2256ad72017-03-04 17:38:15 -0800245 protected:
246 int32_t MutateInt32(int32_t value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800247 int64_t MutateInt64(int64_t value) override { return GetRandomValue(); }
Vitaly Buka0fa21bd2017-03-08 17:02:45 -0800248 uint32_t MutateUInt32(uint32_t value) override {
249 return fabs(GetRandomValue());
250 }
251 uint64_t MutateUInt64(uint64_t value) override {
252 return fabs(GetRandomValue());
253 }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800254 float MutateFloat(float value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800255 double MutateDouble(double value) override { return GetRandomValue(); }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800256 std::string MutateString(const std::string& value,
257 size_t size_increase_hint) override {
258 return strings_[std::uniform_int_distribution<uint8_t>(
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800259 0, strings_.size() - 1)(*random())];
Vitaly Buka2256ad72017-03-04 17:38:15 -0800260 }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800261
262 private:
Vitaly Buka2256ad72017-03-04 17:38:15 -0800263 float GetRandomValue() {
264 return values_[std::uniform_int_distribution<uint8_t>(
Vitaly Bukaf62fe472017-03-01 23:05:15 -0800265 0, values_.size() - 1)(*random())];
Vitaly Buka2256ad72017-03-04 17:38:15 -0800266 }
267
Vitaly Buka2256ad72017-03-04 17:38:15 -0800268 std::vector<float> values_;
269 std::vector<std::string> strings_ = {
270 "", "\001", "\000", "a", "b", "ab",
271 };
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800272};
273
Vitaly Buka4af611d2016-12-03 18:57:32 -0800274std::vector<std::string> Split(const std::string& str) {
275 std::istringstream iss(str);
276 std::vector<std::string> result;
277 for (std::string line; std::getline(iss, line, '\n');) result.push_back(line);
278 return result;
Vitaly Buka0e17fd72016-11-18 10:02:46 -0800279}
280
Vitaly Bukafb193372017-03-04 19:25:29 -0800281using TestParams = std::tuple<const protobuf::Message*, const char*, size_t>;
282
283template <class T>
284std::vector<TestParams> GetFieldTestParams(
Vitaly Buka4af611d2016-12-03 18:57:32 -0800285 const std::vector<const char*>& tests) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800286 std::vector<TestParams> results;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800287 for (auto t : tests) {
288 auto lines = Split(t);
289 for (size_t i = 0; i != lines.size(); ++i) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800290 if (lines[i].find(':') != std::string::npos)
291 results.push_back(std::make_tuple(&T::default_instance(), t, i));
Vitaly Buka781853c2016-11-21 23:09:35 -0800292 }
Vitaly Buka781853c2016-11-21 23:09:35 -0800293 }
Vitaly Buka4af611d2016-12-03 18:57:32 -0800294 return results;
Vitaly Buka00b61072016-10-19 16:22:51 -0700295}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800296
Vitaly Bukafb193372017-03-04 19:25:29 -0800297template <class T>
298std::vector<TestParams> GetMessageTestParams(
Vitaly Buka4af611d2016-12-03 18:57:32 -0800299 const std::vector<const char*>& tests) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800300 std::vector<TestParams> results;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800301 for (auto t : tests) {
302 auto lines = Split(t);
303 for (size_t i = 0; i != lines.size(); ++i) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800304 if (lines[i].find("{}") != std::string::npos)
305 results.push_back(std::make_tuple(&T::default_instance(), t, i));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800306 }
307 }
308 return results;
309}
Vitaly Bukaac2b7bf2016-11-21 14:07:02 -0800310
Vitaly Bukafb193372017-03-04 19:25:29 -0800311bool Mutate(const protobuf::Message& from, const protobuf::Message& to) {
Vitaly Buka43f748f2017-01-05 20:59:32 -0800312 EXPECT_FALSE(MessageDifferencer::Equals(from, to));
Vitaly Bukae79e0182017-03-01 16:02:14 -0800313 ReducedTestMutator mutator;
Vitaly Bukafb193372017-03-04 19:25:29 -0800314 std::unique_ptr<protobuf::Message> message(from.New());
Vitaly Buka4af611d2016-12-03 18:57:32 -0800315 for (int j = 0; j < 1000000; ++j) {
Vitaly Bukafb193372017-03-04 19:25:29 -0800316 message->CopyFrom(from);
317 mutator.Mutate(message.get(), 1000);
318 if (MessageDifferencer::Equals(*message, to)) return true;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800319 }
Vitaly Buka2256ad72017-03-04 17:38:15 -0800320
321 ADD_FAILURE() << "Failed to get from:\n"
Vitaly Bukabe54a442017-03-01 16:39:33 -0800322 << SaveMessageAsText(from) << "\nto:\n"
323 << SaveMessageAsText(to);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800324 return false;
325}
326
Vitaly Bukae79e0182017-03-01 16:02:14 -0800327class MutatorTest : public TestWithParam<TestParams> {
Vitaly Buka4af611d2016-12-03 18:57:32 -0800328 protected:
329 void SetUp() override {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800330 m1_.reset(std::get<0>(GetParam())->New());
331 m2_.reset(std::get<0>(GetParam())->New());
332 text_ = std::get<1>(GetParam());
333 line_ = std::get<2>(GetParam());
Vitaly Buka4af611d2016-12-03 18:57:32 -0800334 }
Vitaly Bukafb193372017-03-04 19:25:29 -0800335
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800336 void LoadMessage(protobuf::Message* message) {
Vitaly Bukabe54a442017-03-01 16:39:33 -0800337 EXPECT_TRUE(ParseTextMessage(text_, message));
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800338 }
339
340 bool LoadWithoutLine(protobuf::Message* message) {
341 std::ostringstream oss;
342 auto lines = Split(text_);
343 for (size_t i = 0; i != lines.size(); ++i) {
344 if (i != line_) oss << lines[i] << '\n';
345 }
Vitaly Bukabe54a442017-03-01 16:39:33 -0800346 return ParseTextMessage(oss.str(), message);
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800347 }
348
349 bool LoadWithChangedLine(protobuf::Message* message, int value) {
350 auto lines = Split(text_);
351 std::ostringstream oss;
352 for (size_t i = 0; i != lines.size(); ++i) {
353 if (i != line_) {
354 oss << lines[i] << '\n';
355 } else {
356 std::string s = lines[i];
357 s.resize(s.find(':') + 2);
358
359 if (lines[i].back() == '\"') {
360 // strings
361 s += value ? "\"\\" + std::to_string(value) + "\"" : "\"\"";
362 } else if (lines[i].back() == 'e') {
363 // bools
364 s += value ? "true" : "false";
365 } else {
366 s += std::to_string(value);
367 }
368 oss << s << '\n';
369 }
370 }
Vitaly Bukabe54a442017-03-01 16:39:33 -0800371 return ParseTextMessage(oss.str(), message);
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800372 }
373
374 std::string text_;
375 size_t line_;
376 std::unique_ptr<protobuf::Message> m1_;
377 std::unique_ptr<protobuf::Message> m2_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800378};
379
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800380// These tests are irrelevant for Proto3 as it has no required fields and
381// insertion/deletion.
Vitaly Bukafb193372017-03-04 19:25:29 -0800382
Vitaly Bukae79e0182017-03-01 16:02:14 -0800383class MutatorFieldInsDelTest : public MutatorTest {};
384INSTANTIATE_TEST_CASE_P(Proto2, MutatorFieldInsDelTest,
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800385 ValuesIn(GetFieldTestParams<Msg>(
386 {kRequiredFields, kOptionalFields, kRepeatedFields,
387 kRequiredNestedFields, kOptionalNestedFields,
388 kRepeatedNestedFields})));
389
Vitaly Bukae79e0182017-03-01 16:02:14 -0800390TEST_P(MutatorFieldInsDelTest, DeleteField) {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800391 LoadMessage(m1_.get());
392 LoadWithoutLine(m2_.get());
393 EXPECT_TRUE(Mutate(*m1_, *m2_));
394}
395
Vitaly Bukae79e0182017-03-01 16:02:14 -0800396TEST_P(MutatorFieldInsDelTest, InsertField) {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800397 LoadWithoutLine(m1_.get());
398 LoadWithChangedLine(m2_.get(), 0);
399 EXPECT_TRUE(Mutate(*m1_, *m2_));
400}
401
Vitaly Bukae79e0182017-03-01 16:02:14 -0800402class MutatorFieldTest : public MutatorTest {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800403 public:
404 template <class Msg>
405 void TestCopyField();
406};
Vitaly Bukae79e0182017-03-01 16:02:14 -0800407INSTANTIATE_TEST_CASE_P(Proto2, MutatorFieldTest,
Vitaly Bukafb193372017-03-04 19:25:29 -0800408 ValuesIn(GetFieldTestParams<Msg>(
Vitaly Buka4af611d2016-12-03 18:57:32 -0800409 {kRequiredFields, kOptionalFields, kRepeatedFields,
410 kRequiredNestedFields, kOptionalNestedFields,
411 kRepeatedNestedFields})));
Vitaly Bukae79e0182017-03-01 16:02:14 -0800412INSTANTIATE_TEST_CASE_P(Proto3, MutatorFieldTest,
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800413 ValuesIn(GetFieldTestParams<Msg3>(
414 {kOptionalFields, kRepeatedFields,
415 kOptionalNestedFields, kRepeatedNestedFields})));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800416
Vitaly Bukae79e0182017-03-01 16:02:14 -0800417TEST_P(MutatorFieldTest, Initialized) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800418 LoadWithoutLine(m1_.get());
Vitaly Bukae79e0182017-03-01 16:02:14 -0800419 TestMutator mutator(true);
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800420 mutator.Mutate(m1_.get(), 1000);
421 EXPECT_TRUE(m1_->IsInitialized());
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800422}
423
Vitaly Bukae79e0182017-03-01 16:02:14 -0800424TEST_P(MutatorFieldTest, ChangeField) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800425 LoadWithChangedLine(m1_.get(), 0);
426 LoadWithChangedLine(m2_.get(), 1);
427 EXPECT_TRUE(Mutate(*m1_, *m2_));
428 EXPECT_TRUE(Mutate(*m2_, *m1_));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800429}
430
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800431template <class Msg>
Vitaly Bukae79e0182017-03-01 16:02:14 -0800432void MutatorFieldTest::TestCopyField() {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800433 LoadWithChangedLine(m1_.get(), 7);
434 LoadWithChangedLine(m2_.get(), 0);
Vitaly Buka4af611d2016-12-03 18:57:32 -0800435
Vitaly Bukafb193372017-03-04 19:25:29 -0800436 Msg from;
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800437 from.add_repeated_msg()->CopyFrom(*m1_);
438 from.add_repeated_msg()->CopyFrom(*m2_);
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800439
Vitaly Bukafb193372017-03-04 19:25:29 -0800440 Msg to;
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800441 to.add_repeated_msg()->CopyFrom(*m1_);
442 to.add_repeated_msg()->CopyFrom(*m1_);
Vitaly Bukafb193372017-03-04 19:25:29 -0800443 EXPECT_TRUE(Mutate(from, to));
Vitaly Bukaa3e59c72016-12-06 16:53:56 -0800444
Vitaly Bukafb193372017-03-04 19:25:29 -0800445 to.Clear();
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800446 to.add_repeated_msg()->CopyFrom(*m2_);
447 to.add_repeated_msg()->CopyFrom(*m2_);
Vitaly Bukafb193372017-03-04 19:25:29 -0800448 EXPECT_TRUE(Mutate(from, to));
Vitaly Buka4af611d2016-12-03 18:57:32 -0800449}
450
Vitaly Bukae79e0182017-03-01 16:02:14 -0800451TEST_P(MutatorFieldTest, CopyField) {
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800452 if (m1_->GetDescriptor() == Msg::descriptor())
453 TestCopyField<Msg>();
454 else
455 TestCopyField<Msg3>();
456}
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800457
Vitaly Bukae79e0182017-03-01 16:02:14 -0800458class MutatorSingleFieldTest : public MutatorTest {};
459INSTANTIATE_TEST_CASE_P(Proto2, MutatorSingleFieldTest,
Vitaly Bukafb193372017-03-04 19:25:29 -0800460 ValuesIn(GetFieldTestParams<Msg>({
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800461 kRequiredFields, kOptionalFields,
462 kRequiredNestedFields, kOptionalNestedFields,
463 })));
Vitaly Bukae79e0182017-03-01 16:02:14 -0800464INSTANTIATE_TEST_CASE_P(Proto3, MutatorSingleFieldTest,
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800465 ValuesIn(GetFieldTestParams<Msg3>({
466 kOptionalFields, kOptionalNestedFields,
467 })));
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800468
Vitaly Bukae79e0182017-03-01 16:02:14 -0800469TEST_P(MutatorSingleFieldTest, CrossOver) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800470 LoadWithoutLine(m1_.get());
471 LoadMessage(m2_.get());
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800472
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800473 EXPECT_FALSE(MessageDifferencer::Equals(*m1_, *m2_));
Vitaly Bukae79e0182017-03-01 16:02:14 -0800474 TestMutator mutator(false);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800475
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800476 int match_m1_ = 0;
477 int match_m2_ = 0;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800478 int iterations = 1000;
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800479 std::unique_ptr<protobuf::Message> message(m1_->New());
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800480 for (int j = 0; j < iterations; ++j) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800481 message->CopyFrom(*m1_);
Vitaly Buka142e08b2017-03-05 16:26:15 -0800482 mutator.NoDeDupCrossOver(*m2_, message.get());
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800483 if (MessageDifferencer::Equals(*message, *m2_)) ++match_m2_;
484 if (MessageDifferencer::Equals(*message, *m1_)) ++match_m1_;
Vitaly Buka4af611d2016-12-03 18:57:32 -0800485 }
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800486
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800487 EXPECT_LT(iterations * .4, match_m1_);
488 EXPECT_GE(iterations * .6, match_m1_);
489 EXPECT_LT(iterations * .4, match_m2_);
490 EXPECT_GE(iterations * .6, match_m2_);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800491}
492
Vitaly Buka89098ff2017-03-03 14:48:04 -0800493template <typename T>
Vitaly Bukae79e0182017-03-01 16:02:14 -0800494class MutatorTypedTest : public ::testing::Test {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800495 public:
496 using Message = T;
497};
498
Vitaly Bukae79e0182017-03-01 16:02:14 -0800499using MutatorTypedTestTypes = testing::Types<Msg, Msg3>;
500TYPED_TEST_CASE(MutatorTypedTest, MutatorTypedTestTypes);
Vitaly Buka89098ff2017-03-03 14:48:04 -0800501
Vitaly Bukae79e0182017-03-01 16:02:14 -0800502TYPED_TEST(MutatorTypedTest, CrossOverRepeated) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800503 typename TestFixture::Message m1;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800504 m1.add_repeated_int32(1);
505 m1.add_repeated_int32(2);
506 m1.add_repeated_int32(3);
507
Vitaly Buka89098ff2017-03-03 14:48:04 -0800508 typename TestFixture::Message m2;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800509 m2.add_repeated_int32(4);
510 m2.add_repeated_int32(5);
511 m2.add_repeated_int32(6);
512
513 int iterations = 10000;
514 std::set<std::set<int>> sets;
Vitaly Bukae79e0182017-03-01 16:02:14 -0800515 TestMutator mutator(false);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800516 for (int j = 0; j < iterations; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800517 typename TestFixture::Message message;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800518 message.CopyFrom(m1);
Vitaly Buka142e08b2017-03-05 16:26:15 -0800519 mutator.NoDeDupCrossOver(m2, &message);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800520 sets.insert(
521 {message.repeated_int32().begin(), message.repeated_int32().end()});
522 }
523
Vitaly Bukad0d09da2018-01-15 17:24:03 -0800524 EXPECT_EQ(1u << 6, sets.size());
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800525}
526
Vitaly Bukae79e0182017-03-01 16:02:14 -0800527TYPED_TEST(MutatorTypedTest, CrossOverRepeatedMessages) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800528 typename TestFixture::Message m1;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800529 auto* rm1 = m1.add_repeated_msg();
530 rm1->add_repeated_int32(1);
531 rm1->add_repeated_int32(2);
532
Vitaly Buka89098ff2017-03-03 14:48:04 -0800533 typename TestFixture::Message m2;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800534 auto* rm2 = m2.add_repeated_msg();
535 rm2->add_repeated_int32(3);
536 rm2->add_repeated_int32(4);
537 rm2->add_repeated_int32(5);
538 rm2->add_repeated_int32(6);
539
540 int iterations = 10000;
541 std::set<std::set<int>> sets;
Vitaly Bukae79e0182017-03-01 16:02:14 -0800542 TestMutator mutator(false);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800543 for (int j = 0; j < iterations; ++j) {
Vitaly Buka89098ff2017-03-03 14:48:04 -0800544 typename TestFixture::Message message;
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800545 message.CopyFrom(m1);
Vitaly Buka142e08b2017-03-05 16:26:15 -0800546 mutator.NoDeDupCrossOver(m2, &message);
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800547 for (const auto& msg : message.repeated_msg())
548 sets.insert({msg.repeated_int32().begin(), msg.repeated_int32().end()});
549 }
550
Vitaly Bukad0d09da2018-01-15 17:24:03 -0800551 EXPECT_EQ(1u << 6, sets.size());
Vitaly Bukaadfc27c2017-02-26 22:36:36 -0800552}
553
Vitaly Bukae79e0182017-03-01 16:02:14 -0800554TYPED_TEST(MutatorTypedTest, FailedMutations) {
555 TestMutator mutator(false);
Vitaly Buka2d609df2017-03-06 23:29:47 -0800556 size_t crossovers = 0;
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800557 for (int i = 0; i < 10000; ++i) {
558 typename TestFixture::Message messages[2];
559 typename TestFixture::Message tmp;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800560 for (int j = 0; j < 20; ++j) {
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800561 for (auto& m : messages) {
562 tmp.CopyFrom(m);
563 mutator.Mutate(&m, 1000);
564 // Mutate must not produce the same result.
565 EXPECT_FALSE(MessageDifferencer::Equals(m, tmp));
566 }
Vitaly Buka8aa75102016-12-09 20:01:15 -0800567 }
Vitaly Bukad3a76b82017-03-04 01:27:22 -0800568
569 tmp.CopyFrom(messages[1]);
570 mutator.CrossOver(messages[0], &tmp);
Vitaly Buka2d609df2017-03-06 23:29:47 -0800571 if (MessageDifferencer::Equals(tmp, messages[1]) ||
572 MessageDifferencer::Equals(tmp, messages[0]))
573 ++crossovers;
Vitaly Buka8aa75102016-12-09 20:01:15 -0800574 }
Vitaly Buka2d609df2017-03-06 23:29:47 -0800575
576 // CrossOver may fail but very rare.
Vitaly Bukad0d09da2018-01-15 17:24:03 -0800577 EXPECT_LT(crossovers, 100u);
Vitaly Buka8aa75102016-12-09 20:01:15 -0800578}
579
Vitaly Bukaaf8136f2017-06-09 16:40:12 -0700580TYPED_TEST(MutatorTypedTest, Serialization) {
581 TestMutator mutator(false);
582 for (int i = 0; i < 10000; ++i) {
583 typename TestFixture::Message message;
584 for (int j = 0; j < 5; ++j) {
585 mutator.Mutate(&message, 1000);
586 typename TestFixture::Message parsed;
587
588 EXPECT_TRUE(ParseTextMessage(SaveMessageAsText(message), &parsed));
589 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
590
591 EXPECT_TRUE(ParseBinaryMessage(SaveMessageAsBinary(message), &parsed));
592 EXPECT_TRUE(MessageDifferencer::Equals(parsed, message));
593 }
594 }
595}
596
Vitaly Bukae79e0182017-03-01 16:02:14 -0800597class MutatorMessagesTest : public MutatorTest {};
598INSTANTIATE_TEST_CASE_P(Proto2, MutatorMessagesTest,
Vitaly Bukafb193372017-03-04 19:25:29 -0800599 ValuesIn(GetMessageTestParams<Msg>({kMessages})));
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800600INSTANTIATE_TEST_CASE_P(
Vitaly Bukae79e0182017-03-01 16:02:14 -0800601 Proto3, MutatorMessagesTest,
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800602 ValuesIn(GetMessageTestParams<Msg3>({kMessagesProto3})));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800603
Vitaly Bukae79e0182017-03-01 16:02:14 -0800604TEST_P(MutatorMessagesTest, DeletedMessage) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800605 LoadMessage(m1_.get());
606 LoadWithoutLine(m2_.get());
607 EXPECT_TRUE(Mutate(*m1_, *m2_));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800608}
609
Vitaly Bukae79e0182017-03-01 16:02:14 -0800610TEST_P(MutatorMessagesTest, InsertMessage) {
Vitaly Bukabbf914d2017-03-04 19:32:21 -0800611 LoadWithoutLine(m1_.get());
612 LoadMessage(m2_.get());
613 EXPECT_TRUE(Mutate(*m1_, *m2_));
Vitaly Buka89098ff2017-03-03 14:48:04 -0800614}
615
Vitaly Buka28ca0ee2017-03-04 21:35:42 -0800616// TODO(vitalybuka): Special tests for oneof.
617
Vitaly Bukae79e0182017-03-01 16:02:14 -0800618TEST(MutatorMessagesTest, UsageExample) {
Vitaly Buka482c1722016-12-14 14:48:32 -0800619 SmallMessage message;
Vitaly Bukae79e0182017-03-01 16:02:14 -0800620 TestMutator mutator(false);
Vitaly Buka482c1722016-12-14 14:48:32 -0800621
622 // Test that we can generate all variation of the message.
623 std::set<std::string> mutations;
624 for (int j = 0; j < 1000; ++j) {
Vitaly Buka72019dc2016-12-14 19:17:24 -0800625 mutator.Mutate(&message, 1000);
Vitaly Buka829ad002017-03-01 16:26:00 -0800626 std::string str = SaveMessageAsText(message);
Vitaly Buka482c1722016-12-14 14:48:32 -0800627 mutations.insert(str);
628 }
629
630 // 3 states for boolean and 5 for enum, including missing fields.
Vitaly Buka0e1e46b2017-01-12 21:54:25 -0800631 EXPECT_EQ(3u * 5u, mutations.size());
Vitaly Buka482c1722016-12-14 14:48:32 -0800632}
Vitaly Bukae8c86432016-12-09 19:49:43 -0800633
Vitaly Bukaf3383a92017-03-19 17:04:18 -0700634TEST(MutatorMessagesTest, EmptyMessage) {
635 EmptyMessage message;
636 TestMutator mutator(false);
637 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
638}
639
640
Vitaly Bukaee1c76a2017-03-15 10:48:53 -0700641TEST(MutatorMessagesTest, Regressions) {
642 RegressionMessage message;
643 TestMutator mutator(false);
644 for (int j = 0; j < 10000; ++j) mutator.Mutate(&message, 1000);
645}
646
Vitaly Buka432b5452016-12-09 14:42:09 -0800647} // namespace protobuf_mutator