blob: 5037c0a179566d8a159f2e5e97f7ada16f356224 [file] [log] [blame]
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -07003 * Copyright (c) 2013-2016 Regents of the University of California,
Spyridon Mastorakis429634f2015-02-19 17:35:33 -08004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070010 *
11 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
12 *
13 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
14 * terms of the GNU Lesser General Public License as published by the Free Software
15 * Foundation, either version 3 of the License, or (at your option) any later version.
16 *
17 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
19 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
20 *
21 * You should have received copies of the GNU General Public License and GNU Lesser
22 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
23 * <http://www.gnu.org/licenses/>.
24 *
25 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
26 */
27
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070028#include "util/notification-subscriber.hpp"
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070029#include "simple-notification.hpp"
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080030#include "util/dummy-client-face.hpp"
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070031
32#include "boost-test.hpp"
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070033#include "../identity-management-time-fixture.hpp"
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070034
35namespace ndn {
Junxiao Shia60d9362014-11-12 09:38:21 -070036namespace util {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070037namespace tests {
38
Teng Liang93adaff2016-07-30 15:57:12 -070039using namespace ndn::tests;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070040
Teng Liang93adaff2016-07-30 15:57:12 -070041class NotificationSubscriberFixture : public IdentityManagementTimeFixture
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070042{
43public:
Teng Liang93adaff2016-07-30 15:57:12 -070044 NotificationSubscriberFixture()
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070045 : streamPrefix("ndn:/NotificationSubscriberTest")
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070046 , subscriberFace(io, m_keyChain)
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080047 , subscriber(subscriberFace, streamPrefix, time::seconds(1))
Teng Liang93adaff2016-07-30 15:57:12 -070048 , nextSendNotificationNo(0)
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070049 {
50 }
51
Teng Liang93adaff2016-07-30 15:57:12 -070052 /** \brief deliver one notification to subscriber
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070053 */
54 void
55 deliverNotification(const std::string& msg)
56 {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070057 SimpleNotification notification(msg);
Alexander Afanasyev370d2602014-08-20 10:21:34 -050058
Teng Liang93adaff2016-07-30 15:57:12 -070059 Name dataName = streamPrefix;
60 dataName.appendSequenceNumber(nextSendNotificationNo);
61 Data data(dataName);
62 data.setContent(notification.wireEncode());
63 data.setFreshnessPeriod(time::seconds(1));
64 m_keyChain.sign(data);
Alexander Afanasyev370d2602014-08-20 10:21:34 -050065
Teng Liang93adaff2016-07-30 15:57:12 -070066 lastDeliveredSeqNo = nextSendNotificationNo;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070067 lastNotification.setMessage("");
Teng Liang93adaff2016-07-30 15:57:12 -070068 ++nextSendNotificationNo;
69 subscriberFace.receive(data);
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070070 }
71
72 void
73 afterNotification(const SimpleNotification& notification)
74 {
75 lastNotification = notification;
76 }
77
78 void
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070079 afterTimeout()
80 {
81 hasTimeout = true;
82 }
83
84 void
85 afterDecodeError(const Data& data)
86 {
87 lastDecodeErrorData = data;
88 }
89
Teng Liang93adaff2016-07-30 15:57:12 -070090 void
91 connectHandlers()
92 {
93 notificationConn = subscriber.onNotification.connect(
94 bind(&NotificationSubscriberFixture::afterNotification, this, _1));
95 subscriber.onTimeout.connect(
96 bind(&NotificationSubscriberFixture::afterTimeout, this));
97 subscriber.onDecodeError.connect(
98 bind(&NotificationSubscriberFixture::afterDecodeError, this, _1));
99 }
100
101 void
102 disconnectHandlers()
103 {
104 notificationConn.disconnect();
105 }
106
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700107 /** \return true if subscriberFace has an initial request (first sent Interest)
108 */
109 bool
110 hasInitialRequest() const
111 {
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800112 if (subscriberFace.sentInterests.empty())
Teng Liang93adaff2016-07-30 15:57:12 -0700113 return false;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700114
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800115 const Interest& interest = subscriberFace.sentInterests[0];
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700116 return interest.getName() == streamPrefix &&
117 interest.getChildSelector() == 1 &&
118 interest.getMustBeFresh() &&
119 interest.getInterestLifetime() == subscriber.getInterestLifetime();
120 }
121
122 /** \return sequence number of the continuation request sent from subscriberFace
123 * or 0 if there's no such request as sole sent Interest
124 */
125 uint64_t
126 getRequestSeqNo() const
127 {
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800128 if (subscriberFace.sentInterests.size() != 1)
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700129 return 0;
130
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800131 const Interest& interest = subscriberFace.sentInterests[0];
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700132 const Name& name = interest.getName();
133 if (streamPrefix.isPrefixOf(name) &&
134 name.size() == streamPrefix.size() + 1 &&
135 interest.getInterestLifetime() == subscriber.getInterestLifetime())
136 return name[-1].toSequenceNumber();
137 else
138 return 0;
139 }
140
141protected:
142 Name streamPrefix;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800143 DummyClientFace subscriberFace;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700144 util::NotificationSubscriber<SimpleNotification> subscriber;
Junxiao Shi728873f2015-01-20 16:01:26 -0700145 util::signal::Connection notificationConn;
Teng Liang93adaff2016-07-30 15:57:12 -0700146 uint64_t nextSendNotificationNo;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700147 uint64_t lastDeliveredSeqNo;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700148 SimpleNotification lastNotification;
149 bool hasTimeout;
150 Data lastDecodeErrorData;
151};
152
Teng Liang93adaff2016-07-30 15:57:12 -0700153BOOST_AUTO_TEST_SUITE(Util)
154BOOST_FIXTURE_TEST_SUITE(TestNotificationSubscriber, NotificationSubscriberFixture)
155
156BOOST_AUTO_TEST_CASE(StartStop)
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700157{
158 BOOST_REQUIRE_EQUAL(subscriber.isRunning(), false);
159
160 // has no effect because onNotification has no handler
161 subscriber.start();
162 BOOST_REQUIRE_EQUAL(subscriber.isRunning(), false);
163
Teng Liang93adaff2016-07-30 15:57:12 -0700164 this->connectHandlers();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700165 subscriber.start();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700166 BOOST_REQUIRE_EQUAL(subscriber.isRunning(), true);
Teng Liang93adaff2016-07-30 15:57:12 -0700167 advanceClocks(time::milliseconds(1));
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700168 BOOST_CHECK(this->hasInitialRequest());
169
Teng Liang93adaff2016-07-30 15:57:12 -0700170 subscriberFace.sentInterests.clear();
171 this->disconnectHandlers();
172 this->deliverNotification("n1");
173 BOOST_REQUIRE_EQUAL(subscriberFace.sentInterests.size(), 0);
174}
175
176BOOST_AUTO_TEST_CASE(Notifications)
177{
178 this->connectHandlers();
179 subscriber.start();
180 advanceClocks(time::milliseconds(1));
181
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700182 // respond to initial request
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800183 subscriberFace.sentInterests.clear();
Teng Liang93adaff2016-07-30 15:57:12 -0700184 this->deliverNotification("n1");
185 advanceClocks(time::milliseconds(1));
186 BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n1");
187 BOOST_CHECK_EQUAL(this->getRequestSeqNo(), lastDeliveredSeqNo + 1);
188
189 // respond to continuation request
190 subscriberFace.sentInterests.clear();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700191 this->deliverNotification("n2");
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800192 advanceClocks(time::milliseconds(1));
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700193 BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n2");
194 BOOST_CHECK_EQUAL(this->getRequestSeqNo(), lastDeliveredSeqNo + 1);
Teng Liang93adaff2016-07-30 15:57:12 -0700195}
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700196
Teng Liang93adaff2016-07-30 15:57:12 -0700197BOOST_AUTO_TEST_CASE(Timeout)
198{
199 this->connectHandlers();
200 subscriber.start();
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800201 advanceClocks(time::milliseconds(1));
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700202
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800203 subscriberFace.sentInterests.clear();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700204 lastNotification.setMessage("");
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800205 advanceClocks(subscriber.getInterestLifetime(), 2);
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700206 BOOST_CHECK(lastNotification.getMessage().empty());
207 BOOST_CHECK_EQUAL(hasTimeout, true);
208 BOOST_CHECK(this->hasInitialRequest());
209
Teng Liang93adaff2016-07-30 15:57:12 -0700210 subscriberFace.sentInterests.clear();
211 this->deliverNotification("n1");
212 advanceClocks(time::milliseconds(1));
213 BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n1");
214}
215
216BOOST_AUTO_TEST_CASE(SequenceError)
217{
218 this->connectHandlers();
219 subscriber.start();
220 advanceClocks(time::milliseconds(1));
221
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700222 Name wrongName = streamPrefix;
223 wrongName.append("%07%07");
224 Data wrongData(wrongName);
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -0700225 m_keyChain.sign(wrongData);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800226 subscriberFace.receive(wrongData);
227 subscriberFace.sentInterests.clear();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700228 lastNotification.setMessage("");
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800229 advanceClocks(time::milliseconds(1));
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700230 BOOST_CHECK(lastNotification.getMessage().empty());
231 BOOST_CHECK_EQUAL(lastDecodeErrorData.getName(), wrongName);
232 BOOST_CHECK(this->hasInitialRequest());
Teng Liang93adaff2016-07-30 15:57:12 -0700233}
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700234
Teng Liang93adaff2016-07-30 15:57:12 -0700235BOOST_AUTO_TEST_CASE(PayloadError)
236{
237 this->connectHandlers();
238 subscriber.start();
239 advanceClocks(time::milliseconds(1));
240
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800241 subscriberFace.sentInterests.clear();
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700242 lastNotification.setMessage("");
243 this->deliverNotification("\x07n4");
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800244 advanceClocks(time::milliseconds(1));
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700245 BOOST_CHECK(lastNotification.getMessage().empty());
246 BOOST_CHECK(this->hasInitialRequest());
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700247}
248
Teng Liang93adaff2016-07-30 15:57:12 -0700249BOOST_AUTO_TEST_SUITE_END() // TestNotificationSubscriber
250BOOST_AUTO_TEST_SUITE_END() // Util
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700251
252} // namespace tests
Junxiao Shia60d9362014-11-12 09:38:21 -0700253} // namespace util
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700254} // namespace ndn