Add test for BinaryHeap

This commit is contained in:
Patrick Niklaus 2014-06-13 01:00:46 +02:00
parent 9f9fde1f2b
commit 8d46ee85f1
3 changed files with 172 additions and 1 deletions

View File

@ -41,8 +41,9 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.c
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
add_custom_target(tests DEPENDS datastructure-tests)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
@ -65,6 +66,7 @@ file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp)
set(
OSRMSources
@ -84,6 +86,9 @@ add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp)
# Unit tests
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob})
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release)
@ -114,6 +119,8 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
endif (HAS_LTO_FLAG)
endif()
add_definitions(-DBOOST_TEST_DYN_LINK)
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
@ -190,6 +197,8 @@ target_link_libraries(osrm-prepare ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
find_package(Threads REQUIRED)
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})

View File

@ -0,0 +1,154 @@
#include "../../DataStructures/BinaryHeap.h"
#include "../../typedefs.h"
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>
#include <random>
BOOST_AUTO_TEST_SUITE(binary_heap)
struct TestData
{
unsigned value;
};
typedef NodeID TestNodeID;
typedef int TestKey;
typedef int TestWeight;
typedef boost::mpl::list<ArrayStorage<TestNodeID, TestKey>,
MapStorage<TestNodeID, TestKey>,
UnorderedMapStorage<TestNodeID, TestKey>> storage_types;
template<unsigned NUM_ELEM>
struct RandomDataFixture
{
RandomDataFixture()
{
for (unsigned i = 0; i < NUM_ELEM; i++)
{
data.push_back(TestData {i*3});
weights.push_back((i+1)*100);
ids.push_back(i);
order.push_back(i);
}
// Choosen by a fair W20 dice roll
std::mt19937 g(15);
std::shuffle(order.begin(), order.end(), g);
}
std::vector<TestData> data;
std::vector<TestWeight> weights;
std::vector<TestNodeID> ids;
std::vector<unsigned> order;
};
constexpr unsigned NUM_NODES = 100;
BOOST_FIXTURE_TEST_CASE_TEMPLATE(insert_test, T, storage_types, RandomDataFixture<NUM_NODES>)
{
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
TestWeight min_weight = std::numeric_limits<TestWeight>::max();
TestNodeID min_id;
for (unsigned idx : order)
{
BOOST_CHECK(!heap.WasInserted(ids[idx]));
heap.Insert(ids[idx], weights[idx], data[idx]);
BOOST_CHECK(heap.WasInserted(ids[idx]));
if (weights[idx] < min_weight)
{
min_weight = weights[idx];
min_id = ids[idx];
}
BOOST_CHECK_EQUAL(min_id, heap.Min());
}
for (auto id : ids)
{
const auto& d = heap.GetData(id);
BOOST_CHECK_EQUAL(d.value, data[id].value);
const auto& w = heap.GetKey(id);
BOOST_CHECK_EQUAL(w, weights[id]);
}
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(delete_min_test, T, storage_types, RandomDataFixture<NUM_NODES>)
{
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
for (unsigned idx : order)
{
heap.Insert(ids[idx], weights[idx], data[idx]);
}
for (auto id : ids)
{
BOOST_CHECK(!heap.WasRemoved(id));
BOOST_CHECK_EQUAL(heap.Min(), id);
BOOST_CHECK_EQUAL(id, heap.DeleteMin());
if (id+1 < NUM_NODES)
BOOST_CHECK_EQUAL(heap.Min(), id+1);
BOOST_CHECK(heap.WasRemoved(id));
}
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(delete_all_test, T, storage_types, RandomDataFixture<NUM_NODES>)
{
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
for (unsigned idx : order)
{
heap.Insert(ids[idx], weights[idx], data[idx]);
}
heap.DeleteAll();
BOOST_CHECK(heap.Empty());
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(decrease_key_test, T, storage_types, RandomDataFixture<10>)
{
BinaryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(10);
for (unsigned idx : order)
{
heap.Insert(ids[idx], weights[idx], data[idx]);
}
std::vector<TestNodeID> rids(ids);
std::reverse(rids.begin(), rids.end());
for (auto id : rids)
{
TestNodeID min_id = heap.Min();
TestWeight min_weight = heap.GetKey(min_id);
// decrease weight until we reach min weight
while (weights[id] > min_weight)
{
heap.DecreaseKey(id, weights[id]);
BOOST_CHECK_EQUAL(heap.Min(), min_id);
weights[id]--;
}
// make weight smaller than min
weights[id] -= 2;
heap.DecreaseKey(id, weights[id]);
BOOST_CHECK_EQUAL(heap.Min(), id);
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,8 @@
#define BOOST_TEST_MODULE datastructure tests
#include <boost/test/unit_test.hpp>
/*
* This file will contain an automatically generated main function.
*/