diff options
author | Vitaly Buka <vitalybuka@google.com> | 2020-01-25 22:33:05 -0800 |
---|---|---|
committer | Vitaly Buka <vitalybuka@gmail.com> | 2020-01-29 11:36:29 -0800 |
commit | 5cd166ec45f1ef3d181a5addb37a81288b56ec7c (patch) | |
tree | 86f7578fddf3bb228ba64078ffd5b7aa0da77cec | |
parent | 40b4d89e7e679839e5d4fe6fc892e6d0efc18167 (diff) | |
download | libprotobuf-mutator-5cd166ec45f1ef3d181a5addb37a81288b56ec7c.tar.gz |
Use size_increase_hint selecting copy source
-rw-r--r-- | src/mutator.cc | 37 | ||||
-rw-r--r-- | src/mutator_test.cc | 6 |
2 files changed, 31 insertions, 12 deletions
diff --git a/src/mutator.cc b/src/mutator.cc index 19ccc19..ac936cf 100644 --- a/src/mutator.cc +++ b/src/mutator.cc @@ -124,14 +124,14 @@ class CanCopyAndDifferentField : public FieldFunction<CanCopyAndDifferentField, bool> { public: template <class T> - bool ForType(const ConstFieldInstance& src, - const ConstFieldInstance& dst) const { + bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst, + int size_increase_hint) const { T s; src.Load(&s); if (!dst.CanStore(s)) return false; T d; dst.Load(&d); - return !IsEqual(s, d); + return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d); } private: @@ -150,6 +150,20 @@ class CanCopyAndDifferentField bool IsEqual(const T& a, const T& b) const { return a == b; } + + int64_t SizeDiff(const std::unique_ptr<protobuf::Message>& src, + const std::unique_ptr<protobuf::Message>& dst) const { + return src->ByteSizeLong() - dst->ByteSizeLong(); + } + + int64_t SizeDiff(const std::string& src, const std::string& dst) const { + return src.size() - dst.size(); + } + + template <class T> + int64_t SizeDiff(const T&, const T&) const { + return 0; + } }; // Selects random field and mutation from the given proto message. @@ -268,8 +282,11 @@ class MutationSampler { class DataSourceSampler { public: DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random, - const Message& message) - : match_(match), random_(random), sampler_(random) { + int size_increase_hint, const Message& message) + : match_(match), + random_(random), + size_increase_hint_(size_increase_hint), + sampler_(random) { Sample(message); } @@ -311,13 +328,13 @@ class DataSourceSampler { if (int field_size = reflection->FieldSize(message, field)) { ConstFieldInstance source(&message, field, GetRandomIndex(random_, field_size)); - if (CanCopyAndDifferentField()(source, match_)) + if (CanCopyAndDifferentField()(source, match_, size_increase_hint_)) sampler_.Try(field_size, source); } } else { if (reflection->HasField(message, field)) { ConstFieldInstance source(&message, field); - if (CanCopyAndDifferentField()(source, match_)) + if (CanCopyAndDifferentField()(source, match_, size_increase_hint_)) sampler_.Try(1, source); } } @@ -326,6 +343,7 @@ class DataSourceSampler { ConstFieldInstance match_; RandomEngine* random_; + int size_increase_hint_; WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_; }; @@ -499,7 +517,7 @@ void Mutator::MutateImpl(const Message& source, Message* message, int size_increase_hint) { if (size_increase_hint > 0) size_increase_hint /= 2; for (;;) { - MutationSampler mutation(keep_initialized_, size_increase_hint > 0, + MutationSampler mutation(keep_initialized_, size_increase_hint > 16, &random_, message); switch (mutation.mutation()) { case Mutation::None: @@ -514,7 +532,8 @@ void Mutator::MutateImpl(const Message& source, Message* message, DeleteField()(mutation.field()); return; case Mutation::Copy: { - DataSourceSampler source_sampler(mutation.field(), &random_, source); + DataSourceSampler source_sampler(mutation.field(), &random_, + size_increase_hint, source); if (source_sampler.IsEmpty()) break; CopyField()(source_sampler.field(), mutation.field()); return; diff --git a/src/mutator_test.cc b/src/mutator_test.cc index 1d754cf..522d7bc 100644 --- a/src/mutator_test.cc +++ b/src/mutator_test.cc @@ -726,7 +726,7 @@ class MutatorMessagesSizeTest : public TestWithParam<size_t> {}; static const size_t kMaxSizes[] = {100, 256, 777, 10101}; INSTANTIATE_TEST_SUITE_P(Proto, MutatorMessagesSizeTest, ValuesIn(kMaxSizes)); -TEST_P(MutatorMessagesSizeTest, MaxSize2) { +TEST_P(MutatorMessagesSizeTest, MaxSize) { TestMutator mutator(false); size_t over_sized_count = 0; Msg message; @@ -735,9 +735,9 @@ TEST_P(MutatorMessagesSizeTest, MaxSize2) { for (int i = 0; i < kIterations; ++i) { mutator.Mutate(&message, kMaxSize); if (message.ByteSizeLong() > kMaxSize) ++over_sized_count; - EXPECT_LT(message.ByteSizeLong(), 1.5 * kMaxSize); + EXPECT_LT(message.ByteSizeLong(), 1.1 * kMaxSize); } - EXPECT_LT(over_sized_count, kIterations * .2); + EXPECT_LT(over_sized_count, kIterations * .1); } // TODO(vitalybuka): Special tests for oneof. |