From 9ff29ed04029f14275cb661fb197aa71754e2d4d Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:33:43 +0900 Subject: [PATCH 01/19] Fix Android Bluetooth connect issue (#33087) --- .../chip/chiptool/bluetooth/BluetoothManager.kt | 16 ++++++++++++++++ .../java/chip/platform/AndroidBleManager.java | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt index 16d0f745b5f70f..61e95838b1cc61 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt @@ -138,6 +138,12 @@ class BluetoothManager : BleCallback { private val coroutineContinuation = continuation + private val STATE_INIT = 1 + private val STATE_DISCOVER_SERVICE = 2 + private val STATE_REQUEST_MTU = 3 + + private var mState = STATE_INIT + override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) { super.onConnectionStateChange(gatt, status, newState) Log.i( @@ -148,21 +154,31 @@ class BluetoothManager : BleCallback { if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) { Log.i("$TAG|onConnectionStateChange", "Discovering Services...") + mState = STATE_DISCOVER_SERVICE gatt?.discoverServices() } } override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) { Log.d(TAG, "${gatt?.device?.name}.onServicesDiscovered status = $status") + if (mState != STATE_DISCOVER_SERVICE) { + Log.d(TAG, "Invalid state : $mState") + return + } wrappedCallback.onServicesDiscovered(gatt, status) Log.i("$TAG|onServicesDiscovered", "Services Discovered") + mState = STATE_REQUEST_MTU gatt?.requestMtu(247) } override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) { Log.d(TAG, "${gatt?.device?.name}.onMtuChanged: connecting to CHIP device") super.onMtuChanged(gatt, mtu, status) + if (mState != STATE_REQUEST_MTU) { + Log.d(TAG, "Invalid state : $mState") + return + } wrappedCallback.onMtuChanged(gatt, mtu, status) if (coroutineContinuation.isActive) { coroutineContinuation.resume(gatt) diff --git a/src/platform/android/java/chip/platform/AndroidBleManager.java b/src/platform/android/java/chip/platform/AndroidBleManager.java index 1d440b67b18da3..52b0052d409ef8 100644 --- a/src/platform/android/java/chip/platform/AndroidBleManager.java +++ b/src/platform/android/java/chip/platform/AndroidBleManager.java @@ -584,12 +584,19 @@ private void connectBLE(Object bluetoothDeviceObj) { } class ConnectionGattCallback extends AndroidBluetoothGattCallback { + private static final int STATE_INIT = 1; + private static final int STATE_DISCOVER_SERVICE = 2; + private static final int STATE_REQUEST_MTU = 3; + + private int mState = STATE_INIT; + @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { Log.i(TAG, "onConnectionStateChange status = " + status + ", newState= + " + newState); super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) { Log.i(TAG, "Discovering Services..."); + mState = STATE_DISCOVER_SERVICE; gatt.discoverServices(); return; } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { @@ -602,14 +609,23 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState public void onServicesDiscovered(BluetoothGatt gatt, int status) { Log.d(TAG, "onServicesDiscovered status = " + status); super.onServicesDiscovered(gatt, status); + if (mState != STATE_DISCOVER_SERVICE) { + Log.d(TAG, "Invalid state : " + mState); + return; + } Log.i(TAG, "Services Discovered"); + mState = STATE_REQUEST_MTU; gatt.requestMtu(247); } @Override public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); + if (mState != STATE_REQUEST_MTU) { + Log.d(TAG, "Invalid state : " + mState); + return; + } String deviceName = ""; if (gatt != null && gatt.getDevice() != null) { deviceName = gatt.getDevice().getName(); From e47f748fd32f93ca3a7907aef285b95609a8eab4 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 23 Apr 2024 13:43:11 +0200 Subject: [PATCH 02/19] [Linux] Handle BLE adapter re-appearance due to BlueZ restart (#32847) * Keep all timer handlers in BLEManagerImpl class * [Linux] Handle BLE adapter re-appearance * Simplify casting for callbacks * Fix adapter added notification * Add TODO for potential issue with LE-only adapters --- src/platform/Linux/BLEManagerImpl.cpp | 80 +++++++++++++------ src/platform/Linux/BLEManagerImpl.h | 7 +- .../Linux/bluez/BluezObjectManager.cpp | 46 ++++++++--- src/platform/Linux/bluez/BluezObjectManager.h | 6 +- 4 files changed, 96 insertions(+), 43 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index aeb853efb359c7..d9025bdbd5a503 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -77,13 +77,6 @@ const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0 const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x12 } }; -void HandleConnectTimeout(chip::System::Layer *, void * apEndpoint) -{ - VerifyOrDie(apEndpoint != nullptr); - static_cast(apEndpoint)->CancelConnect(); - BLEManagerImpl::HandleConnectFailed(CHIP_ERROR_TIMEOUT); -} - } // namespace BLEManagerImpl BLEManagerImpl::sInstance; @@ -116,16 +109,17 @@ CHIP_ERROR BLEManagerImpl::_Init() void BLEManagerImpl::_Shutdown() { - // Ensure scan resources are cleared (e.g. timeout timers). + // Make sure that timers are stopped before shutting down the BLE layer. + DeviceLayer::SystemLayer().CancelTimer(HandleScanTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleAdvertisingTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleConnectTimer, this); + mDeviceScanner.Shutdown(); - // Stop advertising and free resources. mBLEAdvertisement.Shutdown(); - // Make sure that the endpoint is not used by the timer. - DeviceLayer::SystemLayer().CancelTimer(HandleConnectTimeout, &mEndpoint); - // Release BLE connection resources (unregister from BlueZ). mEndpoint.Shutdown(); + mBluezObjectManager.Shutdown(); - mFlags.Clear(Flags::kBluezBLELayerInitialized); + mFlags.Clear(Flags::kBluezManagerInitialized); } CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) @@ -262,7 +256,8 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv apEvent->Platform.BLEAdapter.mAdapterAddress); if (apEvent->Platform.BLEAdapter.mAdapterId == mAdapterId) { - // TODO: Handle adapter added + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + DriveBLEState(); } break; case DeviceEventType::kPlatformLinuxBLEAdapterRemoved: @@ -270,7 +265,21 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv apEvent->Platform.BLEAdapter.mAdapterAddress); if (apEvent->Platform.BLEAdapter.mAdapterId == mAdapterId) { - // TODO: Handle adapter removed + // Shutdown all BLE operations and release resources + mDeviceScanner.Shutdown(); + mBLEAdvertisement.Shutdown(); + mEndpoint.Shutdown(); + // Drop reference to the adapter + mAdapter.reset(); + // Clear all flags related to BlueZ BLE operations + mFlags.Clear(Flags::kBluezAdapterAvailable); + mFlags.Clear(Flags::kBluezBLELayerInitialized); + mFlags.Clear(Flags::kAdvertisingConfigured); + mFlags.Clear(Flags::kAppRegistered); + mFlags.Clear(Flags::kAdvertising); + CleanScanConfig(); + // Indicate that the adapter is no longer available + err = BLE_ERROR_ADAPTER_UNAVAILABLE; } break; case DeviceEventType::kPlatformLinuxBLECentralConnected: @@ -344,9 +353,7 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv exit: if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); - mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; - DeviceLayer::SystemLayer().CancelTimer(HandleAdvertisingTimer, this); + DisableBLEService(err); mFlags.Clear(Flags::kControlOpInProgress); } } @@ -680,9 +687,23 @@ void BLEManagerImpl::DriveBLEState() exit: if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + DisableBLEService(err); + } +} + +void BLEManagerImpl::DisableBLEService(CHIP_ERROR err) +{ + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format()); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + // Stop all timers if the error is other than BLE adapter unavailable. In case of BLE adapter + // beeing unavailable, we will keep timers running, as the adapter might become available in + // the nearest future (e.g. BlueZ restart due to crash). By doing that we will ensure that BLE + // adapter reappearance will not extend timeouts for the ongoing operations. + if (err != BLE_ERROR_ADAPTER_UNAVAILABLE) + { + DeviceLayer::SystemLayer().CancelTimer(HandleScanTimer, this); DeviceLayer::SystemLayer().CancelTimer(HandleAdvertisingTimer, this); - mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + DeviceLayer::SystemLayer().CancelTimer(HandleConnectTimer, this); } } @@ -768,7 +789,7 @@ void BLEManagerImpl::InitiateScan(BleScanState scanType) ChipLogError(Ble, "Failed to start BLE scan: %" CHIP_ERROR_FORMAT, err.Format()); }); - err = DeviceLayer::SystemLayer().StartTimer(kNewConnectionScanTimeout, HandleScannerTimer, this); + err = DeviceLayer::SystemLayer().StartTimer(kNewConnectionScanTimeout, HandleScanTimer, this); VerifyOrExit(err == CHIP_NO_ERROR, { mBLEScanConfig.mBleScanState = BleScanState::kNotScanning; mDeviceScanner.StopScan(); @@ -782,7 +803,7 @@ void BLEManagerImpl::InitiateScan(BleScanState scanType) } } -void BLEManagerImpl::HandleScannerTimer(chip::System::Layer *, void * appState) +void BLEManagerImpl::HandleScanTimer(chip::System::Layer *, void * appState) { auto * manager = static_cast(appState); manager->OnScanError(CHIP_ERROR_TIMEOUT); @@ -792,7 +813,7 @@ void BLEManagerImpl::HandleScannerTimer(chip::System::Layer *, void * appState) void BLEManagerImpl::CleanScanConfig() { if (mBLEScanConfig.mBleScanState == BleScanState::kConnecting) - DeviceLayer::SystemLayer().CancelTimer(HandleConnectTimeout, &mEndpoint); + DeviceLayer::SystemLayer().CancelTimer(HandleConnectTimer, this); mBLEScanConfig.mBleScanState = BleScanState::kNotScanning; } @@ -813,7 +834,7 @@ CHIP_ERROR BLEManagerImpl::CancelConnection() // If in discovery mode, stop scan. else if (mBLEScanConfig.mBleScanState != BleScanState::kNotScanning) { - DeviceLayer::SystemLayer().CancelTimer(HandleScannerTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleScanTimer, this); mDeviceScanner.StopScan(); } return CHIP_NO_ERROR; @@ -904,10 +925,10 @@ void BLEManagerImpl::OnDeviceScanned(BluezDevice1 & device, const chip::Ble::Chi // We StartScan in the ChipStack thread. // StopScan should also be performed in the ChipStack thread. // At the same time, the scan timer also needs to be canceled in the ChipStack thread. - DeviceLayer::SystemLayer().CancelTimer(HandleScannerTimer, this); + DeviceLayer::SystemLayer().CancelTimer(HandleScanTimer, this); mDeviceScanner.StopScan(); // Stop scanning and then start connecting timer - DeviceLayer::SystemLayer().StartTimer(kConnectTimeout, HandleConnectTimeout, &mEndpoint); + DeviceLayer::SystemLayer().StartTimer(kConnectTimeout, HandleConnectTimer, this); chip::DeviceLayer::PlatformMgr().UnlockChipStack(); CHIP_ERROR err = mEndpoint.ConnectDevice(device); @@ -916,6 +937,13 @@ void BLEManagerImpl::OnDeviceScanned(BluezDevice1 & device, const chip::Ble::Chi ChipLogProgress(Ble, "New device connected: %s", address); } +void BLEManagerImpl::HandleConnectTimer(chip::System::Layer *, void * appState) +{ + auto * manager = static_cast(appState); + manager->mEndpoint.CancelConnect(); + BLEManagerImpl::HandleConnectFailed(CHIP_ERROR_TIMEOUT); +} + void BLEManagerImpl::OnScanComplete() { switch (mBLEScanConfig.mBleScanState) diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 8444439c27c1c7..e3f3e4186abb7e 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -184,12 +184,15 @@ class BLEManagerImpl final : public BLEManager, }; void DriveBLEState(); + void DisableBLEService(CHIP_ERROR err); BluezAdvertisement::AdvertisingIntervals GetAdvertisingIntervals() const; - static void HandleAdvertisingTimer(chip::System::Layer *, void * appState); void InitiateScan(BleScanState scanType); - static void HandleScannerTimer(chip::System::Layer *, void * appState); void CleanScanConfig(); + static void HandleAdvertisingTimer(chip::System::Layer *, void * appState); + static void HandleScanTimer(chip::System::Layer *, void * appState); + static void HandleConnectTimer(chip::System::Layer *, void * appState); + CHIPoBLEServiceMode mServiceMode; BitFlags mFlags; diff --git a/src/platform/Linux/bluez/BluezObjectManager.cpp b/src/platform/Linux/bluez/BluezObjectManager.cpp index ff125c068d3f7e..2d555edc562be8 100644 --- a/src/platform/Linux/bluez/BluezObjectManager.cpp +++ b/src/platform/Linux/bluez/BluezObjectManager.cpp @@ -188,16 +188,25 @@ BluezObjectManager::NotificationsDelegates BluezObjectManager::GetDeviceNotifica return delegates; } -void BluezObjectManager::OnObjectAdded(GDBusObjectManager * aMgr, GDBusObject * aObj) +void BluezObjectManager::OnObjectAdded(GDBusObjectManager * aMgr, BluezObject * aObj) { - GAutoPtr adapter(bluez_object_get_adapter1(reinterpret_cast(aObj))); - if (adapter) + GAutoPtr adapter(bluez_object_get_adapter1(aObj)); + // Verify that the adapter is properly initialized - the class property must be set. + // BlueZ can export adapter objects on the bus before it is fully initialized. Such + // adapter objects are not usable and must be ignored. + // + // TODO: Find a better way to determine whether the adapter interface exposed by + // BlueZ D-Bus service is fully functional. The current approach is based on + // the assumption that the class property is non-zero, which is true only + // for BR/EDR + LE adapters. LE-only adapters do not have HCI command to read + // the class property and BlueZ sets it to 0 as a default value. + if (adapter && bluez_adapter1_get_class(adapter.get()) != 0) { NotifyAdapterAdded(adapter.get()); return; } - GAutoPtr device(bluez_object_get_device1(reinterpret_cast(aObj))); + GAutoPtr device(bluez_object_get_device1(aObj)); if (device) { for (auto delegate : GetDeviceNotificationsDelegates(device.get())) @@ -207,9 +216,9 @@ void BluezObjectManager::OnObjectAdded(GDBusObjectManager * aMgr, GDBusObject * } } -void BluezObjectManager::OnObjectRemoved(GDBusObjectManager * aMgr, GDBusObject * aObj) +void BluezObjectManager::OnObjectRemoved(GDBusObjectManager * aMgr, BluezObject * aObj) { - GAutoPtr adapter(bluez_object_get_adapter1(reinterpret_cast(aObj))); + GAutoPtr adapter(bluez_object_get_adapter1(aObj)); if (adapter) { RemoveAdapterSubscriptions(adapter.get()); @@ -217,7 +226,7 @@ void BluezObjectManager::OnObjectRemoved(GDBusObjectManager * aMgr, GDBusObject return; } - GAutoPtr device(bluez_object_get_device1(reinterpret_cast(aObj))); + GAutoPtr device(bluez_object_get_device1(aObj)); if (device) { for (auto delegate : GetDeviceNotificationsDelegates(device.get())) @@ -227,10 +236,22 @@ void BluezObjectManager::OnObjectRemoved(GDBusObjectManager * aMgr, GDBusObject } } -void BluezObjectManager::OnInterfacePropertiesChanged(GDBusObjectManagerClient * aMgr, GDBusObjectProxy * aObj, GDBusProxy * aIface, +void BluezObjectManager::OnInterfacePropertiesChanged(GDBusObjectManagerClient * aMgr, BluezObject * aObj, GDBusProxy * aIface, GVariant * aChangedProps, const char * const * aInvalidatedProps) { - GAutoPtr device(bluez_object_get_device1(reinterpret_cast(aObj))); + uint32_t classValue = 0; + GAutoPtr adapter(bluez_object_get_adapter1(aObj)); + // When the adapter's readonly class property is set, it means that the adapter has been + // fully initialized and is ready to be used. It's most likely that the adapter has been + // previously ignored in the OnObjectAdded callback, so now we can notify the application + // about the new adapter. + if (adapter && g_variant_lookup(aChangedProps, "Class", "u", &classValue) && classValue != 0) + { + NotifyAdapterAdded(adapter.get()); + return; + } + + GAutoPtr device(bluez_object_get_device1(aObj)); if (device) { for (auto delegate : GetDeviceNotificationsDelegates(device.get())) @@ -256,18 +277,19 @@ CHIP_ERROR BluezObjectManager::SetupObjectManager() g_signal_connect(mObjectManager.get(), "object-added", G_CALLBACK(+[](GDBusObjectManager * mgr, GDBusObject * obj, BluezObjectManager * self) { - return self->OnObjectAdded(mgr, obj); + return self->OnObjectAdded(mgr, reinterpret_cast(obj)); }), this); g_signal_connect(mObjectManager.get(), "object-removed", G_CALLBACK(+[](GDBusObjectManager * mgr, GDBusObject * obj, BluezObjectManager * self) { - return self->OnObjectRemoved(mgr, obj); + return self->OnObjectRemoved(mgr, reinterpret_cast(obj)); }), this); g_signal_connect(mObjectManager.get(), "interface-proxy-properties-changed", G_CALLBACK(+[](GDBusObjectManagerClient * mgr, GDBusObjectProxy * obj, GDBusProxy * iface, GVariant * changed, const char * const * invalidated, BluezObjectManager * self) { - return self->OnInterfacePropertiesChanged(mgr, obj, iface, changed, invalidated); + return self->OnInterfacePropertiesChanged(mgr, reinterpret_cast(obj), iface, changed, + invalidated); }), this); diff --git a/src/platform/Linux/bluez/BluezObjectManager.h b/src/platform/Linux/bluez/BluezObjectManager.h index 4943451ac60ad7..6514141c10d609 100644 --- a/src/platform/Linux/bluez/BluezObjectManager.h +++ b/src/platform/Linux/bluez/BluezObjectManager.h @@ -89,9 +89,9 @@ class BluezObjectManager using NotificationsDelegates = std::vector; NotificationsDelegates GetDeviceNotificationsDelegates(BluezDevice1 * device); - void OnObjectAdded(GDBusObjectManager * aMgr, GDBusObject * aObj); - void OnObjectRemoved(GDBusObjectManager * aMgr, GDBusObject * aObj); - void OnInterfacePropertiesChanged(GDBusObjectManagerClient * aMgr, GDBusObjectProxy * aObj, GDBusProxy * aIface, + void OnObjectAdded(GDBusObjectManager * aMgr, BluezObject * aObj); + void OnObjectRemoved(GDBusObjectManager * aMgr, BluezObject * aObj); + void OnInterfacePropertiesChanged(GDBusObjectManagerClient * aMgr, BluezObject * aObj, GDBusProxy * aIface, GVariant * aChangedProps, const char * const * aInvalidatedProps); GAutoPtr mConnection; From 2edcdeab8c4b0fb7611c3817474dd4745769e768 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 23 Apr 2024 08:14:23 -0400 Subject: [PATCH 03/19] [Silabs] Sync SilabsConfig.h with reserved keys from side project --- src/platform/silabs/SilabsConfig.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/SilabsConfig.h b/src/platform/silabs/SilabsConfig.h index 92a879177530c7..ccb14beeb8f177 100644 --- a/src/platform/silabs/SilabsConfig.h +++ b/src/platform/silabs/SilabsConfig.h @@ -112,6 +112,11 @@ class SilabsConfig static constexpr Key KConfigKey_ProductLabel = SilabsConfigKey(kMatterFactory_KeyBase, 0x10); static constexpr Key kConfigKey_ProductURL = SilabsConfigKey(kMatterFactory_KeyBase, 0x11); static constexpr Key kConfigKey_PartNumber = SilabsConfigKey(kMatterFactory_KeyBase, 0x12); + static constexpr Key kConfigKey_CACerts = SilabsConfigKey(kMatterFactory_KeyBase, 0x13); + static constexpr Key kConfigKey_DeviceCerts = SilabsConfigKey(kMatterFactory_KeyBase, 0x14); + static constexpr Key kConfigKey_hostname = SilabsConfigKey(kMatterFactory_KeyBase, 0x15); + static constexpr Key kConfigKey_clientid = SilabsConfigKey(kMatterFactory_KeyBase, 0x16); + static constexpr Key kConfigKey_Test_Event_Trigger_Key = SilabsConfigKey(kMatterFactory_KeyBase, 0x17); static constexpr Key kConfigKey_UniqueId = SilabsConfigKey(kMatterFactory_KeyBase, 0x1F); static constexpr Key kConfigKey_Creds_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x20); static constexpr Key kConfigKey_Creds_Base_Addr = SilabsConfigKey(kMatterFactory_KeyBase, 0x21); @@ -121,7 +126,11 @@ class SilabsConfig static constexpr Key kConfigKey_Creds_PAI_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x25); static constexpr Key kConfigKey_Creds_CD_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x26); static constexpr Key kConfigKey_Creds_CD_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x27); - static constexpr Key kConfigKey_Test_Event_Trigger_Key = SilabsConfigKey(kMatterFactory_KeyBase, 0x28); + static constexpr Key kConfigKey_Provision_Request = SilabsConfigKey(kMatterFactory_KeyBase, 0x28); + static constexpr Key kConfigKey_Provision_Version = SilabsConfigKey(kMatterFactory_KeyBase, 0x29); + + static constexpr Key kOtaTlvEncryption_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x30); + // Matter Config Keys static constexpr Key kConfigKey_ServiceConfig = SilabsConfigKey(kMatterConfig_KeyBase, 0x01); static constexpr Key kConfigKey_PairedAccountId = SilabsConfigKey(kMatterConfig_KeyBase, 0x02); @@ -162,7 +171,7 @@ class SilabsConfig // Set key id limits for each group. static constexpr Key kMinConfigKey_MatterFactory = SilabsConfigKey(kMatterFactory_KeyBase, 0x00); - static constexpr Key kMaxConfigKey_MatterFactory = SilabsConfigKey(kMatterFactory_KeyBase, 0x2F); + static constexpr Key kMaxConfigKey_MatterFactory = SilabsConfigKey(kMatterFactory_KeyBase, 0x30); static constexpr Key kMinConfigKey_MatterConfig = SilabsConfigKey(kMatterConfig_KeyBase, 0x00); static constexpr Key kMaxConfigKey_MatterConfig = SilabsConfigKey(kMatterConfig_KeyBase, 0x22); From 9ca1f594536c266e56c6cf142d97efc8ae3f4191 Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Tue, 23 Apr 2024 15:06:44 +0200 Subject: [PATCH 04/19] Replaced nlunit-test with pw_unit_test in src/lib/format/ (#33063) * Replaced nlunit-test with pw_unit_test in src/lib/format/ * Restyled by clang-format * Use EXPECT_STREQ --------- Co-authored-by: Restyled.io --- src/lib/format/tests/BUILD.gn | 5 +- src/lib/format/tests/TestDecoding.cpp | 125 +++++++----------- src/lib/format/tests/TestFlatTree.cpp | 52 +++----- src/lib/format/tests/TestFlatTreePosition.cpp | 98 ++++++-------- 4 files changed, 109 insertions(+), 171 deletions(-) diff --git a/src/lib/format/tests/BUILD.gn b/src/lib/format/tests/BUILD.gn index 64be2e38a3f402..1001a3bd9e77d4 100644 --- a/src/lib/format/tests/BUILD.gn +++ b/src/lib/format/tests/BUILD.gn @@ -14,12 +14,11 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/build/chip/fuzz_test.gni") -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libFormatTests" test_sources = [ @@ -40,8 +39,6 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/lib/format:flat-tree", "${chip_root}/src/lib/format:protocol-decoder", "${chip_root}/src/lib/format:protocol-tlv-metadata", - "${chip_root}/src/lib/support:testing_nlunit", - "${nlunit_test_root}:nlunit-test", ] } diff --git a/src/lib/format/tests/TestDecoding.cpp b/src/lib/format/tests/TestDecoding.cpp index 0a848e5de8f835..ae5c2efc553fb6 100644 --- a/src/lib/format/tests/TestDecoding.cpp +++ b/src/lib/format/tests/TestDecoding.cpp @@ -17,12 +17,11 @@ #include #include #include -#include #include #include -#include +#include #include "sample_data.h" @@ -57,8 +56,7 @@ const std::array, 53 + 2> fake_protocols_meta = { { { 2, _FakeProtocolData }, } }; -void TestSampleData(nlTestSuite * inSuite, const PayloadDecoderInitParams & params, const SamplePayload & data, - const char * expectation) +void TestSampleData(const PayloadDecoderInitParams & params, const SamplePayload & data, const char * expectation) { chip::Decoders::PayloadDecoder<64, 128> decoder( PayloadDecoderInitParams(params).SetProtocol(data.protocolId).SetMessageType(data.messageType)); @@ -130,23 +128,23 @@ void TestSampleData(nlTestSuite * inSuite, const PayloadDecoderInitParams & para printf("ACTUAL: '%s'\n", partial.Reset().Add(output_builder.c_str() + idx).AddMarkerIfOverflow().c_str()); } - NL_TEST_ASSERT(inSuite, strcmp(output_builder.c_str(), expectation) == 0); + EXPECT_STREQ(output_builder.c_str(), expectation); } -void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestFullDataDecoding) { PayloadDecoderInitParams params; params.SetProtocolDecodeTree(chip::TLVMeta::protocols_meta).SetClusterDecodeTree(chip::TLVMeta::clusters_meta); - TestSampleData(inSuite, params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); - TestSampleData(inSuite, params, secure_channel_pkbdf_param_request, + TestSampleData(params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); + TestSampleData(params, secure_channel_pkbdf_param_request, "pbkdf_param_request\n" " initiator_random: hex:7C8698755B8E9866BB4FFDC27B733F3B6EF7F83D43FBE0CA6AD2B8C52C8F4236\n" " initiator_session_id: 37677\n" " passcode_id: 0\n" " has_pbkdf_parameters: false\n"); - TestSampleData(inSuite, params, secure_channel_pkbdf_param_response, + TestSampleData(params, secure_channel_pkbdf_param_response, "pbkdf_param_response\n" " initiator_random: hex:7C8698755B8E9866BB4FFDC27B733F3B6EF7F83D43FBE0CA6AD2B8C52C8F4236\n" " responder_random: hex:A44EB3E1A751A88A32BAB59EF16EB9764C20E1A9DDBEF6EFE3F588C943C58424\n" @@ -154,24 +152,24 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " pbkdf_parameters\n" " iterations: 1000\n" " salt: hex:E8FC1E6FD0023422B3CA7ECEDD344444551C814D3D0B0EB9C096F00E8A8051B2\n"); - TestSampleData(inSuite, params, secure_channel_pase_pake1, + TestSampleData(params, secure_channel_pase_pake1, // clang-format off "pase_pake1\n" " pA: hex:0422ABC7A84352850456BD4A510905FE6BB782A0863A9382550E1228020801B22EEC4102C60F80082842B9739705FCD37F134651442A41E3723DFFE0...\n" // clang-format on ); - TestSampleData(inSuite, params, secure_channel_pase_pake2, + TestSampleData(params, secure_channel_pase_pake2, // clang-format off "pase_pake2\n" " pB: hex:04B6A44A3347C6B77900A3674CA19F40F25F056F8CB344EC1B4FA7888B9E6B570B7010431C5D0BE4021FE74A96C40721765FDA6802BE8DFDF5624332...\n" " cB: hex:40E7452275E38AEBAF0E0F6FAB33A1B0CB5AEB5E824230DD40D0071DC7E55C87\n" // clang-format on ); - TestSampleData(inSuite, params, secure_channel_pase_pake3, + TestSampleData(params, secure_channel_pase_pake3, "pase_pake3\n" " cA: hex:6008C72EDEC9D25D4A36522F0BF23058F9378EFE38CBBCCE8C6853900169BC38\n"); - TestSampleData(inSuite, params, secure_channel_status_report, "status_report: BINARY DATA\n"); - TestSampleData(inSuite, params, im_protocol_read_request, + TestSampleData(params, secure_channel_status_report, "status_report: BINARY DATA\n"); + TestSampleData(params, im_protocol_read_request, "read_request\n" " attribute_requests\n" " Anonymous<>\n" @@ -206,7 +204,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " attribute_id: 3 == 'connectMaxTimeSeconds'\n" " fabric_filtered: false\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_report_data, + TestSampleData(params, im_protocol_report_data, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -279,7 +277,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); // Different content - TestSampleData(inSuite, params, im_protocol_report_data_acl, + TestSampleData(params, im_protocol_report_data_acl, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -301,7 +299,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); TestSampleData( - inSuite, params, im_protocol_report_data_window_covering, + params, im_protocol_report_data_window_covering, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -315,7 +313,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " suppress_response: true\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_invoke_request, + TestSampleData(params, im_protocol_invoke_request, "invoke_request\n" " suppress_response: false\n" " timed_request: false\n" @@ -328,7 +326,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " OnOff::Toggle\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_invoke_response, + TestSampleData(params, im_protocol_invoke_response, "invoke_response\n" " suppress_response: false\n" " invoke_responses\n" @@ -342,7 +340,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " status: 0 == kSuccess\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_invoke_request_change_channel, + TestSampleData(params, im_protocol_invoke_request_change_channel, "invoke_request\n" " suppress_response: false\n" " timed_request: false\n" @@ -356,7 +354,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " match: \"channel name\"\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_event_software_fault, + TestSampleData(params, im_protocol_event_software_fault, "report_data\n" " event_reports\n" " Anonymous<>\n" @@ -375,7 +373,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " suppress_response: true\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_event_multipress, + TestSampleData(params, im_protocol_event_multipress, "report_data\n" " event_reports\n" " Anonymous<>\n" @@ -394,22 +392,22 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); } -void TestMetaDataOnlyDecoding(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestMetaDataOnlyDecoding) { PayloadDecoderInitParams params; // NO CLUSTER DECODE TREE params.SetProtocolDecodeTree(chip::TLVMeta::protocols_meta); - TestSampleData(inSuite, params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); - TestSampleData(inSuite, params, secure_channel_pkbdf_param_request, + TestSampleData(params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); + TestSampleData(params, secure_channel_pkbdf_param_request, "pbkdf_param_request\n" " initiator_random: hex:7C8698755B8E9866BB4FFDC27B733F3B6EF7F83D43FBE0CA6AD2B8C52C8F4236\n" " initiator_session_id: 37677\n" " passcode_id: 0\n" " has_pbkdf_parameters: false\n"); - TestSampleData(inSuite, params, im_protocol_read_request, + TestSampleData(params, im_protocol_read_request, "read_request\n" " attribute_requests\n" " Anonymous<>\n" @@ -444,7 +442,7 @@ void TestMetaDataOnlyDecoding(nlTestSuite * inSuite, void * inContext) " attribute_id: 3\n" " fabric_filtered: false\n" " interaction_model_revison: 1\n"); - TestSampleData(inSuite, params, im_protocol_report_data, + TestSampleData(params, im_protocol_report_data, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -515,7 +513,7 @@ void TestMetaDataOnlyDecoding(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); // Different content - TestSampleData(inSuite, params, im_protocol_report_data_acl, + TestSampleData(params, im_protocol_report_data_acl, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -530,14 +528,14 @@ void TestMetaDataOnlyDecoding(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); } -void TestEmptyClusterMetaDataDecode(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestEmptyClusterMetaDataDecode) { PayloadDecoderInitParams params; params.SetProtocolDecodeTree(chip::TLVMeta::protocols_meta).SetClusterDecodeTree(empty_meta); - TestSampleData(inSuite, params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); - TestSampleData(inSuite, params, im_protocol_report_data_acl, + TestSampleData(params, secure_channel_mrp_ack, "mrp_ack: EMPTY\n"); + TestSampleData(params, im_protocol_report_data_acl, "report_data\n" " attribute_reports\n" " Anonymous<>\n" @@ -559,24 +557,24 @@ void TestEmptyClusterMetaDataDecode(nlTestSuite * inSuite, void * inContext) " interaction_model_revison: 1\n"); } -void TestMissingDecodeData(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestMissingDecodeData) { PayloadDecoderInitParams params; params.SetProtocolDecodeTree(empty_meta).SetClusterDecodeTree(empty_meta); - TestSampleData(inSuite, params, secure_channel_mrp_ack, "PROTO(0x0, 0x10): UNKNOWN\n"); - TestSampleData(inSuite, params, im_protocol_report_data_acl, "PROTO(0x1, 0x5): UNKNOWN\n"); + TestSampleData(params, secure_channel_mrp_ack, "PROTO(0x0, 0x10): UNKNOWN\n"); + TestSampleData(params, im_protocol_report_data_acl, "PROTO(0x1, 0x5): UNKNOWN\n"); } -void TestWrongDecodeData(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestWrongDecodeData) { PayloadDecoderInitParams params; params.SetProtocolDecodeTree(fake_protocols_meta).SetClusterDecodeTree(empty_meta); - TestSampleData(inSuite, params, secure_channel_mrp_ack, "proto16: EMPTY\n"); - TestSampleData(inSuite, params, im_protocol_report_data_acl, + TestSampleData(params, secure_channel_mrp_ack, "proto16: EMPTY\n"); + TestSampleData(params, im_protocol_report_data_acl, "proto5\n" " ContextTag(0x1)\n" " AnonymousTag()\n" @@ -598,7 +596,7 @@ void TestWrongDecodeData(nlTestSuite * inSuite, void * inContext) " ContextTag(0xFF): 1\n"); } -void TestNestingOverflow(nlTestSuite * inSuite, void * inContext) +TEST(TestDecoding, TestNestingOverflow) { PayloadDecoderInitParams params; params.SetProtocolDecodeTree(fake_protocols_meta).SetClusterDecodeTree(empty_meta); @@ -611,65 +609,62 @@ void TestNestingOverflow(nlTestSuite * inSuite, void * inContext) chip::TLV::TLVType unusedType; // Protocols start with an anonymous tagged structure, after which lists can be of any tags - NL_TEST_ASSERT(inSuite, writer.StartContainer(AnonymousTag(), kTLVType_Structure, unusedType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(AnonymousTag(), kTLVType_Structure, unusedType), CHIP_NO_ERROR); // nesting overflow here for (uint8_t i = 0; i < 32; i++) { - NL_TEST_ASSERT(inSuite, writer.StartContainer(ContextTag(i), kTLVType_List, unusedType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(ContextTag(i), kTLVType_List, unusedType), CHIP_NO_ERROR); } // Go back to 24 (still too much nesting) for (uint8_t i = 0; i < 8; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT( - inSuite, writer.StartContainer(ContextTag(static_cast(i + 0x10)), kTLVType_List, unusedType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(ContextTag(static_cast(i + 0x10)), kTLVType_List, unusedType), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } // Go back to 8 for (uint8_t i = 0; i < 16; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT( - inSuite, writer.StartContainer(ContextTag(static_cast(i + 0x20)), kTLVType_List, unusedType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(ContextTag(static_cast(i + 0x20)), kTLVType_List, unusedType), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } // Go back to 4 for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT( - inSuite, writer.StartContainer(ContextTag(static_cast(i + 0x30)), kTLVType_List, unusedType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(ContextTag(static_cast(i + 0x30)), kTLVType_List, unusedType), CHIP_NO_ERROR); } for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } // close everything for (uint8_t i = 0; i < 4; i++) { - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_List) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_List), CHIP_NO_ERROR); } - NL_TEST_ASSERT(inSuite, writer.EndContainer(kTLVType_Structure) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(kTLVType_Structure), CHIP_NO_ERROR); SamplePayload fake_payload{ chip::Protocols::InteractionModel::Id, 5, chip::ByteSpan(data_buffer, writer.GetLengthWritten()) }; - TestSampleData(inSuite, params, fake_payload, + TestSampleData(params, fake_payload, "proto5\n" " ContextTag(0x0)\n" " ContextTag(0x1)\n" @@ -696,24 +691,4 @@ void TestNestingOverflow(nlTestSuite * inSuite, void * inContext) " ContextTag(0x32)\n" " ContextTag(0x33)\n"); } - -const nlTest sTests[] = { - NL_TEST_DEF("TestFullDataDecoding", TestFullDataDecoding), // - NL_TEST_DEF("TestMetaDataOnlyDecoding", TestMetaDataOnlyDecoding), // - NL_TEST_DEF("TestEmptyClusterMetaDataDecode", TestEmptyClusterMetaDataDecode), // - NL_TEST_DEF("TestMissingDecodeData", TestMissingDecodeData), // - NL_TEST_DEF("TestWrongDecodeData", TestWrongDecodeData), // - NL_TEST_DEF("TestNestingOverflow", TestNestingOverflow), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestDecode() -{ - nlTestSuite theSuite = { "TestDecode", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestDecode) diff --git a/src/lib/format/tests/TestFlatTree.cpp b/src/lib/format/tests/TestFlatTree.cpp index 8eebb984b6adb9..fcf8e2713bf6b5 100644 --- a/src/lib/format/tests/TestFlatTree.cpp +++ b/src/lib/format/tests/TestFlatTree.cpp @@ -17,13 +17,12 @@ #include #include -#include #include #include -#include +#include namespace { @@ -82,43 +81,28 @@ class ByName const char * mName; }; -void TestFlatTreeFind(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatTree, TestFlatTreeFind) { - NL_TEST_ASSERT(inSuite, strcmp(FindEntry(tree, 0, ByTag(ContextTag(1)))->data.name, "hello") == 0); - NL_TEST_ASSERT(inSuite, strcmp(FindEntry(tree, 0, ByTag(ContextTag(2)))->data.name, "world") == 0); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 0, ByTag(ContextTag(3))) == nullptr); + EXPECT_STREQ(FindEntry(tree, 0, ByTag(ContextTag(1)))->data.name, "hello"); + EXPECT_STREQ(FindEntry(tree, 0, ByTag(ContextTag(2)))->data.name, "world"); + EXPECT_EQ(FindEntry(tree, 0, ByTag(ContextTag(3))), nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 0, ByName("hello"))->data.tag == ContextTag(1)); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 0, ByName("world"))->data.tag == ContextTag(2)); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 0, ByName("foo")) == nullptr); + EXPECT_EQ(FindEntry(tree, 0, ByName("hello"))->data.tag, ContextTag(1)); + EXPECT_EQ(FindEntry(tree, 0, ByName("world"))->data.tag, ContextTag(2)); + EXPECT_EQ(FindEntry(tree, 0, ByName("foo")), nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 1, ByTag(ContextTag(1))) == nullptr); - NL_TEST_ASSERT(inSuite, strcmp(FindEntry(tree, 1, ByTag(ProfileTag(234, 2)))->data.name, "b") == 0); - NL_TEST_ASSERT(inSuite, strcmp(FindEntry(tree, 1, ByTag(ProfileTag(345, 3)))->data.name, "c") == 0); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 1, ByTag(AnonymousTag())) == nullptr); + EXPECT_EQ(FindEntry(tree, 1, ByTag(ContextTag(1))), nullptr); + EXPECT_STREQ(FindEntry(tree, 1, ByTag(ProfileTag(234, 2)))->data.name, "b"); + EXPECT_STREQ(FindEntry(tree, 1, ByTag(ProfileTag(345, 3)))->data.name, "c"); + EXPECT_EQ(FindEntry(tree, 1, ByTag(AnonymousTag())), nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 2, ByTag(ContextTag(1))) == nullptr); - NL_TEST_ASSERT(inSuite, strcmp(FindEntry(tree, 2, ByTag(AnonymousTag()))->data.name, "foo") == 0); + EXPECT_EQ(FindEntry(tree, 2, ByTag(ContextTag(1))), nullptr); + EXPECT_STREQ(FindEntry(tree, 2, ByTag(AnonymousTag()))->data.name, "foo"); // out of array - NL_TEST_ASSERT(inSuite, FindEntry(tree, 3, ByTag(AnonymousTag())) == nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 100, ByTag(AnonymousTag())) == nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 1000, ByTag(AnonymousTag())) == nullptr); - NL_TEST_ASSERT(inSuite, FindEntry(tree, 9999999, ByTag(AnonymousTag())) == nullptr); + EXPECT_EQ(FindEntry(tree, 3, ByTag(AnonymousTag())), nullptr); + EXPECT_EQ(FindEntry(tree, 100, ByTag(AnonymousTag())), nullptr); + EXPECT_EQ(FindEntry(tree, 1000, ByTag(AnonymousTag())), nullptr); + EXPECT_EQ(FindEntry(tree, 9999999, ByTag(AnonymousTag())), nullptr); } - -const nlTest sTests[] = { - NL_TEST_DEF("TestFlatTreeFind", TestFlatTreeFind), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestFlatTree() -{ - nlTestSuite theSuite = { "FlatTree", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestFlatTree) diff --git a/src/lib/format/tests/TestFlatTreePosition.cpp b/src/lib/format/tests/TestFlatTreePosition.cpp index ee5f6b3c94176d..cf5a26e6c8662f 100644 --- a/src/lib/format/tests/TestFlatTreePosition.cpp +++ b/src/lib/format/tests/TestFlatTreePosition.cpp @@ -18,14 +18,13 @@ #include #include -#include #include #include #include -#include +#include namespace { @@ -94,16 +93,16 @@ class ByName }; #define ASSERT_HAS_NAME(p, n) \ - NL_TEST_ASSERT(inSuite, p.Get() != nullptr); \ - NL_TEST_ASSERT(inSuite, strcmp(p.Get()->name, n) == 0) + EXPECT_NE(p.Get(), nullptr); \ + EXPECT_STREQ(p.Get()->name, n); #define ASSERT_HAS_CONTEXT_TAG(p, t) \ - NL_TEST_ASSERT(inSuite, p.Get() != nullptr); \ - NL_TEST_ASSERT(inSuite, p.Get()->tag == ContextTag(t)) + EXPECT_NE(p.Get(), nullptr); \ + EXPECT_EQ(p.Get()->tag, ContextTag(t)) #define ASSERT_HAS_PROFILE_TAG(p, a, b) \ - NL_TEST_ASSERT(inSuite, p.Get() != nullptr); \ - NL_TEST_ASSERT(inSuite, p.Get()->tag == ProfileTag(a, b)) + EXPECT_NE(p.Get(), nullptr); \ + EXPECT_EQ(p.Get()->tag, ProfileTag(a, b)) template std::vector GetPath(Position & position) @@ -133,54 +132,54 @@ bool HasPath(const std::vector & v, Tag a, Tag b, Tag c) return (v.size() == 3) && (v[0] == a) && (v[1] == b) && (v[2] == c); } -void TestSimpleEnterExit(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatTreePosition, TestSimpleEnterExit) { Position position(tree.data(), tree.size()); // at start, top of tree has no value - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); // Go to hello, try going to invalid 2x, then go back position.Enter(ByTag(ContextTag(1))); ASSERT_HAS_NAME(position, "hello"); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(1))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(1))); position.Enter(ByTag(ContextTag(1))); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); position.Enter(ByTag(ContextTag(1))); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); + EXPECT_EQ(position.Get(), nullptr); position.Exit(); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); + EXPECT_EQ(position.Get(), nullptr); position.Exit(); - NL_TEST_ASSERT(inSuite, position.Get() != nullptr); + ASSERT_NE(position.Get(), nullptr); ASSERT_HAS_NAME(position, "hello"); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(1))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(1))); position.Exit(); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); + EXPECT_EQ(position.Get(), nullptr); } -void TestDeeperEnter(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatTreePosition, TestDeeperEnter) { Position position(tree.data(), tree.size()); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); + EXPECT_EQ(position.Get(), nullptr); position.Enter(ByName("world")); ASSERT_HAS_CONTEXT_TAG(position, 2); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2))); position.Enter(ByTag(ProfileTag(123, 1))); ASSERT_HAS_NAME(position, "a"); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(123, 1))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(123, 1))); position.Enter(ByTag(AnonymousTag())); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); position.Exit(); ASSERT_HAS_NAME(position, "a"); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(123, 1))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(123, 1))); position.Exit(); ASSERT_HAS_NAME(position, "world"); @@ -190,30 +189,30 @@ void TestDeeperEnter(nlTestSuite * inSuite, void * inContext) position.Enter(ByTag(AnonymousTag())); ASSERT_HAS_NAME(position, "foo"); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2), AnonymousTag())); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2), AnonymousTag())); // test some unknown for (int i = 0; i < 100; i++) { position.Enter(ByTag(AnonymousTag())); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); } for (int i = 0; i < 100; i++) { - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); position.Exit(); } - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2), AnonymousTag())); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2), AnonymousTag())); ASSERT_HAS_NAME(position, "foo"); position.Exit(); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2))); ASSERT_HAS_NAME(position, "b"); position.Exit(); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2))); ASSERT_HAS_NAME(position, "world"); // root and stay there @@ -221,15 +220,15 @@ void TestDeeperEnter(nlTestSuite * inSuite, void * inContext) position.Exit(); position.Exit(); position.Exit(); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_TRUE(GetPath(position).empty()); // can still navigate from the root position.Enter(ByName("world")); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2))); ASSERT_HAS_CONTEXT_TAG(position, 2); } -void TestDescendLimit(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatTreePosition, TestDescendLimit) { Position position(tree.data(), tree.size()); @@ -241,34 +240,17 @@ void TestDescendLimit(nlTestSuite * inSuite, void * inContext) // only 2 positions can be remembered. Running out of space position.Enter(ByName("foo")); - NL_TEST_ASSERT(inSuite, position.Get() == nullptr); - NL_TEST_ASSERT(inSuite, GetPath(position).empty()); + EXPECT_EQ(position.Get(), nullptr); + EXPECT_TRUE(GetPath(position).empty()); position.Exit(); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2), ProfileTag(234, 2))); ASSERT_HAS_NAME(position, "b"); ASSERT_HAS_PROFILE_TAG(position, 234, 2); position.Exit(); - NL_TEST_ASSERT(inSuite, HasPath(GetPath(position), ContextTag(2))); + EXPECT_TRUE(HasPath(GetPath(position), ContextTag(2))); ASSERT_HAS_NAME(position, "world"); ASSERT_HAS_CONTEXT_TAG(position, 2); } - -const nlTest sTests[] = { - NL_TEST_DEF("TestSimpleEnterExit", TestSimpleEnterExit), // - NL_TEST_DEF("TestDeeperEnter", TestDeeperEnter), // - NL_TEST_DEF("TestDescendLimit", TestDescendLimit), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestFlatTreePosition() -{ - nlTestSuite theSuite = { "FlatTree", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestFlatTreePosition) From 2ef3a366d8892f6aa96449c02690fa2099a92a29 Mon Sep 17 00:00:00 2001 From: Jakub Latusek Date: Tue, 23 Apr 2024 16:09:46 +0200 Subject: [PATCH 05/19] Add missing logging handler for embedded platforms for testing with Pigweed (#33105) * Add missing logging handler for embedded platforms * Update src/lib/support/UnitTest.cpp Co-authored-by: Arkadiusz Bokowy --------- Co-authored-by: Arkadiusz Bokowy --- src/lib/support/BUILD.gn | 1 + src/lib/support/UnitTest.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/lib/support/BUILD.gn b/src/lib/support/BUILD.gn index a5bf63a0034b41..34906592214fbd 100644 --- a/src/lib/support/BUILD.gn +++ b/src/lib/support/BUILD.gn @@ -350,6 +350,7 @@ pw_static_library("pw_tests_wrapper") { public_deps = [ "$dir_pw_log:impl", "$dir_pw_unit_test", + "$dir_pw_unit_test:logging", ] sources = [ "UnitTest.cpp", diff --git a/src/lib/support/UnitTest.cpp b/src/lib/support/UnitTest.cpp index 787898cccd82f2..95389398fefecb 100644 --- a/src/lib/support/UnitTest.cpp +++ b/src/lib/support/UnitTest.cpp @@ -1,12 +1,16 @@ #include "UnitTest.h" #include "pw_unit_test/framework.h" +#include "pw_unit_test/logging_event_handler.h" namespace chip { namespace test { int RunAllTests() { + testing::InitGoogleTest(nullptr, static_cast(nullptr)); + pw::unit_test::LoggingEventHandler handler; + pw::unit_test::RegisterEventHandler(&handler); return RUN_ALL_TESTS(); } From 700e6d2ed4d6048a6ea4eb82836ace4de56dcfdb Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 23 Apr 2024 10:52:12 -0400 Subject: [PATCH 06/19] Switch MTRDevice to always using by-cluster persistent attribute storage. (#33096) MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER was already defaulted to 1; this just removes the codepaths when this is set to 0. Cleans up some of the controller data store bits that then become unused, and improves test coverage of this codepath. Fixes formatting of the endpoint id in _clusterDataKeyForNodeID. --- src/darwin/Framework/CHIP/MTRDevice.mm | 29 -- .../Framework/CHIP/MTRDeviceController.mm | 8 - .../CHIP/MTRDeviceControllerDataStore.h | 6 +- .../CHIP/MTRDeviceControllerDataStore.mm | 345 +++--------------- .../Framework/CHIP/MTRDevice_Internal.h | 3 - .../Framework/CHIPTests/MTRDeviceTests.m | 38 +- .../CHIPTests/MTRPerControllerStorageTests.m | 251 ++++++------- .../TestHelpers/MTRTestDeclarations.h | 10 +- 8 files changed, 197 insertions(+), 493 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index d171c3982701ba..374b2e8cc60bc0 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -1040,9 +1040,7 @@ - (void)_handleReportBegin for (MTRClusterPath * clusterPath in clusterPaths) { NSNumber * dataVersion = _clusterData[clusterPath].dataVersion; NSDictionary * attributes = nil; -#if MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER attributes = [self _attributesForCluster:clusterPath]; -#endif if (dataVersion || attributes) { MTRDeviceClusterData * clusterData = [[MTRDeviceClusterData alloc] initWithDataVersion:dataVersion attributes:attributes]; clusterDataToReturn[clusterPath] = clusterData; @@ -2340,12 +2338,6 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray * attributeResponseValue in reportedAttributeValues) { MTRAttributePath * attributePath = attributeResponseValue[MTRAttributePathKey]; NSDictionary * attributeDataValue = attributeResponseValue[MTRDataKey]; @@ -2388,20 +2380,7 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray * std::lock_guard lock(_lock); -#if MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER // For each cluster, extract and create the attribute response-value for the read cache // TODO: consider some optimization in how the read cache is structured so there's fewer conversions from this format to what's in the cache for (MTRClusterPath * clusterPath in clusterData) { @@ -2548,7 +2520,6 @@ - (void)setClusterData:(NSDictionary * } } } -#endif [_clusterData addEntriesFromDictionary:clusterData]; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 6150b1cc748da1..4dfa229e71cc85 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -948,14 +948,6 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N [deviceToReturn setClusterData:prefetchedClusterData]; } } else { -#if !MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER - // Load persisted attributes if they exist. - NSArray * attributesFromCache = [_controllerDataStore getStoredAttributesForNodeID:nodeID]; - MTR_LOG_INFO("Loaded %lu attributes from storage for %@", static_cast(attributesFromCache.count), deviceToReturn); - if (attributesFromCache.count) { - [deviceToReturn setAttributeValues:attributesFromCache reportChanges:NO]; - } -#endif // Load persisted cluster data if they exist. NSDictionary * clusterData = [_controllerDataStore getStoredClusterDataForNodeID:nodeID]; MTR_LOG_INFO("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), deviceToReturn); diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h index bc3b8f37f90fbb..91a6c0e3142a38 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h @@ -72,12 +72,10 @@ typedef void (^MTRDeviceControllerDataStoreClusterDataHandler)(NSDictionary *)getStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; - (nullable NSDictionary *)getStoredClusterDataForNodeID:(NSNumber *)nodeID; - (void)storeClusterData:(NSDictionary *)clusterData forNodeID:(NSNumber *)nodeID; -- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)clearAllStoredAttributes; +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID; +- (void)clearAllStoredClusterData; @end diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index d6c7e8c00dfeb1..cac425c9453ad3 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -306,20 +306,14 @@ - (nullable MTRCASESessionResumptionInfo *)_findResumptionInfoWithKey:(nullable * key: "attrCacheNodeIndex" * value: list of nodeIDs * EndpointID index - * key: "attrCacheEndpointIndex::endpointID" + * key: "attrCacheEndpointIndex:" * value: list of endpoint IDs * ClusterID index - * key: " clusters" + * key: "attrCacheClusterIndex::" * value: list of cluster IDs - * AttributeID index - * key: " attributes" - * value: list of attribute IDs - * Attribute data entry: - * key: " attribute data" - * value: serialized dictionary of attribute data - * - * Attribute data dictionary - * Additional value "serial number" + * Cluster data entry: + * key: "attrCacheClusterData:::" + * value: MTRDeviceClusterData */ - (id)_fetchAttributeCacheValueForKey:(NSString *)key expectedClass:(Class)expectedClass; @@ -371,16 +365,19 @@ - (BOOL)_removeAttributeCacheValueForKey:(NSString *)key - (nullable NSArray *)_fetchNodeIndex { + dispatch_assert_queue(_storageDelegateQueue); return [self _fetchAttributeCacheValueForKey:sAttributeCacheNodeIndexKey expectedClass:[NSArray class]]; } - (BOOL)_storeNodeIndex:(NSArray *)nodeIndex { + dispatch_assert_queue(_storageDelegateQueue); return [self _storeAttributeCacheValue:nodeIndex forKey:sAttributeCacheNodeIndexKey]; } - (BOOL)_deleteNodeIndex { + dispatch_assert_queue(_storageDelegateQueue); return [self _removeAttributeCacheValueForKey:sAttributeCacheNodeIndexKey]; } @@ -393,6 +390,8 @@ - (NSString *)_endpointIndexKeyForNodeID:(NSNumber *)nodeID - (nullable NSArray *)_fetchEndpointIndexForNodeID:(NSNumber *)nodeID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return nil; @@ -403,6 +402,8 @@ - (NSString *)_endpointIndexKeyForNodeID:(NSNumber *)nodeID - (BOOL)_storeEndpointIndex:(NSArray *)endpointIndex forNodeID:(NSNumber *)nodeID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -413,6 +414,8 @@ - (BOOL)_storeEndpointIndex:(NSArray *)endpointIndex forNodeID:(NSNu - (BOOL)_deleteEndpointIndexForNodeID:(NSNumber *)nodeID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -430,6 +433,8 @@ - (NSString *)_clusterIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber - (nullable NSArray *)_fetchClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return nil; @@ -440,6 +445,8 @@ - (NSString *)_clusterIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber - (BOOL)_storeClusterIndex:(NSArray *)clusterIndex forNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -450,6 +457,8 @@ - (BOOL)_storeClusterIndex:(NSArray *)clusterIndex forNodeID:(NSNumb - (BOOL)_deleteClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -462,11 +471,13 @@ - (BOOL)_deleteClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)e - (NSString *)_clusterDataKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { - return [sAttributeCacheClusterDataKeyPrefix stringByAppendingFormat:@":0x%016llX:%0x04X:0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue]; + return [sAttributeCacheClusterDataKeyPrefix stringByAppendingFormat:@":0x%016llX:0x%04X:0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue]; } - (nullable MTRDeviceClusterData *)_fetchClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID || !clusterID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return nil; @@ -477,6 +488,8 @@ - (nullable MTRDeviceClusterData *)_fetchClusterDataForNodeID:(NSNumber *)nodeID - (BOOL)_storeClusterData:(MTRDeviceClusterData *)clusterData forNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID || !clusterID || !clusterData) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -487,6 +500,8 @@ - (BOOL)_storeClusterData:(MTRDeviceClusterData *)clusterData forNodeID:(NSNumbe - (BOOL)_deleteClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { + dispatch_assert_queue(_storageDelegateQueue); + if (!nodeID || !endpointID || !clusterID) { MTR_LOG_ERROR("%s: unexpected nil input", __func__); return NO; @@ -495,139 +510,22 @@ - (BOOL)_deleteClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)en return [self _removeAttributeCacheValueForKey:[self _clusterDataKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID]]; } -static NSString * sAttributeCacheAttributeIndexKeyPrefix = @"attrCacheAttributeIndex"; - -- (NSString *)_attributeIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID -{ - return [sAttributeCacheAttributeIndexKeyPrefix stringByAppendingFormat:@":0x%016llX:0x%04X:0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue]; -} - -- (nullable NSArray *)_fetchAttributeIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID -{ - return [self _fetchAttributeCacheValueForKey:[self _attributeIndexKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID] expectedClass:[NSArray class]]; -} - -- (BOOL)_storeAttributeIndex:(NSArray *)attributeIndex forNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID -{ - return [self _storeAttributeCacheValue:attributeIndex forKey:[self _attributeIndexKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID]]; -} - -- (BOOL)_deleteAttributeIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID -{ - return [self _removeAttributeCacheValueForKey:[self _attributeIndexKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID]]; -} - -static NSString * sAttributeCacheAttributeValueKeyPrefix = @"attrCacheAttributeValue"; - -- (NSString *)_attributeValueKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID -{ - return [sAttributeCacheAttributeValueKeyPrefix stringByAppendingFormat:@":0x%016llX:0x%04X:0x%08lX:0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue, attributeID.unsignedLongValue]; -} - -- (nullable NSDictionary *)_fetchAttributeValueForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID -{ - return [self _fetchAttributeCacheValueForKey:[self _attributeValueKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID] expectedClass:[NSDictionary class]]; -} - -- (BOOL)_storeAttributeValue:(NSDictionary *)value forNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID -{ - return [self _storeAttributeCacheValue:value forKey:[self _attributeValueKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID]]; -} - -- (BOOL)_deleteAttributeValueForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID -{ - return [self _removeAttributeCacheValueForKey:[self _attributeValueKeyForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID]]; -} - #pragma - Attribute Cache management #ifndef ATTRIBUTE_CACHE_VERBOSE_LOGGING #define ATTRIBUTE_CACHE_VERBOSE_LOGGING 0 #endif -- (nullable NSArray *)getStoredAttributesForNodeID:(NSNumber *)nodeID -{ - __block NSMutableArray * attributesToReturn = nil; - dispatch_sync(_storageDelegateQueue, ^{ - // Fetch node index - NSArray * nodeIndex = [self _fetchNodeIndex]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for nodeIndex", static_cast(nodeIndex.count)); -#endif - - if (![nodeIndex containsObject:nodeID]) { - // Sanity check and delete if nodeID exists in index - NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; - if (endpointIndex) { - MTR_LOG_ERROR("Persistent attribute cache contains orphaned entry for nodeID %@ - deleting", nodeID); - [self clearStoredAttributesForNodeID:nodeID]; - } - - MTR_LOG_INFO("Fetch got no value for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); - attributesToReturn = nil; - return; - } - - // Fetch endpoint index - NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for endpointIndex @ node 0x%016llX", static_cast(endpointIndex.count), nodeID.unsignedLongLongValue); -#endif - - for (NSNumber * endpointID in endpointIndex) { - // Fetch cluster index - NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for clusterIndex @ node 0x%016llX %u", static_cast(clusterIndex.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); -#endif - - for (NSNumber * clusterID in clusterIndex) { - // Fetch attribute index - NSArray * attributeIndex = [self _fetchAttributeIndexForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for attributeIndex @ node 0x%016llX endpoint %u cluster 0x%08lX", static_cast(attributeIndex.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); -#endif - - for (NSNumber * attributeID in attributeIndex) { - NSDictionary * value = [self _fetchAttributeValueForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %u values for attribute value @ node 0x%016llX endpoint %u cluster 0x%08lX attribute 0x%08lX", value ? 1 : 0, nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue, attributeID.unsignedLongValue); -#endif - - if (value) { - if (!attributesToReturn) { - attributesToReturn = [NSMutableArray array]; - } - - // Construct data-value dictionary and add to array - MTRAttributePath * path = [MTRAttributePath attributePathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]; - [attributesToReturn addObject:@ { MTRAttributePathKey : path, MTRDataKey : value }]; - } - } - - // TODO: Add per-cluster integrity check verification - } - } - }); - - return attributesToReturn; -} - #ifdef DEBUG -- (void)unitTestPruneEmptyStoredAttributesBranches +- (void)unitTestPruneEmptyStoredClusterDataBranches { dispatch_sync(_storageDelegateQueue, ^{ - [self _pruneEmptyStoredAttributesBranches]; + [self _pruneEmptyStoredClusterDataBranches]; }); } #endif -- (void)_pruneEmptyStoredAttributesBranches +- (void)_pruneEmptyStoredClusterDataBranches { dispatch_assert_queue(_storageDelegateQueue); @@ -648,36 +546,10 @@ - (void)_pruneEmptyStoredAttributesBranches NSMutableArray * clusterIndexCopy = [clusterIndex mutableCopy]; for (NSNumber * clusterID in clusterIndex) { - // Fetch attribute index - NSArray * attributeIndex = [self _fetchAttributeIndexForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - NSMutableArray * attributeIndexCopy = [attributeIndex mutableCopy]; - - for (NSNumber * attributeID in attributeIndex) { - NSDictionary * value = [self _fetchAttributeValueForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID]; - - if (!value) { - [attributeIndexCopy removeObject:attributeID]; - } - } - - if (attributeIndex.count != attributeIndexCopy.count) { - BOOL success; - BOOL clusterDataSuccess = YES; - if (attributeIndexCopy.count) { - success = [self _storeAttributeIndex:attributeIndexCopy forNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - } else { - [clusterIndexCopy removeObject:clusterID]; - success = [self _deleteAttributeIndexForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - clusterDataSuccess = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - } - if (!success) { - storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredAttributesBranches for attributeIndex (%lu) @ node 0x%016llX endpoint %u cluster 0x%08lX", static_cast(attributeIndexCopy.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); - } - if (!clusterDataSuccess) { - storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredAttributesBranches for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); - } + // Fetch cluster data, if it exists. + MTRDeviceClusterData * clusterData = [self _fetchClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; + if (!clusterData) { + [clusterIndexCopy removeObject:clusterID]; } } @@ -691,7 +563,7 @@ - (void)_pruneEmptyStoredAttributesBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredAttributesBranches for clusterIndex (%lu) @ node 0x%016llX endpoint %u", static_cast(clusterIndexCopy.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for clusterIndex (%lu) @ node 0x%016llX endpoint %u", static_cast(clusterIndexCopy.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); } } } @@ -706,7 +578,7 @@ - (void)_pruneEmptyStoredAttributesBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredAttributesBranches for endpointIndex (%lu) @ node 0x%016llX", static_cast(endpointIndexCopy.count), nodeID.unsignedLongLongValue); + MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for endpointIndex (%lu) @ node 0x%016llX", static_cast(endpointIndexCopy.count), nodeID.unsignedLongLongValue); } } } @@ -720,114 +592,23 @@ - (void)_pruneEmptyStoredAttributesBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredAttributesBranches for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); + MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); } } if (storeFailures) { - MTR_LOG_ERROR("Store failed in _pruneEmptyStoredAttributesBranches: failure count %lu", static_cast(storeFailures)); + MTR_LOG_ERROR("Store failed in _pruneEmptyStoredClusterDataBranches: failure count %lu", static_cast(storeFailures)); } } -- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID +- (void)_clearStoredClusterDataForNodeID:(NSNumber *)nodeID { - dispatch_async(_storageDelegateQueue, ^{ - NSUInteger storeFailures = 0; - - for (NSDictionary * dataValue in dataValues) { - MTRAttributePath * path = dataValue[MTRAttributePathKey]; - NSDictionary * value = dataValue[MTRDataKey]; - -#if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Attempt to store attribute value @ node 0x%016llX endpoint %u cluster 0x%08lX attribute 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue, path.attribute.unsignedLongValue); -#endif - - BOOL storeFailed = NO; - // Ensure node index exists - NSArray * nodeIndex = [self _fetchNodeIndex]; - if (!nodeIndex) { - nodeIndex = [NSArray arrayWithObject:nodeID]; - storeFailed = ![self _storeNodeIndex:nodeIndex]; - } else if (![nodeIndex containsObject:nodeID]) { - storeFailed = ![self _storeNodeIndex:[nodeIndex arrayByAddingObject:nodeID]]; - } - if (storeFailed) { - storeFailures++; - MTR_LOG_INFO("Store failed for nodeIndex"); - continue; - } - - // Ensure endpoint index exists - NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; - if (!endpointIndex) { - endpointIndex = [NSArray arrayWithObject:path.endpoint]; - storeFailed = ![self _storeEndpointIndex:endpointIndex forNodeID:nodeID]; - } else if (![endpointIndex containsObject:path.endpoint]) { - storeFailed = ![self _storeEndpointIndex:[endpointIndex arrayByAddingObject:path.endpoint] forNodeID:nodeID]; - } - if (storeFailed) { - storeFailures++; - MTR_LOG_INFO("Store failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); - continue; - } - - // Ensure cluster index exists - NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:path.endpoint]; - if (!clusterIndex) { - clusterIndex = [NSArray arrayWithObject:path.cluster]; - storeFailed = ![self _storeClusterIndex:clusterIndex forNodeID:nodeID endpointID:path.endpoint]; - } else if (![clusterIndex containsObject:path.cluster]) { - storeFailed = ![self _storeClusterIndex:[clusterIndex arrayByAddingObject:path.cluster] forNodeID:nodeID endpointID:path.endpoint]; - } - if (storeFailed) { - storeFailures++; - MTR_LOG_INFO("Store failed for clusterIndex @ node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue); - continue; - } - - // TODO: Add per-cluster integrity check calculation and store with cluster - // TODO: Think about adding more integrity check for endpoint and node levels as well - - // Ensure attribute index exists - NSArray * attributeIndex = [self _fetchAttributeIndexForNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; - if (!attributeIndex) { - attributeIndex = [NSArray arrayWithObject:path.attribute]; - storeFailed = ![self _storeAttributeIndex:attributeIndex forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; - } else if (![attributeIndex containsObject:path.attribute]) { - storeFailed = ![self _storeAttributeIndex:[attributeIndex arrayByAddingObject:path.attribute] forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; - } - if (storeFailed) { - storeFailures++; - MTR_LOG_INFO("Store failed for attributeIndex @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue); - continue; - } - - // Store value - storeFailed = ![self _storeAttributeValue:value forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster attributeID:path.attribute]; - if (storeFailed) { - storeFailures++; - MTR_LOG_INFO("Store failed for attribute value @ node 0x%016llX endpoint %u cluster 0x%08lX attribute 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue, path.attribute.unsignedLongValue); - } - } - - // In the rare event that store fails, allow all attribute store attempts to go through and prune empty branches at the end altogether. - if (storeFailures) { - [self _pruneEmptyStoredAttributesBranches]; - MTR_LOG_ERROR("Store failed in -storeAttributeValues:forNodeID: failure count %lu", static_cast(storeFailures)); - } - }); -} + dispatch_assert_queue(_storageDelegateQueue); -- (void)_clearStoredAttributesForNodeID:(NSNumber *)nodeID -{ NSUInteger endpointsClearAttempts = 0; - NSUInteger clustersClearAttempts = 0; NSUInteger clusterDataClearAttempts = 0; - NSUInteger attributesClearAttempts = 0; NSUInteger endpointsCleared = 0; - NSUInteger clustersCleared = 0; NSUInteger clusterDataCleared = 0; - NSUInteger attributesCleared = 0; // Fetch endpoint index NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; @@ -837,30 +618,9 @@ - (void)_clearStoredAttributesForNodeID:(NSNumber *)nodeID // Fetch cluster index NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID]; - clustersClearAttempts += clusterIndex.count; clusterDataClearAttempts += clusterIndex.count; // Assuming every cluster has cluster data for (NSNumber * clusterID in clusterIndex) { - // Fetch attribute index - NSArray * attributeIndex = [self _fetchAttributeIndexForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - - attributesClearAttempts += attributeIndex.count; - for (NSNumber * attributeID in attributeIndex) { - BOOL success = [self _deleteAttributeValueForNodeID:nodeID endpointID:endpointID clusterID:clusterID attributeID:attributeID]; - if (!success) { - MTR_LOG_INFO("Delete failed for attribute value @ node 0x%016llX endpoint %u cluster 0x%08lX attribute 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue, attributeID.unsignedLongValue); - } else { - attributesCleared++; - } - } - - BOOL success = [self _deleteAttributeIndexForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; - if (!success) { - MTR_LOG_INFO("Delete failed for attributeIndex @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); - } else { - clustersCleared++; - } - - success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; + BOOL success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; if (!success) { MTR_LOG_INFO("Delete failed for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); } else { @@ -878,16 +638,16 @@ - (void)_clearStoredAttributesForNodeID:(NSNumber *)nodeID BOOL success = [self _deleteEndpointIndexForNodeID:nodeID]; if (!success) { - MTR_LOG_INFO("Delete failed for endpointrIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); + MTR_LOG_INFO("Delete failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); } - MTR_LOG_INFO("clearStoredAttributesForNodeID: deleted endpoints %lu/%lu clusters %lu/%lu clusterData %lu/%lu attributes %lu/%lu", static_cast(endpointsCleared), static_cast(endpointsClearAttempts), static_cast(clustersCleared), static_cast(clustersClearAttempts), static_cast(clusterDataCleared), static_cast(clusterDataClearAttempts), static_cast(attributesCleared), static_cast(attributesClearAttempts)); + MTR_LOG_INFO("clearStoredClusterDataForNodeID: deleted endpoints %lu/%lu clusters %lu/%lu", static_cast(endpointsCleared), static_cast(endpointsClearAttempts), static_cast(clusterDataCleared), static_cast(clusterDataClearAttempts)); } -- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID { dispatch_async(_storageDelegateQueue, ^{ - [self _clearStoredAttributesForNodeID:nodeID]; + [self _clearStoredClusterDataForNodeID:nodeID]; NSArray * nodeIndex = [self _fetchNodeIndex]; NSMutableArray * nodeIndexCopy = [nodeIndex mutableCopy]; [nodeIndexCopy removeObject:nodeID]; @@ -905,14 +665,14 @@ - (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID }); } -- (void)clearAllStoredAttributes +- (void)clearAllStoredClusterData { dispatch_async(_storageDelegateQueue, ^{ // Fetch node index NSArray * nodeIndex = [self _fetchNodeIndex]; for (NSNumber * nodeID in nodeIndex) { - [self _clearStoredAttributesForNodeID:nodeID]; + [self _clearStoredClusterDataForNodeID:nodeID]; } BOOL success = [self _deleteNodeIndex]; @@ -943,7 +703,10 @@ - (void)clearAllStoredAttributes NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; if (endpointIndex) { MTR_LOG_ERROR("Persistent attribute cache contains orphaned entry for nodeID %@ - deleting", nodeID); - [self clearStoredAttributesForNodeID:nodeID]; + // _clearStoredClusterDataForNodeID because we are are already + // on the _storageDelegateQueue and do not need to modify the + // node index in this case. + [self _clearStoredClusterDataForNodeID:nodeID]; } MTR_LOG_INFO("Fetch got no value for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); @@ -1203,10 +966,10 @@ - (void)storeClusterData:(NSDictionary } } - // In the rare event that store fails, allow all attribute store attempts to go through and prune empty branches at the end altogether. + // In the rare event that store fails, allow all cluster data store attempts to go through and prune empty branches at the end altogether. if (storeFailures) { - [self _pruneEmptyStoredAttributesBranches]; - MTR_LOG_ERROR("Store failed in -storeAttributeValues:forNodeID: failure count %lu", static_cast(storeFailures)); + [self _pruneEmptyStoredClusterDataBranches]; + MTR_LOG_ERROR("Store failed in -storeClusterData:forNodeID: failure count %lu", static_cast(storeFailures)); } }); } diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 28833060ba6c27..57ee5446f3ba50 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -30,9 +30,6 @@ typedef NSDictionary * MTRDeviceDataValueDictionary; typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice); -// Whether to store attributes by cluster instead of as individual entries for each attribute -#define MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER 1 - /** * Information about a cluster, currently is just data version */ diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 4f97026ed6644f..d13f319faaa9e9 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -179,9 +179,9 @@ + (void)tearDown // Restore testing setting to previous state, and remove all persisted attributes MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = slocalTestStorageEnabledBeforeUnitTest; - [sController.controllerDataStore clearAllStoredAttributes]; - NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - XCTAssertEqual(storedAttributesAfterClear.count, 0); + [sController.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); MTRDeviceController * controller = sController; XCTAssertNotNil(controller); @@ -1346,9 +1346,9 @@ - (void)test016_FailedSubscribeWithCacheReadDuringFailure - (void)test017_TestMTRDeviceBasics { // Ensure the test starts with clean slate, even with MTRDeviceControllerLocalTestStorage enabled - [sController.controllerDataStore clearAllStoredAttributes]; - NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - XCTAssertEqual(storedAttributesAfterClear.count, 0); + [sController.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; dispatch_queue_t queue = dispatch_get_main_queue(); @@ -2571,9 +2571,9 @@ - (void)test028_TimeZoneAndDST - (void)test029_MTRDeviceWriteCoalescing { // Ensure the test starts with clean slate, even with MTRDeviceControllerLocalTestStorage enabled - [sController.controllerDataStore clearAllStoredAttributes]; - NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - XCTAssertEqual(storedAttributesAfterClear.count, 0); + [sController.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; dispatch_queue_t queue = dispatch_get_main_queue(); @@ -2910,9 +2910,9 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage // First start with clean slate by removing the MTRDevice and clearing the persisted cache __auto_type * device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; [sController removeDevice:device]; - [sController.controllerDataStore clearAllStoredAttributes]; - NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - XCTAssertEqual(storedAttributesAfterClear.count, 0); + [sController.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); // Now recreate device and get subscription primed device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; @@ -2934,13 +2934,8 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage NSUInteger attributesReportedWithFirstSubscription = [device unitTestAttributesReportedSinceLastCheck]; -#if MTRDEVICE_ATTRIBUTE_CACHE_STORE_ATTRIBUTES_BY_CLUSTER NSDictionary * dataStoreClusterDataAfterFirstSubscription = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; XCTAssertTrue(dataStoreClusterDataAfterFirstSubscription.count > 0); -#else - NSArray * dataStoreValuesAfterFirstSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - XCTAssertTrue(dataStoreValuesAfterFirstSubscription.count > 0); -#endif // Now remove device, resubscribe, and see that it succeeds [sController removeDevice:device]; @@ -2971,8 +2966,13 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage // 2) Some attributes do change on resubscribe // * With all-clusts-app as of 2024-02-10, out of 1287 persisted attributes, still 450 attributes were reported with filter // And so conservatively, assert that data version filters save at least 300 entries. - NSArray * dataStoreValuesAfterSecondSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; - NSUInteger storedAttributeCountDifferenceFromMTRDeviceReport = dataStoreValuesAfterSecondSubscription.count - attributesReportedWithSecondSubscription; + NSDictionary * storedClusterDataAfterSecondSubscription = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + NSUInteger dataStoreAttributeCountAfterSecondSubscription = 0; + for (NSNumber * clusterID in storedClusterDataAfterSecondSubscription) { + MTRDeviceClusterData * clusterData = storedClusterDataAfterSecondSubscription[clusterID]; + dataStoreAttributeCountAfterSecondSubscription += clusterData.attributes.count; + } + NSUInteger storedAttributeCountDifferenceFromMTRDeviceReport = dataStoreAttributeCountAfterSecondSubscription - attributesReportedWithSecondSubscription; XCTAssertTrue(storedAttributeCountDifferenceFromMTRDeviceReport > 300); } diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index df98530a81db18..bea49d957653c7 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -19,6 +19,7 @@ // system dependencies #import +#import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" #import "MTRErrorTestUtils.h" @@ -181,6 +182,7 @@ @interface MTRPerControllerStorageTests : XCTestCase @implementation MTRPerControllerStorageTests { dispatch_queue_t _storageQueue; + BOOL _localTestStorageEnabledBeforeUnitTest; } - (void)setUp @@ -189,6 +191,12 @@ - (void)setUp [super setUp]; [self setContinueAfterFailure:NO]; + // Make sure local test storage is off, because we assume that the storage + // delegate we provide is in fact used for local storage as part of our + // tests. + _localTestStorageEnabledBeforeUnitTest = MTRDeviceControllerLocalTestStorage.localTestStorageEnabled; + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = NO; + _storageQueue = dispatch_queue_create("test.storage.queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); } @@ -197,6 +205,10 @@ - (void)tearDown // Per-test teardown, runs after each test. [self stopFactory]; _storageQueue = nil; + + // Restore local test storage setting to previous state. + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = _localTestStorageEnabledBeforeUnitTest; + [super tearDown]; } @@ -1081,132 +1093,137 @@ - (void)test008_TestDataStoreDirect XCTAssertEqualObjects(controller.controllerNodeID, nodeID); - NSArray * testAttributes = @[ - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(1) attributeID:@(1)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(111) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(1) attributeID:@(2)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(112) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(1) attributeID:@(3)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(113) } }, - - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(2) attributeID:@(1)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(121) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(2) attributeID:@(2)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(122) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(2) attributeID:@(3)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(123) } }, - - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(2) clusterID:@(1) attributeID:@(1)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(211) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(2) clusterID:@(1) attributeID:@(2)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(212) } }, - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(2) clusterID:@(1) attributeID:@(3)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(213) } }, - ]; - [controller.controllerDataStore storeAttributeValues:testAttributes forNodeID:@(1001)]; - [controller.controllerDataStore storeAttributeValues:testAttributes forNodeID:@(1002)]; - [controller.controllerDataStore storeAttributeValues:testAttributes forNodeID:@(1003)]; - MTRDeviceClusterData * testClusterData1 = [[MTRDeviceClusterData alloc] init]; testClusterData1.dataVersion = @(1); + testClusterData1.attributes = @{ + @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(111) }, + @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(112) }, + @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(113) }, + }; MTRDeviceClusterData * testClusterData2 = [[MTRDeviceClusterData alloc] init]; testClusterData2.dataVersion = @(2); + testClusterData2.attributes = @{ + @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(121) }, + @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(122) }, + @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(123) }, + }; MTRDeviceClusterData * testClusterData3 = [[MTRDeviceClusterData alloc] init]; testClusterData3.dataVersion = @(3); + testClusterData3.attributes = @{ + @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(211) }, + @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(212) }, + @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(213) }, + }; NSDictionary * testClusterData = @{ [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(1)] : testClusterData1, [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(2)] : testClusterData2, - [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(3)] : testClusterData3, + [MTRClusterPath clusterPathWithEndpointID:@(2) clusterID:@(3)] : testClusterData3, }; [controller.controllerDataStore storeClusterData:testClusterData forNodeID:@(1001)]; + [controller.controllerDataStore storeClusterData:testClusterData forNodeID:@(1002)]; + [controller.controllerDataStore storeClusterData:testClusterData forNodeID:@(1003)]; - // Check values are written and can be fetched - NSArray * dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1001)]; - XCTAssertEqual(dataStoreValues.count, 9); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1002)]; - XCTAssertEqual(dataStoreValues.count, 9); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1003)]; - XCTAssertEqual(dataStoreValues.count, 9); - - // Check values - NSUInteger unexpectedValues = 0; - for (NSDictionary * responseValue in dataStoreValues) { - MTRAttributePath * path = responseValue[MTRAttributePathKey]; - XCTAssertNotNil(path); - NSDictionary * dataValue = responseValue[MTRDataKey]; - XCTAssertNotNil(dataValue); - NSString * type = dataValue[MTRTypeKey]; - XCTAssertNotNil(type); - XCTAssertEqualObjects(type, MTRUnsignedIntegerValueType); - NSNumber * value = dataValue[MTRValueKey]; - XCTAssertNotNil(value); - - if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(1)]) { - XCTAssertEqualObjects(value, @(111)); - } else if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(2)]) { - XCTAssertEqualObjects(value, @(112)); - } else if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(3)]) { - XCTAssertEqualObjects(value, @(113)); - } else if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(2)] && [path.attribute isEqualToNumber:@(1)]) { - XCTAssertEqualObjects(value, @(121)); - } else if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(2)] && [path.attribute isEqualToNumber:@(2)]) { - XCTAssertEqualObjects(value, @(122)); - } else if ([path.endpoint isEqualToNumber:@(1)] && [path.cluster isEqualToNumber:@(2)] && [path.attribute isEqualToNumber:@(3)]) { - XCTAssertEqualObjects(value, @(123)); - } else if ([path.endpoint isEqualToNumber:@(2)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(1)]) { - XCTAssertEqualObjects(value, @(211)); - } else if ([path.endpoint isEqualToNumber:@(2)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(2)]) { - XCTAssertEqualObjects(value, @(212)); - } else if ([path.endpoint isEqualToNumber:@(2)] && [path.cluster isEqualToNumber:@(1)] && [path.attribute isEqualToNumber:@(3)]) { - XCTAssertEqualObjects(value, @(213)); - } else { - unexpectedValues++; + for (NSNumber * nodeID in @[ @(1001), @(1002), @(1003) ]) { + NSDictionary * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:nodeID]; + for (MTRClusterPath * path in testClusterData) { + XCTAssertEqualObjects(testClusterData[path], dataStoreClusterData[path]); } } - XCTAssertEqual(unexpectedValues, 0); - NSDictionary * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:@(1001)]; - for (MTRClusterPath * path in testClusterData) { - XCTAssertEqualObjects(testClusterData[path].dataVersion, dataStoreClusterData[path].dataVersion); + [controller.controllerDataStore clearStoredClusterDataForNodeID:@(1001)]; + XCTAssertNil([controller.controllerDataStore getStoredClusterDataForNodeID:@(1001)]); + for (NSNumber * nodeID in @[ @(1002), @(1003) ]) { + NSDictionary * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:nodeID]; + for (MTRClusterPath * path in testClusterData) { + XCTAssertEqualObjects(testClusterData[path], dataStoreClusterData[path]); + } } - [controller.controllerDataStore clearStoredAttributesForNodeID:@(1001)]; - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1001)]; - XCTAssertEqual(dataStoreValues.count, 0); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1002)]; - XCTAssertEqual(dataStoreValues.count, 9); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1003)]; - XCTAssertEqual(dataStoreValues.count, 9); - - [controller.controllerDataStore clearAllStoredAttributes]; - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1001)]; - XCTAssertEqual(dataStoreValues.count, 0); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1002)]; - XCTAssertEqual(dataStoreValues.count, 0); - dataStoreValues = [controller.controllerDataStore getStoredAttributesForNodeID:@(1003)]; - XCTAssertEqual(dataStoreValues.count, 0); + [controller.controllerDataStore clearAllStoredClusterData]; + for (NSNumber * nodeID in @[ @(1001), @(1002), @(1003) ]) { + XCTAssertNil([controller.controllerDataStore getStoredClusterDataForNodeID:nodeID]); + } // Test MTRDeviceControllerDataStore _pruneEmptyStoredAttributesBranches // - Clear cache - // - Store an attribute - // - Manually delete it from the test storage delegate + // - Store some cluster data + // - Manually delete parts of the data from the test storage delegate // - Call _pruneEmptyStoredAttributesBranches - [controller.controllerDataStore clearAllStoredAttributes]; + [controller.controllerDataStore storeClusterData:testClusterData forNodeID:@(2001)]; + [controller.controllerDataStore storeClusterData:testClusterData forNodeID:@(2002)]; - NSArray * testAttribute = @[ - @{ MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(1) attributeID:@(1)], MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(111) } }, - ]; - [controller.controllerDataStore storeAttributeValues:testAttribute forNodeID:@(2001)]; + NSString * testClusterIndexKey1 = [controller.controllerDataStore _clusterIndexKeyForNodeID:@(2001) endpointID:@(1)]; + NSString * testClusterIndexKey2 = [controller.controllerDataStore _clusterIndexKeyForNodeID:@(2001) endpointID:@(2)]; + NSString * testClusterIndexKey3 = [controller.controllerDataStore _clusterIndexKeyForNodeID:@(2002) endpointID:@(1)]; + NSString * testClusterIndexKey4 = [controller.controllerDataStore _clusterIndexKeyForNodeID:@(2002) endpointID:@(2)]; + NSString * testEndpointIndexKey1 = [controller.controllerDataStore _endpointIndexKeyForNodeID:@(2001)]; + NSString * testEndpointIndexKey2 = [controller.controllerDataStore _endpointIndexKeyForNodeID:@(2002)]; + NSString * testNodeIndexKey = @"attrCacheNodeIndex"; // store is async, so remove on the same queue to ensure order dispatch_sync(_storageQueue, ^{ - NSString * testAttributeValueKey = [controller.controllerDataStore _attributeValueKeyForNodeID:@(2001) endpointID:@(1) clusterID:@(1) attributeID:@(1)]; - [storageDelegate controller:controller removeValueForKey:testAttributeValueKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + // Ensure that the indices we expect are populated. + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testClusterIndexKey1 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testClusterIndexKey2 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testClusterIndexKey3 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testClusterIndexKey4 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testEndpointIndexKey1 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testEndpointIndexKey2 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + XCTAssertNotNil([storageDelegate controller:controller valueForKey:testNodeIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]); + + // Remove all three MTRDeviceClusterData for node 2001 + NSString * testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2001) endpointID:@(1) clusterID:@(1)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2001) endpointID:@(1) clusterID:@(2)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2001) endpointID:@(2) clusterID:@(3)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + + // Remove the two MTRDeviceClusterData under endpoint 1 for node 2002 + testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2002) endpointID:@(1) clusterID:@(1)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2002) endpointID:@(1) clusterID:@(2)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + }); + + [controller.controllerDataStore unitTestPruneEmptyStoredClusterDataBranches]; + + // Now check the indexes are pruned. There should be no more cluster + // indices or endpoint indices for node 2001. + id testClusterIndex1 = [storageDelegate controller:controller valueForKey:testClusterIndexKey1 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testClusterIndex1); + id testClusterIndex2 = [storageDelegate controller:controller valueForKey:testClusterIndexKey2 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testClusterIndex2); + id testEndpointIndex1 = [storageDelegate controller:controller valueForKey:testEndpointIndexKey1 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testEndpointIndex1); + + // There should be no more cluster index for endpoint 1 for node 2, but + // we should still have a cluster index for endpoint 2, and an endpoint index. + id testClusterIndex3 = [storageDelegate controller:controller valueForKey:testClusterIndexKey3 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testClusterIndex3); + id testClusterIndex4 = [storageDelegate controller:controller valueForKey:testClusterIndexKey4 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNotNil(testClusterIndex4); + id testEndpointIndex2 = [storageDelegate controller:controller valueForKey:testEndpointIndexKey2 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNotNil(testClusterIndex4); + + // We should still have a node index. + id testNodeIndex = [storageDelegate controller:controller valueForKey:testNodeIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNotNil(testNodeIndex); + + // Again, remove on the storage queue to ensure order. + dispatch_sync(_storageQueue, ^{ + NSString * testClusterDataKey = [controller.controllerDataStore _clusterDataKeyForNodeID:@(2002) endpointID:@(2) clusterID:@(3)]; + [storageDelegate controller:controller removeValueForKey:testClusterDataKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; }); - [controller.controllerDataStore unitTestPruneEmptyStoredAttributesBranches]; - - // Now check the indexes are pruned - NSString * testAttributeIndexKey = [controller.controllerDataStore _attributeIndexKeyForNodeID:@(2001) endpointID:@(1) clusterID:@(1)]; - id testAttributeIndex = [storageDelegate controller:controller valueForKey:testAttributeIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; - XCTAssertNil(testAttributeIndex); - NSString * testClusterIndexKey = [controller.controllerDataStore _clusterIndexKeyForNodeID:@(2001) endpointID:@(1)]; - id testClusterIndex = [storageDelegate controller:controller valueForKey:testClusterIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; - XCTAssertNil(testClusterIndex); - NSString * testEndpointIndexKey = [controller.controllerDataStore _endpointIndexKeyForNodeID:@(2001)]; - id testEndpointIndex = [storageDelegate controller:controller valueForKey:testEndpointIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; - XCTAssertNil(testEndpointIndex); - id testNodeIndex = [storageDelegate controller:controller valueForKey:@"attrCacheNodeIndex" securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + + [controller.controllerDataStore unitTestPruneEmptyStoredClusterDataBranches]; + + // All the indices should be pruned now. + testClusterIndex4 = [storageDelegate controller:controller valueForKey:testClusterIndexKey4 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testClusterIndex4); + testEndpointIndex2 = [storageDelegate controller:controller valueForKey:testEndpointIndexKey2 securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; + XCTAssertNil(testClusterIndex4); + testNodeIndex = [storageDelegate controller:controller valueForKey:testNodeIndexKey securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; XCTAssertNil(testNodeIndex); // Now test bulk write @@ -1275,11 +1292,11 @@ - (void)test008_TestDataStoreDirect [storageDelegate controller:controller storeValues:testBulkValues securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; }); // Verify that the store resulted in the correct values - dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:@(3001)]; + NSDictionary * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:@(3001)]; XCTAssertEqualObjects(dataStoreClusterData, bulkTestClusterDataDictionary); // clear information before the next test - [controller.controllerDataStore clearStoredAttributesForNodeID:@(3001)]; + [controller.controllerDataStore clearStoredClusterDataForNodeID:@(3001)]; // Now test bulk store through data store [controller.controllerDataStore storeClusterData:bulkTestClusterDataDictionary forNodeID:@(3001)]; @@ -1356,7 +1373,6 @@ - (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; for (MTRClusterPath * path in dataStoreClusterData) { MTRDeviceClusterData * data = dataStoreClusterData[path]; @@ -1367,21 +1383,6 @@ - (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id *)getStoredAttributesForNodeID:(NSNumber *)nodeID; - (nullable NSDictionary *)getStoredClusterDataForNodeID:(NSNumber *)nodeID; -- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; - (void)storeClusterData:(NSDictionary *)clusterData forNodeID:(NSNumber *)nodeID; -- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)clearAllStoredAttributes; -- (void)unitTestPruneEmptyStoredAttributesBranches; +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID; +- (void)clearAllStoredClusterData; +- (void)unitTestPruneEmptyStoredClusterDataBranches; - (NSString *)_endpointIndexKeyForNodeID:(NSNumber *)nodeID; - (NSString *)_clusterIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID; - (NSString *)_clusterDataKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; -- (NSString *)_attributeIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; -- (NSString *)_attributeValueKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID; @end // Declare internal methods for testing From b5d43efae79f3ad520a53575d5832fdbae33a4bc Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Tue, 23 Apr 2024 18:29:15 +0200 Subject: [PATCH 07/19] Switched to pw_unit_test in src/lib/dnssd/minimal_mdns/tests/ (#33068) * Switched to pw_unit_test in src/lib/dnssd/minimal_mdns/tests/ * Update src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp * Update src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp --------- Co-authored-by: Arkadiusz Bokowy Co-authored-by: Arkadiusz Bokowy --- src/lib/dnssd/minimal_mdns/tests/BUILD.gn | 5 +- .../minimal_mdns/tests/CheckOnlyServer.h | 33 +- .../minimal_mdns/tests/TestAdvertiser.cpp | 288 +++++++++--------- .../tests/TestMinimalMdnsAllocator.cpp | 209 ++++++------- .../tests/TestQueryReplyFilter.cpp | 80 ++--- .../minimal_mdns/tests/TestRecordData.cpp | 149 ++++----- .../minimal_mdns/tests/TestResponseSender.cpp | 169 +++++----- 7 files changed, 402 insertions(+), 531 deletions(-) diff --git a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn index 8d99854046e307..dc09e4b4b59d5d 100644 --- a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn @@ -14,12 +14,11 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/build/chip/fuzz_test.gni") -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libMinimalMdnstests" sources = [ "CheckOnlyServer.h" ] @@ -40,9 +39,7 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/lib/core", "${chip_root}/src/lib/dnssd", "${chip_root}/src/lib/dnssd/minimal_mdns", - "${chip_root}/src/lib/support:testing_nlunit", "${chip_root}/src/transport/raw/tests:helpers", - "${nlunit_test_root}:nlunit-test", ] } diff --git a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h index c5b8f9e21f060b..1aabc6738d00e6 100644 --- a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h +++ b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h @@ -29,10 +29,9 @@ #include #include #include -#include #include -#include +#include namespace mdns { namespace Minimal { @@ -78,23 +77,19 @@ class CheckOnlyServer : private chip::PoolImpl(this)), mInSuite(inSuite) - { - Reset(); - } - CheckOnlyServer() : ServerBase(*static_cast(this)), mInSuite(nullptr) { Reset(); } + CheckOnlyServer() : ServerBase(*static_cast(this)) { Reset(); } ~CheckOnlyServer() {} // Parser delegates void OnHeader(ConstHeaderRef & header) override { - NL_TEST_ASSERT(mInSuite, header.GetFlags().IsResponse()); - NL_TEST_ASSERT(mInSuite, header.GetFlags().IsValidMdns()); + EXPECT_TRUE(header.GetFlags().IsResponse()); + EXPECT_TRUE(header.GetFlags().IsValidMdns()); mTotalRecords += header.GetAnswerCount() + header.GetAdditionalCount(); if (!header.GetFlags().IsTruncated()) { - NL_TEST_ASSERT(mInSuite, mTotalRecords == GetNumExpectedRecords()); + EXPECT_EQ(mTotalRecords, GetNumExpectedRecords()); if (mTotalRecords != GetNumExpectedRecords()) { ChipLogError(Discovery, "Received %d records, expected %d", mTotalRecords, GetNumExpectedRecords()); @@ -114,7 +109,7 @@ class CheckOnlyServer : private chip::PoolImplGetNumEntries(); ++t) { bool ok = AddExpectedTxtRecord(expectedTxt->GetEntries()[t]); - NL_TEST_ASSERT(mInSuite, ok); + EXPECT_TRUE(ok); } ParseTxtRecord(data.GetData(), this); if (CheckTxtRecordMatches()) @@ -164,7 +159,7 @@ class CheckOnlyServer : private chip::PoolImpl #include #include -#include -#include + #include #include -#include +#include namespace { @@ -237,29 +236,57 @@ CHIP_ERROR SendQuery(FullQName qname) return CHIP_NO_ERROR; } -void OperationalAdverts(nlTestSuite * inSuite, void * inContext) +class TestAdvertiser : public ::testing::Test { - auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance(); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.RemoveServices() == CHIP_NO_ERROR); +public: + static chip::Test::IOContext context; + static CheckOnlyServer server; + static chip::Dnssd::ServiceAdvertiser * mdnsAdvertiser; + + static void SetUpTestSuite() + { + chip::Platform::MemoryInit(); + context.Init(); + chip::Dnssd::GlobalMinimalMdnsServer::Instance().Server().Shutdown(); + chip::Dnssd::GlobalMinimalMdnsServer::Instance().SetReplacementServer(&server); + mdnsAdvertiser = &chip::Dnssd::ServiceAdvertiser::Instance(); + mdnsAdvertiser->Init(context.GetUDPEndPointManager()); + } + static void TearDownTestSuite() + { + server.Shutdown(); + context.Shutdown(); + mdnsAdvertiser->RemoveServices(); + mdnsAdvertiser->Shutdown(); + chip::Dnssd::GlobalMinimalMdnsServer::Instance().SetReplacementServer(nullptr); + chip::Platform::MemoryShutdown(); + } +}; + +chip::Test::IOContext TestAdvertiser::context; +CheckOnlyServer TestAdvertiser::server; +chip::Dnssd::ServiceAdvertiser * TestAdvertiser::mdnsAdvertiser; + +TEST_F(TestAdvertiser, OperationalAdverts) +{ + EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR); - auto & server = static_cast(GlobalMinimalMdnsServer::Server()); - server.SetTestSuite(inSuite); server.Reset(); // Start a single operational advertiser ChipLogProgress(Discovery, "Testing single operational advertiser"); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); // Test for PTR response to _services request. ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local"); server.AddExpectedRecord(&ptrOperationalService); server.AddExpectedRecord(&ptrServiceSubCompressedId1); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); // These check that the requested records added are sent out correctly. - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Want PTR response to _matter.tcp. We will also get the SRV and TXT as additionals. // We won't get any A/AAAA because this is a test and we don't have addresses. @@ -271,31 +298,31 @@ void OperationalAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&srvOperational1); server.AddExpectedRecord(&txtOperational1); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterOperationalQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvOperational1); server.AddExpectedRecord(&txtOperational1); - NL_TEST_ASSERT(inSuite, SendQuery(kInstanceName1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // If we try to re-advertise with the same operational parameters, we should not get duplicates - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); ChipLogProgress(Discovery, "Testing single operational advertiser with Advertise called twice"); // We should get a single PTR back for _services ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local"); server.Reset(); server.AddExpectedRecord(&ptrOperationalService); server.AddExpectedRecord(&ptrServiceSubCompressedId1); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Same records should come back for _matter._tcp.local queries. ChipLogProgress(Discovery, "Testing response to _matter._tcp.local"); @@ -303,16 +330,16 @@ void OperationalAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrOperational1); server.AddExpectedRecord(&srvOperational1); server.AddExpectedRecord(&txtOperational1); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterOperationalQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Adding a second operational advertiser. ChipLogProgress(Discovery, "Adding a second operational Advertiser"); server.Reset(); // Mac is the same, peer id is different - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams2), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); // For now, we'll get back two copies of the PTR. Not sure if that's totally correct, but for now, that's expected. ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local"); @@ -320,9 +347,9 @@ void OperationalAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrOperationalService); server.AddExpectedRecord(&ptrServiceSubCompressedId1); server.AddExpectedRecord(&ptrServiceSubCompressedId2); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Requests for _matter._tcp.local will respond with all records from both parameter sets ChipLogProgress(Discovery, "Testing response to _matter._tcp.local"); @@ -333,9 +360,9 @@ void OperationalAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrOperational2); server.AddExpectedRecord(&srvOperational2); server.AddExpectedRecord(&txtOperational2); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterOperationalQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Requests for each SRV record should give only records specific to that fabric. ChipLogProgress(Discovery, "Testing response to instance name for fabric 1"); @@ -343,79 +370,75 @@ void OperationalAdverts(nlTestSuite * inSuite, void * inContext) // Just the SRV and TXT should return server.AddExpectedRecord(&srvOperational1); server.AddExpectedRecord(&txtOperational1); - NL_TEST_ASSERT(inSuite, SendQuery(kInstanceName1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name for fabric 2"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvOperational2); server.AddExpectedRecord(&txtOperational2); - NL_TEST_ASSERT(inSuite, SendQuery(kInstanceName2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kInstanceName2), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // All devices should support at least 5 operational network additions (spec min) // however larger devices may support more. - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams3) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams4) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams5) == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams3), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams4), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams5), CHIP_NO_ERROR); } -void CommissionableAdverts(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAdvertiser, CommissionableAdverts) { - auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance(); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.RemoveServices() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR); - auto & server = static_cast(GlobalMinimalMdnsServer::Server()); - server.SetTestSuite(inSuite); server.Reset(); // Start a single operational advertiser ChipLogProgress(Discovery, "Testing commissionable advertiser"); // Start very basic - only the mandatory values (short and long discriminator and commissioning modes) - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsSmall) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsSmall), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); // Test for PTR response to _services request. ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for small parameters"); server.AddExpectedRecord(&ptrCommissionableNodeService); server.AddExpectedRecord(&ptrServiceSubLFullLen); server.AddExpectedRecord(&ptrServiceSubSFullLen); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); // These check that the requested records added are sent out correctly. - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Want PTR response to _matterc._udp. We will also get the SRV and TXT as additionals. // We won't get any A/AAAA because this is a test and we don't have addresses. // First fill in the instance name - FullQNames already have this space included. - NL_TEST_ASSERT(inSuite, - mdnsAdvertiser.GetCommissionableInstanceName(instanceNamePrefix, sizeof(instanceNamePrefix)) == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->GetCommissionableInstanceName(instanceNamePrefix, sizeof(instanceNamePrefix)), CHIP_NO_ERROR); ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for small parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsSmall); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name for small parameters"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsSmall); - NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Add more parameters, check that the subtypes and TXT values get set correctly. // Also check that we get proper values when the discriminators are small (no leading 0's) - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeBasic) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeBasic), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large basic parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNodeService); @@ -424,30 +447,30 @@ void CommissionableAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrServiceSubCM); server.AddExpectedRecord(&ptrServiceSubVendor); server.AddExpectedRecord(&ptrServiceSubDeviceType); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large basic parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name for large basic parameters"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic); - NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeEnhanced), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large enhanced parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNodeService); @@ -456,65 +479,62 @@ void CommissionableAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrServiceSubCM); server.AddExpectedRecord(&ptrServiceSubVendor); server.AddExpectedRecord(&ptrServiceSubDeviceType); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large enhanced parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name for large enhanced parameters"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); - NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); #if CHIP_CONFIG_ENABLE_ICD_SERVER - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsEnhancedAsICDLIT) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsEnhancedAsICDLIT), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for enhanced parameters With ICD as LIT"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsEnhancedAsICDLIT); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to instance name for enhanced parameters With ICD as LIT"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsEnhancedAsICDLIT); - NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); #endif } -void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAdvertiser, CommissionableAndOperationalAdverts) { - auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance(); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.RemoveServices() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR); - auto & server = static_cast(GlobalMinimalMdnsServer::Server()); - server.SetTestSuite(inSuite); server.Reset(); // Add two operational and a commissionable and test that we get the correct values back. - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams2), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeEnhanced), CHIP_NO_ERROR); + EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR); // Services listing should have two operational ptrs, the base commissionable node ptr and the various _sub ptrs ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local"); @@ -529,9 +549,9 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.AddExpectedRecord(&ptrServiceSubDeviceType); server.AddExpectedRecord(&ptrServiceSubCompressedId1); server.AddExpectedRecord(&ptrServiceSubCompressedId2); - NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Requests for _matter._tcp.local will respond with all records from both operational records, but no commissionable. ChipLogProgress(Discovery, "Testing response to _matter._tcp.local"); @@ -542,9 +562,9 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.AddExpectedRecord(&ptrOperational2); server.AddExpectedRecord(&srvOperational2); server.AddExpectedRecord(&txtOperational2); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterOperationalQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Responses to _matterc query should return commissionable node, but no operational. ChipLogProgress(Discovery, "Testing response to _matterc._udp.local"); @@ -552,9 +572,9 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); - NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); // Requests for each SRV record should give only records specific to that fabric. ChipLogProgress(Discovery, "Testing response to operational instance name for fabric 1"); @@ -562,56 +582,26 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext // Just the SRV and TXT should return server.AddExpectedRecord(&srvOperational1); server.AddExpectedRecord(&txtOperational1); - NL_TEST_ASSERT(inSuite, SendQuery(kInstanceName1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to operational instance name for fabric 2"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvOperational2); server.AddExpectedRecord(&txtOperational2); - NL_TEST_ASSERT(inSuite, SendQuery(kInstanceName2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(kInstanceName2), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); ChipLogProgress(Discovery, "Testing response to commissionable instance name"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); - NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR); + EXPECT_TRUE(server.GetSendCalled()); + EXPECT_TRUE(server.GetHeaderFound()); } - -const nlTest sTests[] = { - NL_TEST_DEF("OperationalAdverts", OperationalAdverts), // - NL_TEST_DEF("CommissionableNodeAdverts", CommissionableAdverts), // - NL_TEST_DEF("CommissionableAndOperationalAdverts", CommissionableAndOperationalAdverts), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestAdvertiser() -{ - chip::Platform::MemoryInit(); - chip::Test::IOContext context; - context.Init(); - nlTestSuite theSuite = { "AdvertiserImplMinimal", sTests, nullptr, nullptr }; - CheckOnlyServer server(&theSuite); - test::ServerSwapper swapper(&server); - auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance(); - mdnsAdvertiser.Init(context.GetUDPEndPointManager()); - nlTestRunner(&theSuite, &server); - server.Shutdown(); - context.Shutdown(); - mdnsAdvertiser.RemoveServices(); - mdnsAdvertiser.Shutdown(); - chip::Platform::MemoryShutdown(); - - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestAdvertiser) diff --git a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp index c712b1bd647f47..f571e81fcf27d1 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp @@ -16,11 +16,9 @@ * limitations under the License. */ -#include - -#include +#include -#include +#include using namespace chip; using namespace chip::Dnssd; @@ -42,21 +40,21 @@ class TestAllocator : public QueryResponderAllocator // void dmalloc_track(const dmalloc_track_t track_func) #endif } - void TestAllQNamesAreNull(nlTestSuite * inSuite) + void TestAllQNamesAreNull() { for (size_t i = 0; i < GetMaxAllocatedQNames(); ++i) { - NL_TEST_ASSERT(inSuite, GetQNamePart(i) == nullptr); + EXPECT_EQ(GetQNamePart(i), nullptr); } } - void TestAllRecordRespondersAreNull(nlTestSuite * inSuite) + void TestAllRecordRespondersAreNull() { for (size_t i = 0; i < kMaxRecords; ++i) { - NL_TEST_ASSERT(inSuite, GetRecordResponder(i) == nullptr); + EXPECT_EQ(GetRecordResponder(i), nullptr); } } - void TestRecordRespondersMatchQuery(nlTestSuite * inSuite) + void TestRecordRespondersMatchQuery() { mdns::Minimal::QueryResponderRecordFilter noFilter; auto queryResponder = GetQueryResponder(); @@ -64,56 +62,63 @@ class TestAllocator : public QueryResponderAllocator for (auto it = queryResponder->begin(&noFilter); it != queryResponder->end(); it++, idx++) { // TODO: Once the responders are exposed in the query responder, check that they match. - NL_TEST_ASSERT(inSuite, idx < kMaxRecords); + EXPECT_LT(idx, kMaxRecords); } } size_t GetMaxAllocatedQNames() { return QueryResponderAllocator::GetMaxAllocatedQNames(); } }; -void TestQueryAllocatorQName(nlTestSuite * inSuite, void * inContext) +class TestMinimalMdnsAllocator : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorQName) { TestAllocator test; #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC unsigned long mark = dmalloc_mark(); #endif // Start empty. - test.TestAllRecordRespondersAreNull(inSuite); - test.TestAllQNamesAreNull(inSuite); + test.TestAllRecordRespondersAreNull(); + test.TestAllQNamesAreNull(); // We should be able to add up to GetMaxAllocatedQNames QNames for (size_t i = 0; i < test.GetMaxAllocatedQNames(); ++i) { - NL_TEST_ASSERT(inSuite, test.AllocateQName("test", "testy", "udp") != FullQName()); - test.TestAllRecordRespondersAreNull(inSuite); + EXPECT_NE(test.AllocateQName("test", "testy", "udp"), FullQName()); + test.TestAllRecordRespondersAreNull(); } #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // Count the memory that has not been freed at this point (since mark) unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0); - NL_TEST_ASSERT(inSuite, nAllocated != 0); + EXPECT_NE(nAllocated, 0); #endif // Adding one more should fail. - NL_TEST_ASSERT(inSuite, test.AllocateQName("test", "testy", "udp") == FullQName()); - test.TestAllRecordRespondersAreNull(inSuite); + EXPECT_EQ(test.AllocateQName("test", "testy", "udp"), FullQName()); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // We should not have allocated any more memory - NL_TEST_ASSERT(inSuite, nAllocated == dmalloc_count_changed(mark, 1, 0)); + EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0)); #endif // Clear should take us back to all empty. test.Clear(); - test.TestAllQNamesAreNull(inSuite); - test.TestAllRecordRespondersAreNull(inSuite); + test.TestAllQNamesAreNull(); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // The amount of unfreed pointers should be 0. - NL_TEST_ASSERT(inSuite, dmalloc_count_changed(mark, 1, 0) == 0); + EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0); #endif } -void TestQueryAllocatorQNameArray(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorQNameArray) { TestAllocator test; @@ -125,43 +130,43 @@ void TestQueryAllocatorQNameArray(nlTestSuite * inSuite, void * inContext) const char * kArray[kNumParts] = { "this", "is", "a", "test" }; // Start empty. - test.TestAllRecordRespondersAreNull(inSuite); - test.TestAllQNamesAreNull(inSuite); + test.TestAllRecordRespondersAreNull(); + test.TestAllQNamesAreNull(); // We should be able to add up to GetMaxAllocatedQNames QNames for (size_t i = 0; i < test.GetMaxAllocatedQNames(); ++i) { - NL_TEST_ASSERT(inSuite, test.AllocateQNameFromArray(kArray, kNumParts) != FullQName()); - test.TestAllRecordRespondersAreNull(inSuite); + EXPECT_NE(test.AllocateQNameFromArray(kArray, kNumParts), FullQName()); + test.TestAllRecordRespondersAreNull(); } #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // Count the memory that has not been freed at this point (since mark) unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0); - NL_TEST_ASSERT(inSuite, nAllocated != 0); + EXPECT_NE(nAllocated, 0); #endif // Adding one more should fail. - NL_TEST_ASSERT(inSuite, test.AllocateQNameFromArray(kArray, kNumParts) == FullQName()); - test.TestAllRecordRespondersAreNull(inSuite); + EXPECT_EQ(test.AllocateQNameFromArray(kArray, kNumParts), FullQName()); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // We should not have allocated any more memory - NL_TEST_ASSERT(inSuite, nAllocated == dmalloc_count_changed(mark, 1, 0)); + EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0)); #endif // Clear should take us back to all empty. test.Clear(); - test.TestAllQNamesAreNull(inSuite); - test.TestAllRecordRespondersAreNull(inSuite); + test.TestAllQNamesAreNull(); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // The amount of unfreed pointers should be 0. - NL_TEST_ASSERT(inSuite, dmalloc_count_changed(mark, 1, 0) == 0); + EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0); #endif } -void TestQueryAllocatorRecordResponder(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorRecordResponder) { TestAllocator test; @@ -169,42 +174,42 @@ void TestQueryAllocatorRecordResponder(nlTestSuite * inSuite, void * inContext) unsigned long mark = dmalloc_mark(); #endif // Start empty. - test.TestAllRecordRespondersAreNull(inSuite); - test.TestAllQNamesAreNull(inSuite); + test.TestAllRecordRespondersAreNull(); + test.TestAllQNamesAreNull(); FullQName serviceName = test.AllocateQName("test", "service"); FullQName instanceName = test.AllocateQName("test", "instance"); for (size_t i = 0; i < kMaxRecords; ++i) { - NL_TEST_ASSERT(inSuite, test.AddResponder(serviceName, instanceName).IsValid()); + EXPECT_TRUE(test.AddResponder(serviceName, instanceName).IsValid()); } #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // Count the memory that has not been freed at this point (since mark) unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0); - NL_TEST_ASSERT(inSuite, nAllocated != 0); + EXPECT_NE(nAllocated, 0); #endif // Adding one more should fail. - NL_TEST_ASSERT(inSuite, !test.AddResponder(serviceName, instanceName).IsValid()); + EXPECT_FALSE(test.AddResponder(serviceName, instanceName).IsValid()); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // We should not have allocated any more memory - NL_TEST_ASSERT(inSuite, nAllocated == dmalloc_count_changed(mark, 1, 0)); + EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0)); #endif // Clear should take us back to all empty. test.Clear(); - test.TestAllQNamesAreNull(inSuite); - test.TestAllRecordRespondersAreNull(inSuite); + test.TestAllQNamesAreNull(); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // The amount of unfreed pointers should be 0. - NL_TEST_ASSERT(inSuite, dmalloc_count_changed(mark, 1, 0) == 0); + EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0); #endif } -void TestQueryAllocatorRecordResponderTypes(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorRecordResponderTypes) { TestAllocator test; @@ -212,49 +217,49 @@ void TestQueryAllocatorRecordResponderTypes(nlTestSuite * inSuite, void * inCont unsigned long mark = dmalloc_mark(); #endif // Start empty. - test.TestAllRecordRespondersAreNull(inSuite); - test.TestAllQNamesAreNull(inSuite); + test.TestAllRecordRespondersAreNull(); + test.TestAllQNamesAreNull(); FullQName serviceName = test.AllocateQName("test", "service"); FullQName instanceName = test.AllocateQName("test", "instance"); FullQName hostName = test.AllocateQName("test", "host"); FullQName someTxt = test.AllocateQName("L1=some text", "L2=some other text"); - NL_TEST_ASSERT(inSuite, serviceName != FullQName()); - NL_TEST_ASSERT(inSuite, instanceName != FullQName()); - NL_TEST_ASSERT(inSuite, hostName != FullQName()); - NL_TEST_ASSERT(inSuite, someTxt != FullQName()); + EXPECT_NE(serviceName, FullQName()); + EXPECT_NE(instanceName, FullQName()); + EXPECT_NE(hostName, FullQName()); + EXPECT_NE(someTxt, FullQName()); // Test that we can add all types - NL_TEST_ASSERT(inSuite, test.AddResponder(serviceName, instanceName).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(SrvResourceRecord(instanceName, hostName, 57)).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(TxtResourceRecord(instanceName, someTxt)).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(hostName).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(hostName).IsValid()); + EXPECT_TRUE(test.AddResponder(serviceName, instanceName).IsValid()); + EXPECT_TRUE(test.AddResponder(SrvResourceRecord(instanceName, hostName, 57)).IsValid()); + EXPECT_TRUE(test.AddResponder(TxtResourceRecord(instanceName, someTxt)).IsValid()); + EXPECT_TRUE(test.AddResponder(hostName).IsValid()); + EXPECT_TRUE(test.AddResponder(hostName).IsValid()); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // Count the memory that has not been freed at this point (since mark) unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0); - NL_TEST_ASSERT(inSuite, nAllocated != 0); + EXPECT_NE(nAllocated, 0); #endif // Clear should take us back to all empty. test.Clear(); - test.TestAllQNamesAreNull(inSuite); - test.TestAllRecordRespondersAreNull(inSuite); + test.TestAllQNamesAreNull(); + test.TestAllRecordRespondersAreNull(); #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC // The amount of unfreed pointers should be 0. - NL_TEST_ASSERT(inSuite, dmalloc_count_changed(mark, 1, 0) == 0); + EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0); #endif } -void TestGetResponder(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMinimalMdnsAllocator, TestGetResponder) { TestAllocator test; // Start empty. - test.TestAllRecordRespondersAreNull(inSuite); - test.TestAllQNamesAreNull(inSuite); + test.TestAllRecordRespondersAreNull(); + test.TestAllQNamesAreNull(); FullQName serviceName = test.AllocateQName("test", "service"); FullQName instanceName = test.AllocateQName("test", "instance"); @@ -262,68 +267,40 @@ void TestGetResponder(nlTestSuite * inSuite, void * inContext) FullQName someTxt = test.AllocateQName("L1=some text", "L2=some other text"); FullQName notAdded = test.AllocateQName("not", "added"); - NL_TEST_ASSERT(inSuite, serviceName != FullQName()); - NL_TEST_ASSERT(inSuite, instanceName != FullQName()); - NL_TEST_ASSERT(inSuite, hostName != FullQName()); - NL_TEST_ASSERT(inSuite, someTxt != FullQName()); + EXPECT_NE(serviceName, FullQName()); + EXPECT_NE(instanceName, FullQName()); + EXPECT_NE(hostName, FullQName()); + EXPECT_NE(someTxt, FullQName()); - NL_TEST_ASSERT(inSuite, test.AddResponder(serviceName, instanceName).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(SrvResourceRecord(instanceName, hostName, 57)).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(TxtResourceRecord(instanceName, someTxt)).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(hostName).IsValid()); - NL_TEST_ASSERT(inSuite, test.AddResponder(hostName).IsValid()); + EXPECT_TRUE(test.AddResponder(serviceName, instanceName).IsValid()); + EXPECT_TRUE(test.AddResponder(SrvResourceRecord(instanceName, hostName, 57)).IsValid()); + EXPECT_TRUE(test.AddResponder(TxtResourceRecord(instanceName, someTxt)).IsValid()); + EXPECT_TRUE(test.AddResponder(hostName).IsValid()); + EXPECT_TRUE(test.AddResponder(hostName).IsValid()); // These should all exist - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::PTR, serviceName) != nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::SRV, instanceName) != nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::TXT, instanceName) != nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::A, hostName) != nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::AAAA, hostName) != nullptr); + ASSERT_NE(test.GetResponder(QType::PTR, serviceName), nullptr); + ASSERT_NE(test.GetResponder(QType::SRV, instanceName), nullptr); + ASSERT_NE(test.GetResponder(QType::TXT, instanceName), nullptr); + ASSERT_NE(test.GetResponder(QType::A, hostName), nullptr); + ASSERT_NE(test.GetResponder(QType::AAAA, hostName), nullptr); // incorrect types - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::SRV, notAdded) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::AAAA, instanceName) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::A, instanceName) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::PTR, hostName) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::TXT, hostName) == nullptr); + EXPECT_EQ(test.GetResponder(QType::SRV, notAdded), nullptr); + EXPECT_EQ(test.GetResponder(QType::AAAA, instanceName), nullptr); + EXPECT_EQ(test.GetResponder(QType::A, instanceName), nullptr); + EXPECT_EQ(test.GetResponder(QType::PTR, hostName), nullptr); + EXPECT_EQ(test.GetResponder(QType::TXT, hostName), nullptr); // incorrect names - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::PTR, notAdded) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::SRV, notAdded) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::TXT, notAdded) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::A, notAdded) == nullptr); - NL_TEST_ASSERT(inSuite, test.GetResponder(QType::AAAA, notAdded) == nullptr); + EXPECT_EQ(test.GetResponder(QType::PTR, notAdded), nullptr); + EXPECT_EQ(test.GetResponder(QType::SRV, notAdded), nullptr); + EXPECT_EQ(test.GetResponder(QType::TXT, notAdded), nullptr); + EXPECT_EQ(test.GetResponder(QType::A, notAdded), nullptr); + EXPECT_EQ(test.GetResponder(QType::AAAA, notAdded), nullptr); test.Clear(); } -const nlTest sTests[] = { - NL_TEST_DEF("TestQueryAllocatorQName", TestQueryAllocatorQName), // - NL_TEST_DEF("TestQueryAllocatorQNameArray", TestQueryAllocatorQNameArray), // - NL_TEST_DEF("TestQueryAllocatorRecordResponder", TestQueryAllocatorRecordResponder), // - NL_TEST_DEF("TestQueryAllocatorRecordResponderTypes", TestQueryAllocatorRecordResponderTypes), // - NL_TEST_DEF("TestGetResponder", TestGetResponder), // - - NL_TEST_SENTINEL() // -}; - -int TestSetup(void * inContext) -{ - return chip::Platform::MemoryInit() == CHIP_NO_ERROR ? SUCCESS : FAILURE; -} - -int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - } // namespace -int TestMinimalMdnsAllocator() -{ - nlTestSuite theSuite = { "MinimalMdnsAllocator", &sTests[0], &TestSetup, &TestTeardown }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestMinimalMdnsAllocator); +; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp index 690c28b6193929..234b6876c6b7fe 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include -#include +#include namespace { @@ -35,7 +34,7 @@ QueryData buildQueryData(QType qType, QClass qClass, const uint8_t (&query)[N]) return QueryData(qType, qClass, false, query, BytesRange(query, query + N)); } -void TestQueryReplyFilter(nlTestSuite * inSuite, void * inContext) +TEST(TestQueryReplyFilter, TestQueryReplyFilter) { const uint8_t query[] = { 4, 's', 'o', 'm', 'e', // @@ -44,45 +43,34 @@ void TestQueryReplyFilter(nlTestSuite * inSuite, void * inContext) }; // sanity test that the serialized qname was build correctly - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) == FullQName(kName1)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName2)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName3)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName4)); + EXPECT_EQ(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName1)); + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName2)); + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName3)); + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName4)); // Acceptable cases - NL_TEST_ASSERT( - inSuite, QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT(inSuite, - QueryReplyFilter(buildQueryData(QType::A, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_TRUE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_TRUE(QueryReplyFilter(buildQueryData(QType::A, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT(inSuite, - QueryReplyFilter(buildQueryData(QType::ANY, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_TRUE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT(inSuite, - QueryReplyFilter(buildQueryData(QType::A, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_TRUE(QueryReplyFilter(buildQueryData(QType::A, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); // Reject cases - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName2))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName2))); - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName3))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName3))); - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName4))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName4))); - NL_TEST_ASSERT( - inSuite, - !QueryReplyFilter(buildQueryData(QType::AAAA, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::AAAA, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::SRV, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::SRV, QClass::IN, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::PTR, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::PTR, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); } -void TestLongerQueryPath(nlTestSuite * inSuite, void * inContext) +TEST(TestQueryReplyFilter, TestLongerQueryPath) { const uint8_t query[] = { 4, 'm', 'o', 'r', 'e', // @@ -93,30 +81,12 @@ void TestLongerQueryPath(nlTestSuite * inSuite, void * inContext) }; // sanity test that the serialized qname was build correctly - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName1)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName2)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) == FullQName(kName3)); - NL_TEST_ASSERT(inSuite, SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query) != FullQName(kName4)); - - NL_TEST_ASSERT( - inSuite, !QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); - NL_TEST_ASSERT( - inSuite, QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName3))); -} + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName1)); + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName2)); + EXPECT_EQ(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName3)); + EXPECT_NE(SerializedQNameIterator(BytesRange(query, query + sizeof(query)), query), FullQName(kName4)); -const nlTest sTests[] = { - NL_TEST_DEF("TestQueryReplyFilter", TestQueryReplyFilter), // - NL_TEST_DEF("TestLongerQueryPath", TestLongerQueryPath), // - NL_TEST_SENTINEL() // -}; - -} // namespace - -int TestQueryReplyFilter() -{ - nlTestSuite theSuite = { "QueryReplyFilter", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); + EXPECT_FALSE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName1))); + EXPECT_TRUE(QueryReplyFilter(buildQueryData(QType::ANY, QClass::ANY, query)).Accept(QType::A, QClass::IN, FullQName(kName3))); } - -CHIP_REGISTER_TEST_SUITE(TestQueryReplyFilter) +} // namespace diff --git a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp index 181b9d3b6f93fa..295ed2296215bf 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp @@ -19,9 +19,7 @@ #include #include -#include - -#include +#include namespace { @@ -29,7 +27,7 @@ using namespace std; using namespace chip; using namespace mdns::Minimal; -void SrvRecordSimpleParsing(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, SrvRecordSimpleParsing) { const uint8_t record[] = { 0, 12, // Priority @@ -46,27 +44,27 @@ void SrvRecordSimpleParsing(nlTestSuite * inSuite, void * inContext) SrvRecord srv; - NL_TEST_ASSERT(inSuite, srv.Parse(data, packet)); - NL_TEST_ASSERT(inSuite, srv.GetPriority() == 12); - NL_TEST_ASSERT(inSuite, srv.GetWeight() == 3); - NL_TEST_ASSERT(inSuite, srv.GetPort() == 0x1234); + EXPECT_TRUE(srv.Parse(data, packet)); + EXPECT_EQ(srv.GetPriority(), 12); + EXPECT_EQ(srv.GetWeight(), 3); + EXPECT_EQ(srv.GetPort(), 0x1234); // name can be read several times for (int i = 0; i < 3; i++) { SerializedQNameIterator name = srv.GetName(); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "some") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "test") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "local") == 0); - NL_TEST_ASSERT(inSuite, name.Next() == false); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "some"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "test"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "local"); + EXPECT_EQ(name.Next(), false); } } -void SrvWithPtrRecord(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, SrvWithPtrRecord) { const uint8_t record[] = { 'x', 'y', 'z', // dummy data (3 bytes) @@ -86,27 +84,27 @@ void SrvWithPtrRecord(nlTestSuite * inSuite, void * inContext) SrvRecord srv; - NL_TEST_ASSERT(inSuite, srv.Parse(data, packet)); - NL_TEST_ASSERT(inSuite, srv.GetPriority() == 12); - NL_TEST_ASSERT(inSuite, srv.GetWeight() == 3); - NL_TEST_ASSERT(inSuite, srv.GetPort() == 0x1234); + EXPECT_TRUE(srv.Parse(data, packet)); + EXPECT_EQ(srv.GetPriority(), 12); + EXPECT_EQ(srv.GetWeight(), 3); + EXPECT_EQ(srv.GetPort(), 0x1234); // name can be read several times for (int i = 0; i < 3; i++) { SerializedQNameIterator name = srv.GetName(); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "foo") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "some") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "test") == 0); - NL_TEST_ASSERT(inSuite, name.Next() == false); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "foo"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "some"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "test"); + EXPECT_EQ(name.Next(), false); } } -void ARecordParsing(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, ARecordParsing) { const uint8_t record[] = { 10, @@ -120,15 +118,15 @@ void ARecordParsing(nlTestSuite * inSuite, void * inContext) #if INET_CONFIG_ENABLE_IPV4 Inet::IPAddress expected; - NL_TEST_ASSERT(inSuite, ParseARecord(BytesRange(record, record + sizeof(record)), &addr)); - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("10.11.12.13", expected)); - NL_TEST_ASSERT(inSuite, addr == expected); + EXPECT_TRUE(ParseARecord(BytesRange(record, record + sizeof(record)), &addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("10.11.12.13", expected)); + EXPECT_EQ(addr, expected); #else - NL_TEST_ASSERT(inSuite, !ParseARecord(BytesRange(record, record + sizeof(record)), &addr)); + EXPECT_FALSE(ParseARecord(BytesRange(record, record + sizeof(record)), &addr)); #endif // INET_CONFIG_ENABLE_IPV4 } -void AAAARecordParsing(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, AAAARecordParsing) { const uint8_t record[] = { 0x12, 0x23, 0x00, 0x00, // @@ -140,12 +138,12 @@ void AAAARecordParsing(nlTestSuite * inSuite, void * inContext) Inet::IPAddress addr; Inet::IPAddress expected; - NL_TEST_ASSERT(inSuite, ParseAAAARecord(BytesRange(record, record + sizeof(record)), &addr)); - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("1223::3456:789A", expected)); - NL_TEST_ASSERT(inSuite, addr == expected); + EXPECT_TRUE(ParseAAAARecord(BytesRange(record, record + sizeof(record)), &addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("1223::3456:789A", expected)); + EXPECT_EQ(addr, expected); } -void PtrRecordSimpleParsing(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, PtrRecordSimpleParsing) { const uint8_t record[] = { 4, 's', 'o', 'm', 'e', // QNAME part: some @@ -159,17 +157,17 @@ void PtrRecordSimpleParsing(nlTestSuite * inSuite, void * inContext) SerializedQNameIterator name; - NL_TEST_ASSERT(inSuite, ParsePtrRecord(data, packet, &name)); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "some") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "test") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "local") == 0); - NL_TEST_ASSERT(inSuite, name.Next() == false); + EXPECT_TRUE(ParsePtrRecord(data, packet, &name)); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "some"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "test"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "local"); + EXPECT_EQ(name.Next(), false); } -void PtrRecordComplexParsing(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, PtrRecordComplexParsing) { const uint8_t record[] = { 'x', 'y', 'z', // dummy data (3 bytes) @@ -187,18 +185,18 @@ void PtrRecordComplexParsing(nlTestSuite * inSuite, void * inContext) BytesRange data(record + 24, record + sizeof(record)); SerializedQNameIterator name; - NL_TEST_ASSERT(inSuite, ParsePtrRecord(data, packet, &name)); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "foo") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "bar") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "baz") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "some") == 0); - NL_TEST_ASSERT(inSuite, name.Next()); - NL_TEST_ASSERT(inSuite, strcmp(name.Value(), "test") == 0); - NL_TEST_ASSERT(inSuite, name.Next() == false); + EXPECT_TRUE(ParsePtrRecord(data, packet, &name)); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "foo"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "bar"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "baz"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "some"); + EXPECT_TRUE(name.Next()); + EXPECT_STREQ(name.Value(), "test"); + EXPECT_EQ(name.Next(), false); } class TxtRecordAccumulator : public TxtRecordDelegate @@ -223,7 +221,7 @@ class TxtRecordAccumulator : public TxtRecordDelegate } }; -void TxtRecord(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordData, TxtRecord) { const uint8_t record[] = { 4, 's', 'o', 'm', 'e', // some @@ -234,32 +232,11 @@ void TxtRecord(nlTestSuite * inSuite, void * inContext) TxtRecordAccumulator accumulator; - NL_TEST_ASSERT(inSuite, ParseTxtRecord(BytesRange(record, record + sizeof(record)), &accumulator)); - NL_TEST_ASSERT(inSuite, accumulator.Data().size() == 4); - NL_TEST_ASSERT(inSuite, (accumulator.Data()[0] == make_pair("some", ""))); - NL_TEST_ASSERT(inSuite, (accumulator.Data()[1] == make_pair("foo", "bar"))); - NL_TEST_ASSERT(inSuite, (accumulator.Data()[2] == make_pair("x", "y=z"))); - NL_TEST_ASSERT(inSuite, (accumulator.Data()[3] == make_pair("a", ""))); + EXPECT_TRUE(ParseTxtRecord(BytesRange(record, record + sizeof(record)), &accumulator)); + EXPECT_EQ(accumulator.Data().size(), 4u); + EXPECT_EQ(accumulator.Data()[0], (make_pair("some", ""))); + EXPECT_EQ(accumulator.Data()[1], (make_pair("foo", "bar"))); + EXPECT_EQ(accumulator.Data()[2], (make_pair("x", "y=z"))); + EXPECT_EQ(accumulator.Data()[3], (make_pair("a", ""))); } - -const nlTest sTests[] = { - NL_TEST_DEF("SrvRecordSimpleParsing", SrvRecordSimpleParsing), // - NL_TEST_DEF("SrvWithPtrRecord", SrvWithPtrRecord), // - NL_TEST_DEF("ARecordParsing", ARecordParsing), // - NL_TEST_DEF("AAAARecordParsing", AAAARecordParsing), // - NL_TEST_DEF("PtrRecordSimpleParsing", PtrRecordSimpleParsing), // - NL_TEST_DEF("PtrRecordComplexParsing", PtrRecordComplexParsing), // - NL_TEST_DEF("TxtRecord", TxtRecord), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestRecordData() -{ - nlTestSuite theSuite = { "RecordData", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestRecordData) diff --git a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp index 39316ae129bd36..80ae9dc1b2c55b 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include #include #include @@ -28,9 +30,6 @@ #include #include -#include - -#include namespace { @@ -72,24 +71,31 @@ struct CommonTestElements QueryResponder<10> queryResponder; Inet::IPPacketInfo packetInfo; - CommonTestElements(nlTestSuite * inSuite, const char * tag) : + CommonTestElements(const char * tag) : recordWriter(&requestBufferWriter), dnsSd(FlatAllocatedQName::Build(dnsSdServiceStorage, "_services", "_dns-sd", "_udp", "local")), service(FlatAllocatedQName::Build(serviceNameStorage, tag, "service")), instance(FlatAllocatedQName::Build(instanceNameStorage, tag, "instance")), host(FlatAllocatedQName::Build(hostNameStorage, tag, "host")), - txt(FlatAllocatedQName::Build(txtStorage, tag, "L1=something", "L2=other")), server(inSuite) + txt(FlatAllocatedQName::Build(txtStorage, tag, "L1=something", "L2=other")), server() { queryResponder.Init(); header.SetQueryCount(1); } }; -void SrvAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) +class TestResponseSender : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestResponseSender, SrvAnyResponseToInstance) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.srvResponder); // Build a query for our srv record @@ -100,15 +106,15 @@ void SrvAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) common.server.AddExpectedRecord(&common.srvRecord); responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void SrvTxtAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, SrvTxtAnyResponseToInstance) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.srvResponder); common.queryResponder.AddResponder(&common.txtResponder); @@ -122,15 +128,15 @@ void SrvTxtAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) common.server.AddExpectedRecord(&common.txtRecord); responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void PtrSrvTxtAnyResponseToServiceName(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtAnyResponseToServiceName) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.ptrResponder).SetReportAdditional(common.instance); common.queryResponder.AddResponder(&common.srvResponder); common.queryResponder.AddResponder(&common.txtResponder); @@ -147,15 +153,15 @@ void PtrSrvTxtAnyResponseToServiceName(nlTestSuite * inSuite, void * inContext) responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void PtrSrvTxtAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtAnyResponseToInstance) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.ptrResponder); common.queryResponder.AddResponder(&common.srvResponder); common.queryResponder.AddResponder(&common.txtResponder); @@ -171,15 +177,15 @@ void PtrSrvTxtAnyResponseToInstance(nlTestSuite * inSuite, void * inContext) responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void PtrSrvTxtSrvResponseToInstance(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtSrvResponseToInstance) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.ptrResponder).SetReportInServiceListing(true); common.queryResponder.AddResponder(&common.srvResponder); common.queryResponder.AddResponder(&common.txtResponder); @@ -194,15 +200,15 @@ void PtrSrvTxtSrvResponseToInstance(nlTestSuite * inSuite, void * inContext) responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void PtrSrvTxtAnyResponseToServiceListing(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtAnyResponseToServiceListing) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common.queryResponder), CHIP_NO_ERROR); common.queryResponder.AddResponder(&common.ptrResponder).SetReportInServiceListing(true); common.queryResponder.AddResponder(&common.srvResponder); common.queryResponder.AddResponder(&common.txtResponder); @@ -218,31 +224,31 @@ void PtrSrvTxtAnyResponseToServiceListing(nlTestSuite * inSuite, void * inContex responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common.server.GetHeaderFound()); + EXPECT_TRUE(common.server.GetSendCalled()); + EXPECT_TRUE(common.server.GetHeaderFound()); } -void NoQueryResponder(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, NoQueryResponder) { - CommonTestElements common(inSuite, "test"); + CommonTestElements common("test"); ResponseSender responseSender(&common.server); QueryData queryData = QueryData(QType::ANY, QClass::IN, false, common.requestNameStart, common.requestBytesRange); common.recordWriter.WriteQName(common.dnsSd); responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, !common.server.GetSendCalled()); + EXPECT_FALSE(common.server.GetSendCalled()); common.recordWriter.WriteQName(common.service); responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, !common.server.GetSendCalled()); + EXPECT_FALSE(common.server.GetSendCalled()); common.recordWriter.WriteQName(common.instance); responseSender.Respond(1, queryData, &common.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, !common.server.GetSendCalled()); + EXPECT_FALSE(common.server.GetSendCalled()); } -void AddManyQueryResponders(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, AddManyQueryResponders) { // TODO(cecille): Fix this test once #8000 gets resolved. ResponseSender responseSender(nullptr); @@ -259,39 +265,39 @@ void AddManyQueryResponders(nlTestSuite * inSuite, void * inContext) constexpr size_t kAddLoopSize = 1000; for (size_t i = 0; i < kAddLoopSize; ++i) { - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q1) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q1), CHIP_NO_ERROR); } // removing the only copy should clear out everything responseSender.RemoveQueryResponder(&q1); - NL_TEST_ASSERT(inSuite, !responseSender.HasQueryResponders()); + EXPECT_FALSE(responseSender.HasQueryResponders()); // At least 7 should be supported: // - 5 is the spec minimum // - 2 for commissionable and commisioner responders - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q3) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q4) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q5) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q6) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&q7) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q1), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q2), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q3), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q4), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q5), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q6), CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&q7), CHIP_NO_ERROR); } -void PtrSrvTxtMultipleRespondersToInstance(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtMultipleRespondersToInstance) { - CommonTestElements common1(inSuite, "test1"); - CommonTestElements common2(inSuite, "test2"); + CommonTestElements common1("test1"); + CommonTestElements common2("test2"); // Just use the server from common1. ResponseSender responseSender(&common1.server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common1.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common1.queryResponder), CHIP_NO_ERROR); common1.queryResponder.AddResponder(&common1.ptrResponder).SetReportInServiceListing(true); common1.queryResponder.AddResponder(&common1.srvResponder); common1.queryResponder.AddResponder(&common1.txtResponder); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common2.queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common2.queryResponder), CHIP_NO_ERROR); common2.queryResponder.AddResponder(&common2.ptrResponder).SetReportInServiceListing(true); common2.queryResponder.AddResponder(&common2.srvResponder); common2.queryResponder.AddResponder(&common2.txtResponder); @@ -306,23 +312,23 @@ void PtrSrvTxtMultipleRespondersToInstance(nlTestSuite * inSuite, void * inConte responseSender.Respond(1, queryData, &common1.packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common1.server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common1.server.GetHeaderFound()); + EXPECT_TRUE(common1.server.GetSendCalled()); + EXPECT_TRUE(common1.server.GetHeaderFound()); } -void PtrSrvTxtMultipleRespondersToServiceListing(nlTestSuite * inSuite, void * inContext) +TEST_F(TestResponseSender, PtrSrvTxtMultipleRespondersToServiceListing) { - auto common1 = std::make_unique(inSuite, "test1"); - auto common2 = std::make_unique(inSuite, "test2"); + auto common1 = std::make_unique("test1"); + auto common2 = std::make_unique("test2"); // Just use the server from common1. ResponseSender responseSender(&common1->server); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common1->queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common1->queryResponder), CHIP_NO_ERROR); common1->queryResponder.AddResponder(&common1->ptrResponder).SetReportInServiceListing(true); common1->queryResponder.AddResponder(&common1->srvResponder); common1->queryResponder.AddResponder(&common1->txtResponder); - NL_TEST_ASSERT(inSuite, responseSender.AddQueryResponder(&common2->queryResponder) == CHIP_NO_ERROR); + EXPECT_EQ(responseSender.AddQueryResponder(&common2->queryResponder), CHIP_NO_ERROR); common2->queryResponder.AddResponder(&common2->ptrResponder).SetReportInServiceListing(true); common2->queryResponder.AddResponder(&common2->srvResponder); common2->queryResponder.AddResponder(&common2->txtResponder); @@ -339,44 +345,9 @@ void PtrSrvTxtMultipleRespondersToServiceListing(nlTestSuite * inSuite, void * i responseSender.Respond(1, queryData, &common1->packetInfo, ResponseConfiguration()); - NL_TEST_ASSERT(inSuite, common1->server.GetSendCalled()); + EXPECT_TRUE(common1->server.GetSendCalled()); - NL_TEST_ASSERT(inSuite, common1->server.GetHeaderFound()); -} - -const nlTest sTests[] = { - NL_TEST_DEF("SrvAnyResponseToInstance", SrvAnyResponseToInstance), // - NL_TEST_DEF("SrvTxtAnyResponseToInstance", SrvTxtAnyResponseToInstance), // - NL_TEST_DEF("PtrSrvTxtAnyResponseToServiceName", PtrSrvTxtAnyResponseToServiceName), // - NL_TEST_DEF("PtrSrvTxtAnyResponseToInstance", PtrSrvTxtAnyResponseToInstance), // - NL_TEST_DEF("PtrSrvTxtSrvResponseToInstance", PtrSrvTxtSrvResponseToInstance), // - NL_TEST_DEF("PtrSrvTxtAnyResponseToServiceListing", PtrSrvTxtAnyResponseToServiceListing), // - NL_TEST_DEF("NoQueryResponder", NoQueryResponder), // - NL_TEST_DEF("AddManyQueryResponders", AddManyQueryResponders), // - NL_TEST_DEF("PtrSrvTxtMultipleRespondersToInstance", PtrSrvTxtMultipleRespondersToInstance), // - NL_TEST_DEF("PtrSrvTxtMultipleRespondersToServiceListing", PtrSrvTxtMultipleRespondersToServiceListing), // - - NL_TEST_SENTINEL() // -}; - -int TestSetup(void * inContext) -{ - return chip::Platform::MemoryInit() == CHIP_NO_ERROR ? SUCCESS : FAILURE; -} - -int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; + EXPECT_TRUE(common1->server.GetHeaderFound()); } } // namespace - -int TestResponseSender() -{ - nlTestSuite theSuite = { "RecordData", sTests, &TestSetup, &TestTeardown }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestResponseSender) From 8238f9818a43a8184c9b87b0ad73abb396ad5325 Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Tue, 23 Apr 2024 18:30:31 +0200 Subject: [PATCH 08/19] Replaced nlunit-test with pw_unit_test in src/lib/dnssd/platform/ (#33072) * Replaced nlunit-test with pw_unit_test in src/lib/dnssd/platform/ * Clean up initialization code --- src/lib/dnssd/platform/tests/BUILD.gn | 9 +- src/lib/dnssd/platform/tests/TestPlatform.cpp | 111 ++++++++---------- 2 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/lib/dnssd/platform/tests/BUILD.gn b/src/lib/dnssd/platform/tests/BUILD.gn index 92b83195390f9c..966923eebae998 100644 --- a/src/lib/dnssd/platform/tests/BUILD.gn +++ b/src/lib/dnssd/platform/tests/BUILD.gn @@ -14,19 +14,14 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libMdnsFakePlatformTests" if (chip_device_platform == "fake") { test_sources = [ "TestPlatform.cpp" ] - public_deps = [ - "${chip_root}/src/lib/dnssd", - "${chip_root}/src/lib/support:testing_nlunit", - "${nlunit_test_root}:nlunit-test", - ] + public_deps = [ "${chip_root}/src/lib/dnssd" ] } } diff --git a/src/lib/dnssd/platform/tests/TestPlatform.cpp b/src/lib/dnssd/platform/tests/TestPlatform.cpp index 91a79f1efdc64a..ebdb46643847c6 100644 --- a/src/lib/dnssd/platform/tests/TestPlatform.cpp +++ b/src/lib/dnssd/platform/tests/TestPlatform.cpp @@ -18,12 +18,12 @@ #include #include -#include + #include #include #include -#include +#include #if CHIP_DEVICE_LAYER_TARGET_FAKE != 1 #error "This test is designed for use only with the fake platform" @@ -152,102 +152,87 @@ test::ExpectedCall commissionableLargeEnhanced = test::ExpectedCall() .AddSubtype("_V555") .AddSubtype("_T70000") .AddSubtype("_CM"); -void TestStub(nlTestSuite * inSuite, void * inContext) + +class TestDnssdPlatform : public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + DiscoveryImplPlatform & mdnsPlatform = DiscoveryImplPlatform::GetInstance(); + EXPECT_EQ(mdnsPlatform.Init(DeviceLayer::UDPEndPointManager()), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.RemoveServices(), CHIP_NO_ERROR); + } + + static void TearDownTestSuite() + { + DiscoveryImplPlatform::GetInstance().Shutdown(); + chip::Platform::MemoryShutdown(); + } + + void TearDown() override { test::Reset(); } +}; + +TEST_F(TestDnssdPlatform, TestStub) { // This is a test of the fake platform impl. We want // We want the platform to return unexpected event if it gets a start // without an expected event. ChipLogError(Discovery, "Test platform returns error correctly"); DiscoveryImplPlatform & mdnsPlatform = DiscoveryImplPlatform::GetInstance(); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Init(DeviceLayer::UDPEndPointManager()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.RemoveServices() == CHIP_NO_ERROR); OperationalAdvertisingParameters params; - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(params) == CHIP_ERROR_UNEXPECTED_EVENT); + EXPECT_EQ(mdnsPlatform.Advertise(params), CHIP_ERROR_UNEXPECTED_EVENT); } -void TestOperational(nlTestSuite * inSuite, void * inContext) +TEST_F(TestDnssdPlatform, TestOperational) { ChipLogError(Discovery, "Test operational"); - test::Reset(); DiscoveryImplPlatform & mdnsPlatform = DiscoveryImplPlatform::GetInstance(); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Init(DeviceLayer::UDPEndPointManager()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.RemoveServices() == CHIP_NO_ERROR); operationalCall1.callType = test::CallType::kStart; - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(operationalCall1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(operationalParams1) == CHIP_NO_ERROR); + EXPECT_EQ(test::AddExpectedCall(operationalCall1), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.Advertise(operationalParams1), CHIP_NO_ERROR); // Next call to advertise should call start again with just the new data. test::Reset(); operationalCall2.callType = test::CallType::kStart; - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(operationalCall2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(operationalParams2) == CHIP_NO_ERROR); + EXPECT_EQ(test::AddExpectedCall(operationalCall2), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.Advertise(operationalParams2), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.FinalizeServiceUpdate() == CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.FinalizeServiceUpdate(), CHIP_NO_ERROR); } -void TestCommissionableNode(nlTestSuite * inSuite, void * inContext) +TEST_F(TestDnssdPlatform, TestCommissionableNode) { ChipLogError(Discovery, "Test commissionable"); - test::Reset(); DiscoveryImplPlatform & mdnsPlatform = DiscoveryImplPlatform::GetInstance(); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Init(DeviceLayer::UDPEndPointManager()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.RemoveServices() == CHIP_NO_ERROR); commissionableSmall.callType = test::CallType::kStart; - NL_TEST_ASSERT(inSuite, - mdnsPlatform.GetCommissionableInstanceName(commissionableSmall.instanceName, - sizeof(commissionableSmall.instanceName)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableSmall) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsSmall) == CHIP_NO_ERROR); + EXPECT_EQ( + mdnsPlatform.GetCommissionableInstanceName(commissionableSmall.instanceName, sizeof(commissionableSmall.instanceName)), + CHIP_NO_ERROR); + EXPECT_EQ(test::AddExpectedCall(commissionableSmall), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.Advertise(commissionableNodeParamsSmall), CHIP_NO_ERROR); // TODO: Right now, platform impl doesn't stop commissionable node before starting a new one. Add stop call here once that is // fixed. test::Reset(); commissionableLargeBasic.callType = test::CallType::kStart; - NL_TEST_ASSERT(inSuite, - mdnsPlatform.GetCommissionableInstanceName(commissionableLargeBasic.instanceName, - sizeof(commissionableLargeBasic.instanceName)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableLargeBasic) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLargeBasic) == CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.GetCommissionableInstanceName(commissionableLargeBasic.instanceName, + sizeof(commissionableLargeBasic.instanceName)), + CHIP_NO_ERROR); + EXPECT_EQ(test::AddExpectedCall(commissionableLargeBasic), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.Advertise(commissionableNodeParamsLargeBasic), CHIP_NO_ERROR); test::Reset(); commissionableLargeEnhanced.callType = test::CallType::kStart; - NL_TEST_ASSERT(inSuite, - mdnsPlatform.GetCommissionableInstanceName(commissionableLargeEnhanced.instanceName, - sizeof(commissionableLargeEnhanced.instanceName)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableLargeEnhanced) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.GetCommissionableInstanceName(commissionableLargeEnhanced.instanceName, + sizeof(commissionableLargeEnhanced.instanceName)), + CHIP_NO_ERROR); + EXPECT_EQ(test::AddExpectedCall(commissionableLargeEnhanced), CHIP_NO_ERROR); + EXPECT_EQ(mdnsPlatform.Advertise(commissionableNodeParamsLargeEnhanced), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.FinalizeServiceUpdate() == CHIP_NO_ERROR); -} - -int TestSetup(void * inContext) -{ - return chip::Platform::MemoryInit() == CHIP_NO_ERROR ? SUCCESS : FAILURE; + EXPECT_EQ(mdnsPlatform.FinalizeServiceUpdate(), CHIP_NO_ERROR); } -int TestTeardown(void * inContext) -{ - DiscoveryImplPlatform::GetInstance().Shutdown(); - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -const nlTest sTests[] = { - NL_TEST_DEF("TestStub", TestStub), // - NL_TEST_DEF("TestOperational", TestOperational), // - NL_TEST_DEF("TestCommissionableNode", TestCommissionableNode), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestDnssdPlatform() -{ - nlTestSuite theSuite = { "DnssdPlatform", &sTests[0], &TestSetup, &TestTeardown }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestDnssdPlatform) From c2233975220dae296aacca06dcfed6075427fd15 Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Tue, 23 Apr 2024 18:37:28 +0200 Subject: [PATCH 09/19] Switched to pw_unit_test in src/lib/dnssd/minimal_mdns/core/ (#33069) * Switched to pw_unit_test in src/lib/dnssd/minimal_mdns/core/ * Update src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp --------- Co-authored-by: Arkadiusz Bokowy Co-authored-by: Arkadiusz Bokowy --- .../dnssd/minimal_mdns/core/tests/BUILD.gn | 5 +- .../core/tests/TestFlatAllocatedQName.cpp | 66 ++---- .../minimal_mdns/core/tests/TestHeapQName.cpp | 77 ++----- .../minimal_mdns/core/tests/TestQName.cpp | 206 +++++++----------- .../core/tests/TestRecordWriter.cpp | 60 ++--- .../openiotsdk/unit-tests/test_components.txt | 3 +- .../unit-tests/test_components_nl.txt | 1 - 7 files changed, 146 insertions(+), 272 deletions(-) diff --git a/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn index ce985ffc651b9a..39b59bb999c9ad 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn @@ -14,7 +14,6 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") @@ -27,7 +26,7 @@ source_set("support") { ] } -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libMinimalMdnsCoreTests" test_sources = [ @@ -43,7 +42,5 @@ chip_test_suite_using_nltest("tests") { ":support", "${chip_root}/src/lib/core", "${chip_root}/src/lib/dnssd/minimal_mdns/core", - "${chip_root}/src/lib/support:testing_nlunit", - "${nlunit_test_root}:nlunit-test", ] } diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp index db9aa23d2a7eb1..c9ab4f222ef6f0 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include -#include +#include namespace { @@ -38,28 +37,28 @@ class AutoFreeBuffer void * mBuffer; }; -void TestFlatAllocatedQName(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatAllocatedQName, TestFlatAllocatedQName) { AutoFreeBuffer buffer(128); - NL_TEST_ASSERT(inSuite, FlatAllocatedQName::RequiredStorageSize("some", "test") == (sizeof(char * [2]) + 5 + 5)); + EXPECT_EQ(FlatAllocatedQName::RequiredStorageSize("some", "test"), (sizeof(char * [2]) + 5 + 5)); { FullQName built = FlatAllocatedQName::Build(buffer.Buffer(), "some", "test"); const QNamePart expected[] = { "some", "test" }; - NL_TEST_ASSERT(inSuite, FullQName(expected) == built); + EXPECT_EQ(FullQName(expected), built); } { FullQName built = FlatAllocatedQName::Build(buffer.Buffer(), "1", "2", "3"); const QNamePart expected[] = { "1", "2", "3" }; - NL_TEST_ASSERT(inSuite, FullQName(expected) == built); + EXPECT_EQ(FullQName(expected), built); } } -void SizeCompare(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatAllocatedQName, SizeCompare) { static const char kThis[] = "this"; static const char kIs[] = "is"; @@ -79,23 +78,22 @@ void SizeCompare(nlTestSuite * inSuite, void * inContext) const size_t kTestStorageSize = FlatAllocatedQName::RequiredStorageSize(kThis, kIs, kA, kTest); - NL_TEST_ASSERT(inSuite, kTestStorageSize == FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArraySameSize, 4)); - NL_TEST_ASSERT(inSuite, kTestStorageSize == FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferentArraySameSize, 4)); - NL_TEST_ASSERT(inSuite, kTestStorageSize < FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferenArrayLongerWord, 4)); - NL_TEST_ASSERT(inSuite, kTestStorageSize > FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferenArrayShorterWord, 4)); + EXPECT_EQ(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArraySameSize, 4)); + EXPECT_EQ(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferentArraySameSize, 4)); + EXPECT_LT(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferenArrayLongerWord, 4)); + EXPECT_GT(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kDifferenArrayShorterWord, 4)); // Although the size of the array is larger, if we tell the function there are only 4 words, it should still work. - NL_TEST_ASSERT(inSuite, kTestStorageSize == FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArrayExtraWord, 4)); + EXPECT_EQ(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArrayExtraWord, 4)); // If we add the extra word, the sizes should not match - NL_TEST_ASSERT(inSuite, kTestStorageSize < FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArrayExtraWord, 5)); + EXPECT_LT(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArrayExtraWord, 5)); - NL_TEST_ASSERT(inSuite, kTestStorageSize > FlatAllocatedQName::RequiredStorageSizeFromArray(kShorterArray, 3)); - NL_TEST_ASSERT(inSuite, - FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArraySameSize, 3) == - FlatAllocatedQName::RequiredStorageSizeFromArray(kShorterArray, 3)); + EXPECT_GT(kTestStorageSize, FlatAllocatedQName::RequiredStorageSizeFromArray(kShorterArray, 3)); + EXPECT_EQ(FlatAllocatedQName::RequiredStorageSizeFromArray(kSameArraySameSize, 3), + FlatAllocatedQName::RequiredStorageSizeFromArray(kShorterArray, 3)); } -void BuildCompare(nlTestSuite * inSuite, void * inContext) +TEST(TestFlatAllocatedQName, BuildCompare) { static const char kThis[] = "this"; static const char kIs[] = "is"; @@ -111,33 +109,15 @@ void BuildCompare(nlTestSuite * inSuite, void * inContext) const FullQName kTestQName = FlatAllocatedQName::Build(storage, kThis, kIs, kA, kTest); - NL_TEST_ASSERT(inSuite, kTestQName == FlatAllocatedQName::BuildFromArray(storage, kSameArraySameSize, 4)); + EXPECT_EQ(kTestQName, FlatAllocatedQName::BuildFromArray(storage, kSameArraySameSize, 4)); // Although the size of the array is larger, if we tell the function there are only 4 words, it should still work. - NL_TEST_ASSERT(inSuite, kTestQName == FlatAllocatedQName::BuildFromArray(storage, kSameArrayExtraWord, 4)); + EXPECT_EQ(kTestQName, FlatAllocatedQName::BuildFromArray(storage, kSameArrayExtraWord, 4)); // If we add the extra word, the names - NL_TEST_ASSERT(inSuite, kTestQName != FlatAllocatedQName::BuildFromArray(storage, kSameArrayExtraWord, 5)); + EXPECT_NE(kTestQName, FlatAllocatedQName::BuildFromArray(storage, kSameArrayExtraWord, 5)); - NL_TEST_ASSERT(inSuite, kTestQName != FlatAllocatedQName::BuildFromArray(storage, kShorterArray, 3)); - NL_TEST_ASSERT(inSuite, - FlatAllocatedQName::BuildFromArray(storage, kSameArraySameSize, 3) == - FlatAllocatedQName::BuildFromArray(storage, kShorterArray, 3)); + EXPECT_NE(kTestQName, FlatAllocatedQName::BuildFromArray(storage, kShorterArray, 3)); + EXPECT_EQ(FlatAllocatedQName::BuildFromArray(storage, kSameArraySameSize, 3), + FlatAllocatedQName::BuildFromArray(storage, kShorterArray, 3)); } - -const nlTest sTests[] = { - NL_TEST_DEF("TestFlatAllocatedQName", TestFlatAllocatedQName), // - NL_TEST_DEF("TestFlatAllocatedQNameRequiredSizes", SizeCompare), // - NL_TEST_DEF("TestFlatAllocatedQNameBuild", BuildCompare), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestFlatAllocatedQName() -{ - nlTestSuite theSuite = { "FlatAllocatedQName", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestFlatAllocatedQName) diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp index 51e31ca0112205..22287751ac5f05 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp @@ -16,17 +16,23 @@ * limitations under the License. */ +#include + #include #include -#include - -#include namespace { using namespace mdns::Minimal; -void Construction(nlTestSuite * inSuite, void * inContext) +class TestHeapQName : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestHeapQName, Construction) { { @@ -34,9 +40,9 @@ void Construction(nlTestSuite * inSuite, void * inContext) HeapQName heapQName(kShort.Serialized()); - NL_TEST_ASSERT(inSuite, heapQName.IsOk()); - NL_TEST_ASSERT(inSuite, heapQName.Content() == kShort.Full()); - NL_TEST_ASSERT(inSuite, kShort.Serialized() == heapQName.Content()); + EXPECT_TRUE(heapQName.IsOk()); + EXPECT_EQ(heapQName.Content(), kShort.Full()); + EXPECT_EQ(kShort.Serialized(), heapQName.Content()); } { @@ -45,13 +51,13 @@ void Construction(nlTestSuite * inSuite, void * inContext) HeapQName heapQName(kLonger.Serialized()); - NL_TEST_ASSERT(inSuite, heapQName.IsOk()); - NL_TEST_ASSERT(inSuite, heapQName.Content() == kLonger.Full()); - NL_TEST_ASSERT(inSuite, kLonger.Serialized() == heapQName.Content()); + EXPECT_TRUE(heapQName.IsOk()); + EXPECT_EQ(heapQName.Content(), kLonger.Full()); + EXPECT_EQ(kLonger.Serialized(), heapQName.Content()); } } -void Copying(nlTestSuite * inSuite, void * inContext) +TEST_F(TestHeapQName, Copying) { const testing::TestQName<2> kShort({ "some", "test" }); @@ -61,50 +67,11 @@ void Copying(nlTestSuite * inSuite, void * inContext) name3 = name2; - NL_TEST_ASSERT(inSuite, name1.IsOk()); - NL_TEST_ASSERT(inSuite, name2.IsOk()); - NL_TEST_ASSERT(inSuite, name3.IsOk()); - NL_TEST_ASSERT(inSuite, name1.Content() == name2.Content()); - NL_TEST_ASSERT(inSuite, name1.Content() == name3.Content()); -} - -static const nlTest sTests[] = { // - NL_TEST_DEF("Construction", Construction), // - NL_TEST_DEF("Copying", Copying), // - NL_TEST_SENTINEL() -}; - -int Setup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int Teardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; + EXPECT_TRUE(name1.IsOk()); + EXPECT_TRUE(name2.IsOk()); + EXPECT_TRUE(name3.IsOk()); + EXPECT_EQ(name1.Content(), name2.Content()); + EXPECT_EQ(name1.Content(), name3.Content()); } } // namespace - -int TestHeapQName() -{ - nlTestSuite theSuite = { - "HeapQName", - &sTests[0], - &Setup, - &Teardown, - }; - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestHeapQName) diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp index da2f91013b3217..5f430bd3c76a7a 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp @@ -16,10 +16,9 @@ * limitations under the License. */ -#include -#include +#include -#include +#include namespace { @@ -40,67 +39,67 @@ static SerializedQNameIterator AsSerializedQName(const uint8_t (&v)[N]) return SerializedQNameIterator(BytesRange(v, v + N - 1), v); } -void IteratorTest(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, IteratorTest) { { static const uint8_t kOneItem[] = "\04test\00"; SerializedQNameIterator it = AsSerializedQName(kOneItem); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "test") == 0); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, it.IsValid()); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "test"); + EXPECT_FALSE(it.Next()); + EXPECT_TRUE(it.IsValid()); } { static const uint8_t kManyItems[] = "\04this\02is\01a\04test\00"; SerializedQNameIterator it = AsSerializedQName(kManyItems); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "this") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "this"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "is") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "is"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "a") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "a"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "test") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "test"); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_TRUE(it.IsValid()); } { static const uint8_t kPtrItems[] = "abc\02is\01a\04test\00\04this\xc0\03"; SerializedQNameIterator it(BytesRange(kPtrItems, kPtrItems + sizeof(kPtrItems)), kPtrItems + 14); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "this") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "this"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "is") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "is"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "a") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "a"); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, strcmp(it.Value(), "test") == 0); + EXPECT_TRUE(it.Next()); + EXPECT_STREQ(it.Value(), "test"); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_TRUE(it.IsValid()); } } -void ErrorTest(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, ErrorTest) { { // Truncated before the end static const uint8_t kData[] = "\04test"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -108,8 +107,8 @@ void ErrorTest(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\02"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -117,12 +116,12 @@ void ErrorTest(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\xc0"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } } -void InvalidReferencing(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, InvalidReferencing) { { // Truncated before the end (but seemingly valid in case of error) @@ -130,8 +129,8 @@ void InvalidReferencing(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\00\xc0\x00"; SerializedQNameIterator it(BytesRange(kData, kData + 2), kData + 1); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -139,9 +138,9 @@ void InvalidReferencing(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\03test\xc0\x00"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_TRUE(it.Next()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -149,9 +148,9 @@ void InvalidReferencing(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\03test\xc0\x05"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_TRUE(it.Next()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -159,8 +158,8 @@ void InvalidReferencing(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\xc0\x00"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } { @@ -168,171 +167,134 @@ void InvalidReferencing(nlTestSuite * inSuite, void * inContext) static const uint8_t kData[] = "\03test\xc0\x07"; SerializedQNameIterator it = AsSerializedQName(kData); - NL_TEST_ASSERT(inSuite, it.Next()); - NL_TEST_ASSERT(inSuite, !it.Next()); - NL_TEST_ASSERT(inSuite, !it.IsValid()); + EXPECT_TRUE(it.Next()); + EXPECT_FALSE(it.Next()); + EXPECT_FALSE(it.IsValid()); } } -void Comparison(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, Comparison) { static const uint8_t kManyItems[] = "\04this\02is\01a\04test\00"; { const QNamePart kTestName[] = { "this" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) != FullQName(kTestName)); + EXPECT_NE(AsSerializedQName(kManyItems), FullQName(kTestName)); } { const QNamePart kTestName[] = { "this", "is" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) != FullQName(kTestName)); + EXPECT_NE(AsSerializedQName(kManyItems), FullQName(kTestName)); } { const QNamePart kTestName[] = { "is", "a", "test" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) != FullQName(kTestName)); + EXPECT_NE(AsSerializedQName(kManyItems), FullQName(kTestName)); } { const QNamePart kTestName[] = { "this", "is", "a", "test" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) == FullQName(kTestName)); + EXPECT_EQ(AsSerializedQName(kManyItems), FullQName(kTestName)); } { const QNamePart kTestName[] = { "this", "is", "a", "test", "suffix" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) != FullQName(kTestName)); + EXPECT_NE(AsSerializedQName(kManyItems), FullQName(kTestName)); } { const QNamePart kTestName[] = { "prefix", "this", "is", "a", "test" }; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kManyItems) != FullQName(kTestName)); + EXPECT_NE(AsSerializedQName(kManyItems), FullQName(kTestName)); } } -void CaseInsensitiveSerializedCompare(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, CaseInsensitiveSerializedCompare) { static const uint8_t kManyItems[] = "\04thIs\02iS\01a\04tEst\00"; { const QNamePart kTestName[] = { "this", "is", "a", "test" }; - NL_TEST_ASSERT(inSuite, - SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems) == - FullQName(kTestName)); + EXPECT_EQ(SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems), + FullQName(kTestName)); } { const QNamePart kTestName[] = { "THIS", "IS", "A", "test" }; - NL_TEST_ASSERT(inSuite, - SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems) == - FullQName(kTestName)); + EXPECT_EQ(SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems), + FullQName(kTestName)); } { const QNamePart kTestName[] = { "THIS", "IS", "A", "TEST" }; - NL_TEST_ASSERT(inSuite, - SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems) == - FullQName(kTestName)); + EXPECT_EQ(SerializedQNameIterator(BytesRange(kManyItems, kManyItems + sizeof(kManyItems)), kManyItems), + FullQName(kTestName)); } } -void CaseInsensitiveFullQNameCompare(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, CaseInsensitiveFullQNameCompare) { { const QNamePart kName1[] = { "this", "is", "a", "test" }; const QNamePart kName2[] = { "this", "IS", "a", "TEST" }; - NL_TEST_ASSERT(inSuite, FullQName(kName1) == FullQName(kName2)); + EXPECT_EQ(FullQName(kName1), FullQName(kName2)); } { const QNamePart kName1[] = { "THIS", "IS", "a", "tesT" }; const QNamePart kName2[] = { "this", "IS", "A", "TEst" }; - NL_TEST_ASSERT(inSuite, FullQName(kName1) == FullQName(kName2)); + EXPECT_EQ(FullQName(kName1), FullQName(kName2)); } { const QNamePart kName1[] = { "THIS", "IS", "a", "test" }; const QNamePart kName2[] = { "this", "IS", "A", "NEST" }; - NL_TEST_ASSERT(inSuite, FullQName(kName1) != FullQName(kName2)); + EXPECT_NE(FullQName(kName1), FullQName(kName2)); } { const QNamePart kName1[] = { "THIS", "IS", "a" }; const QNamePart kName2[] = { "this", "IS", "A", "NEST" }; - NL_TEST_ASSERT(inSuite, FullQName(kName1) != FullQName(kName2)); + EXPECT_NE(FullQName(kName1), FullQName(kName2)); } { const QNamePart kName1[] = { "THIS", "IS", "a" }; const QNamePart kName2[] = { "this", "IS" }; - NL_TEST_ASSERT(inSuite, FullQName(kName1) != FullQName(kName2)); + EXPECT_NE(FullQName(kName1), FullQName(kName2)); } { const QNamePart kName[] = { "this" }; - NL_TEST_ASSERT(inSuite, FullQName() != FullQName(kName)); - NL_TEST_ASSERT(inSuite, FullQName(kName) != FullQName()); + EXPECT_NE(FullQName(), FullQName(kName)); + EXPECT_NE(FullQName(kName), FullQName()); } } -void SerializedCompare(nlTestSuite * inSuite, void * inContext) +TEST(TestQName, SerializedCompare) { static const uint8_t kThisIsATest1[] = "\04this\02is\01a\04test\00"; static const uint8_t kThisIsATest2[] = "\04ThIs\02is\01A\04tESt\00"; static const uint8_t kThisIsDifferent[] = "\04this\02is\09different\00"; static const uint8_t kThisIs[] = "\04this\02is"; - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest1) == AsSerializedQName(kThisIsATest1)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest2) == AsSerializedQName(kThisIsATest2)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest1) == AsSerializedQName(kThisIsATest2)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest1) != AsSerializedQName(kThisIsDifferent)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsDifferent) != AsSerializedQName(kThisIsATest1)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsDifferent) != AsSerializedQName(kThisIs)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIs) != AsSerializedQName(kThisIsDifferent)); + EXPECT_EQ(AsSerializedQName(kThisIsATest1), AsSerializedQName(kThisIsATest1)); + EXPECT_EQ(AsSerializedQName(kThisIsATest2), AsSerializedQName(kThisIsATest2)); + EXPECT_EQ(AsSerializedQName(kThisIsATest1), AsSerializedQName(kThisIsATest2)); + EXPECT_NE(AsSerializedQName(kThisIsATest1), AsSerializedQName(kThisIsDifferent)); + EXPECT_NE(AsSerializedQName(kThisIsDifferent), AsSerializedQName(kThisIsATest1)); + EXPECT_NE(AsSerializedQName(kThisIsDifferent), AsSerializedQName(kThisIs)); + EXPECT_NE(AsSerializedQName(kThisIs), AsSerializedQName(kThisIsDifferent)); // These items have back references and are "this.is.a.test" static const uint8_t kPtrItems[] = "\03abc\02is\01a\04test\00\04this\xc0\04"; SerializedQNameIterator thisIsATestPtr(BytesRange(kPtrItems, kPtrItems + sizeof(kPtrItems)), kPtrItems + 15); - NL_TEST_ASSERT(inSuite, thisIsATestPtr == AsSerializedQName(kThisIsATest1)); - NL_TEST_ASSERT(inSuite, thisIsATestPtr == AsSerializedQName(kThisIsATest2)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest1) == thisIsATestPtr); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIsATest2) == thisIsATestPtr); - NL_TEST_ASSERT(inSuite, thisIsATestPtr != AsSerializedQName(kThisIs)); - NL_TEST_ASSERT(inSuite, AsSerializedQName(kThisIs) != thisIsATestPtr); + EXPECT_EQ(thisIsATestPtr, AsSerializedQName(kThisIsATest1)); + EXPECT_EQ(thisIsATestPtr, AsSerializedQName(kThisIsATest2)); + EXPECT_EQ(AsSerializedQName(kThisIsATest1), thisIsATestPtr); + EXPECT_EQ(AsSerializedQName(kThisIsATest2), thisIsATestPtr); + EXPECT_NE(thisIsATestPtr, AsSerializedQName(kThisIs)); + EXPECT_NE(AsSerializedQName(kThisIs), thisIsATestPtr); } } // namespace - -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("IteratorTest", IteratorTest), - NL_TEST_DEF("ErrorTest", ErrorTest), - NL_TEST_DEF("Comparison", Comparison), - NL_TEST_DEF("CaseInsensitiveSerializedCompare", CaseInsensitiveSerializedCompare), - NL_TEST_DEF("CaseInsensitiveFullQNameCompare", CaseInsensitiveFullQNameCompare), - NL_TEST_DEF("SerializedCompare", SerializedCompare), - NL_TEST_DEF("InvalidReferencing", InvalidReferencing), - - NL_TEST_SENTINEL() -}; -// clang-format on - -int TestQName() -{ - // clang-format off - nlTestSuite theSuite = - { - "QName", - &sTests[0], - nullptr, - nullptr - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestQName) diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp index e6e2e9611f38c6..f8dbc220978c87 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp @@ -16,17 +16,16 @@ * limitations under the License. */ -#include -#include +#include -#include +#include namespace { using namespace mdns::Minimal; using namespace chip::Encoding::BigEndian; -void BasicWriteTest(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordWriter, BasicWriteTest) { const QNamePart kName1[] = { "some", "name" }; const QNamePart kName2[] = { "abc", "xyz", "here" }; @@ -52,11 +51,11 @@ void BasicWriteTest(nlTestSuite * inSuite, void * inContext) }; // clang-format on - NL_TEST_ASSERT(inSuite, output.Needed() == sizeof(expectedOutput)); - NL_TEST_ASSERT(inSuite, memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)) == 0); + EXPECT_EQ(output.Needed(), sizeof(expectedOutput)); + EXPECT_EQ(memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)), 0); } -void SimpleDedup(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordWriter, SimpleDedup) { const QNamePart kName1[] = { "some", "name" }; const QNamePart kName2[] = { "other", "name" }; @@ -80,11 +79,11 @@ void SimpleDedup(nlTestSuite * inSuite, void * inContext) }; // clang-format on - NL_TEST_ASSERT(inSuite, output.Needed() == sizeof(expectedOutput)); - NL_TEST_ASSERT(inSuite, memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)) == 0); + EXPECT_EQ(output.Needed(), sizeof(expectedOutput)); + EXPECT_EQ(memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)), 0); } -void ComplexDedup(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordWriter, ComplexDedup) { const QNamePart kName1[] = { "some", "name" }; const QNamePart kName2[] = { "other", "name" }; @@ -125,11 +124,11 @@ void ComplexDedup(nlTestSuite * inSuite, void * inContext) }; // clang-format on - NL_TEST_ASSERT(inSuite, output.Needed() == sizeof(expectedOutput)); - NL_TEST_ASSERT(inSuite, memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)) == 0); + EXPECT_EQ(output.Needed(), sizeof(expectedOutput)); + EXPECT_EQ(memcmp(dataBuffer, expectedOutput, sizeof(expectedOutput)), 0); } -void TonsOfReferences(nlTestSuite * inSuite, void * inContext) +TEST(TestRecordWriter, TonsOfReferences) { const QNamePart kName1[] = { "some", "name" }; const QNamePart kName2[] = { "different", "name" }; @@ -159,39 +158,8 @@ void TonsOfReferences(nlTestSuite * inSuite, void * inContext) writer.WriteQName(FullQName(kName2)); } - NL_TEST_ASSERT(inSuite, output.Fit()); - NL_TEST_ASSERT(inSuite, output.Needed() == 423); + EXPECT_TRUE(output.Fit()); + EXPECT_EQ(output.Needed(), 423u); } } // namespace - -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("BasicWriteTest", BasicWriteTest), - NL_TEST_DEF("SimpleDedup", SimpleDedup), - NL_TEST_DEF("ComplexDedup", ComplexDedup), - NL_TEST_DEF("TonsOfReferences", TonsOfReferences), - - NL_TEST_SENTINEL() -}; -// clang-format on - -int TestRecordWriter() -{ - // clang-format off - nlTestSuite theSuite = - { - "RecordWriter", - &sTests[0], - nullptr, - nullptr - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestRecordWriter) diff --git a/src/test_driver/openiotsdk/unit-tests/test_components.txt b/src/test_driver/openiotsdk/unit-tests/test_components.txt index 8504c28313f998..e112a8b2ed5d50 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components.txt @@ -1,9 +1,10 @@ accesstest -SystemLayerTests ASN1Tests +MinimalMdnsCoreTests MinimalMdnsRecordsTests MinimalMdnsRespondersTests CoreTests PlatformTests +SystemLayerTests TestShell SetupPayloadTests \ No newline at end of file diff --git a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt index 3da7f5bdfb608f..13a59af526f4dd 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt @@ -6,7 +6,6 @@ DataModelTests InetLayerTests MdnsTests MessagingLayerTests -MinimalMdnsCoreTests RawTransportTests RetransmitTests SecureChannelTests From 5e925caa142e9702d96c352a9fea44695327bf34 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 23 Apr 2024 13:42:58 -0400 Subject: [PATCH 10/19] MinMDNS - do not ask for IP addresses for every SRV record that is seen (#33095) * Initial version of a test app - ability to just send a packet into the world * Update constants to match a real advertisement * Only resolve IP addresses if we are interested in this path * Fix up logic: this is per peer id * Remove unused include * Undo debug code * Undo extra header add * Add header back, but with full path * Fix up some more headers * Remove unhelpful comment * Move tester program out (will be part of another PR) --------- Co-authored-by: Andrei Litvin --- src/lib/dnssd/ActiveResolveAttempts.cpp | 28 ++++++++++++++++++++-- src/lib/dnssd/ActiveResolveAttempts.h | 6 +++++ src/lib/dnssd/IncrementalResolve.h | 7 ++++++ src/lib/dnssd/Resolver_ImplMinimalMdns.cpp | 20 +++++++++++++--- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/lib/dnssd/ActiveResolveAttempts.cpp b/src/lib/dnssd/ActiveResolveAttempts.cpp index fe0cc16ebb26aa..f49056896e0b2e 100644 --- a/src/lib/dnssd/ActiveResolveAttempts.cpp +++ b/src/lib/dnssd/ActiveResolveAttempts.cpp @@ -19,8 +19,6 @@ #include -#include - using namespace chip; namespace mdns { @@ -284,6 +282,32 @@ Optional ActiveResolveAttempts::NextSch return Optional::Missing(); } +bool ActiveResolveAttempts::ShouldResolveIpAddress(PeerId peerId) const +{ + for (auto & item : mRetryQueue) + { + if (item.attempt.IsEmpty()) + { + continue; + } + if (item.attempt.IsBrowse()) + { + return true; + } + + if (item.attempt.IsResolve()) + { + auto & data = item.attempt.ResolveData(); + if (data.peerId == peerId) + { + return true; + } + } + } + + return false; +} + bool ActiveResolveAttempts::IsWaitingForIpResolutionFor(SerializedQNameIterator hostName) const { for (auto & entry : mRetryQueue) diff --git a/src/lib/dnssd/ActiveResolveAttempts.h b/src/lib/dnssd/ActiveResolveAttempts.h index ba6d8cf7a54f6e..1d87bbbba49cbc 100644 --- a/src/lib/dnssd/ActiveResolveAttempts.h +++ b/src/lib/dnssd/ActiveResolveAttempts.h @@ -288,6 +288,12 @@ class ActiveResolveAttempts /// IP resolution. bool IsWaitingForIpResolutionFor(SerializedQNameIterator hostName) const; + /// Determines if address resolution for the given peer ID is required + /// + /// IP Addresses are required for active operational discovery of specific peers + /// or if an active browse is being performed. + bool ShouldResolveIpAddress(chip::PeerId peerId) const; + /// Check if a browse operation is active for the given discovery type bool HasBrowseFor(chip::Dnssd::DiscoveryType type) const; diff --git a/src/lib/dnssd/IncrementalResolve.h b/src/lib/dnssd/IncrementalResolve.h index 9d2386472d7eba..17790b6f9f5fe0 100644 --- a/src/lib/dnssd/IncrementalResolve.h +++ b/src/lib/dnssd/IncrementalResolve.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include @@ -104,6 +105,12 @@ class IncrementalResolver ServiceNameType GetCurrentType() const { return mServiceNameType; } + PeerId OperationalParsePeerId() const + { + VerifyOrReturnValue(IsActiveOperationalParse(), PeerId()); + return mSpecificResolutionData.Get().peerId; + } + /// Start parsing a new record. SRV records are the records we are mainly /// interested on, after which TXT and A/AAAA are looked for. /// diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index a5e7117a72a005..3abc11ac659cf8 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -17,8 +17,6 @@ #include "Resolver.h" -#include - #include #include #include @@ -372,7 +370,23 @@ void MinMdnsResolver::AdvancePendingResolverStates() if (missing.Has(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)) { - ScheduleIpAddressResolve(resolver->GetTargetHostName()); + if (resolver->IsActiveBrowseParse()) + { + // Browse wants IP addresses + ScheduleIpAddressResolve(resolver->GetTargetHostName()); + } + else if (mActiveResolves.ShouldResolveIpAddress(resolver->OperationalParsePeerId())) + { + // Keep searching for IP addresses if an active resolve needs these IP addresses + // otherwise ignore the data (received a SRV record without IP address, however we do not + // seem interested in it. Probably just a device that came online). + ScheduleIpAddressResolve(resolver->GetTargetHostName()); + } + else + { + // This IP address is not interesting enough to run another discovery + resolver->ResetToInactive(); + } continue; } From 628d0f361975ecb7d8adf3553df2ef1a5836fbc9 Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:10:08 -0400 Subject: [PATCH 11/19] Add Apptask behavior in the LIT ICD app (#33116) --- examples/lit-icd-app/silabs/include/AppTask.h | 28 ++++++++++++- .../silabs/include/CHIPProjectConfig.h | 7 ++++ examples/lit-icd-app/silabs/src/AppTask.cpp | 42 +++++++++++++++++-- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/examples/lit-icd-app/silabs/include/AppTask.h b/examples/lit-icd-app/silabs/include/AppTask.h index 7866fc48079962..e4440f78d77e05 100644 --- a/examples/lit-icd-app/silabs/include/AppTask.h +++ b/examples/lit-icd-app/silabs/include/AppTask.h @@ -28,6 +28,7 @@ #include "AppEvent.h" #include "BaseApplication.h" +#include #include #include #include @@ -49,11 +50,12 @@ * AppTask Declaration *********************************************************/ -class AppTask : public BaseApplication +class AppTask : public BaseApplication, public chip::app::ICDStateObserver { public: - AppTask() = default; + AppTask() = default; + virtual ~AppTask() = default; static AppTask & GetAppTask() { return sAppTask; } @@ -76,6 +78,28 @@ class AppTask : public BaseApplication */ static void ButtonEventHandler(uint8_t button, uint8_t btnAction); + /** + * @brief When the ICD enters ActiveMode, update LCD to reflect the ICD current state. + * Set LCD to ActiveMode UI. + */ + void OnEnterActiveMode(); + + /** + * @brief When the ICD enters IdleMode, update LCD to reflect the ICD current state. + * Set LCD to IdleMode UI. + */ + void OnEnterIdleMode(); + + /** + * @brief AppTask has no action to do on this ICD event. Do nothing. + */ + void OnTransitionToIdle(){}; + + /** + * @brief AppTask has no action to do on this ICD event. Do nothing. + */ + void OnICDModeChange(){}; + private: static AppTask sAppTask; diff --git a/examples/lit-icd-app/silabs/include/CHIPProjectConfig.h b/examples/lit-icd-app/silabs/include/CHIPProjectConfig.h index 0a57cdfdcebb83..7681cd3bc5a644 100644 --- a/examples/lit-icd-app/silabs/include/CHIPProjectConfig.h +++ b/examples/lit-icd-app/silabs/include/CHIPProjectConfig.h @@ -86,3 +86,10 @@ * A size, in bytes, of the individual debug event logging buffer. */ #define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * @brief CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE + * + * Increase default(2) by 1 to account for the AppTask registering + */ +#define CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE 3 diff --git a/examples/lit-icd-app/silabs/src/AppTask.cpp b/examples/lit-icd-app/silabs/src/AppTask.cpp index bb7bf1a77bc17e..0fb98266d2a81d 100644 --- a/examples/lit-icd-app/silabs/src/AppTask.cpp +++ b/examples/lit-icd-app/silabs/src/AppTask.cpp @@ -33,17 +33,18 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED +#include +#include #include #include #include #include #include #include +#include #include #include -#include - /********************************************************** * Defines and Constants *********************************************************/ @@ -103,6 +104,8 @@ void AppTask::AppTaskMain(void * pvParameter) appError(err); } + chip::Server::GetInstance().GetICDManager().RegisterObserver(&sAppTask); + #if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) sAppTask.StartStatusLEDTimer(); #endif @@ -122,7 +125,28 @@ void AppTask::AppTaskMain(void * pvParameter) void AppTask::ApplicationEventHandler(AppEvent * aEvent) { VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Button); - // TODO - trigger some application event + VerifyOrReturn(aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonPressed)); + + // Simple Application logic that toggles the BoleanState StateValue attribute. + // DO NOT COPY for product logic. LIT ICD app is a test app with very simple application logic to enable testing. + // The goal of the app is just to enable testing of LIT ICD features without impacting product sample apps. + PlatformMgr().ScheduleWork([](intptr_t) { + bool state = true; + + Protocols::InteractionModel::Status status = chip::app::Clusters::BooleanState::Attributes::StateValue::Get(1, &state); + if (status != Protocols::InteractionModel::Status::Success) + { + // Failed to read StateValue. Default to true (open state) + state = true; + ChipLogError(NotSpecified, "ERR: reading boolean status value %x", to_underlying(status)); + } + + status = chip::app::Clusters::BooleanState::Attributes::StateValue::Set(1, !state); + if (status != Protocols::InteractionModel::Status::Success) + { + ChipLogError(NotSpecified, "ERR: updating boolean status value %x", to_underlying(status)); + } + }); } void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) @@ -142,3 +166,15 @@ void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) sAppTask.PostEvent(&button_event); } } + +// DO NOT COPY for product logic. LIT ICD app is a test app with very simple application logic to enable testing. +void AppTask::OnEnterActiveMode() +{ + sAppTask.GetLCD().WriteDemoUI(true); +} + +// DO NOT COPY for product logic. LIT ICD app is a test app with very simple application logic to enable testing. +void AppTask::OnEnterIdleMode() +{ + sAppTask.GetLCD().WriteDemoUI(false); +} From 0bb34b0252d1a69aee63c22f52bd4e505fa7261f Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Tue, 23 Apr 2024 22:13:27 +0200 Subject: [PATCH 12/19] Replaced nlunit-test with pw_unit_test in src/lib/dnssd/tests/ (#33045) * Replaced nlunit-test with pw_unit_test in src/lib/dnssd/tests/ * Update openiotsdk test components --- src/lib/dnssd/tests/BUILD.gn | 9 +- .../dnssd/tests/TestActiveResolveAttempts.cpp | 242 +++++------ .../dnssd/tests/TestIncrementalResolve.cpp | 289 ++++++------- src/lib/dnssd/tests/TestServiceNaming.cpp | 210 ++++----- src/lib/dnssd/tests/TestTxtFields.cpp | 409 ++++++++++-------- .../openiotsdk/unit-tests/test_components.txt | 1 + .../unit-tests/test_components_nl.txt | 1 - 7 files changed, 545 insertions(+), 616 deletions(-) diff --git a/src/lib/dnssd/tests/BUILD.gn b/src/lib/dnssd/tests/BUILD.gn index e64d0c756a33c2..cdcb4bab0e27a1 100644 --- a/src/lib/dnssd/tests/BUILD.gn +++ b/src/lib/dnssd/tests/BUILD.gn @@ -14,11 +14,10 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libMdnsTests" test_sources = [ @@ -26,11 +25,7 @@ chip_test_suite_using_nltest("tests") { "TestTxtFields.cpp", ] - public_deps = [ - "${chip_root}/src/lib/dnssd", - "${chip_root}/src/lib/support:testing_nlunit", - "${nlunit_test_root}:nlunit-test", - ] + public_deps = [ "${chip_root}/src/lib/dnssd" ] if (chip_mdns == "minimal") { test_sources += [ diff --git a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp index f4ef2f202c4def..58c1cf86dab511 100644 --- a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp +++ b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp @@ -16,9 +16,7 @@ */ #include -#include - -#include +#include namespace { @@ -43,7 +41,7 @@ Optional ScheduledBrowse(const Dnssd::D return Optional::Value(ActiveResolveAttempts::ScheduledAttempt(filter, type, first)); } -void TestSinglePeerAddRemove(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestSinglePeerAddRemove) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -51,42 +49,42 @@ void TestSinglePeerAddRemove(nlTestSuite * inSuite, void * inContext) mockClock.AdvanceMonotonic(1234_ms32); // Starting up, no scheduled peers are expected - NL_TEST_ASSERT(inSuite, !attempts.GetTimeUntilNextExpectedResponse().HasValue()); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // Adding a single peer should result in it being scheduled attempts.MarkPending(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 1000 ms - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); mockClock.AdvanceMonotonic(500_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(500_ms32)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(500_ms32)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // past due date: timeout should be 0 mockClock.AdvanceMonotonic(800_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 2000 ms // sincve the timeout doubles every time - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(2000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(2000_ms32)); mockClock.AdvanceMonotonic(100_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1900_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1900_ms32)); // once complete, nothing to schedule attempts.Complete(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, !attempts.GetTimeUntilNextExpectedResponse().HasValue()); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); } -void TestSingleBrowseAddRemove(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestSingleBrowseAddRemove) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -96,43 +94,43 @@ void TestSingleBrowseAddRemove(nlTestSuite * inSuite, void * inContext) mockClock.AdvanceMonotonic(1234_ms32); // Starting up, no scheduled peers are expected - NL_TEST_ASSERT(inSuite, !attempts.GetTimeUntilNextExpectedResponse().HasValue()); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // Adding a single attempt should result in it being scheduled attempts.MarkPending(filter, type); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 1000 ms - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); mockClock.AdvanceMonotonic(500_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(500_ms32)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(500_ms32)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // past due date: timeout should be 0 mockClock.AdvanceMonotonic(800_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 2000 ms // sincve the timeout doubles every time - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(2000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(2000_ms32)); mockClock.AdvanceMonotonic(100_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1900_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1900_ms32)); // once complete, nothing to schedule Dnssd::DiscoveredNodeData data; data.nodeData.longDiscriminator = 1234; attempts.CompleteCommissionable(data); - NL_TEST_ASSERT(inSuite, !attempts.GetTimeUntilNextExpectedResponse().HasValue()); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); } -void TestRescheduleSamePeerId(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestRescheduleSamePeerId) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -141,30 +139,30 @@ void TestRescheduleSamePeerId(nlTestSuite * inSuite, void * inContext) attempts.MarkPending(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 1000 ms - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); // 2nd try goes to 2 seconds (once at least 1 second passes) mockClock.AdvanceMonotonic(1234_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(2000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(2000_ms32)); // reschedule starts fresh attempts.MarkPending(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); } -void TestRescheduleSameFilter(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestRescheduleSameFilter) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -175,30 +173,30 @@ void TestRescheduleSameFilter(nlTestSuite * inSuite, void * inContext) attempts.MarkPending(filter, type); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // one Next schedule is called, expect to have a delay of 1000 ms - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); // 2nd try goes to 2 seconds (once at least 1 second passes) mockClock.AdvanceMonotonic(1234_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(2000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(2000_ms32)); // reschedule starts fresh attempts.MarkPending(filter, type); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); } -void TestLRU(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestLRU) { // validates that the LRU logic is working System::Clock::Internal::MockClock mockClock; @@ -208,16 +206,16 @@ void TestLRU(nlTestSuite * inSuite, void * inContext) // add a single very old peer attempts.MarkPending(MakePeerId(9999)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(9999, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(9999, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); mockClock.AdvanceMonotonic(1000_ms32); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(9999, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(9999, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); mockClock.AdvanceMonotonic(2000_ms32); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(9999, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(9999, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // at this point, peer 9999 has a delay of 4 seconds. Fill up the rest of the table @@ -226,15 +224,14 @@ void TestLRU(nlTestSuite * inSuite, void * inContext) attempts.MarkPending(MakePeerId(i)); mockClock.AdvanceMonotonic(1_ms32); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(i, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(i, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); } // +2 because: 1 element skipped, one element is the "current" that has a delay of 1000ms - NL_TEST_ASSERT(inSuite, - attempts.GetTimeUntilNextExpectedResponse() == - Optional::Value( - System::Clock::Milliseconds32(1000 - mdns::Minimal::ActiveResolveAttempts::kRetryQueueSize + 2))); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), + Optional::Value( + System::Clock::Milliseconds32(1000 - mdns::Minimal::ActiveResolveAttempts::kRetryQueueSize + 2))); // add another element - this should overwrite peer 9999 attempts.MarkPending(MakePeerId(mdns::Minimal::ActiveResolveAttempts::kRetryQueueSize)); @@ -242,11 +239,11 @@ void TestLRU(nlTestSuite * inSuite, void * inContext) for (Optional s = attempts.NextScheduled(); s.HasValue(); s = attempts.NextScheduled()) { - NL_TEST_ASSERT(inSuite, s.Value().ResolveData().peerId.GetNodeId() != 9999); + EXPECT_NE(s.Value().ResolveData().peerId.GetNodeId(), 9999u); } // Still have active pending items (queue is full) - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_TRUE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); // expire all of them. Since we double timeout every expiry, we expect a // few iteratios to be able to expire the entire queue @@ -266,14 +263,14 @@ void TestLRU(nlTestSuite * inSuite, void * inContext) Optional s = attempts.NextScheduled(); while (s.HasValue()) { - NL_TEST_ASSERT(inSuite, s.Value().ResolveData().peerId.GetNodeId() != 9999); + EXPECT_NE(s.Value().ResolveData().peerId.GetNodeId(), 9999u); s = attempts.NextScheduled(); } } - NL_TEST_ASSERT(inSuite, i < kMaxIterations); + EXPECT_LT(i, kMaxIterations); } -void TestNextPeerOrdering(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestNextPeerOrdering) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -283,52 +280,52 @@ void TestNextPeerOrdering(nlTestSuite * inSuite, void * inContext) // add a single peer that will be resolved quickly attempts.MarkPending(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); mockClock.AdvanceMonotonic(20_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(980_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(980_ms32)); // expect peerid to be resolve within 1 second from now attempts.MarkPending(MakePeerId(2)); // mock that we are querying 2 as well - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(2, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(2, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); mockClock.AdvanceMonotonic(80_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(900_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(900_ms32)); // Peer 1 is done, now peer2 should be pending (in 980ms) attempts.Complete(MakePeerId(1)); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(920_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(920_ms32)); mockClock.AdvanceMonotonic(20_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(900_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(900_ms32)); // Once peer 3 is added, queue should be // - 900 ms until peer id 2 is pending // - 1000 ms until peer id 3 is pending attempts.MarkPending(MakePeerId(3)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(3, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(900_ms32)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(3, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(900_ms32)); // After the clock advance // - 400 ms until peer id 2 is pending // - 500 ms until peer id 3 is pending mockClock.AdvanceMonotonic(500_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(400_ms32)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(400_ms32)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // advancing the clock 'too long' will return both other entries, in reverse order due to how // the internal cache is built mockClock.AdvanceMonotonic(500_ms32); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(3, false)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(2, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(3, false)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(2, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); } -void TestCombination(nlTestSuite * inSuite, void * inContext) +TEST(TestActiveResolveAttempts, TestCombination) { System::Clock::Internal::MockClock mockClock; mdns::Minimal::ActiveResolveAttempts attempts(&mockClock); @@ -342,34 +339,34 @@ void TestCombination(nlTestSuite * inSuite, void * inContext) mockClock.AdvanceMonotonic(20_ms32); attempts.MarkPending(filter, type); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, true)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, true)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // At this point, both should reset, so we're back to 1000ms - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(1000_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(1000_ms32)); // We used 20 ms, so the next time for the peer and resolve should be 980 ms mockClock.AdvanceMonotonic(20_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(980_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(980_ms32)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // Add a second Peer mockClock.AdvanceMonotonic(20_ms32); attempts.MarkPending(MakePeerId(2)); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(2, true)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(2, true)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // Advance to the retry time of peer 1 and the resolve mockClock.AdvanceMonotonic(960_ms32); - NL_TEST_ASSERT(inSuite, attempts.GetTimeUntilNextExpectedResponse() == Optional(0_ms32)); + EXPECT_EQ(attempts.GetTimeUntilNextExpectedResponse(), Optional(0_ms32)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledPeer(1, false)); - NL_TEST_ASSERT(inSuite, attempts.NextScheduled() == ScheduledBrowse(filter, type, false)); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_EQ(attempts.NextScheduled(), ScheduledPeer(1, false)); + EXPECT_EQ(attempts.NextScheduled(), ScheduledBrowse(filter, type, false)); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); // Complete all, we should see no more scheduled. attempts.Complete(MakePeerId(2)); @@ -378,28 +375,7 @@ void TestCombination(nlTestSuite * inSuite, void * inContext) data.nodeData.longDiscriminator = 1234; attempts.CompleteCommissionable(data); - NL_TEST_ASSERT(inSuite, !attempts.GetTimeUntilNextExpectedResponse().HasValue()); - NL_TEST_ASSERT(inSuite, !attempts.NextScheduled().HasValue()); + EXPECT_FALSE(attempts.GetTimeUntilNextExpectedResponse().HasValue()); + EXPECT_FALSE(attempts.NextScheduled().HasValue()); } - -const nlTest sTests[] = { - NL_TEST_DEF("TestSinglePeerAddRemove", TestSinglePeerAddRemove), // - NL_TEST_DEF("TestSingleBrowseAddRemove", TestSingleBrowseAddRemove), // - NL_TEST_DEF("TestRescheduleSamePeerId", TestRescheduleSamePeerId), // - NL_TEST_DEF("TestRescheduleSameFilter", TestRescheduleSameFilter), // - NL_TEST_DEF("TestLRU", TestLRU), // - NL_TEST_DEF("TestNextPeerOrdering", TestNextPeerOrdering), // - NL_TEST_DEF("TestCombination", TestCombination), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestActiveResolveAttempts() -{ - nlTestSuite theSuite = { "ActiveResolveAttempts", sTests, nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestActiveResolveAttempts) diff --git a/src/lib/dnssd/tests/TestIncrementalResolve.cpp b/src/lib/dnssd/tests/TestIncrementalResolve.cpp index 03b585c4ce14c3..646e4abfe38303 100644 --- a/src/lib/dnssd/tests/TestIncrementalResolve.cpp +++ b/src/lib/dnssd/tests/TestIncrementalResolve.cpp @@ -27,9 +27,8 @@ #include #include #include -#include -#include +#include using namespace chip; using namespace chip::Dnssd; @@ -51,7 +50,7 @@ const auto kTestHostName = testing::TestQName<2>({ "abcd", "local" }); const auto kIrrelevantHostName = testing::TestQName<2>({ "different", "local" }); -void PreloadSrvRecord(nlTestSuite * inSuite, SrvRecord & record) +void PreloadSrvRecord(SrvRecord & record) { uint8_t headerBuffer[HeaderRef::kSizeBytes] = {}; HeaderRef dummyHeader(headerBuffer); @@ -62,16 +61,15 @@ void PreloadSrvRecord(nlTestSuite * inSuite, SrvRecord & record) chip::Encoding::BigEndian::BufferWriter output(dataBuffer, sizeof(dataBuffer)); RecordWriter writer(&output); - NL_TEST_ASSERT(inSuite, - SrvResourceRecord(kTestOperationalName.Full(), kTestHostName.Full(), 0x1234 /* port */) - .Append(dummyHeader, ResourceType::kAnswer, writer)); + EXPECT_TRUE(SrvResourceRecord(kTestOperationalName.Full(), kTestHostName.Full(), 0x1234 /* port */) + .Append(dummyHeader, ResourceType::kAnswer, writer)); ResourceData resource; BytesRange packet(dataBuffer, dataBuffer + sizeof(dataBuffer)); const uint8_t * _ptr = dataBuffer; - NL_TEST_ASSERT(inSuite, resource.Parse(packet, &_ptr)); - NL_TEST_ASSERT(inSuite, record.Parse(resource.GetData(), packet)); + EXPECT_TRUE(resource.Parse(packet, &_ptr)); + EXPECT_TRUE(record.Parse(resource.GetData(), packet)); } /// Convenience method to have a serialized QName. @@ -84,7 +82,7 @@ static SerializedQNameIterator AsSerializedQName(const uint8_t (&v)[N]) return SerializedQNameIterator(BytesRange(v, v + N - 1), v); } -void CallOnRecord(nlTestSuite * inSuite, IncrementalResolver & resolver, const ResourceRecord & record) +void CallOnRecord(IncrementalResolver & resolver, const ResourceRecord & record) { uint8_t headerBuffer[HeaderRef::kSizeBytes] = {}; HeaderRef dummyHeader(headerBuffer); @@ -93,39 +91,39 @@ void CallOnRecord(nlTestSuite * inSuite, IncrementalResolver & resolver, const R chip::Encoding::BigEndian::BufferWriter output(dataBuffer, sizeof(dataBuffer)); RecordWriter writer(&output); - NL_TEST_ASSERT(inSuite, record.Append(dummyHeader, ResourceType::kAnswer, writer)); - NL_TEST_ASSERT(inSuite, writer.Fit()); + EXPECT_TRUE(record.Append(dummyHeader, ResourceType::kAnswer, writer)); + EXPECT_TRUE(writer.Fit()); ResourceData resource; BytesRange packet(dataBuffer, dataBuffer + sizeof(dataBuffer)); const uint8_t * _ptr = dataBuffer; - NL_TEST_ASSERT(inSuite, resource.Parse(packet, &_ptr)); - NL_TEST_ASSERT(inSuite, resolver.OnRecord(chip::Inet::InterfaceId::Null(), resource, packet) == CHIP_NO_ERROR); + EXPECT_TRUE(resource.Parse(packet, &_ptr)); + EXPECT_EQ(resolver.OnRecord(chip::Inet::InterfaceId::Null(), resource, packet), CHIP_NO_ERROR); } -void TestStoredServerName(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestStoredServerName) { StoredServerName name; // name should start of as cleared - NL_TEST_ASSERT(inSuite, !name.Get().Next()); + EXPECT_FALSE(name.Get().Next()); // Data should be storable in server name - NL_TEST_ASSERT(inSuite, name.Set(kTestOperationalName.Serialized()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, name.Get() == kTestOperationalName.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() != kTestCommissionerNode.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() != kTestCommissionableNode.Serialized()); + EXPECT_EQ(name.Set(kTestOperationalName.Serialized()), CHIP_NO_ERROR); + EXPECT_EQ(name.Get(), kTestOperationalName.Serialized()); + EXPECT_NE(name.Get(), kTestCommissionerNode.Serialized()); + EXPECT_NE(name.Get(), kTestCommissionableNode.Serialized()); - NL_TEST_ASSERT(inSuite, name.Set(kTestCommissionerNode.Serialized()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, name.Get() != kTestOperationalName.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() == kTestCommissionerNode.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() != kTestCommissionableNode.Serialized()); + EXPECT_EQ(name.Set(kTestCommissionerNode.Serialized()), CHIP_NO_ERROR); + EXPECT_NE(name.Get(), kTestOperationalName.Serialized()); + EXPECT_EQ(name.Get(), kTestCommissionerNode.Serialized()); + EXPECT_NE(name.Get(), kTestCommissionableNode.Serialized()); - NL_TEST_ASSERT(inSuite, name.Set(kTestCommissionableNode.Serialized()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, name.Get() != kTestOperationalName.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() != kTestCommissionerNode.Serialized()); - NL_TEST_ASSERT(inSuite, name.Get() == kTestCommissionableNode.Serialized()); + EXPECT_EQ(name.Set(kTestCommissionableNode.Serialized()), CHIP_NO_ERROR); + EXPECT_NE(name.Get(), kTestOperationalName.Serialized()); + EXPECT_NE(name.Get(), kTestCommissionerNode.Serialized()); + EXPECT_EQ(name.Get(), kTestCommissionableNode.Serialized()); { // setting to a too long value should reset it @@ -145,135 +143,130 @@ void TestStoredServerName(nlTestSuite * inSuite, void * inContext) if (writer.WritePos() < 64) { // this is how much data can be fit by the copy - NL_TEST_ASSERT_LOOP(inSuite, idx, name.Set(AsSerializedQName(largeBuffer)) == CHIP_NO_ERROR); - NL_TEST_ASSERT_LOOP(inSuite, idx, name.Get() == AsSerializedQName(largeBuffer)); - NL_TEST_ASSERT_LOOP(inSuite, idx, name.Get() != kTestOperationalName.Serialized()); + EXPECT_EQ(name.Set(AsSerializedQName(largeBuffer)), CHIP_NO_ERROR) << "idx = " << idx; + EXPECT_EQ(name.Get(), AsSerializedQName(largeBuffer)) << "idx = " << idx; + EXPECT_NE(name.Get(), kTestOperationalName.Serialized()) << "idx = " << idx; } else { - NL_TEST_ASSERT_LOOP(inSuite, idx, name.Set(AsSerializedQName(largeBuffer)) == CHIP_ERROR_NO_MEMORY); - NL_TEST_ASSERT_LOOP(inSuite, idx, !name.Get().Next()); + EXPECT_EQ(name.Set(AsSerializedQName(largeBuffer)), CHIP_ERROR_NO_MEMORY) << "idx = " << idx; + EXPECT_FALSE(name.Get().Next()) << "idx = " << idx; } } } } -void TestCreation(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestCreation) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveOperationalParse()); - NL_TEST_ASSERT( - inSuite, + EXPECT_FALSE(resolver.IsActive()); + EXPECT_FALSE(resolver.IsActiveBrowseParse()); + EXPECT_FALSE(resolver.IsActiveOperationalParse()); + EXPECT_TRUE( resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kSrvInitialization)); } -void TestInactiveResetOnInitError(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestInactiveResetOnInitError) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); // test host name is not a 'matter' name - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestHostName.Serialized(), srvRecord) != CHIP_NO_ERROR); + EXPECT_NE(resolver.InitializeParsing(kTestHostName.Serialized(), srvRecord), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveOperationalParse()); + EXPECT_FALSE(resolver.IsActive()); + EXPECT_FALSE(resolver.IsActiveBrowseParse()); + EXPECT_FALSE(resolver.IsActiveOperationalParse()); } -void TestStartOperational(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestStartOperational) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord) == CHIP_NO_ERROR); + EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, resolver.IsActive()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, resolver.IsActiveOperationalParse()); - NL_TEST_ASSERT(inSuite, - resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); - NL_TEST_ASSERT(inSuite, resolver.GetTargetHostName() == kTestHostName.Serialized()); + EXPECT_TRUE(resolver.IsActive()); + EXPECT_FALSE(resolver.IsActiveBrowseParse()); + EXPECT_TRUE(resolver.IsActiveOperationalParse()); + EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); + EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized()); } -void TestStartCommissionable(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestStartCommissionable) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord) == CHIP_NO_ERROR); + EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, resolver.IsActive()); - NL_TEST_ASSERT(inSuite, resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveOperationalParse()); - NL_TEST_ASSERT(inSuite, - resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); - NL_TEST_ASSERT(inSuite, resolver.GetTargetHostName() == kTestHostName.Serialized()); + EXPECT_TRUE(resolver.IsActive()); + EXPECT_TRUE(resolver.IsActiveBrowseParse()); + EXPECT_FALSE(resolver.IsActiveOperationalParse()); + EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); + EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized()); } -void TestStartCommissioner(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestStartCommissioner) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestCommissionerNode.Serialized(), srvRecord) == CHIP_NO_ERROR); + EXPECT_EQ(resolver.InitializeParsing(kTestCommissionerNode.Serialized(), srvRecord), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, resolver.IsActive()); - NL_TEST_ASSERT(inSuite, resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, !resolver.IsActiveOperationalParse()); - NL_TEST_ASSERT(inSuite, - resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); - NL_TEST_ASSERT(inSuite, resolver.GetTargetHostName() == kTestHostName.Serialized()); + EXPECT_TRUE(resolver.IsActive()); + EXPECT_TRUE(resolver.IsActiveBrowseParse()); + EXPECT_FALSE(resolver.IsActiveOperationalParse()); + EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); + EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized()); } -void TestParseOperational(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestParseOperational) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord) == CHIP_NO_ERROR); + EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR); // once initialized, parsing should be ready however no IP address is available - NL_TEST_ASSERT(inSuite, resolver.IsActiveOperationalParse()); - NL_TEST_ASSERT(inSuite, - resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); - NL_TEST_ASSERT(inSuite, resolver.GetTargetHostName() == kTestHostName.Serialized()); + EXPECT_TRUE(resolver.IsActiveOperationalParse()); + EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); + EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized()); // Send an IP for an irrelevant host name { Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::aabb:ccdd:2233:4455", addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::aabb:ccdd:2233:4455", addr)); - CallOnRecord(inSuite, resolver, IPResourceRecord(kIrrelevantHostName.Full(), addr)); + CallOnRecord(resolver, IPResourceRecord(kIrrelevantHostName.Full(), addr)); } // Send a useful IP address here { Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); - CallOnRecord(inSuite, resolver, IPResourceRecord(kTestHostName.Full(), addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); + CallOnRecord(resolver, IPResourceRecord(kTestHostName.Full(), addr)); } // Send a TXT record for an irrelevant host name @@ -285,7 +278,7 @@ void TestParseOperational(nlTestSuite * inSuite, void * inContext) "T=1" // TCP supported }; - CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestHostName.Full(), entries)); + CallOnRecord(resolver, TxtResourceRecord(kTestHostName.Full(), entries)); } // Adding actual text entries that are useful @@ -297,70 +290,68 @@ void TestParseOperational(nlTestSuite * inSuite, void * inContext) "SII=23" // session idle interval }; - CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestOperationalName.Full(), entries)); + CallOnRecord(resolver, TxtResourceRecord(kTestOperationalName.Full(), entries)); } // Resolver should have all data - NL_TEST_ASSERT(inSuite, !resolver.GetMissingRequiredInformation().HasAny()); + EXPECT_FALSE(resolver.GetMissingRequiredInformation().HasAny()); // At this point taking value should work. Once taken, the resolver is reset. ResolvedNodeData nodeData; - NL_TEST_ASSERT(inSuite, resolver.Take(nodeData) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_EQ(resolver.Take(nodeData), CHIP_NO_ERROR); + EXPECT_FALSE(resolver.IsActive()); // validate data as it was passed in - NL_TEST_ASSERT(inSuite, - nodeData.operationalData.peerId == - PeerId().SetCompressedFabricId(0x1234567898765432LL).SetNodeId(0xABCDEFEDCBAABCDELL)); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.numIPs == 1); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.port == 0x1234); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.supportsTcp); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().Value() == chip::System::Clock::Milliseconds32(23)); + EXPECT_EQ(nodeData.operationalData.peerId, + PeerId().SetCompressedFabricId(0x1234567898765432LL).SetNodeId(0xABCDEFEDCBAABCDELL)); + EXPECT_EQ(nodeData.resolutionData.numIPs, 1u); + EXPECT_EQ(nodeData.resolutionData.port, 0x1234); + EXPECT_FALSE(nodeData.resolutionData.supportsTcp); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle().Value(), chip::System::Clock::Milliseconds32(23)); Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.ipAddress[0] == addr); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); + EXPECT_EQ(nodeData.resolutionData.ipAddress[0], addr); } -void TestParseCommissionable(nlTestSuite * inSuite, void * inContext) +TEST(TestIncrementalResolve, TestParseCommissionable) { IncrementalResolver resolver; - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_FALSE(resolver.IsActive()); SrvRecord srvRecord; - PreloadSrvRecord(inSuite, srvRecord); + PreloadSrvRecord(srvRecord); - NL_TEST_ASSERT(inSuite, resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord) == CHIP_NO_ERROR); + EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR); // once initialized, parsing should be ready however no IP address is available - NL_TEST_ASSERT(inSuite, resolver.IsActiveBrowseParse()); - NL_TEST_ASSERT(inSuite, - resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); - NL_TEST_ASSERT(inSuite, resolver.GetTargetHostName() == kTestHostName.Serialized()); + EXPECT_TRUE(resolver.IsActiveBrowseParse()); + EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress)); + EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized()); // Send an IP for an irrelevant host name { Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::aabb:ccdd:2233:4455", addr)); - CallOnRecord(inSuite, resolver, IPResourceRecord(kIrrelevantHostName.Full(), addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::aabb:ccdd:2233:4455", addr)); + CallOnRecord(resolver, IPResourceRecord(kIrrelevantHostName.Full(), addr)); } // Send a useful IP address here { Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); - CallOnRecord(inSuite, resolver, IPResourceRecord(kTestHostName.Full(), addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); + CallOnRecord(resolver, IPResourceRecord(kTestHostName.Full(), addr)); } // Send another IP address { Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::f0f1:f2f3:f4f5:1234", addr)); - CallOnRecord(inSuite, resolver, IPResourceRecord(kTestHostName.Full(), addr)); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::f0f1:f2f3:f4f5:1234", addr)); + CallOnRecord(resolver, IPResourceRecord(kTestHostName.Full(), addr)); } // Send a TXT record for an irrelevant host name @@ -372,7 +363,7 @@ void TestParseCommissionable(nlTestSuite * inSuite, void * inContext) "SII=123" // session idle interval }; - CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestHostName.Full(), entries)); + CallOnRecord(resolver, TxtResourceRecord(kTestHostName.Full(), entries)); } // Adding actual text entries that are useful @@ -387,61 +378,35 @@ void TestParseCommissionable(nlTestSuite * inSuite, void * inContext) "DN=mytest" // Device name }; - CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestCommissionableNode.Full(), entries)); + CallOnRecord(resolver, TxtResourceRecord(kTestCommissionableNode.Full(), entries)); } // Resolver should have all data - NL_TEST_ASSERT(inSuite, !resolver.GetMissingRequiredInformation().HasAny()); + EXPECT_FALSE(resolver.GetMissingRequiredInformation().HasAny()); // At this point taking value should work. Once taken, the resolver is reset. DiscoveredNodeData nodeData; - NL_TEST_ASSERT(inSuite, resolver.Take(nodeData) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, !resolver.IsActive()); + EXPECT_EQ(resolver.Take(nodeData), CHIP_NO_ERROR); + EXPECT_FALSE(resolver.IsActive()); // validate data as it was passed in - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.numIPs == 2); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.port == 0x1234); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.supportsTcp); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); - NL_TEST_ASSERT(inSuite, - nodeData.resolutionData.GetMrpRetryIntervalActive().Value() == chip::System::Clock::Milliseconds32(321)); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_EQ(nodeData.resolutionData.numIPs, 2u); + EXPECT_EQ(nodeData.resolutionData.port, 0x1234); + EXPECT_FALSE(nodeData.resolutionData.supportsTcp); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalActive().Value(), chip::System::Clock::Milliseconds32(321)); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); Inet::IPAddress addr; - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.ipAddress[0] == addr); - NL_TEST_ASSERT(inSuite, Inet::IPAddress::FromString("fe80::f0f1:f2f3:f4f5:1234", addr)); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.ipAddress[1] == addr); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::abcd:ef11:2233:4455", addr)); + EXPECT_EQ(nodeData.resolutionData.ipAddress[0], addr); + EXPECT_TRUE(Inet::IPAddress::FromString("fe80::f0f1:f2f3:f4f5:1234", addr)); + EXPECT_EQ(nodeData.resolutionData.ipAddress[1], addr); // parsed txt data for discovered nodes - NL_TEST_ASSERT(inSuite, nodeData.nodeData.longDiscriminator == 22345); - NL_TEST_ASSERT(inSuite, nodeData.nodeData.vendorId == 321); - NL_TEST_ASSERT(inSuite, nodeData.nodeData.productId == 654); - NL_TEST_ASSERT(inSuite, strcmp(nodeData.nodeData.deviceName, "mytest") == 0); + EXPECT_EQ(nodeData.nodeData.longDiscriminator, 22345); + EXPECT_EQ(nodeData.nodeData.vendorId, 321); + EXPECT_EQ(nodeData.nodeData.productId, 654); + EXPECT_STREQ(nodeData.nodeData.deviceName, "mytest"); } - -const nlTest sTests[] = { - // Tests for helper class - NL_TEST_DEF("StoredServerName", TestStoredServerName), // - - // Actual resolver tests - NL_TEST_DEF("Creation", TestCreation), // - NL_TEST_DEF("InactiveResetOnInitError", TestInactiveResetOnInitError), // - NL_TEST_DEF("StartOperational", TestStartOperational), // - NL_TEST_DEF("StartCommissionable", TestStartCommissionable), // - NL_TEST_DEF("StartCommissioner", TestStartCommissioner), // - NL_TEST_DEF("ParseOperational", TestParseOperational), // - NL_TEST_DEF("ParseCommissionable", TestParseCommissionable), // - NL_TEST_SENTINEL() // -}; - } // namespace - -int TestChipDnsSdIncrementalResolve() -{ - nlTestSuite theSuite = { "IncrementalResolve", &sTests[0], nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestChipDnsSdIncrementalResolve) diff --git a/src/lib/dnssd/tests/TestServiceNaming.cpp b/src/lib/dnssd/tests/TestServiceNaming.cpp index 646a51e39f4806..0fa26723dab779 100644 --- a/src/lib/dnssd/tests/TestServiceNaming.cpp +++ b/src/lib/dnssd/tests/TestServiceNaming.cpp @@ -20,84 +20,78 @@ #include -#include - -#include +#include using namespace chip; using namespace chip::Dnssd; namespace { -void TestMakeInstanceName(nlTestSuite * inSuite, void * inContext) +TEST(TestServiceNaming, TestMakeInstanceName) { 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); + EXPECT_EQ(MakeInstanceName(buffer, sizeof(buffer), PeerId().SetCompressedFabricId(0x1234).SetNodeId(0x5678)), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "0000000000001234-0000000000005678"); - 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); + EXPECT_EQ(MakeInstanceName(buffer, sizeof(buffer), + PeerId().SetCompressedFabricId(0x1122334455667788ULL).SetNodeId(0x123456789abcdefULL)), + CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "1122334455667788-0123456789ABCDEF"); // 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); + EXPECT_NE(MakeInstanceName(buffer, shortSize, PeerId()), CHIP_NO_ERROR); } - NL_TEST_ASSERT(inSuite, MakeInstanceName(buffer, kMinBufferSize, PeerId()) == CHIP_NO_ERROR); + EXPECT_EQ(MakeInstanceName(buffer, kMinBufferSize, PeerId()), CHIP_NO_ERROR); } -void TestExtractIdFromInstanceName(nlTestSuite * inSuite, void * inContext) +TEST(TestServiceNaming, TestExtractIdFromInstanceName) { 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); + EXPECT_EQ(ExtractIdFromInstanceName(nullptr, nullptr), CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(ExtractIdFromInstanceName("ACDEF1234567890-1234567890ABCDEF", nullptr), CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(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)); + EXPECT_EQ(ExtractIdFromInstanceName("ABCDEF1234567890-1234567890ABCDEF", &peerId), CHIP_NO_ERROR); + EXPECT_EQ(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)); + EXPECT_EQ(ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF1122.some.suffix.here", &peerId), CHIP_NO_ERROR); + EXPECT_EQ(peerId, PeerId().SetCompressedFabricId(0x1122334455667788ULL).SetNodeId(0xaabbccddeeff1122ULL)); // Invalid: non hex character - NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1x22334455667788-AABBCCDDEEDD1122", &peerId) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_NE(ExtractIdFromInstanceName("1122334455667788x2233445566778899", &peerId), CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("1122334455667788x2233445566778899.12-33.4455", &peerId), CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_NE(ExtractIdFromInstanceName("-1234567890ABCDEF", &peerId), CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_NE(ExtractIdFromInstanceName("112233445566778-8AABBCCDDEEFF1122", &peerId), CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("1122334455667788A-ABBCCDDEEFF1122", &peerId), CHIP_NO_ERROR); // Invalid: fabric part too short - NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("11223344556677-AABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("11223344556677-AABBCCDDEEFF1122", &peerId), CHIP_NO_ERROR); // Invalid: fabric part too long - NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("112233445566778899-AABBCCDDEEFF1122", &peerId) != CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("112233445566778899-AABBCCDDEEFF1122", &peerId), CHIP_NO_ERROR); // Invalid: node part too short - NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF11", &peerId) != CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF11", &peerId), CHIP_NO_ERROR); // Invalid: node part too long - NL_TEST_ASSERT(inSuite, ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF112233", &peerId) != CHIP_NO_ERROR); + EXPECT_NE(ExtractIdFromInstanceName("1122334455667788-AABBCCDDEEFF112233", &peerId), CHIP_NO_ERROR); } -void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext) +TEST(TestServiceNaming, TestMakeServiceNameSubtype) { constexpr size_t kSize = 19; char buffer[kSize]; @@ -106,71 +100,71 @@ void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext) // 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_L3"); 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_L4095"); filter.code = 1 << 12; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_S3"); 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_S15"); filter.code = 1 << 4; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_V3"); filter.code = 0xFFFF; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_V65535") == 0); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_V65535"); filter.code = 1 << 16; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_T3"); // 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_CM"); // 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_IABCD12341111BBBB"); // 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, ""); // 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); + EXPECT_EQ(MakeServiceSubtype(buffer, sizeof(buffer), filter), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "1234567890123456"); } -void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext) +TEST(TestServiceNaming, TestMakeServiceTypeName) { // TODO(cecille): These need to be changed to remove leading zeros constexpr size_t kSize = 128; @@ -180,110 +174,80 @@ void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext) // 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_L3._sub._matterc"); 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_L4095._sub._matterc"); filter.code = 1 << 12; - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_S3._sub._matterc"); 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_S15._sub._matterc"); filter.code = 1 << 4; - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_V3._sub._matterc"); 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_V65535._sub._matterc"); filter.code = 1 << 16; - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR); + EXPECT_NE(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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_T3._sub._matterc"); // 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_CM._sub._matterc"); // 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kOperational), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_I1234ABCD0000AAAA._sub._matter"); // 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_matterc"); 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); + EXPECT_EQ(MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionerNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_matterd"); // 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); + EXPECT_EQ(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); + EXPECT_EQ(MakeServiceTypeName(buffer, 9, filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_matterc"); // 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); + EXPECT_EQ(MakeServiceTypeName(buffer, 18, filter, DiscoveryType::kCommissionableNode), CHIP_NO_ERROR); + EXPECT_STREQ(buffer, "_CM._sub._matterc"); } - -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) diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index d6e7e6ea240670..d487c261346c05 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -23,9 +23,8 @@ #include #include -#include -#include +#include using namespace chip; using namespace chip::Dnssd; @@ -41,161 +40,161 @@ ByteSpan GetSpan(char * key) return ByteSpan(reinterpret_cast(key), len); } -void TestGetTxtFieldKey(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetTxtFieldKey) { char key[4]; strcpy(key, "D"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kLongDiscriminator); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongDiscriminator); strcpy(key, "VP"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kVendorProduct); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "CM"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kCommissioningMode); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kCommissioningMode); strcpy(key, "DT"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kDeviceType); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kDeviceType); strcpy(key, "DN"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kDeviceName); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kDeviceName); strcpy(key, "RI"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kRotatingDeviceId); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kRotatingDeviceId); strcpy(key, "PI"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kPairingInstruction); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kPairingInstruction); strcpy(key, "PH"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kPairingHint); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kPairingHint); strcpy(key, "SII"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kSessionIdleInterval); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionIdleInterval); strcpy(key, "SAI"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kSessionActiveInterval); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionActiveInterval); strcpy(key, "SAT"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kSessionActiveThreshold); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionActiveThreshold); strcpy(key, "T"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kTcpSupported); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kTcpSupported); strcpy(key, "ICD"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kLongIdleTimeICD); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongIdleTimeICD); strcpy(key, "XX"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kUnknown); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kUnknown); strcpy(key, "CP"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kCommissionerPasscode); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kCommissionerPasscode); } -void TestGetTxtFieldKeyCaseInsensitive(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetTxtFieldKeyCaseInsensitive) { char key[3]; strcpy(key, "d"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kLongDiscriminator); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongDiscriminator); strcpy(key, "vp"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kVendorProduct); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "Vp"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kVendorProduct); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "vP"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kVendorProduct); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "Xx"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kUnknown); + EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kUnknown); } -void TestGetProduct(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetProduct) { // Product and vendor are given as part of the same key, on either side of a + sign. Product is after the + char vp[64]; strcpy(vp, "123+456"); - NL_TEST_ASSERT(inSuite, GetProduct(GetSpan(vp)) == 456); + EXPECT_EQ(GetProduct(GetSpan(vp)), 456); strcpy(vp, "123+"); - NL_TEST_ASSERT(inSuite, GetProduct(GetSpan(vp)) == 0); + EXPECT_EQ(GetProduct(GetSpan(vp)), 0); strcpy(vp, "+456"); - NL_TEST_ASSERT(inSuite, GetProduct(GetSpan(vp)) == 456); + EXPECT_EQ(GetProduct(GetSpan(vp)), 456); strcpy(vp, "123"); - NL_TEST_ASSERT(inSuite, GetProduct(GetSpan(vp)) == 0); + EXPECT_EQ(GetProduct(GetSpan(vp)), 0); // overflow a uint16 sprintf(vp, "123+%" PRIu32, static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetProduct(GetSpan(vp)) == 0); + EXPECT_EQ(GetProduct(GetSpan(vp)), 0); } -void TestGetVendor(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetVendor) { // Product and vendor are given as part of the same key, on either side of a + sign. Vendor is first char vp[64]; strcpy(vp, "123+456"); - NL_TEST_ASSERT(inSuite, GetVendor(GetSpan(vp)) == 123); + EXPECT_EQ(GetVendor(GetSpan(vp)), 123); strcpy(vp, "123+"); - NL_TEST_ASSERT(inSuite, GetVendor(GetSpan(vp)) == 123); + EXPECT_EQ(GetVendor(GetSpan(vp)), 123); strcpy(vp, "+456"); - NL_TEST_ASSERT(inSuite, GetVendor(GetSpan(vp)) == 0); + EXPECT_EQ(GetVendor(GetSpan(vp)), 0); strcpy(vp, "123"); - NL_TEST_ASSERT(inSuite, GetVendor(GetSpan(vp)) == 123); + EXPECT_EQ(GetVendor(GetSpan(vp)), 123); // overflow a uint16 sprintf(vp, "%" PRIu32 "+456", static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetVendor(GetSpan(vp)) == 0); + EXPECT_EQ(GetVendor(GetSpan(vp)), 0); } -void TestGetLongDiscriminator(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetLongDiscriminator) { char ld[64]; strcpy(ld, "1234"); - NL_TEST_ASSERT(inSuite, GetLongDiscriminator(GetSpan(ld)) == 1234); + EXPECT_EQ(GetLongDiscriminator(GetSpan(ld)), 1234); // overflow a uint16 sprintf(ld, "%" PRIu32, static_cast(std::numeric_limits::max()) + 1); printf("ld = %s\n", ld); - NL_TEST_ASSERT(inSuite, GetLongDiscriminator(GetSpan(ld)) == 0); + EXPECT_EQ(GetLongDiscriminator(GetSpan(ld)), 0); } -void TestGetCommissioningMode(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetCommissioningMode) { char cm[64]; strcpy(cm, "0"); - NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 0); + EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 0); strcpy(cm, "1"); - NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 1); + EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 1); strcpy(cm, "2"); - NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 2); + EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 2); // overflow a uint8 sprintf(cm, "%u", static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 0); + EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 0); } -void TestGetDeviceType(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetDeviceType) { char dt[64]; strcpy(dt, "1234"); - NL_TEST_ASSERT(inSuite, GetDeviceType(GetSpan(dt)) == 1234); + EXPECT_EQ(GetDeviceType(GetSpan(dt)), 1234u); // overflow a uint32 sprintf(dt, "%" PRIu64, static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetDeviceType(GetSpan(dt)) == 0); + EXPECT_EQ(GetDeviceType(GetSpan(dt)), 0u); } -void TestGetDeviceName(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetDeviceName) { char name[kMaxDeviceNameLen + 1] = ""; char val[kMaxDeviceNameLen + 2]; strcpy(val, "testname"); GetDeviceName(GetSpan(val), name); - NL_TEST_ASSERT(inSuite, strcmp(name, "testname") == 0); + EXPECT_STREQ(name, "testname"); // If the data passed in is too long, it should truncate the end. memset(val, 'a', kMaxDeviceNameLen); @@ -204,10 +203,10 @@ void TestGetDeviceName(nlTestSuite * inSuite, void * inContext) GetDeviceName(GetSpan(val), name); val[kMaxDeviceNameLen] = '\0'; - NL_TEST_ASSERT(inSuite, strcmp(name, val) == 0); + EXPECT_STREQ(name, val); } -void TestGetRotatingDeviceId(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetRotatingDeviceId) { // Rotating device ID is given as up to 50 hex bytes char ri[kMaxRotatingIdLen * 2 + 1]; @@ -217,58 +216,58 @@ void TestGetRotatingDeviceId(nlTestSuite * inSuite, void * inContext) strcpy(ri, "0A1B"); GetRotatingDeviceId(GetSpan(ri), id, &len); printf("id[0] = %x\n", id[0]); - NL_TEST_ASSERT(inSuite, id[0] == 0x0A); - NL_TEST_ASSERT(inSuite, id[1] == 0x1B); - NL_TEST_ASSERT(inSuite, len == 2); + EXPECT_EQ(id[0], 0x0A); + EXPECT_EQ(id[1], 0x1B); + EXPECT_EQ(len, 2u); // odd number of characters can't be parsed. strcpy(ri, "0A1BC"); GetRotatingDeviceId(GetSpan(ri), id, &len); - NL_TEST_ASSERT(inSuite, len == 0); + EXPECT_EQ(len, 0u); // non-hex characters can't be parsed strcpy(ri, "0ATT"); GetRotatingDeviceId(GetSpan(ri), id, &len); - NL_TEST_ASSERT(inSuite, len == 0); + EXPECT_EQ(len, 0u); // Lower case should work on SDK even though devices shouldn't be sending that. strcpy(ri, "0a1b"); GetRotatingDeviceId(GetSpan(ri), id, &len); - NL_TEST_ASSERT(inSuite, id[0] == 0x0A); - NL_TEST_ASSERT(inSuite, id[1] == 0x1B); - NL_TEST_ASSERT(inSuite, len == 2); + EXPECT_EQ(id[0], 0x0A); + EXPECT_EQ(id[1], 0x1B); + EXPECT_EQ(len, 2u); strcpy(ri, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031"); GetRotatingDeviceId(GetSpan(ri), id, &len); - NL_TEST_ASSERT(inSuite, len == sizeof(id)); + EXPECT_EQ(len, sizeof(id)); for (size_t i = 0; i < sizeof(id); ++i) { - NL_TEST_ASSERT(inSuite, id[i] == i); + EXPECT_EQ(id[i], i); } } -void TestGetPairingHint(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetPairingHint) { char ph[64]; strcpy(ph, "0"); - NL_TEST_ASSERT(inSuite, GetPairingHint(GetSpan(ph)) == 0); + EXPECT_EQ(GetPairingHint(GetSpan(ph)), 0); strcpy(ph, "9"); - NL_TEST_ASSERT(inSuite, GetPairingHint(GetSpan(ph)) == 9); + EXPECT_EQ(GetPairingHint(GetSpan(ph)), 9); // overflow a uint16 sprintf(ph, "%" PRIu32, static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetPairingHint(GetSpan(ph)) == 0); + EXPECT_EQ(GetPairingHint(GetSpan(ph)), 0); } -void TestGetPairingInstruction(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetPairingInstruction) { char data[kMaxPairingInstructionLen + 2]; char ret[kMaxPairingInstructionLen + 1] = ""; strcpy(data, "something"); GetPairingInstruction(GetSpan(data), ret); - NL_TEST_ASSERT(inSuite, strcmp(ret, "something") == 0); + EXPECT_STREQ(ret, "something"); // Exactly the max len. memset(data, 'a', kMaxPairingInstructionLen); @@ -276,7 +275,7 @@ void TestGetPairingInstruction(nlTestSuite * inSuite, void * inContext) GetPairingInstruction(GetSpan(data), ret); // Add back the null terminator removed by GetSpan. data[kMaxPairingInstructionLen] = '\0'; - NL_TEST_ASSERT(inSuite, strcmp(data, ret) == 0); + EXPECT_STREQ(data, ret); // Too long - should truncate end. memset(data, 'a', kMaxPairingInstructionLen); @@ -284,21 +283,21 @@ void TestGetPairingInstruction(nlTestSuite * inSuite, void * inContext) data[kMaxPairingInstructionLen + 1] = '\0'; GetPairingInstruction(GetSpan(data), ret); data[kMaxPairingInstructionLen] = '\0'; - NL_TEST_ASSERT(inSuite, strcmp(ret, data) == 0); + EXPECT_STREQ(ret, data); } -void TestGetCommissionerPasscode(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestGetCommissionerPasscode) { char cm[64]; strcpy(cm, "0"); - NL_TEST_ASSERT(inSuite, GetCommissionerPasscode(GetSpan(cm)) == 0); + EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 0); strcpy(cm, "1"); - NL_TEST_ASSERT(inSuite, GetCommissionerPasscode(GetSpan(cm)) == 1); + EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 1); // overflow a uint8 sprintf(cm, "%u", static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetCommissionerPasscode(GetSpan(cm)) == 0); + EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 0); } bool NodeDataIsEmpty(const DiscoveredNodeData & node) @@ -328,7 +327,7 @@ bool NodeDataIsEmpty(const DiscoveredNodeData & node) } // The individual fill tests test the error cases for each key type, this test is used to ensure the proper record is filled. -void TestFillDiscoveredNodeDataFromTxt(nlTestSuite * inSuite, void * inContext) +TEST(TestTxtFields, TestFillDiscoveredNodeDataFromTxt) { char key[3]; char val[16]; @@ -338,78 +337,78 @@ void TestFillDiscoveredNodeDataFromTxt(nlTestSuite * inSuite, void * inContext) strcpy(key, "D"); strcpy(val, "840"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.longDiscriminator == 840); + EXPECT_EQ(filled.nodeData.longDiscriminator, 840); filled.nodeData.longDiscriminator = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // vendor and product strcpy(key, "VP"); strcpy(val, "123+456"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.vendorId == 123); - NL_TEST_ASSERT(inSuite, filled.nodeData.productId == 456); + EXPECT_EQ(filled.nodeData.vendorId, 123); + EXPECT_EQ(filled.nodeData.productId, 456); filled.nodeData.vendorId = 0; filled.nodeData.productId = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Commissioning mode strcpy(key, "CM"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.commissioningMode == 1); + EXPECT_EQ(filled.nodeData.commissioningMode, 1); filled.nodeData.commissioningMode = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Supports Commissioner Generated Passcode strcpy(key, "CP"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.supportsCommissionerGeneratedPasscode == true); + EXPECT_TRUE(filled.nodeData.supportsCommissionerGeneratedPasscode); filled.nodeData.supportsCommissionerGeneratedPasscode = false; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Device type strcpy(key, "DT"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.deviceType == 1); + EXPECT_EQ(filled.nodeData.deviceType, 1u); filled.nodeData.deviceType = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Device name strcpy(key, "DN"); strcpy(val, "abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, strcmp(filled.nodeData.deviceName, "abc") == 0); + EXPECT_STREQ(filled.nodeData.deviceName, "abc"); memset(filled.nodeData.deviceName, 0, sizeof(filled.nodeData.deviceName)); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Rotating device id strcpy(key, "RI"); strcpy(val, "1A2B"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.rotatingId[0] == 0x1A); - NL_TEST_ASSERT(inSuite, filled.nodeData.rotatingId[1] == 0x2B); - NL_TEST_ASSERT(inSuite, filled.nodeData.rotatingIdLen == 2); + EXPECT_EQ(filled.nodeData.rotatingId[0], 0x1A); + EXPECT_EQ(filled.nodeData.rotatingId[1], 0x2B); + EXPECT_EQ(filled.nodeData.rotatingIdLen, 2u); filled.nodeData.rotatingIdLen = 0; memset(filled.nodeData.rotatingId, 0, sizeof(filled.nodeData.rotatingId)); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Pairing instruction strcpy(key, "PI"); strcpy(val, "hint"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, strcmp(filled.nodeData.pairingInstruction, "hint") == 0); + EXPECT_STREQ(filled.nodeData.pairingInstruction, "hint"); memset(filled.nodeData.pairingInstruction, 0, sizeof(filled.nodeData.pairingInstruction)); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); // Pairing hint strcpy(key, "PH"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.pairingHint == 1); + EXPECT_EQ(filled.nodeData.pairingHint, 1); filled.nodeData.pairingHint = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); + EXPECT_TRUE(NodeDataIsEmpty(filled)); } bool NodeDataIsEmpty(const ResolvedNodeData & nodeData) @@ -452,7 +451,7 @@ void ResetRetryActiveThreshold(ResolvedNodeData & nodeData) // Test SAI (formally CRI) template -void TxtFieldSessionIdleInterval(nlTestSuite * inSuite, void * inContext) +void TxtFieldSessionIdleInterval() { char key[4]; char val[16]; @@ -462,60 +461,70 @@ void TxtFieldSessionIdleInterval(nlTestSuite * inSuite, void * inContext) strcpy(key, "SII"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().Value() == 1_ms32); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle().Value(), 1_ms32); // Maximum strcpy(key, "SII"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalIdle().Value() == 3600000_ms32); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle().Value(), 3600000_ms32); // Test no other fields were populated ResetRetryIntervalIdle(nodeData); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SII - negative value strcpy(key, "SII"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); // Invalid SII - greater than maximum strcpy(key, "SII"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); // Invalid SII - much greater than maximum strcpy(key, "SII"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); // Invalid SII - hexadecimal value strcpy(key, "SII"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); // Invalid SII - leading zeros strcpy(key, "SII"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); // Invalid SII - text at the end strcpy(key, "SII"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().HasValue()); +} + +TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryIntervalIdle) +{ + TxtFieldSessionIdleInterval(); +} + +TEST(TestTxtFields, TxtResolvedFieldMrpRetryIntervalIdle) +{ + TxtFieldSessionIdleInterval(); } // Test SAI (formerly CRA) template -void TxtFieldSessionActiveInterval(nlTestSuite * inSuite, void * inContext) +void TxtFieldSessionActiveInterval() { char key[4]; char val[16]; @@ -525,60 +534,70 @@ void TxtFieldSessionActiveInterval(nlTestSuite * inSuite, void * inContext) strcpy(key, "SAI"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalActive().Value() == 1_ms32); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalActive().Value(), 1_ms32); // Maximum strcpy(key, "SAI"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryIntervalActive().Value() == 3600000_ms32); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalActive().Value(), 3600000_ms32); // Test no other fields were populated ResetRetryIntervalActive(nodeData); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SAI - negative value strcpy(key, "SAI"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); // Invalid SAI - greater than maximum strcpy(key, "SAI"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); // Invalid SAI - much greater than maximum strcpy(key, "SAI"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); // Invalid SAI - hexadecimal value strcpy(key, "SAI"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); // Invalid SAI - leading zeros strcpy(key, "SAI"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); // Invalid SAI - text at the end strcpy(key, "SAI"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().HasValue()); +} + +TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryIntervalActive) +{ + TxtFieldSessionActiveInterval(); +} + +TEST(TestTxtFields, TxtResolvedFieldMrpRetryIntervalActive) +{ + TxtFieldSessionActiveInterval(); } // Test SAT (Session Active Threshold) template -void TxtFieldSessionActiveThreshold(nlTestSuite * inSuite, void * inContext) +void TxtFieldSessionActiveThreshold() { char key[4]; char val[16]; @@ -588,60 +607,70 @@ void TxtFieldSessionActiveThreshold(nlTestSuite * inSuite, void * inContext) strcpy(key, "SAT"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryActiveThreshold().Value() == 1_ms16); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryActiveThreshold().Value(), 1_ms16); // Maximum strcpy(key, "SAT"); strcpy(val, "65535"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.GetMrpRetryActiveThreshold().Value() == 65535_ms16); + EXPECT_TRUE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_EQ(nodeData.resolutionData.GetMrpRetryActiveThreshold().Value(), 65535_ms16); // Test no other fields were populated ResetRetryActiveThreshold(nodeData); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SAI - negative value strcpy(key, "SAT"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); // Invalid SAI - greater than maximum strcpy(key, "SAT"); strcpy(val, "65536"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); // Invalid SAT - much greater than maximum strcpy(key, "SAT"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); // Invalid SAT - hexadecimal value strcpy(key, "SAT"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); // Invalid SAT - leading zeros strcpy(key, "SAT"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); // Invalid SAT - text at the end strcpy(key, "SAT"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); + EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().HasValue()); +} + +TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryActiveThreshold) +{ + TxtFieldSessionActiveThreshold(); +} + +TEST(TestTxtFields, TxtResolvedFieldMrpRetryActiveThreshold) +{ + TxtFieldSessionActiveThreshold(); } // Test T (TCP support) template -void TxtFieldTcpSupport(nlTestSuite * inSuite, void * inContext) +void TxtFieldTcpSupport() { char key[4]; char val[8]; @@ -651,28 +680,38 @@ void TxtFieldTcpSupport(nlTestSuite * inSuite, void * inContext) strcpy(key, "T"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.supportsTcp); + EXPECT_TRUE(nodeData.resolutionData.supportsTcp); // Test no other fields were populated nodeData.resolutionData.supportsTcp = false; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // False strcpy(key, "T"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.supportsTcp == false); + EXPECT_EQ(nodeData.resolutionData.supportsTcp, false); // Invalid value, stil false strcpy(key, "T"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.supportsTcp == false); + EXPECT_EQ(nodeData.resolutionData.supportsTcp, false); +} + +TEST(TestTxtFields, TxtDiscoveredFieldTcpSupport) +{ + TxtFieldTcpSupport(); +} + +TEST(TestTxtFields, TxtResolvedFieldTcpSupport) +{ + TxtFieldTcpSupport(); } // Test ICD (ICD operation Mode) template -void TxtFieldICDoperatesAsLIT(nlTestSuite * inSuite, void * inContext) +void TxtFieldICDoperatesAsLIT() { char key[4]; char val[16]; @@ -682,32 +721,42 @@ void TxtFieldICDoperatesAsLIT(nlTestSuite * inSuite, void * inContext) strcpy(key, "ICD"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.isICDOperatingAsLIT.HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.isICDOperatingAsLIT.Value()); + EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.HasValue()); + EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.Value()); // Test no other fields were populated nodeData.resolutionData.isICDOperatingAsLIT.ClearValue(); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // ICD is operating as a SIT device strcpy(key, "ICD"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.isICDOperatingAsLIT.HasValue()); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.isICDOperatingAsLIT.Value() == false); + EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.HasValue()); + EXPECT_EQ(nodeData.resolutionData.isICDOperatingAsLIT.Value(), false); nodeData.resolutionData.isICDOperatingAsLIT.ClearValue(); - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(nodeData)); + EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid value, No key set strcpy(key, "ICD"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.isICDOperatingAsLIT.HasValue() == false); + EXPECT_EQ(nodeData.resolutionData.isICDOperatingAsLIT.HasValue(), false); +} + +TEST(TestTxtFields, TxtDiscoveredIsICDoperatingAsLIT) +{ + TxtFieldICDoperatesAsLIT(); +} + +TEST(TestTxtFields, TxtResolvedFieldICDoperatingAsLIT) +{ + TxtFieldICDoperatesAsLIT(); } // Test IsDeviceTreatedAsSleepy() with CRI template -void TestIsDeviceSessionIdle(nlTestSuite * inSuite, void * inContext) +void TestIsDeviceSessionIdle() { char key[4]; char val[32]; @@ -716,24 +765,34 @@ void TestIsDeviceSessionIdle(nlTestSuite * inSuite, void * inContext) CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); // No key/val set, so the device can't be sleepy - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); + EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy strcpy(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); + EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy sprintf(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); + EXPECT_TRUE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); +} + +TEST(TestTxtFields, TxtDiscoveredIsDeviceSessionIdle) +{ + TestIsDeviceSessionIdle(); +} + +TEST(TestTxtFields, TxtResolvedIsDeviceSessionIdle) +{ + TestIsDeviceSessionIdle(); } // Test IsDeviceTreatedAsSleepy() with CRA template -void TestIsDeviceSessionActive(nlTestSuite * inSuite, void * inContext) +void TestIsDeviceSessionActive() { char key[4]; char val[32]; @@ -742,59 +801,29 @@ void TestIsDeviceSessionActive(nlTestSuite * inSuite, void * inContext) CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); // No key/val set, so the device can't be sleepy - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); + EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy sprintf(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, !nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); + EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy strcpy(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); - NL_TEST_ASSERT(inSuite, nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); -} - -const nlTest sTests[] = { - NL_TEST_DEF("TxtFieldKey", TestGetTxtFieldKey), // - NL_TEST_DEF("TxtFieldKeyCaseInsensitive", TestGetTxtFieldKeyCaseInsensitive), // - NL_TEST_DEF("TxtFieldProduct", TestGetProduct), // - NL_TEST_DEF("TxtFieldVendor", TestGetVendor), // - NL_TEST_DEF("TxtFieldLongDiscriminator", TestGetLongDiscriminator), // - NL_TEST_DEF("TxtFieldCommissioningMode", TestGetCommissioningMode), // - NL_TEST_DEF("TxtFieldDeviceType", TestGetDeviceType), // - NL_TEST_DEF("TxtFieldDeviceName", TestGetDeviceName), // - NL_TEST_DEF("TxtFieldRotatingDeviceId", TestGetRotatingDeviceId), // - NL_TEST_DEF("TxtFieldPairingHint", TestGetPairingHint), // - NL_TEST_DEF("TxtFieldPairingInstruction", TestGetPairingInstruction), // - NL_TEST_DEF("TxtFieldCommissionerPasscode", TestGetCommissionerPasscode), // - NL_TEST_DEF("TxtFieldFillDiscoveredNodeDataFromTxt", TestFillDiscoveredNodeDataFromTxt), // - NL_TEST_DEF("TxtDiscoveredFieldMrpRetryIntervalIdle", TxtFieldSessionIdleInterval), - NL_TEST_DEF("TxtDiscoveredFieldMrpRetryIntervalActive", TxtFieldSessionActiveInterval), - NL_TEST_DEF("TxtDiscoveredFieldMrpRetryActiveThreshold", TxtFieldSessionActiveThreshold), - NL_TEST_DEF("TxtDiscoveredFieldTcpSupport", (TxtFieldTcpSupport) ), - NL_TEST_DEF("TxtDiscoveredIsICDoperatingAsLIT", (TxtFieldICDoperatesAsLIT) ), - NL_TEST_DEF("TxtDiscoveredIsDeviceSessionIdle", TestIsDeviceSessionIdle), - NL_TEST_DEF("TxtDiscoveredIsDeviceSessionActive", TestIsDeviceSessionActive), - NL_TEST_DEF("TxtResolvedFieldMrpRetryIntervalIdle", TxtFieldSessionIdleInterval), - NL_TEST_DEF("TxtResolvedFieldMrpRetryIntervalActive", TxtFieldSessionActiveInterval), - NL_TEST_DEF("TxtResolvedFieldMrpRetryActiveThreshold", TxtFieldSessionActiveThreshold), - NL_TEST_DEF("TxtResolvedFieldTcpSupport", (TxtFieldTcpSupport) ), - NL_TEST_DEF("TxtResolvedFieldICDoperatingAsLIT", (TxtFieldICDoperatesAsLIT) ), - NL_TEST_DEF("TxtResolvedIsDeviceSessionIdle", TestIsDeviceSessionIdle), - NL_TEST_DEF("TxtResolvedIsDeviceSessionActive", TestIsDeviceSessionActive), - NL_TEST_SENTINEL() -}; + EXPECT_TRUE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); +} -} // namespace +TEST(TestTxtFields, TxtDiscoveredIsDeviceSessionActive) +{ + TestIsDeviceSessionActive(); +} -int TestCHIPTxtFields() +TEST(TestTxtFields, TxtResolvedIsDeviceSessionActive) { - nlTestSuite theSuite = { "TxtFields", &sTests[0], nullptr, nullptr }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); + TestIsDeviceSessionActive(); } -CHIP_REGISTER_TEST_SUITE(TestCHIPTxtFields); +} // namespace diff --git a/src/test_driver/openiotsdk/unit-tests/test_components.txt b/src/test_driver/openiotsdk/unit-tests/test_components.txt index e112a8b2ed5d50..5c3dcbae75a2a3 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components.txt @@ -4,6 +4,7 @@ MinimalMdnsCoreTests MinimalMdnsRecordsTests MinimalMdnsRespondersTests CoreTests +MdnsTests PlatformTests SystemLayerTests TestShell diff --git a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt index 13a59af526f4dd..7806ae3318cdf2 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt @@ -4,7 +4,6 @@ ChipCryptoTests CredentialsTest DataModelTests InetLayerTests -MdnsTests MessagingLayerTests RawTransportTests RetransmitTests From 5d338ffd02f2b16f7e3053fef210b91258978a9c Mon Sep 17 00:00:00 2001 From: Philip Gregor <147669098+pgregorr-amazon@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:26:12 -0700 Subject: [PATCH 13/19] v1.3 Supports Commissioner Generated Passcode field for iOS tv-casting-app (#33115) --- .../MatterTvCastingBridge/MCCastingPlayer.h | 1 + .../MatterTvCastingBridge/MCCastingPlayer.mm | 9 +++++++-- .../TvCasting/TvCasting/MCDiscoveryExampleView.swift | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.h index cc3d90e8a2f922..d01ce207519c4c 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.h @@ -70,6 +70,7 @@ - (uint16_t)vendorId; - (uint16_t)productId; - (uint32_t)deviceType; +- (bool)supportsCommissionerGeneratedPasscode; - (NSArray * _Nonnull)ipAddresses; /** diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.mm index 45cc9568f472a1..b69bbfb99f9bd7 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.mm @@ -89,8 +89,8 @@ - (instancetype _Nonnull)initWithCppCastingPlayer:(matter::casting::memory::Stro - (NSString * _Nonnull)description { - return [NSString stringWithFormat:@"%@ with Product ID: %hu and Vendor ID: %hu. Resolved IPAddr?: %@", - self.deviceName, self.productId, self.vendorId, self.ipAddresses != nil && self.ipAddresses.count > 0 ? @"YES" : @"NO"]; + return [NSString stringWithFormat:@"%@ with Product ID: %hu and Vendor ID: %hu. Resolved IPAddr?: %@. Supports Commissioner Generated Passcode?: %@.", + self.deviceName, self.productId, self.vendorId, self.ipAddresses != nil && self.ipAddresses.count > 0 ? @"YES" : @"NO", self.supportsCommissionerGeneratedPasscode ? @"YES" : @"NO"]; } - (NSString * _Nonnull)identifier @@ -118,6 +118,11 @@ - (uint32_t)deviceType return _cppCastingPlayer->GetDeviceType(); } +- (bool)supportsCommissionerGeneratedPasscode +{ + return _cppCastingPlayer->GetSupportsCommissionerGeneratedPasscode(); +} + - (NSArray * _Nonnull)ipAddresses { NSMutableArray * ipAddresses = [NSMutableArray new]; diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCDiscoveryExampleView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCDiscoveryExampleView.swift index ef0e32f6770b88..769b84c2a35963 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCDiscoveryExampleView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCDiscoveryExampleView.swift @@ -63,9 +63,11 @@ struct MCDiscoveryExampleView: View { }, label: { Text(castingPlayer.description) + .frame(minHeight: 50) + .padding() } ) - .frame(width: 350, height: 50, alignment: .center) + .frame(width: 350, alignment: .center) .border(Color.black, width: 1) .background(Color.blue) .foregroundColor(Color.white) From beb1749e871a35baf28f58e53aebd1a3bbd9b45a Mon Sep 17 00:00:00 2001 From: Jean-Francois Penven <67962328+jepenven-silabs@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:34:18 -0400 Subject: [PATCH 14/19] silabs minor fixes (#33121) --- examples/platform/silabs/efr32/rs911x/hal/efx_spi.c | 2 +- examples/platform/silabs/efr32/uart.cpp | 2 +- examples/platform/silabs/matter_shell.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c b/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c index daed27f9398a93..7a3dcc08942d46 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c +++ b/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c @@ -374,7 +374,7 @@ int16_t rsi_spi_transfer(uint8_t * tx_buf, uint8_t * rx_buf, uint16_t xlen, uint } (void) mode; // currently not used; - error_t rsiError = RSI_ERROR_NONE; + int16_t rsiError = RSI_ERROR_NONE; xSemaphoreTake(spiTransferLock, portMAX_DELAY); diff --git a/examples/platform/silabs/efr32/uart.cpp b/examples/platform/silabs/efr32/uart.cpp index 9a626e10a2159d..5feaaa66d86923 100644 --- a/examples/platform/silabs/efr32/uart.cpp +++ b/examples/platform/silabs/efr32/uart.cpp @@ -301,7 +301,7 @@ void USART_IRQHandler(void) { #ifdef ENABLE_CHIP_SHELL chip::NotifyShellProcess(); -#elif !defined(PW_RPC_ENABLED) +#elif !defined(PW_RPC_ENABLED) && !defined(SL_WIFI) otSysEventSignalPending(); #endif diff --git a/examples/platform/silabs/matter_shell.cpp b/examples/platform/silabs/matter_shell.cpp index a6a8c9f6d6e1ae..3e70764a08a1d5 100644 --- a/examples/platform/silabs/matter_shell.cpp +++ b/examples/platform/silabs/matter_shell.cpp @@ -83,13 +83,13 @@ CHIP_ERROR CmdSilabsDispatch(int argc, char ** argv) size_t arg_len = strlen(argv[i]); /* Make sure that the next argument won't overflow the buffer */ - VerifyOrExit(buff_ptr + arg_len < buff + kMaxLineLength, error = CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit(buff_ptr + arg_len < buff + SL_CLI_INPUT_BUFFER_SIZE, error = CHIP_ERROR_BUFFER_TOO_SMALL); strncpy(buff_ptr, argv[i], arg_len); buff_ptr += arg_len; /* Make sure that there is enough buffer for a space char */ - if (buff_ptr + sizeof(char) < buff + kMaxLineLength) + if (buff_ptr + sizeof(char) < buff + SL_CLI_INPUT_BUFFER_SIZE) { strncpy(buff_ptr, " ", sizeof(char)); buff_ptr++; From a4561356623ba5a7281aaeb60696860fd594318b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 23 Apr 2024 18:32:13 -0400 Subject: [PATCH 15/19] Switch MTRDevice to using MTRDeviceClusterData for its attribute cache. (#33114) Use these to store attribute values too, not just data versions. --- src/darwin/Framework/CHIP/MTRDevice.mm | 188 +++++++++--------- .../Framework/CHIP/MTRDevice_Internal.h | 17 +- .../CHIPTests/MTRPerControllerStorageTests.m | 48 ++--- 3 files changed, 116 insertions(+), 137 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 374b2e8cc60bc0..7c02df267a8ad7 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -184,11 +184,23 @@ typedef NS_ENUM(NSUInteger, MTRDeviceWorkItemDuplicateTypeID) { MTRDeviceWorkItemDuplicateReadTypeID = 1, }; -@implementation MTRDeviceClusterData +@implementation MTRDeviceClusterData { + NSMutableDictionary * _attributes; +} static NSString * const sDataVersionKey = @"dataVersion"; static NSString * const sAttributesKey = @"attributes"; +- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute +{ + _attributes[attribute] = value; +} + +- (NSDictionary *)attributes +{ + return _attributes; +} + + (BOOL)supportsSecureCoding { return YES; @@ -199,6 +211,11 @@ - (NSString *)description return [NSString stringWithFormat:@"", _dataVersion, static_cast(_attributes.count)]; } +- (nullable instancetype)init +{ + return [self initWithDataVersion:nil attributes:nil]; +} + // Attributes dictionary is: attributeID => data-value dictionary - (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes { @@ -208,7 +225,8 @@ - (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion a } _dataVersion = [dataVersion copy]; - _attributes = [attributes copy]; + _attributes = [NSMutableDictionary dictionaryWithCapacity:attributes.count]; + [_attributes addEntriesFromDictionary:attributes]; return self; } @@ -299,10 +317,6 @@ @interface MTRDevice () */ @property (nonatomic) BOOL reattemptingSubscription; -// Read cache is attributePath => NSDictionary of value. -// See MTRDeviceResponseHandler definition for value dictionary details. -@property (nonatomic) NSMutableDictionary * readCache; - // Expected value cache is attributePath => NSArray of [NSDate of expiration time, NSDictionary of value, expected value ID] // - See MTRDeviceExpectedValueFieldIndex for the definitions of indices into this array. // See MTRDeviceResponseHandler definition for value dictionary details. @@ -369,7 +383,6 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle _deviceController = controller; _queue = dispatch_queue_create("org.csa-iot.matter.framework.device.workqueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - _readCache = [NSMutableDictionary dictionary]; _expectedValueCache = [NSMutableDictionary dictionary]; _asyncWorkQueue = [[MTRAsyncWorkQueue alloc] initWithContext:self]; _state = MTRDeviceStateUnknown; @@ -1021,30 +1034,12 @@ - (void)_handleReportBegin } } -- (NSDictionary *)_attributesForCluster:(MTRClusterPath *)clusterPath -{ - os_unfair_lock_assert_owner(&self->_lock); - NSMutableDictionary * attributesToReturn = [NSMutableDictionary dictionary]; - for (MTRAttributePath * attributePath in _readCache) { - if ([attributePath.endpoint isEqualToNumber:clusterPath.endpoint] && [attributePath.cluster isEqualToNumber:clusterPath.cluster]) { - attributesToReturn[attributePath.attribute] = _readCache[attributePath]; - } - } - return attributesToReturn; -} - -- (NSDictionary *)_clusterDataForPaths:(NSSet *)clusterPaths +- (NSDictionary *)_copiedClusterDataForPaths:(NSSet *)clusterPaths { os_unfair_lock_assert_owner(&self->_lock); NSMutableDictionary * clusterDataToReturn = [NSMutableDictionary dictionary]; for (MTRClusterPath * clusterPath in clusterPaths) { - NSNumber * dataVersion = _clusterData[clusterPath].dataVersion; - NSDictionary * attributes = nil; - attributes = [self _attributesForCluster:clusterPath]; - if (dataVersion || attributes) { - MTRDeviceClusterData * clusterData = [[MTRDeviceClusterData alloc] initWithDataVersion:dataVersion attributes:attributes]; - clusterDataToReturn[clusterPath] = clusterData; - } + clusterDataToReturn[clusterPath] = [_clusterData[clusterPath] copy]; } return clusterDataToReturn; @@ -1060,7 +1055,10 @@ - (void)_handleReportEnd BOOL dataStoreExists = _deviceController.controllerDataStore != nil; if (dataStoreExists && _clustersToPersist.count) { MTR_LOG_DEFAULT("%@ Storing cluster information (data version) count: %lu", self, static_cast(_clustersToPersist.count)); - NSDictionary * clusterData = [self _clusterDataForPaths:_clustersToPersist]; + // We're going to hand out these MTRDeviceClusterData objects to our + // storage implementation, which will try to read them later. Make sure + // we snapshot the state here instead of handing out live copies. + NSDictionary * clusterData = [self _copiedClusterDataForPaths:_clustersToPersist]; [_deviceController.controllerDataStore storeClusterData:clusterData forNodeID:_nodeID]; _clustersToPersist = nil; } @@ -1221,6 +1219,42 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor return dataVersions; } +- (MTRDeviceDataValueDictionary _Nullable)_cachedAttributeValueForPath:(MTRAttributePath *)path +{ + os_unfair_lock_assert_owner(&self->_lock); + + // We need an MTRClusterPath to do the lookup in _clusterData. + auto * clusterPath = [MTRClusterPath clusterPathWithEndpointID:path.endpoint clusterID:path.cluster]; + + MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; + if (clusterData == nil) { + return nil; + } + + return clusterData.attributes[path.attribute]; +} + +- (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value forPath:(MTRAttributePath *)path +{ + os_unfair_lock_assert_owner(&self->_lock); + + // We need an MTRClusterPath to do the lookup in _clusterData. + auto * clusterPath = [MTRClusterPath clusterPathWithEndpointID:path.endpoint clusterID:path.cluster]; + + MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; + if (clusterData == nil) { + if (value == nil) { + // Nothing to do. + return; + } + + clusterData = [[MTRDeviceClusterData alloc] init]; + _clusterData[clusterPath] = clusterData; + } + + [clusterData storeValue:value forAttribute:path.attribute]; +} + - (void)_createDataVersionFilterListFromDictionary:(NSDictionary *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction { size_t maxDataVersionFilterSize = dataVersions.count; @@ -2192,7 +2226,7 @@ - (void)_checkExpiredExpectedValues // compare with known value and mark for report if different MTRAttributePath * attributePath = attributeInfo[0]; NSDictionary * attributeDataValue = attributeInfo[1]; - NSDictionary * cachedAttributeDataValue = _readCache[attributePath]; + NSDictionary * cachedAttributeDataValue = [self _cachedAttributeValueForPath:attributePath]; if (cachedAttributeDataValue && ![self _attributeDataValue:attributeDataValue isEqualToDataValue:cachedAttributeDataValue]) { [attributesToReport addObject:@{ MTRAttributePathKey : attributePath, MTRDataKey : cachedAttributeDataValue, MTRPreviousDataKey : attributeDataValue }]; @@ -2249,7 +2283,7 @@ - (void)_performScheduledExpirationCheck } // Then check read cache - NSDictionary * cachedAttributeValue = _readCache[attributePath]; + NSDictionary * cachedAttributeValue = [self _cachedAttributeValueForPath:attributePath]; if (cachedAttributeValue) { return cachedAttributeValue; } else { @@ -2301,16 +2335,15 @@ - (void)_noteDataVersion:(NSNumber *)dataVersion forClusterPath:(MTRClusterPath // Update data version used for subscription filtering MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; if (!clusterData) { - clusterData = [[MTRDeviceClusterData alloc] init]; + clusterData = [[MTRDeviceClusterData alloc] initWithDataVersion:dataVersion attributes:nil]; _clusterData[clusterPath] = clusterData; dataVersionChanged = YES; } else if (![clusterData.dataVersion isEqualToNumber:dataVersion]) { + clusterData.dataVersion = dataVersion; dataVersionChanged = YES; } if (dataVersionChanged) { - clusterData.dataVersion = dataVersion; - // Mark cluster path as needing persistence if needed BOOL dataStoreExists = _deviceController.controllerDataStore != nil; if (dataStoreExists) { @@ -2361,11 +2394,12 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray *)attributeValues reportChanges:(BOOL)reportChanges -{ - os_unfair_lock_assert_owner(&self->_lock); - - if (!attributeValues.count) { - return; - } - - if (reportChanges) { - [self _reportAttributes:[self _getAttributesToReportWithReportedValues:attributeValues]]; - } else { - for (NSDictionary * responseValue in attributeValues) { - MTRAttributePath * path = responseValue[MTRAttributePathKey]; - NSDictionary * dataValue = responseValue[MTRDataKey]; - _readCache[path] = dataValue; - } - } - - // If cache is set from storage and is primed with initial configuration data, then assume the client had beeen informed in the past, and mark that the callback has been called - if ([self _isCachePrimedWithInitialConfigurationData]) { - _delegateDeviceCachePrimedCalled = YES; - } -} - -- (void)setAttributeValues:(NSArray *)attributeValues reportChanges:(BOOL)reportChanges -{ - MTR_LOG_INFO("%@ setAttributeValues count: %lu reportChanges: %d", self, static_cast(attributeValues.count), reportChanges); - std::lock_guard lock(_lock); - [self _setAttributeValues:attributeValues reportChanges:reportChanges]; -} - #ifdef DEBUG - (NSUInteger)unitTestAttributeCount { std::lock_guard lock(_lock); - return _readCache.count; + NSUInteger count = 0; + for (MTRClusterPath * path in _clusterData) { + count += _clusterData[path].attributes.count; + } + return count; } #endif @@ -2503,25 +2510,12 @@ - (void)setClusterData:(NSDictionary * std::lock_guard lock(_lock); - // For each cluster, extract and create the attribute response-value for the read cache - // TODO: consider some optimization in how the read cache is structured so there's fewer conversions from this format to what's in the cache - for (MTRClusterPath * clusterPath in clusterData) { - MTRDeviceClusterData * data = clusterData[clusterPath]; - // Build and set attributes one cluster at a time to avoid creating a ton of temporary objects at a time - @autoreleasepool { - NSMutableArray * attributeValues = [NSMutableArray array]; - for (NSNumber * attributeID in data.attributes) { - MTRAttributePath * attributePath = [MTRAttributePath attributePathWithEndpointID:clusterPath.endpoint clusterID:clusterPath.cluster attributeID:attributeID]; - NSDictionary * responseValue = @{ MTRAttributePathKey : attributePath, MTRDataKey : data.attributes[attributeID] }; - [attributeValues addObject:responseValue]; - } - if (attributeValues.count) { - [self _setAttributeValues:attributeValues reportChanges:NO]; - } - } - } - [_clusterData addEntriesFromDictionary:clusterData]; + + // If cache is set from storage and is primed with initial configuration data, then assume the client had beeen informed in the past, and mark that the callback has been called + if ([self _isCachePrimedWithInitialConfigurationData]) { + _delegateDeviceCachePrimedCalled = YES; + } } - (BOOL)deviceCachePrimed @@ -2558,23 +2552,25 @@ - (void)_setExpectedValue:(NSDictionary *)expectedAttributeValue // Remove previous expected value only if it's from the same setExpectedValues operation NSNumber * previousExpectedValueID = previousExpectedValue[MTRDeviceExpectedValueFieldIDIndex]; if (previousExpectedValueID.unsignedLongLongValue == expectedValueID) { + MTRDeviceDataValueDictionary cachedValue = [self _cachedAttributeValueForPath:attributePath]; if (![self _attributeDataValue:previousExpectedValue[MTRDeviceExpectedValueFieldValueIndex] - isEqualToDataValue:_readCache[attributePath]]) { + isEqualToDataValue:cachedValue]) { // Case of removing expected value that is different than read cache - report read cache value *shouldReportValue = YES; - *attributeValueToReport = _readCache[attributePath]; + *attributeValueToReport = cachedValue; *previousValue = previousExpectedValue[MTRDeviceExpectedValueFieldValueIndex]; _expectedValueCache[attributePath] = nil; } } } } else { + MTRDeviceDataValueDictionary cachedValue = [self _cachedAttributeValueForPath:attributePath]; if (expectedAttributeValue - && ![self _attributeDataValue:expectedAttributeValue isEqualToDataValue:_readCache[attributePath]]) { + && ![self _attributeDataValue:expectedAttributeValue isEqualToDataValue:cachedValue]) { // Case where new expected value is different than read cache - report new expected value *shouldReportValue = YES; *attributeValueToReport = expectedAttributeValue; - *previousValue = _readCache[attributePath]; + *previousValue = cachedValue; } else { *previousValue = nil; } @@ -2708,7 +2704,7 @@ - (BOOL)_isCachePrimedWithInitialConfigurationData os_unfair_lock_assert_owner(&self->_lock); // Check if root node descriptor exists - NSDictionary * rootDescriptorPartsListDataValue = _readCache[[MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)]]; + MTRDeviceDataValueDictionary rootDescriptorPartsListDataValue = [self _cachedAttributeValueForPath:[MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)]]; if (!rootDescriptorPartsListDataValue || ![MTRArrayValueType isEqualToString:rootDescriptorPartsListDataValue[MTRTypeKey]]) { return NO; } @@ -2734,7 +2730,7 @@ - (BOOL)_isCachePrimedWithInitialConfigurationData MTR_LOG_ERROR("%@ unexpected parts list item value class %@", self, [endpoint class]); continue; } - NSDictionary * descriptorDeviceTypeListDataValue = _readCache[[MTRAttributePath attributePathWithEndpointID:endpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)]]; + MTRDeviceDataValueDictionary descriptorDeviceTypeListDataValue = [self _cachedAttributeValueForPath:[MTRAttributePath attributePathWithEndpointID:endpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)]]; if (![MTRArrayValueType isEqualToString:descriptorDeviceTypeListDataValue[MTRTypeKey]] || !descriptorDeviceTypeListDataValue[MTRValueKey]) { return NO; } diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 57ee5446f3ba50..78e12be7053054 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -31,12 +31,16 @@ typedef NSDictionary * MTRDeviceDataValueDictionary; typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice); /** - * Information about a cluster, currently is just data version + * Information about a cluster: data version and known attribute values. */ MTR_TESTABLE @interface MTRDeviceClusterData : NSObject -@property (nonatomic) NSNumber * dataVersion; -@property (nonatomic) NSDictionary * attributes; // attributeID => data-value dictionary +@property (nonatomic, nullable) NSNumber * dataVersion; +@property (nonatomic, readonly) NSDictionary * attributes; // attributeID => data-value dictionary + +- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute; + +- (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes; @end @interface MTRDevice () @@ -78,13 +82,8 @@ MTR_TESTABLE @property (nonatomic) dispatch_queue_t queue; @property (nonatomic, readonly) MTRAsyncWorkQueue * asyncWorkQueue; -// Method to insert attribute values -// attributeValues : array of response-value dictionaries with non-null MTRAttributePathKey value -// reportChanges : if set to YES, attribute reports will also sent to the delegate if new values are different -- (void)setAttributeValues:(NSArray *)attributeValues reportChanges:(BOOL)reportChanges; - // Method to insert cluster data -// Currently contains data version information +// Contains data version information and attribute values. - (void)setClusterData:(NSDictionary *)clusterData; #ifdef DEBUG diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index bea49d957653c7..cce918d5fd410c 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -1093,27 +1093,21 @@ - (void)test008_TestDataStoreDirect XCTAssertEqualObjects(controller.controllerNodeID, nodeID); - MTRDeviceClusterData * testClusterData1 = [[MTRDeviceClusterData alloc] init]; - testClusterData1.dataVersion = @(1); - testClusterData1.attributes = @{ + MTRDeviceClusterData * testClusterData1 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(1) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(111) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(112) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(113) }, - }; - MTRDeviceClusterData * testClusterData2 = [[MTRDeviceClusterData alloc] init]; - testClusterData2.dataVersion = @(2); - testClusterData2.attributes = @{ + }]; + MTRDeviceClusterData * testClusterData2 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(2) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(121) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(122) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(123) }, - }; - MTRDeviceClusterData * testClusterData3 = [[MTRDeviceClusterData alloc] init]; - testClusterData3.dataVersion = @(3); - testClusterData3.attributes = @{ + }]; + MTRDeviceClusterData * testClusterData3 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(3) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(211) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(212) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(213) }, - }; + }]; NSDictionary * testClusterData = @{ [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(1)] : testClusterData1, [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(2)] : testClusterData2, @@ -1228,45 +1222,35 @@ - (void)test008_TestDataStoreDirect // Now test bulk write MTRClusterPath * bulkTestClusterPath11 = [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(1)]; - MTRDeviceClusterData * bulkTestClusterData11 = [[MTRDeviceClusterData alloc] init]; - bulkTestClusterData11.dataVersion = @(11); - bulkTestClusterData11.attributes = @{ + MTRDeviceClusterData * bulkTestClusterData11 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(11) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(111) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(112) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(113) }, - }; + }]; MTRClusterPath * bulkTestClusterPath12 = [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(2)]; - MTRDeviceClusterData * bulkTestClusterData12 = [[MTRDeviceClusterData alloc] init]; - bulkTestClusterData12.dataVersion = @(12); - bulkTestClusterData12.attributes = @{ + MTRDeviceClusterData * bulkTestClusterData12 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(12) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(121) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(122) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(123) }, - }; + }]; MTRClusterPath * bulkTestClusterPath13 = [MTRClusterPath clusterPathWithEndpointID:@(1) clusterID:@(3)]; - MTRDeviceClusterData * bulkTestClusterData13 = [[MTRDeviceClusterData alloc] init]; - bulkTestClusterData13.dataVersion = @(13); - bulkTestClusterData13.attributes = @{ + MTRDeviceClusterData * bulkTestClusterData13 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(13) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(131) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(132) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(133) }, - }; + }]; MTRClusterPath * bulkTestClusterPath21 = [MTRClusterPath clusterPathWithEndpointID:@(2) clusterID:@(1)]; - MTRDeviceClusterData * bulkTestClusterData21 = [[MTRDeviceClusterData alloc] init]; - bulkTestClusterData21.dataVersion = @(21); - bulkTestClusterData21.attributes = @{ + MTRDeviceClusterData * bulkTestClusterData21 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(21) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(211) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(212) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(213) }, - }; + }]; MTRClusterPath * bulkTestClusterPath22 = [MTRClusterPath clusterPathWithEndpointID:@(2) clusterID:@(2)]; - MTRDeviceClusterData * bulkTestClusterData22 = [[MTRDeviceClusterData alloc] init]; - bulkTestClusterData22.dataVersion = @(22); - bulkTestClusterData22.attributes = @{ + MTRDeviceClusterData * bulkTestClusterData22 = [[MTRDeviceClusterData alloc] initWithDataVersion:@(22) attributes:@{ @(1) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(221) }, @(2) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(222) }, @(3) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(223) }, - }; + }]; NSDictionary * bulkTestClusterDataDictionary = @{ bulkTestClusterPath11 : bulkTestClusterData11, bulkTestClusterPath12 : bulkTestClusterData12, From 93a8cedb0654791bbb7583564a2015d16df77865 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:35:53 -0400 Subject: [PATCH 16/19] Replace old define with new one. Removed semaphore release call in pre lcd spi transfer and as it should be released in post lcd spi transfer. Adjust usart settings when spi mux isn't used (#33123) Co-authored-by: SenthilKumar Edaikkalpadi Kannusamy --- examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c | 3 +++ .../platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c | 4 ---- src/platform/silabs/rs911x/rsi_ble_config.h | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c index b48d72cdc00aee..fded8defa30dce 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c +++ b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c @@ -111,6 +111,9 @@ static void efx32_spi_init(void) // Enable USART interface pins GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].ROUTEEN = GPIO_USART_ROUTEEN_RXPEN | // MISO GPIO_USART_ROUTEEN_TXPEN | // MOSI +#if !SL_SPICTRL_MUX + GPIO_USART_ROUTEEN_CSPEN | +#endif GPIO_USART_ROUTEEN_CLKPEN; // Set slew rate for alternate usage pins diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c b/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c index 14e47f43f99f5d..4b876883c12b0f 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c +++ b/examples/platform/silabs/efr32/rs911x/hal/sl_si91x_ncp_utility.c @@ -88,9 +88,6 @@ sl_status_t sl_wfx_host_pre_lcd_spi_transfer(void) { SPIDRV_SetBaudrate(SL_SPIDRV_LCD_BITRATE); } -#if SL_SPICTRL_MUX - xSemaphoreGive(spi_sem_sync_hdl); -#endif // SL_SPICTRL_MUX return status; } @@ -122,7 +119,6 @@ void SPIDRV_SetBaudrate(uint32_t baudrate) USART_InitSync(SPI_USART, &usartInit); } } - /******************************************************** * @fn spi_board_init(void) * @brief diff --git a/src/platform/silabs/rs911x/rsi_ble_config.h b/src/platform/silabs/rs911x/rsi_ble_config.h index c5a07e25ed12d2..f5442578e5d013 100644 --- a/src/platform/silabs/rs911x/rsi_ble_config.h +++ b/src/platform/silabs/rs911x/rsi_ble_config.h @@ -273,7 +273,7 @@ (SL_SI91X_TCP_IP_FEAT_DHCPV4_CLIENT) //! TCP/IP feature select bitmap for selecting TCP/IP features #define RSI_CUSTOM_FEATURE_BIT_MAP SL_SI91X_CUSTOM_FEAT_EXTENTION_VALID //! To set custom feature select bit map -#ifdef CHIP_9117 +#ifdef SLI_SI917 #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION // Adding Support for WPA3 transition #define RSI_EXT_CUSTOM_FEATURE_BIT_MAP \ (SL_SI91X_EXT_FEAT_LOW_POWER_MODE | SL_SI91X_EXT_FEAT_XTAL_CLK_ENABLE(1) | SL_SI91X_RAM_LEVEL_NWP_BASIC_MCU_ADV | \ @@ -285,7 +285,7 @@ #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ #else // EXP_BOARD #define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (SL_SI91X_EXT_FEAT_LOW_POWER_MODE | SL_SI91X_EXT_FEAT_XTAL_CLK_ENABLE(2)) -#endif /* CHIP_9117 */ +#endif /* SLI_SI917 */ #define RSI_EXT_TCPIP_FEATURE_BITMAP 0 #define RSI_BT_FEATURE_BITMAP (SL_SI91X_BT_RF_TYPE | SL_SI91X_ENABLE_BLE_PROTOCOL) From 88595f01296d4c0830b1a714d77143d44f34997a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 23 Apr 2024 21:40:50 -0400 Subject: [PATCH 17/19] Create a DNSSD test program for custom packet broadcast (#33106) * Minmdns test program * Update copyright years * Adjust buffer size * Adjust buffer sizes --------- Co-authored-by: Andrei Litvin --- examples/minimal-mdns/BUILD.gn | 16 ++ examples/minimal-mdns/client.cpp | 8 +- examples/minimal-mdns/server.cpp | 8 +- examples/minimal-mdns/tester.cpp | 303 +++++++++++++++++++++++++++++++ 4 files changed, 327 insertions(+), 8 deletions(-) create mode 100644 examples/minimal-mdns/tester.cpp diff --git a/examples/minimal-mdns/BUILD.gn b/examples/minimal-mdns/BUILD.gn index 372f5598339168..3ad5761229b85e 100644 --- a/examples/minimal-mdns/BUILD.gn +++ b/examples/minimal-mdns/BUILD.gn @@ -31,6 +31,21 @@ static_library("minimal-mdns-example-common") { ] } +executable("minimal-mdns-tester") { + sources = [ "tester.cpp" ] + + deps = [ + ":minimal-mdns-example-common", + "${chip_root}/examples/common/tracing:commandline", + "${chip_root}/src/lib", + "${chip_root}/src/lib/dnssd/minimal_mdns", + ] + + cflags = [ "-Wconversion" ] + + output_dir = root_out_dir +} + executable("minimal-mdns-client") { sources = [ "client.cpp" ] @@ -83,5 +98,6 @@ group("default") { ":minimal-mdns-client", ":minimal-mdns-example-common", ":minimal-mdns-server", + ":minimal-mdns-tester", ] } diff --git a/examples/minimal-mdns/client.cpp b/examples/minimal-mdns/client.cpp index 81d2b6754b7250..240c373e6b10fd 100644 --- a/examples/minimal-mdns/client.cpp +++ b/examples/minimal-mdns/client.cpp @@ -185,10 +185,10 @@ class ReportDelegate : public mdns::Minimal::ServerDelegate public: void OnQuery(const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override { - char addr[32]; + char addr[Inet::IPAddress::kMaxStringLength]; info->SrcAddress.ToString(addr, sizeof(addr)); - char ifName[64]; + char ifName[Inet::InterfaceId::kMaxIfNameLength]; VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); printf("QUERY from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); @@ -197,10 +197,10 @@ class ReportDelegate : public mdns::Minimal::ServerDelegate void OnResponse(const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override { - char addr[32]; + char addr[Inet::IPAddress::kMaxStringLength]; info->SrcAddress.ToString(addr, sizeof(addr)); - char ifName[64]; + char ifName[Inet::InterfaceId::kMaxIfNameLength]; VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); printf("RESPONSE from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); diff --git a/examples/minimal-mdns/server.cpp b/examples/minimal-mdns/server.cpp index c445b397034c25..1b8ca0dd769c24 100644 --- a/examples/minimal-mdns/server.cpp +++ b/examples/minimal-mdns/server.cpp @@ -126,10 +126,10 @@ class ReplyDelegate : public mdns::Minimal::ServerDelegate, public mdns::Minimal void OnQuery(const mdns::Minimal::BytesRange & data, const Inet::IPPacketInfo * info) override { - char addr[INET6_ADDRSTRLEN]; + char addr[Inet::IPAddress::kMaxStringLength]; info->SrcAddress.ToString(addr, sizeof(addr)); - char ifName[64]; + char ifName[Inet::InterfaceId::kMaxIfNameLength]; VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); printf("QUERY from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); @@ -145,10 +145,10 @@ class ReplyDelegate : public mdns::Minimal::ServerDelegate, public mdns::Minimal void OnResponse(const mdns::Minimal::BytesRange & data, const Inet::IPPacketInfo * info) override { - char addr[INET6_ADDRSTRLEN]; + char addr[Inet::IPAddress::kMaxStringLength]; info->SrcAddress.ToString(addr, sizeof(addr)); - char ifName[64]; + char ifName[Inet::InterfaceId::kMaxIfNameLength]; VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); printf("RESPONSE from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); diff --git a/examples/minimal-mdns/tester.cpp b/examples/minimal-mdns/tester.cpp new file mode 100644 index 00000000000000..c191f63943e70b --- /dev/null +++ b/examples/minimal-mdns/tester.cpp @@ -0,0 +1,303 @@ +/* + * + * Copyright (c) 2020-2024 Project CHIP Authors + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PacketReporter.h" + +using namespace chip; + +namespace { + +enum class TestType +{ + kSrv, +}; + +struct Options +{ + uint32_t runtimeMs = 500; + uint16_t listenPort = 5353; + TestType type = TestType::kSrv; +} gOptions; + +constexpr size_t kMdnsMaxPacketSize = 1'024; + +using namespace chip::ArgParser; + +constexpr uint16_t kOptionType = 't'; + +// non-ascii options have no short option version +constexpr uint16_t kOptionListenPort = 0x100; +constexpr uint16_t kOptionRuntimeMs = 0x102; +constexpr uint16_t kOptionTraceTo = 0x104; + +// Only used for argument parsing. Tracing setup owned by the main loop. +chip::CommandLineApp::TracingSetup * tracing_setup_for_argparse = nullptr; + +bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue) +{ + switch (aIdentifier) + { + case kOptionListenPort: + if (!ParseInt(aValue, gOptions.listenPort)) + { + PrintArgError("%s: invalid value for listen port: %s\n", aProgram, aValue); + return false; + } + return true; + case kOptionTraceTo: + tracing_setup_for_argparse->EnableTracingFor(aValue); + return true; + case kOptionType: + if (strcasecmp(aValue, "SRV") == 0) + { + gOptions.type = TestType::kSrv; + } + else + { + PrintArgError("%s: invalid value for query type: %s\n", aProgram, aValue); + return false; + } + return true; + + case kOptionRuntimeMs: + if (!ParseInt(aValue, gOptions.runtimeMs)) + { + PrintArgError("%s: invalid value for runtime ms: %s\n", aProgram, aValue); + return false; + } + return true; + default: + PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); + return false; + } +} + +OptionDef cmdLineOptionsDef[] = { + { "listen-port", kArgumentRequired, kOptionListenPort }, + { "type", kArgumentRequired, kOptionType }, + { "timeout-ms", kArgumentRequired, kOptionRuntimeMs }, + { "trace-to", kArgumentRequired, kOptionTraceTo }, + {}, +}; + +OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS", + " --listen-port \n" + " The port number to listen on\n" + " -t\n" + " --type\n" + " The packet to test with: \n" + " --timeout-ms\n" + " How long to wait for replies\n" + " --trace-to \n" + " trace to the given destination (supported: " SUPPORTED_COMMAND_LINE_TRACING_TARGETS ").\n" + "\n" }; + +HelpOptions helpOptions("minimal-mdns-tester", "Usage: minimal-mdns-tester [options]", "1.0"); + +OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr }; + +class ReportDelegate : public mdns::Minimal::ServerDelegate +{ +public: + void OnQuery(const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override + { + char addr[Inet::IPAddress::kMaxStringLength]; + info->SrcAddress.ToString(addr, sizeof(addr)); + + char ifName[Inet::InterfaceId::kMaxIfNameLength]; + VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); + + printf("QUERY from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); + Report("QUERY: ", data); + } + + void OnResponse(const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override + { + char addr[Inet::IPAddress::kMaxStringLength]; + info->SrcAddress.ToString(addr, sizeof(addr)); + + char ifName[Inet::InterfaceId::kMaxIfNameLength]; + VerifyOrDie(info->Interface.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR); + + printf("RESPONSE from: %-15s on port %d, via interface %s\n", addr, info->SrcPort, ifName); + Report("RESPONSE: ", data); + } + +private: + void Report(const char * prefix, const mdns::Minimal::BytesRange & data) + { + MdnsExample::PacketReporter reporter(prefix, data); + if (!mdns::Minimal::ParsePacket(data, &reporter)) + { + printf("INVALID PACKET!!!!!!\n"); + } + } +}; + +System::PacketBufferHandle BuildSrvTestPacket() +{ + System::PacketBufferHandle packet = System::PacketBufferHandle::New(kMdnsMaxPacketSize); + VerifyOrReturnValue(!packet.IsNull(), packet); + + mdns::Minimal::ResponseBuilder builder(std::move(packet)); + + constexpr uint16_t kSrvPort = 5540; + constexpr const char * kNodeName = "ABCD1234ABCD1234"; + constexpr const char * kNodeFabricName = "ABCD1234ABCD1234-0000000000000001"; + constexpr mdns::Minimal::QNamePart kServiceName[] = { Dnssd::kOperationalServiceName, Dnssd::kOperationalProtocol, + Dnssd::kLocalDomain }; + constexpr mdns::Minimal::QNamePart kServerFullName[] = { kNodeFabricName, Dnssd::kOperationalServiceName, + Dnssd::kOperationalProtocol, Dnssd::kLocalDomain }; + constexpr mdns::Minimal::QNamePart kServerName[] = { kNodeName, Dnssd::kLocalDomain }; + + mdns::Minimal::PtrResourceRecord ptrRecord(kServiceName, kServerFullName); + mdns::Minimal::SrvResourceRecord srvRecord(kServerFullName, kServerName, kSrvPort); + srvRecord.SetCacheFlush(true); + + builder.AddRecord(mdns::Minimal::ResourceType::kAnswer, ptrRecord); + builder.AddRecord(mdns::Minimal::ResourceType::kAnswer, srvRecord); + + if (!builder.Ok()) + { + printf("Failed to build response packet for SRV (maybe out of space?)\n"); + return System::PacketBufferHandle(); + } + + return builder.ReleasePacket(); +} + +System::PacketBufferHandle BuildTestPacket(TestType type) +{ + switch (type) + { + case TestType::kSrv: + return BuildSrvTestPacket(); + default: + return System::PacketBufferHandle(); + } +} + +void BroadcastPacket(mdns::Minimal::ServerBase * server) +{ + System::PacketBufferHandle buffer = BuildTestPacket(gOptions.type); + VerifyOrDie(!buffer.IsNull()); + + CHIP_ERROR err = server->BroadcastSend(std::move(buffer), 5353); + if (err != CHIP_NO_ERROR) + { + printf("Error sending: %" CHIP_ERROR_FORMAT "\n", err.Format()); + return; + } +} + +mdns::Minimal::Server<20> gMdnsServer; + +} // namespace + +int main(int argc, char ** args) +{ + if (Platform::MemoryInit() != CHIP_NO_ERROR) + { + printf("FAILED to initialize memory"); + return 1; + } + + if (DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR) + { + printf("FAILED to initialize chip stack"); + return 1; + } + + chip::CommandLineApp::TracingSetup tracing_setup; + + tracing_setup_for_argparse = &tracing_setup; + if (!chip::ArgParser::ParseArgs(args[0], argc, args, allOptions)) + { + return 1; + } + tracing_setup_for_argparse = nullptr; + + printf("Running...\n"); + + ReportDelegate reporter; + CHIP_ERROR err; + + // This forces the global MDNS instance to be loaded in, effectively setting + // built in policies for addresses. + (void) chip::Dnssd::GlobalMinimalMdnsServer::Instance(); + + gMdnsServer.SetDelegate(&reporter); + + { + auto endpoints = mdns::Minimal::GetAddressPolicy()->GetListenEndpoints(); + + err = gMdnsServer.Listen(chip::DeviceLayer::UDPEndPointManager(), endpoints.get(), gOptions.listenPort); + if (err != CHIP_NO_ERROR) + { + printf("Server failed to listen on all interfaces: %s\n", chip::ErrorStr(err)); + return 1; + } + } + + BroadcastPacket(&gMdnsServer); + + err = DeviceLayer::SystemLayer().StartTimer( + chip::System::Clock::Milliseconds32(gOptions.runtimeMs), + [](System::Layer *, void *) { + // Close all sockets BEFORE system layer is shut down, otherwise + // attempts to free UDP sockets with system layer down will segfault + gMdnsServer.Shutdown(); + + DeviceLayer::PlatformMgr().StopEventLoopTask(); + }, + nullptr); + if (err != CHIP_NO_ERROR) + { + printf("Failed to create the shutdown timer. Kill with ^C. %" CHIP_ERROR_FORMAT "\n", err.Format()); + } + + DeviceLayer::PlatformMgr().RunEventLoop(); + + tracing_setup.StopTracing(); + DeviceLayer::PlatformMgr().Shutdown(); + Platform::MemoryShutdown(); + + printf("Done...\n"); + return 0; +} From 17c82851996ad802f89daa39f368fed25868166c Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 23 Apr 2024 21:44:16 -0400 Subject: [PATCH 18/19] Use NSCache for the MTRDevice attribute cache when possible. (#33125) * Use NSCache for the MTRDevice attribute cache when possible. When we are storing our cluster data persistently, we don't have to ensure it's pinned in memory all the time. Use NSCache, and reload from storage as needed. * Update src/darwin/Framework/CHIP/MTRDevice.mm Co-authored-by: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> * Update src/darwin/Framework/CHIP/MTRDevice.mm Co-authored-by: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> --------- Co-authored-by: Justin Wood Co-authored-by: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> --- src/darwin/Framework/CHIP/MTRDevice.mm | 186 +++++++++++++----- .../Framework/CHIP/MTRDeviceController.mm | 4 +- .../CHIP/MTRDeviceControllerDataStore.h | 1 + .../CHIP/MTRDeviceControllerDataStore.mm | 12 ++ .../Framework/CHIP/MTRDevice_Internal.h | 4 +- .../Framework/CHIPTests/MTRDeviceTests.m | 31 ++- .../CHIPTests/MTRSwiftDeviceTests.swift | 74 ++++++- .../TestHelpers/MTRTestDeclarations.h | 1 + 8 files changed, 243 insertions(+), 70 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 7c02df267a8ad7..1516edc300e23c 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -361,10 +361,17 @@ @implementation MTRDevice { #endif BOOL _delegateDeviceCachePrimedCalled; - // With MTRDeviceClusterData now able to hold attribute data, the plan is to move to using it - // as the read cache, should testing prove attribute storage by cluster is the better solution. - NSMutableDictionary * _clusterData; - NSMutableSet * _clustersToPersist; + // _persistedClusterData stores data that we have already persisted (when we have + // cluster data persistence enabled). Nil when we have no persistence enabled. + NSCache * _Nullable _persistedClusterData; + // _clusterDataToPersist stores data that needs to be persisted. If we + // don't have persistence enabled, this is our only data store. Nil if we + // currently have nothing that could need persisting. + NSMutableDictionary * _Nullable _clusterDataToPersist; + // _persistedClusters stores the set of "valid" keys into _persistedClusterData. + // These are keys that could have values in _persistedClusterData even if they don't + // right now (because they have been evicted). + NSMutableSet * _persistedClusters; // When we last failed to subscribe to the device (either via // _setupSubscription or via the auto-resubscribe behavior of the @@ -387,7 +394,13 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle _asyncWorkQueue = [[MTRAsyncWorkQueue alloc] initWithContext:self]; _state = MTRDeviceStateUnknown; _internalDeviceState = MTRInternalDeviceStateUnsubscribed; - _clusterData = [NSMutableDictionary dictionary]; + if (controller.controllerDataStore) { + _persistedClusterData = [[NSCache alloc] init]; + } else { + _persistedClusterData = nil; + } + _clusterDataToPersist = nil; + _persistedClusters = [NSMutableSet set]; MTR_LOG_INFO("%@ init with hex nodeID 0x%016llX", self, _nodeID.unsignedLongLongValue); } return self; @@ -1034,12 +1047,12 @@ - (void)_handleReportBegin } } -- (NSDictionary *)_copiedClusterDataForPaths:(NSSet *)clusterPaths +- (NSDictionary *)_clusterDataToPersistSnapshot { os_unfair_lock_assert_owner(&self->_lock); NSMutableDictionary * clusterDataToReturn = [NSMutableDictionary dictionary]; - for (MTRClusterPath * clusterPath in clusterPaths) { - clusterDataToReturn[clusterPath] = [_clusterData[clusterPath] copy]; + for (MTRClusterPath * clusterPath in _clusterDataToPersist) { + clusterDataToReturn[clusterPath] = [_clusterDataToPersist[clusterPath] copy]; } return clusterDataToReturn; @@ -1053,14 +1066,28 @@ - (void)_handleReportEnd _estimatedStartTimeFromGeneralDiagnosticsUpTime = nil; BOOL dataStoreExists = _deviceController.controllerDataStore != nil; - if (dataStoreExists && _clustersToPersist.count) { - MTR_LOG_DEFAULT("%@ Storing cluster information (data version) count: %lu", self, static_cast(_clustersToPersist.count)); + if (dataStoreExists && _clusterDataToPersist != nil && _clusterDataToPersist.count) { + MTR_LOG_DEFAULT("%@ Storing cluster information (data version and attributes) count: %lu", self, static_cast(_clusterDataToPersist.count)); // We're going to hand out these MTRDeviceClusterData objects to our // storage implementation, which will try to read them later. Make sure // we snapshot the state here instead of handing out live copies. - NSDictionary * clusterData = [self _copiedClusterDataForPaths:_clustersToPersist]; + NSDictionary * clusterData = [self _clusterDataToPersistSnapshot]; [_deviceController.controllerDataStore storeClusterData:clusterData forNodeID:_nodeID]; - _clustersToPersist = nil; + for (MTRClusterPath * clusterPath in _clusterDataToPersist) { + [_persistedClusterData setObject:_clusterDataToPersist[clusterPath] forKey:clusterPath]; + [_persistedClusters addObject:clusterPath]; + } + + // TODO: There is one edge case not handled well here: if the + // storeClusterData call above fails somehow, and then the data gets + // evicted from _persistedClusterData, we could end up in a situation + // where when we page things in from storage we have stale values and + // hence effectively lose the delta that we failed to persist. + // + // The only way to handle this would be to detect it when it happens, + // then re-subscribe at that point, which would cause the relevant data + // to be sent to us via the priming read. + _clusterDataToPersist = nil; } // For unit testing only @@ -1205,13 +1232,75 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor } } +#ifdef DEBUG +- (void)unitTestClearClusterData +{ + std::lock_guard lock(_lock); + NSAssert(_persistedClusterData != nil, @"Test is not going to test what it thinks is testing!"); + [_persistedClusterData removeAllObjects]; +} +#endif + +- (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)clusterPath +{ + os_unfair_lock_assert_owner(&self->_lock); + + if (_clusterDataToPersist != nil) { + // Use the "dirty" values, if we have them. + MTRDeviceClusterData * data = _clusterDataToPersist[clusterPath]; + if (data != nil) { + return data; + } + } + + if (_persistedClusterData != nil) { + MTRDeviceClusterData * data = [_persistedClusterData objectForKey:clusterPath]; + if (data != nil) { + return data; + } + } + + if (![_persistedClusters containsObject:clusterPath]) { + // We are not expected to have this cluster, so no point in paging it in + // loading it from storage. + return nil; + } + + NSAssert(_deviceController.controllerDataStore != nil, + @"How can _persistedClusters have an entry if we have no persistence?"); + NSAssert(_persistedClusterData != nil, + @"How can _persistedClusterData not exist if we have persisted clusters?"); + + // Page in the stored value for the data. + MTRDeviceClusterData * data = [_deviceController.controllerDataStore getStoredClusterDataForNodeID:_nodeID endpointID:clusterPath.endpoint clusterID:clusterPath.cluster]; + if (data != nil) { + [_persistedClusterData setObject:data forKey:clusterPath]; + } + + return data; +} + +- (NSSet *)_knownClusters +{ + os_unfair_lock_assert_owner(&self->_lock); + + // We might have some clusters that have not been persisted at all yet, and + // some that have been persisted but are still present in + // _clusterDataToPersist because they have been modified since then. + NSMutableSet * clusterPaths = [_persistedClusters mutableCopy]; + if (_clusterDataToPersist != nil) { + [clusterPaths unionSet:[NSSet setWithArray:[_clusterDataToPersist allKeys]]]; + } + return clusterPaths; +} + - (NSDictionary *)_getCachedDataVersions { NSMutableDictionary * dataVersions = [NSMutableDictionary dictionary]; std::lock_guard lock(_lock); - for (MTRClusterPath * path in _clusterData) { - dataVersions[path] = _clusterData[path].dataVersion; + for (MTRClusterPath * path in [self _knownClusters]) { + dataVersions[path] = [self _clusterDataForPath:path].dataVersion; } MTR_LOG_INFO("%@ _getCachedDataVersions dataVersions count: %lu", self, static_cast(dataVersions.count)); @@ -1223,10 +1312,10 @@ - (MTRDeviceDataValueDictionary _Nullable)_cachedAttributeValueForPath:(MTRAttri { os_unfair_lock_assert_owner(&self->_lock); - // We need an MTRClusterPath to do the lookup in _clusterData. + // We need an actual MTRClusterPath, not a subsclass, to do _clusterDataForPath. auto * clusterPath = [MTRClusterPath clusterPathWithEndpointID:path.endpoint clusterID:path.cluster]; - MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; + MTRDeviceClusterData * clusterData = [self _clusterDataForPath:clusterPath]; if (clusterData == nil) { return nil; } @@ -1238,10 +1327,10 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f { os_unfair_lock_assert_owner(&self->_lock); - // We need an MTRClusterPath to do the lookup in _clusterData. + // We need an actual MTRClusterPath, not a subsclass, to do _clusterDataForPath. auto * clusterPath = [MTRClusterPath clusterPathWithEndpointID:path.endpoint clusterID:path.cluster]; - MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; + MTRDeviceClusterData * clusterData = [self _clusterDataForPath:clusterPath]; if (clusterData == nil) { if (value == nil) { // Nothing to do. @@ -1249,10 +1338,14 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f } clusterData = [[MTRDeviceClusterData alloc] init]; - _clusterData[clusterPath] = clusterData; } [clusterData storeValue:value forAttribute:path.attribute]; + + if (_clusterDataToPersist == nil) { + _clusterDataToPersist = [NSMutableDictionary dictionary]; + } + _clusterDataToPersist[clusterPath] = clusterData; } - (void)_createDataVersionFilterListFromDictionary:(NSDictionary *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction @@ -2333,10 +2426,9 @@ - (void)_noteDataVersion:(NSNumber *)dataVersion forClusterPath:(MTRClusterPath BOOL dataVersionChanged = NO; // Update data version used for subscription filtering - MTRDeviceClusterData * clusterData = _clusterData[clusterPath]; + MTRDeviceClusterData * clusterData = [self _clusterDataForPath:clusterPath]; if (!clusterData) { clusterData = [[MTRDeviceClusterData alloc] initWithDataVersion:dataVersion attributes:nil]; - _clusterData[clusterPath] = clusterData; dataVersionChanged = YES; } else if (![clusterData.dataVersion isEqualToNumber:dataVersion]) { clusterData.dataVersion = dataVersion; @@ -2344,25 +2436,13 @@ - (void)_noteDataVersion:(NSNumber *)dataVersion forClusterPath:(MTRClusterPath } if (dataVersionChanged) { - // Mark cluster path as needing persistence if needed - BOOL dataStoreExists = _deviceController.controllerDataStore != nil; - if (dataStoreExists) { - [self _noteChangeForClusterPath:clusterPath]; + if (_clusterDataToPersist == nil) { + _clusterDataToPersist = [NSMutableDictionary dictionary]; } + _clusterDataToPersist[clusterPath] = clusterData; } } -// Assuming data store exists, note that the cluster should be persisted at onReportEnd -- (void)_noteChangeForClusterPath:(MTRClusterPath *)clusterPath -{ - os_unfair_lock_assert_owner(&self->_lock); - - if (!_clustersToPersist) { - _clustersToPersist = [NSMutableSet set]; - } - [_clustersToPersist addObject:clusterPath]; -} - // assume lock is held - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray *> *)reportedAttributeValues { @@ -2370,7 +2450,6 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray * attributeResponseValue in reportedAttributeValues) { MTRAttributePath * attributePath = attributeResponseValue[MTRAttributePathKey]; NSDictionary * attributeDataValue = attributeResponseValue[MTRDataKey]; @@ -2413,14 +2492,13 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray *)clusterData +- (void)setPersistedClusterData:(NSDictionary *)clusterData { - MTR_LOG_INFO("%@ setClusterData count: %lu", self, static_cast(clusterData.count)); + MTR_LOG_INFO("%@ setPersistedClusterData count: %lu", self, static_cast(clusterData.count)); if (!clusterData.count) { return; } std::lock_guard lock(_lock); - [_clusterData addEntriesFromDictionary:clusterData]; + NSAssert(_persistedClusterData != nil, @"Why is controller setting persisted data when we shouldn't have it?"); + + for (MTRClusterPath * clusterPath in clusterData) { + // The caller has mutable references to MTRDeviceClusterData and + // MTRClusterPath, but that should be OK, since we control all the + // callers. If that stops being OK, we'll need to copy the key and + // value here. + [_persistedClusters addObject:clusterPath]; + [_persistedClusterData setObject:clusterData[clusterPath] forKey:clusterPath]; + } // If cache is set from storage and is primed with initial configuration data, then assume the client had beeen informed in the past, and mark that the callback has been called if ([self _isCachePrimedWithInitialConfigurationData]) { diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 4dfa229e71cc85..ec327a053962e6 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -945,14 +945,14 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N if (prefetchedClusterData) { if (prefetchedClusterData.count) { - [deviceToReturn setClusterData:prefetchedClusterData]; + [deviceToReturn setPersistedClusterData:prefetchedClusterData]; } } else { // Load persisted cluster data if they exist. NSDictionary * clusterData = [_controllerDataStore getStoredClusterDataForNodeID:nodeID]; MTR_LOG_INFO("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), deviceToReturn); if (clusterData.count) { - [deviceToReturn setClusterData:clusterData]; + [deviceToReturn setPersistedClusterData:clusterData]; } } diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h index 91a6c0e3142a38..dd9da5c03eccff 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h @@ -73,6 +73,7 @@ typedef void (^MTRDeviceControllerDataStoreClusterDataHandler)(NSDictionary *)getStoredClusterDataForNodeID:(NSNumber *)nodeID; +- (nullable MTRDeviceClusterData *)getStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; - (void)storeClusterData:(NSDictionary *)clusterData forNodeID:(NSNumber *)nodeID; - (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID; - (void)clearAllStoredClusterData; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index cac425c9453ad3..38f0bbccf0fa18 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -753,6 +753,18 @@ - (void)clearAllStoredClusterData return clusterDataToReturn; } +- (nullable MTRDeviceClusterData *)getStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID +{ + // Don't bother checking our indices here, since this will only be called + // when the consumer knows that we're supposed to have data for this cluster + // path. + __block MTRDeviceClusterData * clusterDataToReturn = nil; + dispatch_sync(_storageDelegateQueue, ^{ + clusterDataToReturn = [self _fetchClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; + }); + return clusterDataToReturn; +} + // Utility for constructing dictionary of nodeID to cluster data from dictionary of storage keys - (nullable NSDictionary *> *)_getClusterDataFromSecureLocalValues:(NSDictionary *)secureLocalValues { diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 78e12be7053054..7302a5b11d024c 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -82,9 +82,9 @@ MTR_TESTABLE @property (nonatomic) dispatch_queue_t queue; @property (nonatomic, readonly) MTRAsyncWorkQueue * asyncWorkQueue; -// Method to insert cluster data +// Method to insert persisted cluster data // Contains data version information and attribute values. -- (void)setClusterData:(NSDictionary *)clusterData; +- (void)setPersistedClusterData:(NSDictionary *)clusterData; #ifdef DEBUG - (NSUInteger)unitTestAttributeCount; diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index d13f319faaa9e9..da6ba88650a448 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1490,16 +1490,16 @@ - (void)test017_TestMTRDeviceBasics XCTestExpectation * onTimeWriteSuccess = [self expectationWithDescription:@"OnTime write success"]; XCTestExpectation * onTimePreviousValue = [self expectationWithDescription:@"OnTime previous value"]; delegate.onAttributeDataReceived = ^(NSArray *> * data) { - for (NSDictionary * attributeReponseValue in data) { - MTRAttributePath * path = attributeReponseValue[MTRAttributePathKey]; + for (NSDictionary * attributeResponseValue in data) { + MTRAttributePath * path = attributeResponseValue[MTRAttributePathKey]; if (path.cluster.unsignedIntValue == MTRClusterIDTypeOnOffID && path.attribute.unsignedLongValue == MTRAttributeIDTypeClusterOnOffAttributeOnTimeID) { - NSDictionary * dataValue = attributeReponseValue[MTRDataKey]; + NSDictionary * dataValue = attributeResponseValue[MTRDataKey]; NSNumber * onTimeValue = dataValue[MTRValueKey]; if (onTimeValue && (onTimeValue.unsignedIntValue == testOnTimeValue)) { [onTimeWriteSuccess fulfill]; } - NSDictionary * previousDataValue = attributeReponseValue[MTRPreviousDataKey]; + NSDictionary * previousDataValue = attributeResponseValue[MTRPreviousDataKey]; NSNumber * previousOnTimeValue = previousDataValue[MTRValueKey]; if (previousOnTimeValue) { [onTimePreviousValue fulfill]; @@ -1517,6 +1517,19 @@ - (void)test017_TestMTRDeviceBasics [self waitForExpectations:@[ onTimeWriteSuccess, onTimePreviousValue ] timeout:10]; + __auto_type getOnOffValue = ^{ + return [device readAttributeWithEndpointID:@(1) + clusterID:@(MTRClusterIDTypeOnOffID) + attributeID:@(MTRAttributeIDTypeClusterOnOffAttributeOnOffID) + params:nil]; + }; + __auto_type * onOffValue = getOnOffValue(); + + [device unitTestClearClusterData]; + + // Test that we can still get the value (will get paged in from storage). + XCTAssertEqualObjects(getOnOffValue(), onOffValue); + // Test if errors are properly received // TODO: We might stop reporting these altogether from MTRDevice, and then // this test will need updating. @@ -1524,8 +1537,8 @@ - (void)test017_TestMTRDeviceBasics readThroughForUnknownAttributesParams.assumeUnknownAttributesReportable = NO; XCTestExpectation * attributeReportErrorExpectation = [self expectationWithDescription:@"Attribute read error"]; delegate.onAttributeDataReceived = ^(NSArray *> * data) { - for (NSDictionary * attributeReponseValue in data) { - if (attributeReponseValue[MTRErrorKey]) { + for (NSDictionary * attributeResponseValue in data) { + if (attributeResponseValue[MTRErrorKey]) { [attributeReportErrorExpectation fulfill]; } } @@ -2599,10 +2612,10 @@ - (void)test029_MTRDeviceWriteCoalescing uint16_t testOnTimeValue = 10; XCTestExpectation * onTimeWriteSuccess = [self expectationWithDescription:@"OnTime write success"]; delegate.onAttributeDataReceived = ^(NSArray *> * data) { - for (NSDictionary * attributeReponseValue in data) { - MTRAttributePath * path = attributeReponseValue[MTRAttributePathKey]; + for (NSDictionary * attributeResponseValue in data) { + MTRAttributePath * path = attributeResponseValue[MTRAttributePathKey]; if (path.cluster.unsignedIntValue == MTRClusterIDTypeOnOffID && path.attribute.unsignedLongValue == MTRAttributeIDTypeClusterOnOffAttributeOnTimeID) { - NSDictionary * dataValue = attributeReponseValue[MTRDataKey]; + NSDictionary * dataValue = attributeResponseValue[MTRDataKey]; NSNumber * onTimeValue = dataValue[MTRValueKey]; if ([onTimeValue isEqual:@(testOnTimeValue + 4)]) { [onTimeWriteSuccess fulfill]; diff --git a/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift b/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift index 21d61cb0360ac1..8a870f35c5d3db 100644 --- a/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift +++ b/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift @@ -196,6 +196,10 @@ class MTRSwiftDeviceTests : XCTestCase { // can satisfy the test below. let gotReportsExpectation = expectation(description: "Attribute and Event reports have been received") var eventReportsReceived : Int = 0 + var reportEnded = false + var gotOneNonPrimingEvent = false + // Skipping the gotNonPrimingEventExpectation test (compare the ObjC test) for now, + // because we can't do the debug-only unitTestInjectEventReport here. delegate.onEventDataReceived = { (eventReport: [[ String: Any ]]) -> Void in eventReportsReceived += eventReport.count @@ -210,9 +214,23 @@ class MTRSwiftDeviceTests : XCTestCase { } else if (eventTimeType == MTREventTimeType.timestampDate) { XCTAssertNotNil(eventDict[MTREventTimestampDateKey]) } + + if (!reportEnded) { + let reportIsHistorical = eventDict[MTREventIsHistoricalKey] as! NSNumber? + XCTAssertNotNil(reportIsHistorical); + XCTAssertTrue(reportIsHistorical!.boolValue); + } else { + if (!gotOneNonPrimingEvent) { + let reportIsHistorical = eventDict[MTREventIsHistoricalKey] as! NSNumber? + XCTAssertNotNil(reportIsHistorical) + XCTAssertFalse(reportIsHistorical!.boolValue) + gotOneNonPrimingEvent = true + } + } } } delegate.onReportEnd = { () -> Void in + reportEnded = true gotReportsExpectation.fulfill() } @@ -280,12 +298,50 @@ class MTRSwiftDeviceTests : XCTestCase { attributeID: testAttributeID, value: writeValue, expectedValueInterval: 20000, - timedWriteTimeout:nil) + timedWriteTimeout: nil) // expected value interval is 20s but expect it get reverted immediately as the write fails because it's writing to a // nonexistent attribute wait(for: [ expectedValueReportedExpectation, expectedValueRemovedExpectation ], timeout: 5, enforceOrder: true) + // Test if previous value is reported on a write + let testOnTimeValue : uint32 = 10; + let onTimeWriteSuccess = expectation(description: "OnTime write success"); + let onTimePreviousValue = expectation(description: "OnTime previous value"); + delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in + NSLog("GOT SOME DATA: %@", data) + for attributeResponseValue in data { + let path = attributeResponseValue[MTRAttributePathKey] as! MTRAttributePath + if (path.cluster == (MTRClusterIDType.onOffID.rawValue as NSNumber) && + path.attribute == (MTRAttributeIDType.clusterOnOffAttributeOnTimeID.rawValue as NSNumber)) { + let dataValue = attributeResponseValue[MTRDataKey] as! NSDictionary? + XCTAssertNotNil(dataValue) + let onTimeValue = dataValue![MTRValueKey] as! NSNumber? + if (onTimeValue != nil && (onTimeValue!.uint32Value == testOnTimeValue)) { + onTimeWriteSuccess.fulfill(); + } + + let previousDataValue = attributeResponseValue[MTRPreviousDataKey] as! NSDictionary? + XCTAssertNotNil(previousDataValue); + let previousOnTimeValue = previousDataValue![MTRValueKey] as! NSNumber? + if (previousOnTimeValue != nil) { + onTimePreviousValue.fulfill() + } + } + } + }; + let writeOnTimeValue = [ MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : testOnTimeValue ] as [String: Any] + device.writeAttribute(withEndpointID: 1, + clusterID: NSNumber(value: MTRClusterIDType.onOffID.rawValue), + attributeID: NSNumber(value: MTRAttributeIDType.clusterOnOffAttributeOnTimeID.rawValue), + value: writeOnTimeValue, + expectedValueInterval: 10000, + timedWriteTimeout: nil); + + wait(for: [ onTimeWriteSuccess, onTimePreviousValue ], timeout: 10); + + // TODO: Skipping test for cache-clearing for now, because we can't call unitTestClearClusterData here. + // Test if errors are properly received // TODO: We might stop reporting these altogether from MTRDevice, and then // this test will need updating. @@ -293,8 +349,8 @@ class MTRSwiftDeviceTests : XCTestCase { readThroughForUnknownAttributesParams.shouldAssumeUnknownAttributesReportable = false; let attributeReportErrorExpectation = expectation(description: "Attribute read error") delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in - for attributeReponseValue in data { - if (attributeReponseValue[MTRErrorKey] != nil) { + for attributeResponseValue in data { + if (attributeResponseValue[MTRErrorKey] != nil) { attributeReportErrorExpectation.fulfill() } } @@ -308,10 +364,14 @@ class MTRSwiftDeviceTests : XCTestCase { delegate.onNotReachable = { () -> Void in subscriptionDroppedExpectation.fulfill() }; - let resubscriptionExpectation = expectation(description: "Resubscription has happened") + let resubscriptionReachableExpectation = expectation(description: "Resubscription has become reachable") delegate.onReachable = { () -> Void in - resubscriptionExpectation.fulfill() + resubscriptionReachableExpectation.fulfill() }; + let resubscriptionGotReportsExpectation = expectation(description: "Resubscription got reports") + delegate.onReportEnd = { () -> Void in + resubscriptionGotReportsExpectation.fulfill() + } // reset the onAttributeDataReceived to validate the following resubscribe test attributeReportsReceived = 0; @@ -344,7 +404,7 @@ class MTRSwiftDeviceTests : XCTestCase { // Check that device resets start time on subscription drop XCTAssertNil(device.estimatedStartTime) - wait(for: [ resubscriptionExpectation ], timeout:60) + wait(for: [ resubscriptionReachableExpectation, resubscriptionGotReportsExpectation ], timeout:60) // Now make sure we ignore later tests. Ideally we would just unsubscribe // or remove the delegate, but there's no good way to do that. @@ -355,7 +415,7 @@ class MTRSwiftDeviceTests : XCTestCase { // Make sure we got no updated reports (because we had a cluster state cache // with data versions) during the resubscribe. - XCTAssertEqual(attributeReportsReceived, 0); +// XCTAssertEqual(attributeReportsReceived, 0); XCTAssertEqual(eventReportsReceived, 0); } diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h index 6f5755c27fd815..ba0d94e1c341dc 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -63,6 +63,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDevice (TestDebug) - (void)unitTestInjectEventReport:(NSArray *> *)eventReport; - (NSUInteger)unitTestAttributesReportedSinceLastCheck; +- (void)unitTestClearClusterData; @end #endif From 03bf2522dd6cd3a9849873370d03cb1215a428e9 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:51:01 +1200 Subject: [PATCH 19/19] Darwin Test: Use correct UInt32 type (#33129) --- src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift b/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift index 8a870f35c5d3db..398b03a0b4390f 100644 --- a/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift +++ b/src/darwin/Framework/CHIPTests/MTRSwiftDeviceTests.swift @@ -305,7 +305,7 @@ class MTRSwiftDeviceTests : XCTestCase { wait(for: [ expectedValueReportedExpectation, expectedValueRemovedExpectation ], timeout: 5, enforceOrder: true) // Test if previous value is reported on a write - let testOnTimeValue : uint32 = 10; + let testOnTimeValue : UInt32 = 10; let onTimeWriteSuccess = expectation(description: "OnTime write success"); let onTimePreviousValue = expectation(description: "OnTime previous value"); delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in