15
15
* See the License for the specific language governing permissions and
16
16
* limitations under the License.
17
17
*/
18
- #include " lib/support/CHIPMem.h"
19
18
#include < app-common/zap-generated/cluster-objects.h>
20
19
#include < app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-cluster-logic.h>
21
20
#include < app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-delegate.h>
22
21
#include < app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-matter-context.h>
22
+ #include < lib/support/CHIPMem.h>
23
+ #include < lib/support/DefaultStorageKeyAllocator.h>
24
+ #include < lib/support/TestPersistentStorageDelegate.h>
23
25
#include < pw_unit_test/framework.h>
24
26
25
27
namespace chip {
@@ -115,7 +117,8 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestConformanceValid)
115
117
TEST_F (TestValveConfigurationAndControlClusterLogic, TestGetAttributesAllFeatures)
116
118
{
117
119
TestDelegate delegate;
118
- MatterContext context = MatterContext (0 );
120
+ TestPersistentStorageDelegate storageDelegate;
121
+ MatterContext context = MatterContext (0 , storageDelegate);
119
122
ClusterLogic logic = ClusterLogic (delegate, context);
120
123
121
124
// Everything on, all should return values
@@ -170,7 +173,8 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestGetAttributesAllFeature
170
173
TEST_F (TestValveConfigurationAndControlClusterLogic, TestGetAttributesNoFeatures)
171
174
{
172
175
TestDelegate delegate;
173
- MatterContext context = MatterContext (0 );
176
+ TestPersistentStorageDelegate storageDelegate;
177
+ MatterContext context = MatterContext (0 , storageDelegate);
174
178
ClusterLogic logic = ClusterLogic (delegate, context);
175
179
176
180
// Everything on, all should return values
@@ -218,7 +222,8 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestGetAttributesNoFeatures
218
222
TEST_F (TestValveConfigurationAndControlClusterLogic, TestGetAttributesStartingState)
219
223
{
220
224
TestDelegate delegate;
221
- MatterContext context = MatterContext (0 );
225
+ TestPersistentStorageDelegate storageDelegate;
226
+ MatterContext context = MatterContext (0 , storageDelegate);
222
227
ClusterLogic logic = ClusterLogic (delegate, context);
223
228
224
229
// Everything on, all should return values
@@ -286,7 +291,8 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestGetAttributesStartingSt
286
291
TEST_F (TestValveConfigurationAndControlClusterLogic, TestGetAttributesUninitialized)
287
292
{
288
293
TestDelegate delegate;
289
- MatterContext context = MatterContext (0 );
294
+ TestPersistentStorageDelegate storageDelegate;
295
+ MatterContext context = MatterContext (0 , storageDelegate);
290
296
ClusterLogic logic = ClusterLogic (delegate, context);
291
297
292
298
DataModel::Nullable<ElapsedS> valElapsedSNullable;
@@ -310,6 +316,194 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestGetAttributesUninitiali
310
316
EXPECT_EQ (logic.GetLevelStep (val8), CHIP_ERROR_INCORRECT_STATE);
311
317
}
312
318
319
+ TEST_F (TestValveConfigurationAndControlClusterLogic, TestSetDefaultOpenDuration)
320
+ {
321
+ TestDelegate delegate;
322
+ TestPersistentStorageDelegate storageDelegate;
323
+ EndpointId endpoint = 0 ;
324
+ MatterContext context = MatterContext (endpoint, storageDelegate);
325
+ ClusterLogic logic = ClusterLogic (delegate, context);
326
+
327
+ DataModel::Nullable<ElapsedS> valElapsedSNullable;
328
+
329
+ // Setting this value before initialization should fail
330
+ auto testVal = DataModel::MakeNullable (static_cast <ElapsedS>(5u ));
331
+ EXPECT_EQ (logic.SetDefaultOpenDuration (testVal), CHIP_ERROR_INCORRECT_STATE);
332
+
333
+ ClusterConformance conformance = { .featureMap = to_underlying (Feature::kLevel ) | to_underlying (Feature::kTimeSync ),
334
+ .supportsDefaultOpenLevel = true ,
335
+ .supportsValveFault = true ,
336
+ .supportsLevelStep = true };
337
+ EXPECT_EQ (logic.Init (conformance), CHIP_NO_ERROR);
338
+
339
+ EXPECT_EQ (logic.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
340
+ EXPECT_EQ (valElapsedSNullable, DataModel::NullNullable);
341
+
342
+ // Lowest possible value
343
+ testVal = DataModel::MakeNullable (static_cast <ElapsedS>(1u ));
344
+ EXPECT_EQ (logic.SetDefaultOpenDuration (testVal), CHIP_NO_ERROR);
345
+
346
+ // Ensure the value is accessible via the API
347
+ EXPECT_EQ (logic.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
348
+ EXPECT_EQ (valElapsedSNullable, testVal);
349
+
350
+ // Ensure the value is persisted in the test storage
351
+ StorageKeyName keyName = DefaultStorageKeyAllocator::VCCDefaultOpenDuration (endpoint);
352
+ uint32_t persistedValue;
353
+ uint16_t size = static_cast <uint16_t >(sizeof (persistedValue));
354
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
355
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
356
+ EXPECT_EQ (persistedValue, testVal.Value ());
357
+ // Test that this doesn't exist for other endpoints. Check 1.
358
+ EXPECT_FALSE (storageDelegate.HasKey (DefaultStorageKeyAllocator::VCCDefaultOpenDuration (1 ).KeyName ()));
359
+
360
+ testVal = DataModel::MakeNullable (static_cast <ElapsedS>(12u ));
361
+ EXPECT_EQ (logic.SetDefaultOpenDuration (testVal), CHIP_NO_ERROR);
362
+
363
+ EXPECT_EQ (logic.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
364
+ EXPECT_EQ (valElapsedSNullable, testVal);
365
+
366
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
367
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
368
+ EXPECT_EQ (persistedValue, testVal.Value ());
369
+
370
+ auto outOfRangeVal = DataModel::MakeNullable (static_cast <ElapsedS>(0u ));
371
+ EXPECT_EQ (logic.SetDefaultOpenDuration (outOfRangeVal), CHIP_ERROR_INVALID_ARGUMENT);
372
+
373
+ // Ensure the value wasn't changed
374
+ EXPECT_EQ (logic.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
375
+ EXPECT_EQ (valElapsedSNullable, testVal);
376
+
377
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
378
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
379
+ EXPECT_EQ (persistedValue, testVal.Value ());
380
+
381
+ // Test that firing up a new logic cluster on the same endpoint loads the value from persisted storage
382
+ ClusterLogic logic_same_endpoint = ClusterLogic (delegate, context);
383
+ EXPECT_EQ (logic_same_endpoint.Init (conformance), CHIP_NO_ERROR);
384
+ EXPECT_EQ (logic_same_endpoint.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
385
+ EXPECT_EQ (valElapsedSNullable, testVal);
386
+
387
+ // Test that a new logic cluster on a different endpoint does not load the value
388
+ MatterContext context_ep1 = MatterContext (1 , storageDelegate);
389
+ ClusterLogic logic_different_endpoint = ClusterLogic (delegate, context_ep1);
390
+ EXPECT_EQ (logic_different_endpoint.Init (conformance), CHIP_NO_ERROR);
391
+ EXPECT_EQ (logic_different_endpoint.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
392
+ EXPECT_EQ (valElapsedSNullable, DataModel::NullNullable);
393
+
394
+ // Test setting back to null, this should clear the persisted value
395
+ testVal = DataModel::NullNullable;
396
+ EXPECT_EQ (logic.SetDefaultOpenDuration (testVal), CHIP_NO_ERROR);
397
+ EXPECT_FALSE (storageDelegate.HasKey (keyName.KeyName ()));
398
+
399
+ // Check that the value is not loaded when a new logic cluster is created
400
+ ClusterLogic logic_same_endpoint_again = ClusterLogic (delegate, context);
401
+ EXPECT_EQ (logic_same_endpoint_again.Init (conformance), CHIP_NO_ERROR);
402
+ EXPECT_EQ (logic_same_endpoint_again.GetDefaultOpenDuration (valElapsedSNullable), CHIP_NO_ERROR);
403
+ EXPECT_EQ (valElapsedSNullable, DataModel::NullNullable);
404
+
405
+ // Test that the calling function fails when write fails are on
406
+ storageDelegate.SetRejectWrites (true );
407
+ testVal.SetNonNull (12u );
408
+ EXPECT_EQ (logic.SetDefaultOpenDuration (testVal), CHIP_ERROR_PERSISTED_STORAGE_FAILED);
409
+ }
410
+
411
+ TEST_F (TestValveConfigurationAndControlClusterLogic, TestSetDefaultOpenLevel)
412
+ {
413
+ TestDelegate delegate;
414
+ TestPersistentStorageDelegate storageDelegate;
415
+ EndpointId endpoint = 0 ;
416
+ MatterContext context = MatterContext (endpoint, storageDelegate);
417
+ ClusterLogic logic = ClusterLogic (delegate, context);
418
+
419
+ uint8_t val8;
420
+
421
+ // Setting this value before initialization should fail
422
+ uint8_t testVal = 5u ;
423
+ EXPECT_EQ (logic.SetDefaultOpenLevel (testVal), CHIP_ERROR_INCORRECT_STATE);
424
+
425
+ ClusterConformance conformance = { .featureMap = to_underlying (Feature::kLevel ) | to_underlying (Feature::kTimeSync ),
426
+ .supportsDefaultOpenLevel = true ,
427
+ .supportsValveFault = true ,
428
+ .supportsLevelStep = true };
429
+ EXPECT_EQ (logic.Init (conformance), CHIP_NO_ERROR);
430
+
431
+ EXPECT_EQ (logic.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
432
+ EXPECT_EQ (val8, 100u );
433
+
434
+ // Lowest possible value
435
+ testVal = 1u ;
436
+ EXPECT_EQ (logic.SetDefaultOpenLevel (testVal), CHIP_NO_ERROR);
437
+
438
+ // Ensure the value is accessible via the API
439
+ EXPECT_EQ (logic.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
440
+ EXPECT_EQ (val8, testVal);
441
+
442
+ // Ensure the value is persisted in the test storage
443
+ StorageKeyName keyName = DefaultStorageKeyAllocator::VCCDefaultOpenLevel (endpoint);
444
+ uint8_t persistedValue;
445
+ uint16_t size = static_cast <uint16_t >(sizeof (persistedValue));
446
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
447
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
448
+ EXPECT_EQ (persistedValue, testVal);
449
+ // Test that this doesn't exist for other endpoints. Check 1.
450
+ EXPECT_FALSE (storageDelegate.HasKey (DefaultStorageKeyAllocator::VCCDefaultOpenLevel (1 ).KeyName ()));
451
+
452
+ // Highest possible value
453
+ testVal = 100u ;
454
+ EXPECT_EQ (logic.SetDefaultOpenLevel (testVal), CHIP_NO_ERROR);
455
+ EXPECT_EQ (logic.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
456
+ EXPECT_EQ (val8, testVal);
457
+
458
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
459
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
460
+ EXPECT_EQ (persistedValue, testVal);
461
+
462
+ uint8_t outOfRangeVal = 0u ;
463
+ EXPECT_EQ (logic.SetDefaultOpenLevel (outOfRangeVal), CHIP_ERROR_INVALID_ARGUMENT);
464
+ outOfRangeVal = 101u ;
465
+ EXPECT_EQ (logic.SetDefaultOpenLevel (outOfRangeVal), CHIP_ERROR_INVALID_ARGUMENT);
466
+
467
+ // Ensure the value wasn't changed
468
+ EXPECT_EQ (logic.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
469
+ EXPECT_EQ (val8, testVal);
470
+
471
+ EXPECT_TRUE (storageDelegate.HasKey (keyName.KeyName ()));
472
+ EXPECT_EQ (storageDelegate.SyncGetKeyValue (keyName.KeyName (), &persistedValue, size), CHIP_NO_ERROR);
473
+ EXPECT_EQ (persistedValue, testVal);
474
+
475
+ // Set Non-default value
476
+ testVal = 12u ;
477
+ EXPECT_EQ (logic.SetDefaultOpenLevel (testVal), CHIP_NO_ERROR);
478
+ // Test that firing up a new logic cluster on the same endpoint loads the value from persisted storage
479
+ ClusterLogic logic_same_endpoint = ClusterLogic (delegate, context);
480
+ EXPECT_EQ (logic_same_endpoint.Init (conformance), CHIP_NO_ERROR);
481
+ EXPECT_EQ (logic_same_endpoint.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
482
+ EXPECT_EQ (val8, testVal);
483
+
484
+ // Test that a new logic cluster on a different endpoint does not load the value
485
+ MatterContext context_ep1 = MatterContext (1 , storageDelegate);
486
+ ClusterLogic logic_different_endpoint = ClusterLogic (delegate, context_ep1);
487
+ EXPECT_EQ (logic_different_endpoint.Init (conformance), CHIP_NO_ERROR);
488
+ EXPECT_EQ (logic_different_endpoint.GetDefaultOpenLevel (val8), CHIP_NO_ERROR);
489
+ EXPECT_EQ (val8, 100u );
490
+
491
+ // Test that the calling function fails when write fails are on
492
+ storageDelegate.SetRejectWrites (true );
493
+ testVal = 15u ;
494
+ EXPECT_EQ (logic.SetDefaultOpenLevel (testVal), CHIP_ERROR_PERSISTED_STORAGE_FAILED);
495
+ storageDelegate.SetRejectWrites (false );
496
+
497
+ // Test that we get an error if this attribute is not supported
498
+ ClusterLogic logic_no_level = ClusterLogic (delegate, context);
499
+ ClusterConformance conformance_no_level = { .featureMap = to_underlying (Feature::kLevel ) | to_underlying (Feature::kTimeSync ),
500
+ .supportsDefaultOpenLevel = false ,
501
+ .supportsValveFault = true ,
502
+ .supportsLevelStep = true };
503
+ EXPECT_EQ (logic_no_level.Init (conformance_no_level), CHIP_NO_ERROR);
504
+ EXPECT_EQ (logic_no_level.SetDefaultOpenLevel (testVal), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
505
+ }
506
+
313
507
} // namespace ValveConfigurationAndControl
314
508
} // namespace Clusters
315
509
} // namespace app
0 commit comments