Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / mdns / minimal / responders / tests / TestQueryResponder.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17 #include <mdns/minimal/responders/QueryResponder.h>
18
19 #include <vector>
20
21 #include <mdns/minimal/records/Ptr.h>
22
23 #include <support/UnitTestRegistration.h>
24
25 #include <nlunit-test.h>
26
27 namespace {
28
29 using namespace chip;
30 using namespace mdns::Minimal;
31
32 const QNamePart kDnsSdname[] = { "_services", "_dns-sd", "_udp", "local" };
33
34 const QNamePart kName1[] = { "some", "test" };
35 const QNamePart kName2[] = { "some", "other", "test" };
36
37 class EmptyResponder : public Responder
38 {
39 public:
40     EmptyResponder(const FullQName & qName) : Responder(QType::NULLVALUE, qName) {}
41     void AddAllResponses(const chip::Inet::IPPacketInfo *, ResponderDelegate *) override {}
42 };
43
44 class DnssdReplyAccumulator : public ResponderDelegate
45 {
46 public:
47     DnssdReplyAccumulator(nlTestSuite * suite) : mSuite(suite) {}
48     void AddResponse(const ResourceRecord & record) override
49     {
50
51         NL_TEST_ASSERT(mSuite, record.GetType() == QType::PTR);
52         NL_TEST_ASSERT(mSuite, record.GetClass() == QClass::IN);
53         NL_TEST_ASSERT(mSuite, record.GetName() == kDnsSdname);
54
55         mCaptures.push_back(reinterpret_cast<const PtrResourceRecord &>(record).GetPtr());
56     }
57
58     std::vector<FullQName> & Captures() { return mCaptures; }
59
60 private:
61     nlTestSuite * mSuite;
62     std::vector<FullQName> mCaptures;
63 };
64
65 void CanIterateOverResponders(nlTestSuite * inSuite, void * inContext)
66 {
67     QueryResponder<10> responder;
68
69     EmptyResponder empty1(kName1);
70     EmptyResponder empty2(kName2);
71     EmptyResponder empty3(kName2);
72
73     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty1).SetReportInServiceListing(true).IsValid());
74     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty2).SetReportInServiceListing(true).IsValid());
75     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty3).SetReportInServiceListing(true).IsValid());
76
77     int idx = 0;
78     QueryResponderRecordFilter noFilter;
79     for (auto it = responder.begin(&noFilter); it != responder.end(); it++, idx++)
80     {
81         FullQName qName = it->responder->GetQName();
82         NL_TEST_ASSERT(inSuite, (idx != 0) || (qName == kDnsSdname));
83         NL_TEST_ASSERT(inSuite, (idx != 1) || (qName == kName1));
84         NL_TEST_ASSERT(inSuite, (idx != 2) || (qName == kName2));
85         NL_TEST_ASSERT(inSuite, (idx != 3) || (qName == kName2));
86     }
87     NL_TEST_ASSERT(inSuite, idx == 4);
88 }
89
90 void RespondsToDnsSdQueries(nlTestSuite * inSuite, void * inContext)
91 {
92     QueryResponder<10> responder;
93     QueryResponderRecordFilter noFilter;
94
95     EmptyResponder empty1(kName1);
96     EmptyResponder empty2(kName2);
97     EmptyResponder empty3(kName1);
98     EmptyResponder empty4(kName1);
99
100     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty1).IsValid());
101     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty2).SetReportInServiceListing(true).IsValid());
102     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty3).SetReportInServiceListing(true).IsValid());
103     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty4).IsValid());
104
105     // It reports itself inside the iterator
106     NL_TEST_ASSERT(inSuite, &(*responder.begin(&noFilter)->responder) == &responder);
107
108     // It reponds dnssd PTR answers
109     NL_TEST_ASSERT(inSuite, responder.GetQClass() == QClass::IN);
110     NL_TEST_ASSERT(inSuite, responder.GetQType() == QType::PTR);
111     NL_TEST_ASSERT(inSuite, responder.GetQName() == kDnsSdname);
112
113     DnssdReplyAccumulator accumulator(inSuite);
114     responder.AddAllResponses(nullptr, &accumulator);
115
116     NL_TEST_ASSERT(inSuite, accumulator.Captures().size() == 2);
117     if (accumulator.Captures().size() == 2)
118     {
119         NL_TEST_ASSERT(inSuite, accumulator.Captures()[0] == kName2);
120         NL_TEST_ASSERT(inSuite, accumulator.Captures()[1] == kName1);
121     }
122 }
123
124 void LimitedStorage(nlTestSuite * inSuite, void * inContext)
125 {
126     QueryResponder<3> responder;
127
128     EmptyResponder empty1(kName1);
129     EmptyResponder empty2(kName2);
130
131     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty1).SetReportInServiceListing(true).IsValid());
132     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty2).SetReportInServiceListing(true).IsValid());
133
134     for (int i = 0; i < 100; i++)
135     {
136         EmptyResponder emptyX(kName1);
137         NL_TEST_ASSERT(inSuite, !responder.AddResponder(&emptyX).SetReportInServiceListing(true).IsValid());
138     }
139
140     int idx = 0;
141     QueryResponderRecordFilter noFilter;
142     for (auto it = responder.begin(&noFilter); it != responder.end(); it++, idx++)
143     {
144         FullQName qName = it->responder->GetQName();
145         NL_TEST_ASSERT(inSuite, (idx != 0) || (qName == kDnsSdname));
146         NL_TEST_ASSERT(inSuite, (idx != 1) || (qName == kName1));
147         NL_TEST_ASSERT(inSuite, (idx != 2) || (qName == kName2));
148     }
149     NL_TEST_ASSERT(inSuite, idx == 3);
150 }
151
152 void NonDiscoverableService(nlTestSuite * inSuite, void * inContext)
153 {
154     QueryResponder<3> responder;
155
156     EmptyResponder empty1(kName1);
157     EmptyResponder empty2(kName2);
158
159     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty1).IsValid());
160     NL_TEST_ASSERT(inSuite, responder.AddResponder(&empty2).SetReportInServiceListing(true).IsValid());
161
162     DnssdReplyAccumulator accumulator(inSuite);
163     responder.AddAllResponses(nullptr, &accumulator);
164
165     NL_TEST_ASSERT(inSuite, accumulator.Captures().size() == 1);
166     if (accumulator.Captures().size() == 1)
167     {
168         NL_TEST_ASSERT(inSuite, accumulator.Captures()[0] == kName2);
169     }
170 }
171
172 const nlTest sTests[] = {
173     NL_TEST_DEF("CanIterateOverResponders", CanIterateOverResponders), //
174     NL_TEST_DEF("RespondsToDnsSdQueries", RespondsToDnsSdQueries),     //
175     NL_TEST_DEF("LimitedStorage", LimitedStorage),                     //
176     NL_TEST_DEF("NonDiscoverableService", NonDiscoverableService),     //
177     NL_TEST_SENTINEL()                                                 //
178 };
179
180 } // namespace
181
182 int TestQueryResponder(void)
183 {
184     nlTestSuite theSuite = { "QueryResponder", sTests, nullptr, nullptr };
185     nlTestRunner(&theSuite, nullptr);
186     return nlTestRunnerStats(&theSuite);
187 }
188
189 CHIP_REGISTER_TEST_SUITE(TestQueryResponder)