Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / messaging / tests / TestExchangeMgr.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *      This file implements unit tests for the ExchangeManager implementation.
22  */
23
24 #include "TestMessagingLayer.h"
25
26 #include <core/CHIPCore.h>
27 #include <messaging/ExchangeContext.h>
28 #include <messaging/ExchangeMgr.h>
29 #include <messaging/Flags.h>
30 #include <messaging/tests/MessagingContext.h>
31 #include <protocols/Protocols.h>
32 #include <support/CHIPMem.h>
33 #include <support/CodeUtils.h>
34 #include <transport/SecureSessionMgr.h>
35 #include <transport/TransportMgr.h>
36
37 #include <nlbyteorder.h>
38 #include <nlunit-test.h>
39
40 #include <errno.h>
41 #include <utility>
42
43 namespace {
44
45 using namespace chip;
46 using namespace chip::Inet;
47 using namespace chip::Transport;
48 using namespace chip::Messaging;
49
50 using TestContext = chip::Test::MessagingContext;
51
52 TestContext sContext;
53
54 class LoopbackTransport : public Transport::Base
55 {
56 public:
57     /// Transports are required to have a constructor that takes exactly one argument
58     CHIP_ERROR Init(const char * unused) { return CHIP_NO_ERROR; }
59
60     CHIP_ERROR SendMessage(const PacketHeader & header, const PeerAddress & address, System::PacketBufferHandle msgBuf) override
61     {
62         HandleMessageReceived(header, address, std::move(msgBuf));
63         return CHIP_NO_ERROR;
64     }
65
66     bool CanSendToPeer(const PeerAddress & address) override { return true; }
67 };
68
69 TransportMgr<LoopbackTransport> gTransportMgr;
70
71 class MockAppDelegate : public ExchangeDelegate
72 {
73 public:
74     void OnMessageReceived(ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
75                            System::PacketBufferHandle buffer) override
76     {
77         IsOnMessageReceivedCalled = true;
78     }
79
80     void OnResponseTimeout(ExchangeContext * ec) override {}
81
82     bool IsOnMessageReceivedCalled = false;
83 };
84
85 void CheckNewContextTest(nlTestSuite * inSuite, void * inContext)
86 {
87     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
88
89     MockAppDelegate mockAppDelegate;
90     ExchangeContext * ec1 = ctx.NewExchangeToLocal(&mockAppDelegate);
91     NL_TEST_ASSERT(inSuite, ec1 != nullptr);
92     NL_TEST_ASSERT(inSuite, ec1->IsInitiator() == true);
93     NL_TEST_ASSERT(inSuite, ec1->GetExchangeId() != 0);
94     auto sessionPeerToLocal = ctx.GetSecureSessionManager().GetPeerConnectionState(ec1->GetSecureSession());
95     NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerNodeId() == ctx.GetSourceNodeId());
96     NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerKeyID() == ctx.GetLocalKeyId());
97     NL_TEST_ASSERT(inSuite, ec1->GetDelegate() == &mockAppDelegate);
98
99     ExchangeContext * ec2 = ctx.NewExchangeToPeer(&mockAppDelegate);
100     NL_TEST_ASSERT(inSuite, ec2 != nullptr);
101     NL_TEST_ASSERT(inSuite, ec2->GetExchangeId() > ec1->GetExchangeId());
102     auto sessionLocalToPeer = ctx.GetSecureSessionManager().GetPeerConnectionState(ec2->GetSecureSession());
103     NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerNodeId() == ctx.GetDestinationNodeId());
104     NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerKeyID() == ctx.GetPeerKeyId());
105 }
106
107 void CheckUmhRegistrationTest(nlTestSuite * inSuite, void * inContext)
108 {
109     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
110
111     CHIP_ERROR err;
112     MockAppDelegate mockAppDelegate;
113
114     err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id(VendorId::Common, 0x0001),
115                                                                                 &mockAppDelegate);
116     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
117
118     err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Id(VendorId::Common, 0x0002), 0x0001,
119                                                                             &mockAppDelegate);
120     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
121
122     err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id(VendorId::Common, 0x0001));
123     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
124
125     err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id(VendorId::Common, 0x0002));
126     NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
127
128     err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Id(VendorId::Common, 0x0002), 0x0001);
129     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
130
131     err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Id(VendorId::Common, 0x0002), 0x0002);
132     NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
133 }
134
135 void CheckExchangeMessages(nlTestSuite * inSuite, void * inContext)
136 {
137     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
138
139     CHIP_ERROR err;
140
141     // create solicited exchange
142     MockAppDelegate mockSolicitedAppDelegate;
143     ExchangeContext * ec1 = ctx.NewExchangeToPeer(&mockSolicitedAppDelegate);
144
145     // create unsolicited exchange
146     MockAppDelegate mockUnsolicitedAppDelegate;
147     err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Id(VendorId::Common, 0x0001), 0x0001,
148                                                                             &mockUnsolicitedAppDelegate);
149     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
150
151     // send a malicious packet
152     // TODO: https://github.com/project-chip/connectedhomeip/issues/4635
153     // ec1->SendMessage(0x0001, 0x0002, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
154     //                 SendFlags(Messaging::SendMessageFlags::kNone));
155     NL_TEST_ASSERT(inSuite, !mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
156
157     // send a good packet
158     ec1->SendMessage(Protocols::Id(VendorId::Common, 0x0001), 0x0001,
159                      System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
160                      SendFlags(Messaging::SendMessageFlags::kNone));
161     NL_TEST_ASSERT(inSuite, mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
162 }
163
164 // Test Suite
165
166 /**
167  *  Test Suite that lists all the test functions.
168  */
169 // clang-format off
170 const nlTest sTests[] =
171 {
172     NL_TEST_DEF("Test ExchangeMgr::NewContext",               CheckNewContextTest),
173     NL_TEST_DEF("Test ExchangeMgr::CheckUmhRegistrationTest", CheckUmhRegistrationTest),
174     NL_TEST_DEF("Test ExchangeMgr::CheckExchangeMessages",    CheckExchangeMessages),
175
176     NL_TEST_SENTINEL()
177 };
178 // clang-format on
179
180 int Initialize(void * aContext);
181 int Finalize(void * aContext);
182
183 // clang-format off
184 nlTestSuite sSuite =
185 {
186     "Test-CHIP-ExchangeManager",
187     &sTests[0],
188     Initialize,
189     Finalize
190 };
191 // clang-format on
192
193 /**
194  *  Initialize the test suite.
195  */
196 int Initialize(void * aContext)
197 {
198     CHIP_ERROR err = chip::Platform::MemoryInit();
199     if (err != CHIP_NO_ERROR)
200         return FAILURE;
201
202     err = gTransportMgr.Init("LOOPBACK");
203     if (err != CHIP_NO_ERROR)
204         return FAILURE;
205
206     err = reinterpret_cast<TestContext *>(aContext)->Init(&sSuite, &gTransportMgr);
207     return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
208 }
209
210 /**
211  *  Finalize the test suite.
212  */
213 int Finalize(void * aContext)
214 {
215     CHIP_ERROR err = reinterpret_cast<TestContext *>(aContext)->Shutdown();
216     chip::Platform::MemoryShutdown();
217     return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
218 }
219
220 } // namespace
221
222 /**
223  *  Main
224  */
225 int TestExchangeMgr()
226 {
227     // Run test suit against one context
228     nlTestRunner(&sSuite, &sContext);
229
230     return (nlTestRunnerStats(&sSuite));
231 }