blob: 08a81f1d56919935018cf525e91e1bfe763b6e0d [file] [log] [blame]
// Copyright 2022 The Centipede Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "./centipede/runner_cmp_trace.h"
#include <cstdint>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace centipede {
namespace {
template <typename T>
std::vector<uint8_t> IntPairToByteVector(T a, T b) {
std::vector<uint8_t> res;
uint8_t buff[sizeof(T)];
memcpy(buff, &a, sizeof(T));
res.insert(res.begin(), buff, buff + sizeof(T));
memcpy(buff, &b, sizeof(T));
res.insert(res.begin(), buff, buff + sizeof(T));
return res;
}
std::vector<uint8_t> TwoArraysToByteVector(const uint8_t *a, const uint8_t *b,
size_t size) {
std::vector<uint8_t> res;
res.insert(res.begin(), a, a + size);
res.insert(res.begin(), b, b + size);
return res;
}
TEST(CmpTrace, T1) {
std::vector<std::vector<uint8_t>> observed_pairs;
auto callback = [&observed_pairs](uint8_t size, const uint8_t *v0,
const uint8_t *v1) {
std::vector<uint8_t> cmp_pair;
cmp_pair.insert(cmp_pair.begin(), v0, v0 + size);
cmp_pair.insert(cmp_pair.begin(), v1, v1 + size);
observed_pairs.push_back(cmp_pair);
};
CmpTrace<2, 10> trace2;
CmpTrace<4, 11> trace4;
CmpTrace<8, 12> trace8;
CmpTrace<0, 13> traceN;
trace2.Clear();
trace4.Clear();
trace8.Clear();
traceN.Clear();
uint16_t small_short_value0 = 10;
uint16_t small_short_value1 = 20;
uint16_t short_value0 = 310;
uint16_t short_value1 = 320;
uint32_t int_value0 = 500;
uint32_t int_value1 = 600;
uint64_t long_value0 = 1000;
uint64_t long_value1 = 2000;
uint64_t long_value2 = 4000;
uint64_t long_value3 = 8000;
trace2.Capture(small_short_value0, small_short_value1); // will be ignored.
trace2.Capture(short_value0, short_value1);
observed_pairs.clear();
trace2.ForEachNonZero(callback);
EXPECT_THAT(observed_pairs, testing::UnorderedElementsAre(IntPairToByteVector(
short_value0, short_value1)));
trace4.Capture(30, 40); // small values, will be ignored.
trace4.Capture(int_value0, int_value1);
observed_pairs.clear();
trace4.ForEachNonZero(callback);
EXPECT_THAT(observed_pairs, testing::UnorderedElementsAre(
IntPairToByteVector(int_value0, int_value1)));
trace8.Capture(200LL, 255LL); // small values, will be ignored.
trace8.Capture(long_value0, long_value1);
trace8.Capture(long_value2, long_value3);
observed_pairs.clear();
trace8.ForEachNonZero(callback);
EXPECT_THAT(observed_pairs,
testing::UnorderedElementsAre(
IntPairToByteVector(long_value0, long_value1),
IntPairToByteVector(long_value2, long_value3)));
constexpr uint8_t value0[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
constexpr uint8_t value1[10] = {0, 9, 8, 7, 6, 5, 4, 3, 2, 1};
constexpr uint8_t long_array[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
traceN.Capture(7, value0, value1);
traceN.Capture(3, value0, value1);
traceN.Capture(10, value0, value1);
traceN.Capture(20, long_array, long_array); // will be trimmed to 16.
observed_pairs.clear();
traceN.ForEachNonZero(callback);
EXPECT_THAT(observed_pairs,
testing::UnorderedElementsAre(
TwoArraysToByteVector(value0, value1, 10),
TwoArraysToByteVector(value0, value1, 7),
TwoArraysToByteVector(value0, value1, 3),
TwoArraysToByteVector(long_array, long_array, 16)));
}
} // namespace
} // namespace centipede