aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2020-01-25 22:33:05 -0800
committerVitaly Buka <vitalybuka@gmail.com>2020-01-29 11:36:29 -0800
commit5cd166ec45f1ef3d181a5addb37a81288b56ec7c (patch)
tree86f7578fddf3bb228ba64078ffd5b7aa0da77cec
parent40b4d89e7e679839e5d4fe6fc892e6d0efc18167 (diff)
downloadlibprotobuf-mutator-5cd166ec45f1ef3d181a5addb37a81288b56ec7c.tar.gz
Use size_increase_hint selecting copy source
-rw-r--r--src/mutator.cc37
-rw-r--r--src/mutator_test.cc6
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.