blob: 57366ff2b3ce8fd2d4c9a39986b60bb1ad4d4ded [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2016-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
* Unit tests for the Chip Pool API.
*
*/
#include <set>
#include <lib/support/Pool.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>
namespace chip {
template <class T, size_t N>
size_t GetNumObjectsInUse(BitMapObjectPool<T, N> & pool)
{
size_t count = 0;
pool.ForEachActiveObject([&count](void *) {
++count;
return true;
});
return count;
}
} // namespace chip
namespace {
using namespace chip;
void TestReleaseNull(nlTestSuite * inSuite, void * inContext)
{
constexpr const size_t size = 10;
BitMapObjectPool<uint32_t, size> pool;
pool.ReleaseObject(nullptr);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == 0);
NL_TEST_ASSERT(inSuite, pool.Allocated() == 0);
}
void TestCreateReleaseObject(nlTestSuite * inSuite, void * inContext)
{
constexpr const size_t size = 100;
BitMapObjectPool<uint32_t, size> pool;
uint32_t * obj[size];
for (size_t i = 0; i < pool.Size(); ++i)
{
obj[i] = pool.CreateObject();
NL_TEST_ASSERT(inSuite, obj[i] != nullptr);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == i + 1);
NL_TEST_ASSERT(inSuite, pool.Allocated() == i + 1);
}
uint32_t * fail = pool.CreateObject();
NL_TEST_ASSERT(inSuite, fail == nullptr);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size);
NL_TEST_ASSERT(inSuite, pool.Allocated() == size);
NL_TEST_ASSERT(inSuite, pool.Exhausted());
pool.ReleaseObject(obj[55]);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size - 1);
NL_TEST_ASSERT(inSuite, pool.Allocated() == size - 1);
NL_TEST_ASSERT(inSuite, !pool.Exhausted());
NL_TEST_ASSERT(inSuite, obj[55] == pool.CreateObject());
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size);
NL_TEST_ASSERT(inSuite, pool.Allocated() == size);
NL_TEST_ASSERT(inSuite, pool.Exhausted());
fail = pool.CreateObject();
NL_TEST_ASSERT(inSuite, fail == nullptr);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size);
NL_TEST_ASSERT(inSuite, pool.Allocated() == size);
NL_TEST_ASSERT(inSuite, pool.Exhausted());
for (size_t i = 0; i < pool.Size(); ++i)
{
pool.ReleaseObject(obj[i]);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size - i - 1);
NL_TEST_ASSERT(inSuite, pool.Allocated() == size - i - 1);
}
}
void TestCreateReleaseStruct(nlTestSuite * inSuite, void * inContext)
{
struct S
{
S(std::set<S *> & set) : mSet(set) { mSet.insert(this); }
~S() { mSet.erase(this); }
std::set<S *> & mSet;
};
std::set<S *> objs1;
constexpr const size_t size = 100;
BitMapObjectPool<S, size> pool;
S * objs2[size];
for (size_t i = 0; i < pool.Size(); ++i)
{
objs2[i] = pool.CreateObject(objs1);
NL_TEST_ASSERT(inSuite, objs2[i] != nullptr);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == i + 1);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == objs1.size());
}
for (size_t i = 0; i < pool.Size(); ++i)
{
pool.ReleaseObject(objs2[i]);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == size - i - 1);
NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == objs1.size());
}
}
int Setup(void * inContext)
{
return SUCCESS;
}
int Teardown(void * inContext)
{
return SUCCESS;
}
} // namespace
#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn)
/**
* Test Suite. It lists all the test functions.
*/
static const nlTest sTests[] = { NL_TEST_DEF_FN(TestReleaseNull), NL_TEST_DEF_FN(TestCreateReleaseObject),
NL_TEST_DEF_FN(TestCreateReleaseStruct), NL_TEST_SENTINEL() };
int TestPool()
{
nlTestSuite theSuite = { "CHIP Pool tests", &sTests[0], Setup, Teardown };
// Run test suit againt one context.
nlTestRunner(&theSuite, nullptr);
return nlTestRunnerStats(&theSuite);
}
CHIP_REGISTER_TEST_SUITE(TestPool);