/* * Copyright (C) 2014 Pavel Kirienko */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include template static bool validateYaml(const T& obj, const std::string& reference) { uavcan::OStream::instance() << "Validating YAML:\n" << obj << "\n" << uavcan::OStream::endl; std::ostringstream os; os << obj; if (os.str() == reference) { return true; } else { std::cout << "INVALID YAML:\n" << "EXPECTED:\n" << "===\n" << reference << "\n===\n" << "ACTUAL:\n" << "\n===\n" << os.str() << "\n===\n" << std::endl; return false; } } TEST(Dsdl, Streaming) { EXPECT_TRUE(validateYaml(uavcan::protocol::GetNodeInfo::Response(), "status: \n" " uptime_sec: 0\n" " health: 0\n" " mode: 0\n" " sub_mode: 0\n" " vendor_specific_status_code: 0\n" "software_version: \n" " major: 0\n" " minor: 0\n" " optional_field_flags: 0\n" " vcs_commit: 0\n" " image_crc: 0\n" "hardware_version: \n" " major: 0\n" " minor: 0\n" " unique_id: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" " certificate_of_authenticity: \"\"\n" "name: \"\"")); root_ns_a::Deep ps; ps.a.resize(1); EXPECT_TRUE(validateYaml(ps, "c: 0\n" "str: \"\"\n" "a: \n" " - \n" " scalar: 0\n" " vector: \n" " - \n" " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" " - \n" " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" "b: \n" " - \n" " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" " - \n" " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]")); } template static bool encodeDecodeValidate(const T& obj, const std::string& reference_bit_string) { uavcan::StaticTransferBuffer<256> buf; { uavcan::BitStream bits(buf); uavcan::ScalarCodec codec(bits); /* * Coding */ if (0 > T::encode(obj, codec)) { std::cout << "Failed to encode" << std::endl; return false; } /* * Validating the encoded bitstream */ const std::string result = bits.toString(); if (result != reference_bit_string) { std::cout << "ENCODED VALUE DOESN'T MATCH THE REFERENCE:\nEXPECTED:\n" << reference_bit_string << "\nACTUAL:\n" << result << std::endl; return false; } } /* * Decoding back and comparing */ uavcan::BitStream bits(buf); uavcan::ScalarCodec codec(bits); T decoded; if (0 > T::decode(decoded, codec)) { std::cout << "Failed to decode" << std::endl; return false; } if (!decoded.isClose(obj)) { std::cout << "DECODED OBJECT DOESN'T MATCH THE REFERENCE:\nEXPECTED:\n" << obj << "\nACTUAL:\n" << decoded << std::endl; return false; } return true; } TEST(Dsdl, Union) { using root_ns_a::UnionTest; using root_ns_a::NestedInUnion; ASSERT_EQ(3, UnionTest::MinBitLen); ASSERT_EQ(16, UnionTest::MaxBitLen); ASSERT_EQ(13, NestedInUnion::MinBitLen); ASSERT_EQ(13, NestedInUnion::MaxBitLen); UnionTest s; EXPECT_TRUE(validateYaml(s, "z: ")); encodeDecodeValidate(s, "00000000"); s.to() = 16; EXPECT_TRUE(validateYaml(s, "a: 16")); EXPECT_TRUE(encodeDecodeValidate(s, "00110000")); s.to() = 31; EXPECT_TRUE(validateYaml(s, "b: 31")); EXPECT_TRUE(encodeDecodeValidate(s, "01011111")); s.to() = 256; EXPECT_TRUE(validateYaml(s, "c: 256")); EXPECT_TRUE(encodeDecodeValidate(s, "01100000 00000001")); s.to().push_back(true); s.to().push_back(false); s.to().push_back(true); s.to().push_back(true); s.to().push_back(false); s.to().push_back(false); s.to().push_back(true); s.to().push_back(true); s.to().push_back(true); ASSERT_EQ(9, s.to().size()); EXPECT_TRUE(validateYaml(s, "d: [1, 0, 1, 1, 0, 0, 1, 1, 1]")); EXPECT_TRUE(encodeDecodeValidate(s, "10010011 01100111")); s.to().array[0] = 0; s.to().array[1] = 1; s.to().array[2] = 2; s.to().array[3] = 3; EXPECT_TRUE(validateYaml(s, "e: \n array: [0, 1, 2, 3]")); EXPECT_TRUE(encodeDecodeValidate(s, "10100000 11011000")); } TEST(Dsdl, ParamGetSetRequestUnion) { uavcan::protocol::param::GetSet::Request req; req.index = 8191; req.name = "123"; // 49, 50, 51 // 00110001, 00110010, 00110011 EXPECT_TRUE(encodeDecodeValidate(req, "11111111 11111000 00110001 00110010 00110011")); req.value.to() = "abc"; // 01100001, 01100010, 01100011 EXPECT_TRUE(encodeDecodeValidate(req, "11111111 11111100 " // Index, Union tag "00000011 " // Array length "01100001 01100010 01100011 " // Payload "00110001 00110010 00110011")); // Name EXPECT_TRUE(validateYaml(req, "index: 8191\n" "value: \n" " string_value: \"abc\"\n" "name: \"123\"")); req.value.to() = 1; EXPECT_TRUE(encodeDecodeValidate(req, "11111111 11111001 " // Index, Union tag "00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 " // Payload "00110001 00110010 00110011")); // Name } TEST(Dsdl, ParamGetSetResponseUnion) { uavcan::protocol::param::GetSet::Response res; res.value.to() = "abc"; res.default_value.to(); // Empty res.name = "123"; EXPECT_TRUE(encodeDecodeValidate(res, "00000100 " // Value union tag "00000011 " // Value array length "01100001 01100010 01100011 " // Value array payload "00000100 " // Default union tag "00000000 " // Default array length "00000000 " // Max value tag "00000000 " // Min value tag "00110001 00110010 00110011")); // Name res.value.to() = true; res.default_value.to(); // False res.name = "123"; EXPECT_TRUE(encodeDecodeValidate(res, "00000011 " // Value union tag "00000001 " // Value "00000011 " // Default union tag "00000000 " // Default value "00000000 " // Max value tag "00000000 " // Min value tag "00110001 00110010 00110011")); // Name }