mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
test: improve tr_bitfield and tr_block_info coverage (#2226)
* test: improve coverage in tr_bitfield::raw() * test: improve coverage in tr_bitfield::count() * test: improve coverage for edge cases in tr_bitfield::setSpan() * test: confirm that excess bits in setRaw() are set to zero * fix: edge case of tr_block_info::initBlocks() where piece_size is 0 this should not happen in production, but cover it anyway
This commit is contained in:
@@ -359,6 +359,13 @@ void tr_bitfield::set(size_t nth, bool value)
|
|||||||
/* Sets bit range [begin, end) to 1 */
|
/* Sets bit range [begin, end) to 1 */
|
||||||
void tr_bitfield::setSpan(size_t begin, size_t end, bool value)
|
void tr_bitfield::setSpan(size_t begin, size_t end, bool value)
|
||||||
{
|
{
|
||||||
|
// bounds check
|
||||||
|
end = std::min(end, bit_count_);
|
||||||
|
if (end == 0 || begin >= end)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// did anything change?
|
// did anything change?
|
||||||
size_t const old_count = count(begin, end);
|
size_t const old_count = count(begin, end);
|
||||||
size_t const new_count = value ? (end - begin) : 0;
|
size_t const new_count = value ? (end - begin) : 0;
|
||||||
@@ -367,13 +374,7 @@ void tr_bitfield::setSpan(size_t begin, size_t end, bool value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bounds check
|
|
||||||
--end;
|
--end;
|
||||||
if (end >= bit_count_ || begin > end)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ensureNthBitAlloced(end))
|
if (!ensureNthBitAlloced(end))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ void tr_block_info::initSizes(uint64_t total_size_in, uint64_t piece_size_in)
|
|||||||
|
|
||||||
if (piece_size == 0 || block_size == 0)
|
if (piece_size == 0 || block_size == 0)
|
||||||
{
|
{
|
||||||
|
*this = {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
#include "crypto-utils.h"
|
#include "crypto-utils.h"
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
TEST(Bitfield, countRange)
|
TEST(Bitfield, count)
|
||||||
{
|
{
|
||||||
auto constexpr IterCount = int{ 10000 };
|
auto constexpr IterCount = int{ 10000 };
|
||||||
|
|
||||||
@@ -59,6 +62,18 @@ TEST(Bitfield, countRange)
|
|||||||
auto const count2 = bf.count(begin, end);
|
auto const count2 = bf.count(begin, end);
|
||||||
EXPECT_EQ(count1, count2);
|
EXPECT_EQ(count1, count2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto bf = tr_bitfield{ 0 };
|
||||||
|
EXPECT_EQ(0, bf.count(0, 0));
|
||||||
|
EXPECT_EQ(0, bf.count(0, 1));
|
||||||
|
|
||||||
|
bf = tr_bitfield{ 100 };
|
||||||
|
EXPECT_EQ(0, bf.count(0, 0));
|
||||||
|
EXPECT_EQ(0, bf.count(0, 100));
|
||||||
|
bf.setHasAll();
|
||||||
|
EXPECT_EQ(0, bf.count(0, 0));
|
||||||
|
EXPECT_EQ(1, bf.count(0, 1));
|
||||||
|
EXPECT_EQ(100, bf.count(0, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Bitfield, ctorFromFlagArray)
|
TEST(Bitfield, ctorFromFlagArray)
|
||||||
@@ -96,7 +111,7 @@ TEST(Bitfield, setRaw)
|
|||||||
auto constexpr TestByte = uint8_t{ 10 };
|
auto constexpr TestByte = uint8_t{ 10 };
|
||||||
auto constexpr TestByteTrueBits = 2;
|
auto constexpr TestByteTrueBits = 2;
|
||||||
|
|
||||||
auto const raw = std::vector<uint8_t>(100, TestByte);
|
auto raw = std::vector<uint8_t>(100, TestByte);
|
||||||
|
|
||||||
auto bf = tr_bitfield(std::size(raw) * 8);
|
auto bf = tr_bitfield(std::size(raw) * 8);
|
||||||
bf.setRaw(std::data(raw), std::size(raw));
|
bf.setRaw(std::data(raw), std::size(raw));
|
||||||
@@ -115,6 +130,24 @@ TEST(Bitfield, setRaw)
|
|||||||
}
|
}
|
||||||
EXPECT_EQ(TestByte, test);
|
EXPECT_EQ(TestByte, test);
|
||||||
EXPECT_EQ(raw, bf.raw());
|
EXPECT_EQ(raw, bf.raw());
|
||||||
|
|
||||||
|
// check that has-all bitfield gets all-true
|
||||||
|
bf = tr_bitfield(std::size(raw) * 8);
|
||||||
|
bf.setHasAll();
|
||||||
|
raw = bf.raw();
|
||||||
|
EXPECT_EQ(std::size(bf) / 8, std::size(raw));
|
||||||
|
EXPECT_EQ(std::numeric_limits<unsigned char>::max(), raw[0]);
|
||||||
|
|
||||||
|
// check that the spare bits t the end are zero
|
||||||
|
bf = tr_bitfield{ 1 };
|
||||||
|
uint8_t by = ~uint8_t{};
|
||||||
|
bf.setRaw(&by, 1);
|
||||||
|
EXPECT_TRUE(bf.hasAll());
|
||||||
|
EXPECT_FALSE(bf.hasNone());
|
||||||
|
EXPECT_EQ(1, bf.count());
|
||||||
|
raw = bf.raw();
|
||||||
|
EXPECT_EQ(1, std::size(raw));
|
||||||
|
EXPECT_EQ(1 << 7, raw[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Bitfield, bitfields)
|
TEST(Bitfield, bitfields)
|
||||||
@@ -211,6 +244,32 @@ TEST(Bitfield, bitfields)
|
|||||||
{
|
{
|
||||||
EXPECT_EQ(field.test(i), (4 <= i && i < 5));
|
EXPECT_EQ(field.test(i), (4 <= i && i < 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* test tr_bitfield::setSpan when end runs beyond the end of the bitfield */
|
||||||
|
field.setHasNone();
|
||||||
|
field.setSpan(100, 1000);
|
||||||
|
EXPECT_FALSE(field.hasNone());
|
||||||
|
EXPECT_FALSE(field.hasAll());
|
||||||
|
EXPECT_EQ(std::size(field) - 100, field.count());
|
||||||
|
|
||||||
|
/* test tr_bitfield::unsetSpan when it changes nothing */
|
||||||
|
field.setHasNone();
|
||||||
|
field.unsetSpan(0, 100);
|
||||||
|
EXPECT_TRUE(field.hasNone());
|
||||||
|
EXPECT_FALSE(field.hasAll());
|
||||||
|
EXPECT_EQ(0, field.count());
|
||||||
|
|
||||||
|
/* test tr_bitfield::setSpan when it changes nothing */
|
||||||
|
field.setHasAll();
|
||||||
|
field.setSpan(0, 100);
|
||||||
|
EXPECT_FALSE(field.hasNone());
|
||||||
|
EXPECT_TRUE(field.hasAll());
|
||||||
|
EXPECT_EQ(std::size(field), field.count());
|
||||||
|
|
||||||
|
/* test tr_bitfield::setSpan with an invalid span doesn't crash */
|
||||||
|
field.setHasAll();
|
||||||
|
field.setSpan(0, 0);
|
||||||
|
EXPECT_TRUE(field.hasAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Bitfield, hasAllNone)
|
TEST(Bitfield, hasAllNone)
|
||||||
|
|||||||
@@ -35,6 +35,16 @@ TEST_F(BlockInfoTest, fieldsAreSet)
|
|||||||
EXPECT_EQ(PieceSize, info.final_piece_size);
|
EXPECT_EQ(PieceSize, info.final_piece_size);
|
||||||
EXPECT_EQ(PieceSize, info.piece_size);
|
EXPECT_EQ(PieceSize, info.piece_size);
|
||||||
EXPECT_EQ(TotalSize, info.total_size);
|
EXPECT_EQ(TotalSize, info.total_size);
|
||||||
|
|
||||||
|
info.initSizes(0, 0);
|
||||||
|
EXPECT_EQ(0, info.block_size);
|
||||||
|
EXPECT_EQ(0, info.final_block_size);
|
||||||
|
EXPECT_EQ(0, info.n_blocks_in_final_piece);
|
||||||
|
EXPECT_EQ(0, info.n_blocks_in_piece);
|
||||||
|
EXPECT_EQ(0, info.n_pieces);
|
||||||
|
EXPECT_EQ(0, info.final_piece_size);
|
||||||
|
EXPECT_EQ(0, info.piece_size);
|
||||||
|
EXPECT_EQ(0, info.total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlockInfoTest, handlesOddSize)
|
TEST_F(BlockInfoTest, handlesOddSize)
|
||||||
@@ -147,4 +157,9 @@ TEST_F(BlockInfoTest, blockSpanForPiece)
|
|||||||
EXPECT_EQ(16, info.blockSpanForPiece(3).end);
|
EXPECT_EQ(16, info.blockSpanForPiece(3).end);
|
||||||
EXPECT_EQ(16, info.blockSpanForPiece(4).begin);
|
EXPECT_EQ(16, info.blockSpanForPiece(4).begin);
|
||||||
EXPECT_EQ(17, info.blockSpanForPiece(4).end);
|
EXPECT_EQ(17, info.blockSpanForPiece(4).end);
|
||||||
|
|
||||||
|
// test that uninitialized block_info returns an invalid span
|
||||||
|
info = tr_block_info{};
|
||||||
|
EXPECT_EQ(0, info.blockSpanForPiece(0).begin);
|
||||||
|
EXPECT_EQ(0, info.blockSpanForPiece(0).end);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user