Skip to content

Commit

Permalink
Add unit tests to test generated code. SAP and SessionSetupReq
Browse files Browse the repository at this point in the history
Signed-off-by: Siebren Weertman <[email protected]>
  • Loading branch information
Siebren Weertman committed Feb 14, 2024
1 parent b64f296 commit 691a78d
Show file tree
Hide file tree
Showing 6 changed files with 392 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ schemas
venv
*~
test/*
tests/build/
45 changes: 45 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.14)

project(cbexigen VERSION 1)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(GTest)

add_subdirectory(cbv2g)

file(GLOB_RECURSE CBV2G_TEST_SOURCES
./unit/sap/*.cpp
./unit/iso20/common/*.cpp
./unit/iso2/*.cpp
)

add_executable(test-${PROJECT_NAME}
${CBV2G_TEST_SOURCES}
)

target_compile_options(test-${PROJECT_NAME} PRIVATE -Wall -Werror -Wshadow)

target_include_directories(test-${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)

target_link_libraries(test-${PROJECT_NAME}
PRIVATE
gtest
gtest_main
gmock
pthread
cbv2g
)

include(GoogleTest)
gtest_discover_tests(test-${PROJECT_NAME}
TEST_PREFIX ${PROJECT_NAME}
TEST_LIST ${PROJECT_NAME}Tests
)

set_tests_properties(${${PROJECT_NAME}Tests} PROPERTIES TIMEOUT 10)
32 changes: 32 additions & 0 deletions tests/cbv2g/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.18)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

set(CBV2G_SOURCE_PATH "../../src/output/c")

file(GLOB_RECURSE CBV2G_SOURCES
${CBV2G_SOURCE_PATH}/common/*.c
${CBV2G_SOURCE_PATH}/appHandshake/*.c
${CBV2G_SOURCE_PATH}/din/*.c
${CBV2G_SOURCE_PATH}/iso-2/*.c
${CBV2G_SOURCE_PATH}/iso-20/*.c
${CBV2G_SOURCE_PATH}/v2gtp/*.c
)

add_library(cbv2g STATIC
${CBV2G_SOURCES}
)

target_compile_options(cbv2g PRIVATE -Werror -Wall -Wextra)

target_include_directories(cbv2g
PUBLIC
${CBV2G_SOURCE_PATH}/
${CBV2G_SOURCE_PATH}/appHandshake
${CBV2G_SOURCE_PATH}/common
${CBV2G_SOURCE_PATH}/din
${CBV2G_SOURCE_PATH}/iso-2
${CBV2G_SOURCE_PATH}/iso-20
${CBV2G_SOURCE_PATH}/v2gtp
)
70 changes: 70 additions & 0 deletions tests/unit/iso20/common/test_sessionSetup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <exi_v2gtp.h>
#include <iso20_CommonMessages_Decoder.h>
#include <iso20_CommonMessages_Encoder.h>

#include "../test_header_utils.hpp"

class Test_SessionSetup : public testing::Test {
protected:
uint8_t data[256] = {0};

Check notice on line 12 in tests/unit/iso20/common/test_sessionSetup.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tests/unit/iso20/common/test_sessionSetup.cpp#L12

class member 'Test_SessionSetup::data' is never used.
exi_bitstream_t stream;
};

/** \param xml_input (that was used to generate the EXI binary using EXIficient)
* <?xml version="1.0" encoding="UTF-8"?>
* <ns0:SessionSetupReq xmlns:ns0="urn:iso:std:iso:15118:-20:CommonMessages">
* <ns1:Header xmlns:ns1="urn:iso:std:iso:15118:-20:CommonTypes">
* <ns1:SessionID>3030303030303030</ns1:SessionID>
* <ns1:TimeStamp>1707896956850052</ns1:TimeStamp>
* </ns1:Header>
* <ns0:EVCCID>PIXV12345678901231</ns0:EVCCID>
* </ns0:SessionSetupReq>
*/
TEST_F(Test_SessionSetup, WhenEncodingKnownSessionSetupRequest_ThenResultMatchesExpected) {
static constexpr uint8_t expected[] =
"\x01\xFE\x80\x02\x00\x00\x00\x28" //<- header
"\x80\x8c\x04\x18\x18\x18\x18\x18\x18\x18\x18\x08\x49\xfb\x4f\xba\xba\xa8\x40\x32\x0a\x28\x24\xac\x2b\x18\x99"
"\x19\x9a\x1a\x9b\x1b\x9c\x1c\x98\x18\x99\x19\x98\x80";
static constexpr size_t streamLen = 0x28;
exi_bitstream_init(&stream, data, sizeof(data), 8, NULL);
iso20_exiDocument exiDoc = {};
exiDoc.SessionSetupReq_isUsed = 1;
uint8_t sessionID[] = "\x30\x30\x30\x30\x30\x30\x30\x30";
setHeader(exiDoc.SessionSetupReq.Header, sessionID, 1707896956850052);
setString(exiDoc.SessionSetupReq.EVCCID, "PIXV12345678901231");

int res = encode_iso20_exiDocument(&stream, &exiDoc);
size_t len = exi_bitstream_get_length(&stream);
V2GTP20_WriteHeader(&data[0], len, V2GTP20_MAINSTREAM_PAYLOAD_ID);

ASSERT_EQ(res, 0);
ASSERT_EQ(len, streamLen);
ASSERT_EQ(memcmp(data, expected, sizeof(expected) - 1), 0)
<< std::string("\\x") << toHexStr(data, data + sizeof(expected) - 1, "\\x") << '\n'
<< std::string("\\x") << toHexStr(&expected[0], &expected[0] + sizeof(expected) - 1, "\\x");
}

TEST_F(Test_SessionSetup, WhenDecodingKnownSessionSetupRequest_ThenResultMatchesExpected) {
uint8_t input[] =
"\x01\xFE\x80\x02\x00\x00\x00\x28" //<- header
"\x80\x8c\x04\x18\x18\x18\x18\x18\x18\x18\x18\x08\x49\xfb\x4f\xba\xba\xa8\x40\x32\x0a\x28\x24\xac\x2b\x18\x99"
"\x19\x9a\x1a\x9b\x1b\x9c\x1c\x98\x18\x99\x19\x98\x80";
iso20_exiDocument exiDoc = {};
exi_bitstream_init(&stream, &input[0], sizeof(input), 8, NULL);
uint32_t len = 0;

int res = V2GTP20_ReadHeader(&input[0], &len, V2GTP20_MAINSTREAM_PAYLOAD_ID);
ASSERT_EQ(res, 0);
res = decode_iso20_exiDocument(&stream, &exiDoc);
ASSERT_EQ(res, 0);

static constexpr size_t streamLen = 0x28;
ASSERT_EQ(len, streamLen);
ASSERT_EQ((int)exiDoc.SessionSetupReq_isUsed, 1);
static const uint8_t sessionID[] = "\x30\x30\x30\x30\x30\x30\x30\x30";
ASSERT_ISO20_HEADER_EQ(exiDoc.SessionSetupReq.Header, sessionID, 1707896956850052);
ASSERT_ISO20_STREQ(exiDoc.SessionSetupReq.EVCCID, "PIXV12345678901231");
}
68 changes: 68 additions & 0 deletions tests/unit/iso20/test_header_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <gtest/gtest.h>
#include <iomanip>
#include <optional>
#include <span>
#include <string>

template <typename HeaderT, size_t Len>
inline void setHeader(HeaderT& header, const uint8_t (&sessionID)[Len], uint64_t timeStamp,
const std::optional<decltype(header.Signature)>& signature = std::nullopt) {
static_assert(Len >= 8, "SessionID must be size 8. Larger is allowed for string literal \\0 term");
header.SessionID.bytesLen = 8;
std::copy(&sessionID[0], &sessionID[0] + 8, header.SessionID.bytes);
header.TimeStamp = timeStamp;
header.Signature_isUsed = false;
if (signature) {
throw std::runtime_error("not supported yet");
}
}
template <typename HeaderT>
inline bool assertHeader(const HeaderT& header, const uint8_t* sessionID, uint64_t timeStamp) {
bool success = false;
[&]() {
ASSERT_EQ(header.SessionID.bytesLen, 8);
ASSERT_EQ(memcmp(header.SessionID.bytes, &sessionID[0], 8), 0);
ASSERT_EQ((int)header.Signature_isUsed, 0);
ASSERT_EQ(header.TimeStamp, timeStamp);
success = true;
}();
return success;
}
#define ASSERT_ISO20_HEADER_EQ(...) \
do { /* NOLINT */ \
if (!assertHeader(__VA_ARGS__)) { \
return; \
} \
} while (0) /* NOLINT */
#define ASSERT_ISO20_STREQ(str, sv) \
do { /* NOLINT */ \
std::string_view svv = sv; \
ASSERT_EQ((str).charactersLen, svv.size()); \
ASSERT_EQ((str).characters, svv); \
} while (0) /* NOLINT */

template <typename StrT>
inline void setString(StrT& out, std::string_view in) {
out.charactersLen = in.size();
std::copy(in.begin(), in.end(), out.characters);
}

template <typename StrT>
inline void setBytes(StrT& out, std::span<uint8_t> in) {
out.bytesLen = in.size();
std::copy(in.begin(), in.end(), out.bytes);
}

template <typename It>
std::string toHexStr(It begin, It end, std::string_view delimit = "\\x") {
std::stringstream ss;
auto it = begin;
for (; it != end; ++it) {
ss << delimit << std::setfill('0') << std::setw(2) << std::hex << (uint16_t)*it;
}
return std::move(ss).str();
}
Loading

0 comments on commit 691a78d

Please sign in to comment.