// Checks whether a `Child::State` matches a `ChildTable::StateFilter`. static bool StateMatchesFilter(Child::State aState, ChildTable::StateFilter aFilter) { bool rval = false; Child child; child.SetState(aState); switch (aFilter) { case ChildTable::kInStateAnyExceptInvalid: rval = (aState != Child::kStateInvalid); break; case ChildTable::kInStateValid: rval = (aState == Child::kStateValid); break; case ChildTable::kInStateValidOrRestoring: rval = child.IsStateValidOrRestoring(); break; case ChildTable::kInStateChildIdRequest: rval = (aState == Child::kStateChildIdRequest); break; case ChildTable::kInStateValidOrAttaching: rval = child.IsStateValidOrAttaching(); break; case ChildTable::kInStateAnyExceptValidOrRestoring: rval = !child.IsStateValidOrRestoring(); break; } return rval; }
void TestChildTable(void) { const TestChild testChildList[] = { { Child::kStateValid, 0x8001, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x16}}, }, { Child::kStateParentRequest, 0x8002, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x17}}, }, { Child::kStateValid, 0x8003, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x18}}, }, { Child::kStateValid, 0x8004, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x19}}, }, { Child::kStateRestored, 0x8005, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x20}}, }, { Child::kStateValid, 0x8006, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x21}}, }, { Child::kStateChildIdRequest, 0x8007, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x22}}, }, { Child::kStateChildUpdateRequest, 0x8008, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x23}}, }, { Child::kStateParentResponse, 0x8009, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x24}}, }, { Child::kStateRestored, 0x800a, {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x25}}, }, }; const uint8_t testListLength = OT_ARRAY_LENGTH(testChildList); uint8_t testNumAllowedChildren = 2; ChildTable *table; otError error; sInstance = testInitInstance(); VerifyOrQuit(sInstance != NULL, "Null instance"); table = &sInstance->Get<ChildTable>(); //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printf("Checking initial state after child table is constructed"); VerifyOrQuit(table->GetMaxChildrenAllowed() == table->GetMaxChildren(), "GetMaxChildrenAllowed() initial value is incorrect "); for (uint8_t i = 0; i < OT_ARRAY_LENGTH(kAllFilters); i++) { ChildTable::StateFilter filter = kAllFilters[i]; VerifyOrQuit(table->HasChildren(filter) == false, "HasChildren() failed after init"); VerifyOrQuit(table->GetNumChildren(filter) == 0, "GetNumChildren() failed after init"); } printf(" -- PASS\n"); //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerifyChildTableContent(*table, 0, testChildList); VerifyOrQuit(table->GetMaxChildrenAllowed() >= testListLength, "Default child table size is too small for the unit test"); // Add the child entries from test list one by one and verify the table content for (uint8_t i = 0; i < testListLength; i++) { Child *child; child = table->GetNewChild(); VerifyOrQuit(child != NULL, "GetNewChild() failed"); child->SetState(testChildList[i].mState); child->SetRloc16(testChildList[i].mRloc16); child->SetExtAddress((static_cast<const Mac::ExtAddress &>(testChildList[i].mExtAddress))); VerifyChildTableContent(*table, i + 1, testChildList); } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Verify Child Table clear table->Clear(); VerifyChildTableContent(*table, 0, testChildList); // Add the child entries from test list in reverse order and verify the table content for (uint8_t i = testListLength; i > 0; i--) { Child *child; child = table->GetNewChild(); VerifyOrQuit(child != NULL, "GetNewChild() failed"); child->SetState(testChildList[i - 1].mState); child->SetRloc16(testChildList[i - 1].mRloc16); child->SetExtAddress((static_cast<const Mac::ExtAddress &>(testChildList[i - 1].mExtAddress))); VerifyChildTableContent(*table, testListLength - i + 1, &testChildList[i - 1]); } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printf("Test Get/SetMaxChildrenAllowed"); error = table->SetMaxChildrenAllowed(kMaxChildren - 1); VerifyOrQuit(error == OT_ERROR_INVALID_STATE, "SetMaxChildrenAllowed() should fail when table is not empty"); table->Clear(); error = table->SetMaxChildrenAllowed(kMaxChildren + 1); VerifyOrQuit(error == OT_ERROR_INVALID_ARGS, "SetMaxChildrenAllowed() did not fail with an invalid arg"); error = table->SetMaxChildrenAllowed(0); VerifyOrQuit(error == OT_ERROR_INVALID_ARGS, "SetMaxChildrenAllowed() did not fail with an invalid arg"); error = table->SetMaxChildrenAllowed(testNumAllowedChildren); VerifyOrQuit(error == OT_ERROR_NONE, "SetMaxChildrenAllowed() failed"); VerifyOrQuit(table->GetMaxChildrenAllowed() == testNumAllowedChildren, "GetMaxChildrenAllowed() failed"); for (uint8_t num = 0; num < testNumAllowedChildren; num++) { Child *child = table->GetNewChild(); VerifyOrQuit(child != NULL, "GetNewChild() failed"); child->SetState(Child::kStateValid); } VerifyOrQuit(table->GetNewChild() == NULL, "GetNewChild() did not fail when table was full"); printf(" -- PASS\n"); testFreeInstance(sInstance); }