Skip to content

Commit e97c6dc

Browse files
author
Divya Kamath
committed
Added Unit Test for Serialization
1 parent 095537e commit e97c6dc

12 files changed

+448
-177
lines changed

.gitignore

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ graphitti
4242
ggraphitti
4343
cgraphitti
4444
tests
45-
serialTest
46-
deserialTest
47-
serialFileAccessTest
48-
#recorderTest
45+
serialFullTest
46+
serialFirstHalfTest
47+
serialSecondHalfTest
48+
core
49+
# core is generated by GDB during debugging
50+
51+
# Recorder Test
4952
*.exe
5053
*.out
5154
*.app

CMakeLists.txt

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ else()
5353
project(Graphitti LANGUAGES CXX C)
5454
endif()
5555

56-
#Setting the base version to C++ 11
56+
#Setting the base version to C++ 17
5757
set(CMAKE_CXX_STANDARD 17)
5858

5959
#set(DEBUG_MODE YES) for debugging, no optimization
@@ -372,35 +372,37 @@ target_link_libraries(tests gtest gtest_main)
372372
# Link the combined library into the 'tests' executable.
373373
target_link_libraries(tests combinedLib)
374374

375-
# add_executable(serialTest
376-
# Testing/RunTests.cpp
377-
# Testing/UnitTesting/SerializationTests.cpp)
375+
#------- SERIALIZATION TESTS --------------------
376+
# Serialization tests must be executed separately, as each test requires the
377+
# simulation to run from start to finish. Running multiple simulations with
378+
# the same singleton instance results in a segmentation fault (SEG FAULT).
378379

379-
# # Links the Googletest framework with the serialTest executable
380-
# target_link_libraries(serialTest gtest gtest_main)
381-
382-
# # Link the combined library into the 'serialTest' executable.
383-
# target_link_libraries(serialTest combinedLib)
380+
add_executable(serialFullTest
381+
Testing/RunTests.cpp
382+
Testing/UnitTesting/SerializationFullTest.cpp)
384383

385-
# add_executable(deserialTest
386-
# Testing/RunTests.cpp
387-
# Testing/UnitTesting/DeserializationTests.cpp)
384+
add_executable(serialFirstHalfTest
385+
Testing/RunTests.cpp
386+
Testing/UnitTesting/SerializationFirstHalfTest.cpp)
388387

389-
# # Links the Googletest framework with the deserialTest executable
390-
# target_link_libraries(deserialTest gtest gtest_main)
388+
add_executable(serialSecondHalfTest
389+
Testing/RunTests.cpp
390+
Testing/UnitTesting/SerializationSecondHalfTest.cpp)
391391

392-
# # Link the combined library into the 'deserialTest' executable.
393-
# target_link_libraries(deserialTest combinedLib)
392+
# Link the GoogleTest framework to each of the serial test executables.
393+
target_link_libraries(serialFullTest gtest gtest_main)
394+
target_link_libraries(serialFirstHalfTest gtest gtest_main)
395+
target_link_libraries(serialSecondHalfTest gtest gtest_main)
394396

395-
# add_executable(serialFileAccessTest
396-
# Testing/RunTests.cpp
397-
# Testing/UnitTesting/SerializationFileAccessTest.cpp)
397+
# Link the combined library and filesystem support to the respective serial test executables.
398+
target_link_libraries(serialFullTest stdc++fs)
399+
target_link_libraries(serialFullTest combinedLib)
398400

399-
# # Links the Googletest framework with the serialFileAccessTest executable
400-
# target_link_libraries(serialFileAccessTest gtest gtest_main)
401+
target_link_libraries(serialFirstHalfTest stdc++fs)
402+
target_link_libraries(serialFirstHalfTest combinedLib)
401403

402-
# # Link the combined library into the 'serialFileAccessTest' executable.
403-
# target_link_libraries(serialFileAccessTest combinedLib)
404+
target_link_libraries(serialSecondHalfTest stdc++fs)
405+
target_link_libraries(serialSecondHalfTest combinedLib)
404406

405407
# Clear ENABLE_CUDA, PERFORMANCE_METRICS and GPROF from the cache so it's reset for subsequent builds
406408
unset(ENABLE_CUDA CACHE)

Testing/UnitTesting/DeserializationTests.cpp

Lines changed: 0 additions & 34 deletions
This file was deleted.

Testing/UnitTesting/SerializationFileAccessTest.cpp

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @file SerializationFirstHalfTest.cpp
3+
*
4+
* @brief The serialization test verifies correctness through a series of steps performed across three files:
5+
* SerializeFullFileTest.cpp, SerializationFirstHalfTest.cpp, and SerializationSecondHalfTest.cpp.
6+
*
7+
* STEP 1: Run a full simulation (e.g., 10 epochs) and save its serialized output.
8+
* STEP 2: Split the full simulation's input configuration file into two halves based on the epoch count
9+
* (e.g., 10 epochs → 5 + 5 epochs).
10+
* Reference file: /configfiles/test-small-long-half.xml
11+
* STEP 3: Run the first half of the simulation (e.g., 5 epochs) and save its serialized output.
12+
* STEP 4: Run the second half of the simulation (e.g., the remaining 5 epochs) using the serialized output
13+
* from the first half as the starting point.
14+
* STEP 5: Compare the serialized output of the second half with the full simulation's serialized output.
15+
* If they match, the final result files should also be identical, confirming successful serialization.
16+
*
17+
* @note This specific test, SerializationFirstHalfTest, covers the third step: first half of the simulation and saving its serialized output
18+
*
19+
* To run the serialization tests, execute the script `run_serial_test.sh` located in the `build` directory.
20+
*
21+
* @ingroup Testing/UnitTesting
22+
*/
23+
24+
25+
#include "SerializationHelper.cpp"
26+
#include "gtest/gtest.h"
27+
28+
using namespace std;
29+
30+
// Test serialization by running full and half simulations, and comparing serialized files
31+
TEST(SerializationTest, SerializeFirstHalfTest)
32+
{
33+
string executable = "./cgraphitti";
34+
35+
// Configuration file for the half simulation
36+
string configFileHalf = "../configfiles/test-small-long-half.xml";
37+
38+
// Path to save the serialized output file
39+
string serialFirstHalf = "../Testing/UnitTesting/TestOutput/First-half-serialized-file.xml";
40+
41+
// Command-line arguments for the simulation
42+
string argumentFirstHalf = "-c " + configFileHalf + " -s " + serialFirstHalf;
43+
44+
// Run simulations
45+
ASSERT_TRUE(runSimulation(executable, argumentFirstHalf)) << "First half simulation failed.";
46+
47+
// Check that the serialized file was created
48+
ASSERT_TRUE(fileExists(serialFirstHalf)) << "Serialized first half file does not exist.";
49+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @file SerializationFullTest.cpp
3+
*
4+
* @brief The serialization test verifies correctness through a series of steps performed across three files:
5+
* SerializeFullFileTest.cpp, SerializationFirstHalfTest.cpp, and SerializationSecondHalfTest.cpp.
6+
*
7+
* STEP 1: Run a full simulation (e.g., 10 epochs) and save its serialized output.
8+
* STEP 2: Split the full simulation's input configuration file into two halves based on the epoch count
9+
* (e.g., 10 epochs → 5 + 5 epochs).
10+
* Reference file: /configfiles/test-small-long-half.xml
11+
* STEP 3: Run the first half of the simulation (e.g., 5 epochs) and save its serialized output.
12+
* STEP 4: Run the second half of the simulation (e.g., the remaining 5 epochs) using the serialized output
13+
* from the first half as the starting point.
14+
* STEP 5: Compare the serialized output of the second half with the full simulation's serialized output.
15+
* If they match, the final result files should also be identical, confirming successful serialization.
16+
*
17+
* @note This specific test, SerializeFullFileTest, covers the first step: running the full simulation and saving the serialized file.
18+
*
19+
* To run the serialization tests, execute the script `run_serial_test.sh` located in the `build` directory.
20+
*
21+
* @ingroup Testing/UnitTesting
22+
*/
23+
24+
#include "SerializationHelper.cpp"
25+
#include "gtest/gtest.h"
26+
27+
using namespace std;
28+
29+
// Test to ensure the full simulation runs, serializes correctly, and the serialized file is created.
30+
TEST(SerializationFull, SerializeFullFileTest)
31+
{
32+
string executable = "./cgraphitti";
33+
34+
// Configuration file for the full simulation
35+
string configFileFull = "../configfiles/test-small-long.xml";
36+
37+
// Path to save the serialized output file
38+
string serialFull = "../Testing/UnitTesting/TestOutput/Full-serialized-file.xml";
39+
40+
// Command-line arguments for the simulation
41+
string argumentFull = "-c " + configFileFull + " -s " + serialFull;
42+
43+
// Run the full simulation
44+
ASSERT_TRUE(runSimulation(executable, argumentFull)) << "Full simulation failed.";
45+
46+
// Check that the serialized file was created
47+
ASSERT_TRUE(fileExists(serialFull)) << "Serialized full simulation file does not exist.";
48+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @file SerializationHelper.cpp
3+
*
4+
* @brief Helper class that contains utility functions for serialization testing.
5+
*
6+
* @ingroup Testing/UnitTesting
7+
*/
8+
9+
#include "Core.h"
10+
#include <filesystem>
11+
#include <fstream>
12+
#include <tinyxml.h>
13+
14+
using namespace std;
15+
namespace fs = std::filesystem;
16+
17+
// Helper function to run the simulation
18+
bool runSimulation(const string &executable, const string &arguments)
19+
{
20+
Core core;
21+
return core.runSimulation(executable, arguments) == 0 ? true : false;
22+
}
23+
24+
// Helper function to check if a file exists
25+
bool fileExists(const string &filePath)
26+
{
27+
return fs::exists(filePath);
28+
}
29+
30+
// Helper function to compare two XML elements recursively
31+
bool compareXmlElements(TiXmlElement *elem1, TiXmlElement *elem2)
32+
{
33+
if (!elem1 || !elem2) {
34+
return false;
35+
}
36+
37+
// Compare element names
38+
if (std::string(elem1->Value()) != std::string(elem2->Value())) {
39+
return false;
40+
}
41+
42+
// Compare attributes
43+
TiXmlAttribute *attr1 = elem1->FirstAttribute();
44+
TiXmlAttribute *attr2 = elem2->FirstAttribute();
45+
46+
while (attr1 && attr2) {
47+
if (std::string(attr1->Name()) != std::string(attr2->Name())
48+
|| std::string(attr1->Value()) != std::string(attr2->Value())) {
49+
return false;
50+
}
51+
attr1 = attr1->Next();
52+
attr2 = attr2->Next();
53+
}
54+
55+
// Check if one element has more attributes than the other
56+
if (attr1 || attr2) {
57+
return false;
58+
}
59+
60+
// Compare child elements
61+
TiXmlElement *child1 = elem1->FirstChildElement();
62+
TiXmlElement *child2 = elem2->FirstChildElement();
63+
64+
while (child1 && child2) {
65+
if (!compareXmlElements(child1, child2)) {
66+
return false;
67+
}
68+
child1 = child1->NextSiblingElement();
69+
child2 = child2->NextSiblingElement();
70+
}
71+
72+
// Check if one element has more children than the other
73+
if (child1 || child2) {
74+
return false;
75+
}
76+
77+
return true;
78+
}
79+
80+
// Helper function to compare XML files
81+
bool compareXmlFiles(const std::string &filePath1, const std::string &filePath2)
82+
{
83+
TiXmlDocument doc1, doc2;
84+
85+
// Load the first XML file
86+
if (!doc1.LoadFile(filePath1.c_str())) {
87+
std::cerr << "Failed to load XML file: " << filePath1 << std::endl;
88+
return false;
89+
}
90+
91+
// Load the second XML file
92+
if (!doc2.LoadFile(filePath2.c_str())) {
93+
std::cerr << "Failed to load XML file: " << filePath2 << std::endl;
94+
return false;
95+
}
96+
97+
// Compare the root elements of both XML documents
98+
TiXmlElement *root1 = doc1.RootElement();
99+
TiXmlElement *root2 = doc2.RootElement();
100+
101+
if (!root1 || !root2) {
102+
std::cerr << "One of the XML files has no root element." << std::endl;
103+
return false;
104+
}
105+
106+
// Recursively compare the XML structures
107+
return compareXmlElements(root1, root2);
108+
}

0 commit comments

Comments
 (0)