| /* |
| * |
| * Copyright (c) 2015-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * This file implements a unit test suite for the WeaveStateFabric |
| * StateChangedDelegate methods. |
| * |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <new> |
| |
| #include <nlunit-test.h> |
| |
| #include "ToolCommon.h" |
| #include "TestGroupKeyStore.h" |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Core/WeaveConfig.h> |
| |
| using namespace nl::Weave; |
| |
| const uint64_t kTestNodeId = 0x18B43000002DCF71ULL; |
| |
| static WeaveFabricState sFabricState; |
| |
| class TestDelegate |
| : public FabricStateDelegate |
| { |
| public: |
| TestDelegate() |
| { |
| ClearState(); |
| } |
| |
| virtual void DidJoinFabric(WeaveFabricState *fabricState, uint64_t newFabricId) |
| { |
| mDidJoinFabricCalled = true; |
| mNewFabricId = newFabricId; |
| |
| } |
| virtual void DidLeaveFabric(WeaveFabricState *fabricState, uint64_t oldFabricId) |
| { |
| mDidLeaveFabricCalled = true; |
| mOldFabricId = oldFabricId; |
| } |
| |
| void ClearState(void) |
| { |
| mDidJoinFabricCalled = false; |
| mDidLeaveFabricCalled = false; |
| mOldFabricId = 0; |
| mNewFabricId = 0; |
| } |
| |
| bool CheckStateIsClear(void) |
| { |
| // Neither callback is invoked |
| return (!mDidJoinFabricCalled && !mDidLeaveFabricCalled); |
| } |
| |
| // Indicate which callback was invoked |
| bool mDidJoinFabricCalled; |
| bool mDidLeaveFabricCalled; |
| uint64_t mOldFabricId; |
| uint64_t mNewFabricId; |
| }; |
| |
| |
| static void Setup(nlTestSuite *inSuite, void *inContext) |
| { |
| WEAVE_ERROR err; |
| static nlDEFINE_ALIGNED_VAR(sTestGroupKeyStore, sizeof(TestGroupKeyStore), void*); |
| |
| err = sFabricState.Init(new (&sTestGroupKeyStore) TestGroupKeyStore()); |
| |
| sFabricState.LocalNodeId = kTestNodeId; |
| |
| NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR); |
| } |
| |
| static void CheckDelegateCallbacks(nlTestSuite *inSuite, void *inContext) |
| { |
| WEAVE_ERROR err; |
| TestDelegate delegate; |
| uint64_t fabricId; |
| uint8_t fabricStateBuffer[512]; |
| uint32_t fabricStateLen; |
| |
| // Set the delegate |
| sFabricState.SetDelegate(&delegate); |
| |
| //------------------------------------------------------------------- |
| // Check callback after CreateFabric() |
| |
| // Test the callback are invoked when creating a new fabric |
| sFabricState.CreateFabric(); |
| NL_TEST_ASSERT(inSuite, delegate.mDidJoinFabricCalled == true); |
| NL_TEST_ASSERT(inSuite, delegate.mDidLeaveFabricCalled == false); |
| fabricId = delegate.mNewFabricId; |
| |
| // Clear the fabric, we should only get a didLeave callback now |
| delegate.ClearState(); |
| NL_TEST_ASSERT(inSuite, delegate.CheckStateIsClear()); |
| |
| sFabricState.ClearFabricState(); |
| |
| NL_TEST_ASSERT(inSuite, delegate.mDidLeaveFabricCalled == true); |
| NL_TEST_ASSERT(inSuite, delegate.mDidJoinFabricCalled == false); |
| NL_TEST_ASSERT(inSuite, delegate.mOldFabricId == fabricId); |
| |
| // Clear again, should get no callback now |
| delegate.ClearState(); |
| NL_TEST_ASSERT(inSuite, delegate.CheckStateIsClear()); |
| |
| sFabricState.ClearFabricState(); |
| |
| NL_TEST_ASSERT(inSuite, delegate.mDidLeaveFabricCalled == false); |
| NL_TEST_ASSERT(inSuite, delegate.mDidJoinFabricCalled == false); |
| |
| //------------------------------------------------------------------- |
| // Test for JoinExistingFabric |
| |
| // Create a random fabric and get the fabric state, then leave fabric |
| |
| err = sFabricState.CreateFabric(); |
| NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR); |
| fabricId = sFabricState.FabricId; |
| |
| err = sFabricState.GetFabricState(fabricStateBuffer, sizeof(fabricStateBuffer), fabricStateLen); |
| NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR); |
| |
| sFabricState.ClearFabricState(); |
| |
| // Now test the callbacks when joining existing fabric, the fabric id matches |
| delegate.ClearState(); |
| NL_TEST_ASSERT(inSuite, delegate.CheckStateIsClear()); |
| |
| err = sFabricState.JoinExistingFabric(fabricStateBuffer, fabricStateLen); |
| NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR); |
| |
| NL_TEST_ASSERT(inSuite, delegate.mDidLeaveFabricCalled == false); |
| NL_TEST_ASSERT(inSuite, delegate.mDidJoinFabricCalled == true); |
| NL_TEST_ASSERT(inSuite, delegate.mNewFabricId == fabricId); |
| |
| } |
| |
| static const nlTest sTests[] = { |
| NL_TEST_DEF("Setup", Setup), |
| NL_TEST_DEF("DelegateCallback", CheckDelegateCallbacks), |
| NL_TEST_SENTINEL() |
| }; |
| |
| int main(void) |
| { |
| WEAVE_ERROR err; |
| |
| nlTestSuite theSuite = { |
| "FabricStateDelegate", |
| &sTests[0] |
| }; |
| |
| err = nl::Weave::Platform::Security::InitSecureRandomDataSource(NULL, 64, NULL, 0); |
| FAIL_ERROR(err, "InitSecureRandomDataSource() failed"); |
| |
| nl_test_set_output_style(OUTPUT_CSV); |
| |
| nlTestRunner(&theSuite, NULL); |
| |
| return nlTestRunnerStats(&theSuite); |
| } |