blob: 646a51e39f4806038aebbe402cb9e7685b2302a3 [file] [log] [blame]
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* 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 <lib/dnssd/ServiceNaming.h>
#include <string.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>
using namespace chip;
using namespace chip::Dnssd;
namespace {
void TestMakeInstanceName(nlTestSuite * inSuite, void * inContext)
{
char buffer[128];
NL_TEST_ASSERT(inSuite,
MakeInstanceName(buffer, sizeof(buffer), PeerId().SetCompressedFabricId(0x1234).SetNodeId(0x5678)) ==
CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "0000000000001234-0000000000005678") == 0);
NL_TEST_ASSERT(inSuite,
MakeInstanceName(buffer, sizeof(buffer),
PeerId().SetCompressedFabricId(0x1122334455667788ULL).SetNodeId(0x123456789abcdefULL)) ==
CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "1122334455667788-0123456789ABCDEF") == 0);
// insufficient buffer size:
// buffer needs at least space for hex encoding + separator + 0 terminator
constexpr size_t kMinBufferSize = 2 * 16 + 1 + 1;
for (size_t shortSize = 0; shortSize < kMinBufferSize; shortSize++)
{
NL_TEST_ASSERT(inSuite, MakeInstanceName(buffer, shortSize, PeerId()) != CHIP_NO_ERROR);
}
NL_TEST_ASSERT(inSuite, MakeInstanceName(buffer, kMinBufferSize, PeerId()) == CHIP_NO_ERROR);
}
void TestExtractIdFromInstanceName(nlTestSuite * inSuite, void * inContext)
{
PeerId peerId;
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName(nullptr, nullptr) == CHIP_ERROR_INVALID_ARGUMENT);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("ACDEF1234567890-1234567890ABCDEF", nullptr) == CHIP_ERROR_INVALID_ARGUMENT);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName(nullptr, &peerId) == CHIP_ERROR_INVALID_ARGUMENT);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("ABCDEF1234567890-1234567890ABCDEF", &peerId) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, peerId == PeerId().SetCompressedFabricId(0xABCDEF1234567890ULL).SetNodeId(0x1234567890ABCDEFULL));
// ending in period (partial name) is acceptable
NL_TEST_ASSERT(inSuite,
ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF1122.some.suffix.here", &peerId) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, peerId == PeerId().SetCompressedFabricId(0x1122334455667788ULL).SetNodeId(0xaabbccddeeff1122ULL));
// Invalid: non hex character
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1x22334455667788-AABBCCDDEEDD1122", &peerId) != CHIP_NO_ERROR);
// Invalid: missing node id part (no - separator)
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788x2233445566778899", &peerId) != CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788x2233445566778899.12-33.4455", &peerId) != CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788x2233445566778899.4455", &peerId) != CHIP_NO_ERROR);
// Invalid: missing part
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("-1234567890ABCDEF", &peerId) != CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1234567890ABCDEF-", &peerId) != CHIP_NO_ERROR);
// Invalid: separator in wrong place
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("112233445566778-8AABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788A-ABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR);
// Invalid: fabric part too short
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("11223344556677-AABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR);
// Invalid: fabric part too long
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("112233445566778899-AABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR);
// Invalid: node part too short
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF11", &peerId) != CHIP_NO_ERROR);
// Invalid: node part too long
NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF112233", &peerId) != CHIP_NO_ERROR);
}
void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext)
{
constexpr size_t kSize = 19;
char buffer[kSize];
DiscoveryFilter filter;
// Long tests
filter.type = DiscoveryFilterType::kLongDiscriminator;
filter.code = 3;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_L3") == 0);
filter.code = (1 << 12) - 1;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_L4095") == 0);
filter.code = 1 << 12;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR);
// Short tests
filter.type = DiscoveryFilterType::kShortDiscriminator;
filter.code = 3;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_S3") == 0);
filter.code = (1 << 4) - 1;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_S15") == 0);
filter.code = 1 << 4;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR);
// Vendor tests
filter.type = DiscoveryFilterType::kVendorId;
filter.code = 3;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_V3") == 0);
filter.code = 0xFFFF;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_V65535") == 0);
filter.code = 1 << 16;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR);
// Device Type tests
filter.type = DiscoveryFilterType::kDeviceType;
filter.code = 3;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_T3") == 0);
// TODO: Add tests for longer device types once spec issue #3226 is closed.
// Commissioning mode tests
filter.type = DiscoveryFilterType::kCommissioningMode;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM") == 0);
// Compressed fabric ID tests.
filter.type = DiscoveryFilterType::kCompressedFabricId;
filter.code = 0xABCD12341111BBBB;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_IABCD12341111BBBB") == 0);
// None tests.
filter.type = DiscoveryFilterType::kNone;
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "") == 0);
// instance name - "1234567890123456._matterc"
filter.type = DiscoveryFilterType::kInstanceName;
filter.instanceName = (char *) "1234567890123456";
NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "1234567890123456") == 0);
}
void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext)
{
// TODO(cecille): These need to be changed to remove leading zeros
constexpr size_t kSize = 128;
char buffer[kSize];
DiscoveryFilter filter;
// Long tests
filter.type = DiscoveryFilterType::kLongDiscriminator;
filter.code = 3;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_L3._sub._matterc") == 0);
filter.code = (1 << 12) - 1;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_L4095._sub._matterc") == 0);
filter.code = 1 << 12;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR);
// Short tests
filter.type = DiscoveryFilterType::kShortDiscriminator;
filter.code = 3;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_S3._sub._matterc") == 0);
filter.code = (1 << 4) - 1;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_S15._sub._matterc") == 0);
filter.code = 1 << 4;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR);
// Vendor tests
filter.type = DiscoveryFilterType::kVendorId;
filter.code = 3;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_V3._sub._matterc") == 0);
filter.code = (1 << 16) - 1;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_V65535._sub._matterc") == 0);
filter.code = 1 << 16;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR);
// Device Type tests
filter.type = DiscoveryFilterType::kDeviceType;
filter.code = 3;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_T3._sub._matterc") == 0);
// Commissioning mode tests
filter.type = DiscoveryFilterType::kCommissioningMode;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM._sub._matterc") == 0);
// Compressed fabric ID tests
filter.type = DiscoveryFilterType::kCompressedFabricId;
filter.code = 0x1234ABCD0000AAAA;
NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kOperational) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_I1234ABCD0000AAAA._sub._matter") == 0);
// None tests
filter.type = DiscoveryFilterType::kNone;
NL_TEST_ASSERT(inSuite,
MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_matterc") == 0);
filter.type = DiscoveryFilterType::kNone;
NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionerNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_matterd") == 0);
// Test buffer just under the right size - "_matterc" = 8 + nullchar = 9
filter.type = DiscoveryFilterType::kNone;
NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, 8, filter, DiscoveryType::kCommissionableNode) == CHIP_ERROR_NO_MEMORY);
// Test buffer exactly the right size - "_matterc" = 8 + nullchar = 9
filter.type = DiscoveryFilterType::kNone;
NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, 9, filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_matterc") == 0);
// Test buffer exactly the right size for subtype - "_CM._sub._matterc" = 17 + nullchar = 18
filter.type = DiscoveryFilterType::kCommissioningMode;
NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, 18, filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM._sub._matterc") == 0);
}
const nlTest sTests[] = {
NL_TEST_DEF("MakeInstanceName", TestMakeInstanceName), //
NL_TEST_DEF("ExtractIdFromInstandceName", TestExtractIdFromInstanceName), //
NL_TEST_DEF("TestMakeServiceNameSubtype", TestMakeServiceNameSubtype), //
NL_TEST_DEF("TestMakeCommisisonableNodeServiceTypeName", TestMakeServiceTypeName), //
NL_TEST_SENTINEL() //
};
} // namespace
int TestCHIPServiceNaming()
{
nlTestSuite theSuite = { "ServiceNaming", &sTests[0], nullptr, nullptr };
nlTestRunner(&theSuite, nullptr);
return nlTestRunnerStats(&theSuite);
}
CHIP_REGISTER_TEST_SUITE(TestCHIPServiceNaming)