/* * Copyright (c) 2021-2022 Cisco and/or its affiliates. * 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: * * http://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 #include #include #include #include #include #include namespace transport { namespace core { namespace { // The fixture for testing class Foo. class InterestTest : public ::testing::Test { protected: InterestTest() : name_("b001::123|321"), interest_(HICN_PACKET_FORMAT_IPV6_TCP) { // You can do set-up work for each test here. } virtual ~InterestTest() { // You can do clean-up work that doesn't throw exceptions here. } // If the constructor and destructor are not enough for setting up // and cleaning up each test, you can define the following methods: virtual void SetUp() { // Code here will be called immediately after the constructor (right // before each test). } virtual void TearDown() { // Code here will be called immediately after each test (right // before the destructor). } Name name_; Interest interest_; std::vector buffer_ = {// IPv6 src=b001::ab:cdab:cdef, dst=b002::ca IPV6_HEADER(TCP_PROTO, 20 + PAYLOAD_SIZE), // ICMP6 echo request TCP_HEADER(0x00), // Payload PAYLOAD}; }; void testFormatConstructor( hicn_packet_format_t format = HICN_PACKET_FORMAT_NONE) { try { Interest interest(format, 0); } catch (...) { char buf[MAXSZ_HICN_PACKET_FORMAT]; FAIL() << "ERROR: Unexpected exception thrown for " << buf; } } void testFormatConstructorException( Packet::Format format = HICN_PACKET_FORMAT_NONE) { try { Interest interest(format, 0); FAIL() << "We expected an exception here"; } catch (errors::MalformedPacketException &exc) { // Ok right exception } catch (...) { FAIL() << "Wrong exception thrown"; } } } // namespace TEST_F(InterestTest, ConstructorWithFormat) { /** * Without arguments it should be format = HICN_PACKET_FORMAT_NONE. * We expect a crash. */ testFormatConstructor(HICN_PACKET_FORMAT_IPV4_TCP); testFormatConstructor(HICN_PACKET_FORMAT_IPV6_TCP); testFormatConstructorException(HICN_PACKET_FORMAT_IPV4_ICMP); testFormatConstructorException(HICN_PACKET_FORMAT_IPV6_ICMP); testFormatConstructor(HICN_PACKET_FORMAT_IPV4_TCP_AH); testFormatConstructor(HICN_PACKET_FORMAT_IPV6_TCP_AH); testFormatConstructorException(HICN_PACKET_FORMAT_IPV4_ICMP_AH); testFormatConstructorException(HICN_PACKET_FORMAT_IPV6_ICMP_AH); } TEST_F(InterestTest, ConstructorWithName) { /** * Without arguments it should be format = HICN_PACKET_FORMAT_NONE. * We expect a crash. */ Name n("b001::1|123"); try { Interest interest(HICN_PACKET_FORMAT_IPV6_TCP, n); } catch (...) { FAIL() << "ERROR: Unexpected exception thrown"; } } TEST_F(InterestTest, ConstructorWithBuffer) { // Ensure buffer is interest #if 0 auto ret = Interest::isInterest(&buffer_[0]); EXPECT_TRUE(ret); #endif // Create interest from buffer try { Interest interest(Interest::COPY_BUFFER, &buffer_[0], buffer_.size()); } catch (...) { FAIL() << "ERROR: Unexpected exception thrown"; } std::vector buffer2{// IPv6 src=b001::ab:cdab:cdef, dst=b002::ca IPV6_HEADER(ICMP6_PROTO, 60 + 44), // ICMP6 echo request TCP_HEADER(0x00), // Payload PAYLOAD}; // Ensure this throws an exception try { Interest interest(Interest::COPY_BUFFER, &buffer2[0], buffer2.size()); FAIL() << "We expected an exception here"; } catch (errors::MalformedPacketException &exc) { // Ok right exception } catch (...) { FAIL() << "Wrong exception thrown"; } } TEST_F(InterestTest, SetGetName) { // Create interest from buffer Interest interest(Interest::COPY_BUFFER, &buffer_[0], buffer_.size()); // Get name auto n = interest.getName(); // ensure name is b002::ca|1 Name n2("b002::ca|1"); auto ret = (n == n2); EXPECT_TRUE(ret); Name n3("b003::1234|1234"); // Change name to b003::1234|1234 interest.setName(n3); // Check name was set n = interest.getName(); ret = (n == n3); EXPECT_TRUE(ret); } TEST_F(InterestTest, SetGetLocator) { // Create interest from buffer Interest interest(Interest::COPY_BUFFER, &buffer_[0], buffer_.size()); // Get locator auto l = interest.getLocator(); hicn_ip_address_t address; inet_pton(AF_INET6, "b006::ab:cdab:cdef", &address); auto ret = !hicn_ip_address_cmp(&l, &address); EXPECT_TRUE(ret); // Set different locator inet_pton(AF_INET6, "2001::1234::4321::abcd::", &address); // Set it on interest interest.setLocator(address); // Check it was set l = interest.getLocator(); ret = !hicn_ip_address_cmp(&l, &address); EXPECT_TRUE(ret); } TEST_F(InterestTest, SetGetLifetime) { // Create interest from buffer Interest interest(HICN_PACKET_FORMAT_IPV6_TCP); const constexpr uint32_t lifetime = 10000; // Set lifetime interest.setLifetime(lifetime); // Get lifetime auto l = interest.getLifetime(); // Ensure they are the same EXPECT_EQ(l, lifetime); } TEST_F(InterestTest, HasManifest) { // Create interest from buffer Interest interest(HICN_PACKET_FORMAT_IPV6_TCP); // Let's expect anexception here try { interest.setPayloadType(PayloadType::UNSPECIFIED); FAIL() << "We expect an esception here"; } catch (errors::RuntimeException &exc) { // Ok right exception } catch (...) { FAIL() << "Wrong exception thrown"; } interest.setPayloadType(PayloadType::DATA); EXPECT_FALSE(interest.hasManifest()); interest.setPayloadType(PayloadType::MANIFEST); EXPECT_TRUE(interest.hasManifest()); } TEST_F(InterestTest, AppendSuffixesEncodeAndIterate) { // Create interest from buffer Interest interest(HICN_PACKET_FORMAT_IPV6_TCP); // Appenad some suffixes, with some duplicates interest.appendSuffix(1); interest.appendSuffix(2); interest.appendSuffix(5); interest.appendSuffix(3); interest.appendSuffix(4); interest.appendSuffix(5); interest.appendSuffix(5); interest.appendSuffix(5); interest.appendSuffix(5); interest.appendSuffix(5); // Encode them in wire format interest.encodeSuffixes(); // Iterate over them. They should be in order and without repetitions auto suffix = interest.firstSuffix(); auto n_suffixes = interest.numberOfSuffixes(); for (uint32_t i = 0; i < n_suffixes; i++) { EXPECT_EQ(*(suffix + i), i); } } TEST_F(InterestTest, AppendSuffixesWithGaps) { // Create interest from buffer Interest interest(HICN_PACKET_FORMAT_IPV6_TCP); // Appenad some suffixes, out of order and with gaps interest.appendSuffix(6); interest.appendSuffix(2); interest.appendSuffix(5); interest.appendSuffix(1); // Encode them in wire format interest.encodeSuffixes(); EXPECT_TRUE(interest.hasManifest()); // Check first suffix correctness auto suffix = interest.firstSuffix(); EXPECT_NE(suffix, nullptr); EXPECT_EQ(*suffix, 0U); // Iterate over them. They should be in order and without repetitions std::vector expected = {interest.getName().getSuffix(), 1, 2, 5, 6}; EXPECT_EQ(interest.numberOfSuffixes(), expected.size()); for (uint32_t seq : expected) { EXPECT_EQ(*suffix, seq); suffix++; } } TEST_F(InterestTest, InterestWithoutManifest) { // Create interest without manifest Interest interest(HICN_PACKET_FORMAT_IPV6_TCP); auto suffix = interest.firstSuffix(); EXPECT_FALSE(interest.hasManifest()); EXPECT_EQ(interest.numberOfSuffixes(), 0U); EXPECT_EQ(suffix, nullptr); } } // namespace core } // namespace transport