Skip to content

Commit

Permalink
Add alignment tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Mi-La committed Nov 25, 2024
1 parent 8fa0dcd commit d714272
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 0 deletions.
1 change: 1 addition & 0 deletions extension/freemarker/Choice.cpp.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<#include "CompoundParameter.inc.ftl">
<@file_header generatorDescription/>

#include <zserio/BitPositionUtil.h>
#include <zserio/ChoiceCaseException.h>
#include <zserio/CppRuntimeException.h>
#include <zserio/HashCodeUtil.h>
Expand Down
1 change: 1 addition & 0 deletions extension/freemarker/Structure.cpp.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<#include "Structure.inc.ftl">
<@file_header generatorDescription/>

#include <zserio/BitPositionUtil.h>
#include <zserio/BitStreamReader.h>
#include <zserio/BitStreamWriter.h>
#include <zserio/HashCodeUtil.h>
Expand Down
1 change: 1 addition & 0 deletions extension/freemarker/Union.cpp.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<#include "CompoundParameter.inc.ftl">
<@file_header generatorDescription/>

#include <zserio/BitPositionUtil.h>
#include <zserio/CppRuntimeException.h>
#include <zserio/HashCodeUtil.h>
#include <zserio/SizeConvertUtil.h>
Expand Down
26 changes: 26 additions & 0 deletions test/language/alignment/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
add_library(alignment_zs STATIC ${TEST_ZS_ROOT}/alignment.zs)
zserio_generate_cpp(
TARGET alignment_zs
SRC_DIR ${TEST_ZS_ROOT}
GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen
EXTRA_ARGS ${ZSERIO_EXTRA_ARGS}
GENERATED_SOURCES_VAR GENERATED_SOURCES
OUTPUT_VAR ZSERIO_LOG
ERROR_VAR ZSERIO_LOG
)
target_link_libraries(alignment_zs PUBLIC ZserioCpp17Runtime)
if (ZSERIO_LOG)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/zserio_log.txt "${ZSERIO_LOG}")
check_zserio_warnings("${ZSERIO_LOG}" 0)
endif ()

add_custom_test(alignment
DEPENDS
alignment_zs
SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/cpp/AutoOptionalMemberAlignmentTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cpp/BitAlignmentTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cpp/OptionalMemberAlignmentTest.cpp
GENERATED_SOURCES
${GENERATED_SOURCES}
)
1 change: 1 addition & 0 deletions test/language/alignment/ClangTidySuppressions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
readability-simplify-boolean-expr:gen/alignment/optional_member_alignment/OptionalMemberAlignment.cpp
106 changes: 106 additions & 0 deletions test/language/alignment/cpp/AutoOptionalMemberAlignmentTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "alignment/auto_optional_member_alignment/AutoOptionalMemberAlignment.h"
#include "gtest/gtest.h"
#include "test_utils/TestUtility.h"

namespace alignment
{
namespace auto_optional_member_alignment
{

class AutoOptionalMemberAlignmentTest : public ::testing::Test
{
protected:
static void writeData(
zserio::BitStreamWriter& writer, bool hasAutoOptional, int32_t autoOptionalField, int32_t field)
{
writer.writeBool(hasAutoOptional);

if (hasAutoOptional)
{
writer.writeUnsignedBits32(0, 31);
writer.writeSignedBits32(autoOptionalField, 32);
}

writer.writeSignedBits32(field, 32);
}

static void fillData(
AutoOptionalMemberAlignment& data, bool hasAutoOptional, int32_t autoOptionalField, int32_t field)
{
if (hasAutoOptional)
{
data.autoOptionalField = autoOptionalField;
}
data.field = field;
}

static constexpr size_t WITH_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE = 96;
static constexpr size_t WITHOUT_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE = 33;
};

TEST_F(AutoOptionalMemberAlignmentTest, readWithOptional)
{
const bool hasAutoOptional = true;
const int32_t autoOptionalField = 0x1234;
const int32_t field = 0x7654;
AutoOptionalMemberAlignment data;
fillData(data, hasAutoOptional, autoOptionalField, field);

test_utils::readTest(
std::bind(writeData, std::placeholders::_1, hasAutoOptional, autoOptionalField, field), data);
}

TEST_F(AutoOptionalMemberAlignmentTest, readWithoutOptional)
{
const bool hasAutoOptional = false;
const int32_t autoOptionalField = 0;
const int32_t field = 0x2222;
AutoOptionalMemberAlignment data;
fillData(data, hasAutoOptional, autoOptionalField, field);

test_utils::readTest(
std::bind(writeData, std::placeholders::_1, hasAutoOptional, autoOptionalField, field), data);
}

TEST_F(AutoOptionalMemberAlignmentTest, bitSizeOfWithOptional)
{
AutoOptionalMemberAlignment data;
fillData(data, true, 0x4433, 0x1122);
zserio::View<AutoOptionalMemberAlignment> view(data);

ASSERT_EQ(WITH_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE, zserio::detail::bitSizeOf(view));
}

TEST_F(AutoOptionalMemberAlignmentTest, bitSizeOfWithoutOptional)
{
AutoOptionalMemberAlignment data;
fillData(data, false, 0, 0x7624);
zserio::View<AutoOptionalMemberAlignment> view(data);

ASSERT_EQ(WITHOUT_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE, zserio::detail::bitSizeOf(view));
}

TEST_F(AutoOptionalMemberAlignmentTest, writeWithOptional)
{
const bool hasAutoOptional = true;
const int32_t autoOptionalField = 0x9ADB;
const int32_t field = 0x8ACD;
AutoOptionalMemberAlignment data;
fillData(data, hasAutoOptional, autoOptionalField, field);

test_utils::writeReadTest(data);
}

TEST_F(AutoOptionalMemberAlignmentTest, writeWithoutOptional)
{
const bool hasAutoOptional = true;
const int32_t autoOptionalField = 0;
const int32_t field = 0x7ACF;
AutoOptionalMemberAlignment data;
fillData(data, hasAutoOptional, autoOptionalField, field);

test_utils::writeReadTest(data);
}

} // namespace auto_optional_member_alignment
} // namespace alignment
131 changes: 131 additions & 0 deletions test/language/alignment/cpp/BitAlignmentTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "alignment/bit_alignment/BitAlignment.h"
#include "gtest/gtest.h"
#include "test_utils/TestUtility.h"
namespace alignment
{
namespace bit_alignment
{

class BitAlignmentTest : public ::testing::Test
{
protected:
static void writeData(zserio::BitStreamWriter& writer)
{
writer.writeUnsignedBits32(ALIGNED1_FIELD_VALUE, 1);

writer.writeUnsignedBits32(0, 1);
writer.writeUnsignedBits32(ALIGNED2_FIELD_VALUE, 2);

writer.writeUnsignedBits32(0, 2);
writer.writeUnsignedBits32(ALIGNED3_FIELD_VALUE, 3);

writer.writeUnsignedBits32(0, 3);
writer.writeUnsignedBits32(ALIGNED4_FIELD_VALUE, 4);

writer.writeUnsignedBits32(0, 4);
writer.writeUnsignedBits32(ALIGNED5_FIELD_VALUE, 5);

writer.writeUnsignedBits32(0, 5);
writer.writeUnsignedBits32(ALIGNED6_FIELD_VALUE, 6);

writer.writeUnsignedBits32(0, 6);
writer.writeUnsignedBits32(ALIGNED7_FIELD_VALUE, 7);

writer.writeUnsignedBits32(0, 7);
writer.writeUnsignedBits32(ALIGNED8_FIELD_VALUE, 8);

writer.writeUnsignedBits32(0, 1);
writer.writeUnsignedBits32(0, 15);
writer.writeUnsignedBits32(ALIGNED16_FIELD_VALUE, 16);

writer.writeUnsignedBits32(0, 1);
writer.writeUnsignedBits32(0, 31);
writer.writeUnsignedBits32(ALIGNED32_FIELD_VALUE, 32);

writer.writeUnsignedBits64(0, 33);
writer.writeUnsignedBits64(0, 63);
writer.writeUnsignedBits64(ALIGNED64_FIELD_VALUE, 64);
}

static void fillData(BitAlignment& data)
{
data.aligned1Field = ALIGNED1_FIELD_VALUE;
data.aligned2Field = ALIGNED2_FIELD_VALUE;
data.aligned3Field = ALIGNED3_FIELD_VALUE;
data.aligned4Field = ALIGNED4_FIELD_VALUE;
data.aligned5Field = ALIGNED5_FIELD_VALUE;
data.aligned6Field = ALIGNED6_FIELD_VALUE;
data.aligned7Field = ALIGNED7_FIELD_VALUE;
data.aligned8Field = ALIGNED8_FIELD_VALUE;
data.alignment16Break = ALIGNMENT16_BREAK;
data.aligned16Field = ALIGNED16_FIELD_VALUE;
data.alignment32Break = ALIGNMENT32_BREAK;
data.aligned32Field = ALIGNED32_FIELD_VALUE;
data.alignment64Break = ALIGNMENT64_BREAK;
data.aligned64Field = ALIGNED64_FIELD_VALUE;
}

// constants
static constexpr size_t BIT_ALIGNMENT_BIT_SIZE = 320;

static constexpr uint8_t ALIGNED1_FIELD_VALUE = 1;
static constexpr uint8_t ALIGNED2_FIELD_VALUE = 2;
static constexpr uint8_t ALIGNED3_FIELD_VALUE = 5;
static constexpr uint8_t ALIGNED4_FIELD_VALUE = 13;
static constexpr uint8_t ALIGNED5_FIELD_VALUE = 26;
static constexpr uint8_t ALIGNED6_FIELD_VALUE = 56;
static constexpr uint8_t ALIGNED7_FIELD_VALUE = 88;
static constexpr uint8_t ALIGNED8_FIELD_VALUE = 222;
static constexpr uint8_t ALIGNMENT16_BREAK = 0;
static constexpr uint16_t ALIGNED16_FIELD_VALUE = 0xcafe;
static constexpr uint8_t ALIGNMENT32_BREAK = 0;
static constexpr uint32_t ALIGNED32_FIELD_VALUE = 0xcafec0de;
static constexpr uint64_t ALIGNMENT64_BREAK = UINT64_C(0);
static constexpr uint64_t ALIGNED64_FIELD_VALUE = UINT64_C(0xcafec0dedeadface);
};

TEST_F(BitAlignmentTest, read)
{
BitAlignment data;
fillData(data);

test_utils::readTest(writeData, data);
}

TEST_F(BitAlignmentTest, bitSizeOf)
{
BitAlignment data;
fillData(data);
zserio::View<BitAlignment> view(data);

// test default argument
ASSERT_EQ(BIT_ALIGNMENT_BIT_SIZE, zserio::detail::bitSizeOf(view));
}

TEST_F(BitAlignmentTest, bitSizeOfWithPosition)
{
BitAlignment data;
fillData(data);
zserio::View<BitAlignment> view(data);

// starting up to bit position 77, the structure still fits into original size thanks to alignments
zserio::BitSize startBitPosition = 0;
for (; startBitPosition < 78; ++startBitPosition)
{
ASSERT_EQ(BIT_ALIGNMENT_BIT_SIZE - startBitPosition, zserio::detail::bitSizeOf(view, startBitPosition));
}
// starting at bit position 78, also next 64bits are needed
ASSERT_EQ(
BIT_ALIGNMENT_BIT_SIZE - startBitPosition + 64, zserio::detail::bitSizeOf(view, startBitPosition));
}

TEST_F(BitAlignmentTest, writeRead)
{
BitAlignment data;
fillData(data);

test_utils::writeReadTest(data);
}

} // namespace bit_alignment
} // namespace alignment
104 changes: 104 additions & 0 deletions test/language/alignment/cpp/OptionalMemberAlignmentTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "alignment/optional_member_alignment/OptionalMemberAlignment.h"
#include "gtest/gtest.h"
#include "test_utils/TestUtility.h"

namespace alignment
{
namespace optional_member_alignment
{

class OptionalMemberAlignmentTest : public ::testing::Test
{
protected:
static void writeData(
zserio::BitStreamWriter& writer, bool hasOptional, int32_t optionalField, int32_t field)
{
writer.writeBool(hasOptional);

if (hasOptional)
{
writer.writeUnsignedBits32(0, 31);
writer.writeSignedBits32(optionalField, 32);
}

writer.writeSignedBits32(field, 32);
}

static void fillData(OptionalMemberAlignment& data, bool hasOptional, int32_t optionalField, int32_t field)
{
data.hasOptional = hasOptional;
if (hasOptional)
{
data.optionalField = optionalField;
}
data.field = field;
}

static constexpr size_t WITH_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE = 96;
static constexpr size_t WITHOUT_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE = 33;
};

TEST_F(OptionalMemberAlignmentTest, readWithOptional)
{
const bool hasOptional = true;
const int32_t optionalField = 0x1234;
const int32_t field = 0x7654;
OptionalMemberAlignment data;
fillData(data, hasOptional, optionalField, field);

test_utils::readTest(std::bind(writeData, std::placeholders::_1, hasOptional, optionalField, field), data);
}

TEST_F(OptionalMemberAlignmentTest, readWithoutOptional)
{
const bool hasOptional = false;
const int32_t optionalField = 0;
const int32_t field = 0x2222;
OptionalMemberAlignment data;
fillData(data, hasOptional, optionalField, field);

test_utils::readTest(std::bind(writeData, std::placeholders::_1, hasOptional, optionalField, field), data);
}

TEST_F(OptionalMemberAlignmentTest, bitSizeOfWithOptional)
{
OptionalMemberAlignment data;
fillData(data, true, 0x4433, 0x1122);
zserio::View<OptionalMemberAlignment> view(data);

ASSERT_EQ(WITH_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE, zserio::detail::bitSizeOf(view));
}

TEST_F(OptionalMemberAlignmentTest, bitSizeOfWithoutOptional)
{
OptionalMemberAlignment data;
fillData(data, false, 0, 0x7624);
zserio::View<OptionalMemberAlignment> view(data);

ASSERT_EQ(WITHOUT_OPTIONAL_MEMBER_ALIGNMENT_BIT_SIZE, zserio::detail::bitSizeOf(view));
}

TEST_F(OptionalMemberAlignmentTest, writeReadWithOptional)
{
const bool hasOptional = true;
const int32_t optionalField = 0x9ADB;
const int32_t field = 0x8ACD;
OptionalMemberAlignment data;
fillData(data, hasOptional, optionalField, field);

test_utils::writeReadTest(data);
}

TEST_F(OptionalMemberAlignmentTest, writeReadWithoutOptional)
{
const bool hasOptional = true;
const int32_t optionalField = 0;
const int32_t field = 0x7ACF;
OptionalMemberAlignment data;
fillData(data, hasOptional, optionalField, field);

test_utils::writeReadTest(data);
}

} // namespace optional_member_alignment
} // namespace alignment

0 comments on commit d714272

Please sign in to comment.