From 95a4ca25cceba391b33c17c7873a55fe785f2fb4 Mon Sep 17 00:00:00 2001 From: ifilot Date: Thu, 21 Dec 2023 09:51:41 +0100 Subject: [PATCH] Adding file creation to test suite --- src/isosurface_mesh.cpp | 4 +- src/test/CMakeLists.txt | 6 +- src/test/test_file_creation.cpp | 134 ++++++++++++++++++++++++++++++++ src/test/test_file_creation.h | 53 +++++++++++++ src/test/testinput/.gitignore | 5 ++ 5 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 src/test/test_file_creation.cpp create mode 100644 src/test/test_file_creation.h create mode 100644 src/test/testinput/.gitignore diff --git a/src/isosurface_mesh.cpp b/src/isosurface_mesh.cpp index bd07920..cd089d9 100644 --- a/src/isosurface_mesh.cpp +++ b/src/isosurface_mesh.cpp @@ -148,10 +148,10 @@ void IsoSurfaceMesh::write_to_file(const std::string& filename, const std::strin if(filename.substr(filename.size()-4) == ".obj") { std::cout << "Writing mesh as Wavefront file (.obj)." << std::endl; - this->write_obj(filename, path.filename().string(), path.filename().string()); + this->write_obj(filename, header, name); } else if(filename.substr(filename.size()-4) == ".ply") { std::cout << "Writing mesh as Standford Triangle Format file (.ply)." << std::endl; - this->write_ply(filename, path.filename().string(), path.filename().string()); + this->write_ply(filename, header, name); } else if(filename.substr(filename.size()-4) == ".stl") { std::cout << "Writing mesh as Stereolithography file (.stl)." << std::endl; this->write_stl(filename); diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index f92c3cf..463559b 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(unittest STATIC unittest.cpp) # set executables -SET(EXECUTABLES TestIsosurface TestScalarField TestD2OFileFormat) +SET(EXECUTABLES TestIsosurface TestScalarField TestD2OFileFormat TestFileCreation) # remove this test from the list as it takes too long if(NOT USE_GCOV) @@ -34,6 +34,7 @@ endif() add_executable(TestIsosurface test_isosurface.cpp) add_executable(TestScalarField test_scalarfield.cpp) add_executable(TestD2OFileFormat test_d2o_fileformat.cpp) +add_executable(TestFileCreation test_file_creation.cpp) # remove this test from the list as it takes too long if(NOT USE_GCOV) @@ -66,7 +67,8 @@ foreach(testexec ${EXECUTABLES}) ${LIBLZMA_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} - -lgcov) + -lgcov + -lcrypto) set_target_properties(${testexec} PROPERTIES COMPILE_FLAGS "--coverage") add_test(NAME ${testexec} COMMAND ${testexec}) set_tests_properties(${testexec} PROPERTIES FIXTURES_REQUIRED Dataset) diff --git a/src/test/test_file_creation.cpp b/src/test/test_file_creation.cpp new file mode 100644 index 0000000..af15639 --- /dev/null +++ b/src/test/test_file_creation.cpp @@ -0,0 +1,134 @@ +/************************************************************************** + * * + * Author: Ivo Filot * + * * + * DEN2OBJ is free software: * + * you can redistribute it and/or modify it under the terms of the * + * GNU General Public License as published by the Free Software * + * Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * DEN2OBJ is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see http://www.gnu.org/licenses/. * + * * + **************************************************************************/ + +#include "test_file_creation.h" + +CPPUNIT_TEST_SUITE_REGISTRATION( TestFileCreation ); + +void TestFileCreation::setUp() { +} + +void TestFileCreation::tearDown() { +} + +void TestFileCreation::test_ply_file() { + // set number of threads to 1 + omp_set_num_threads(1); + + // read scalar field + ScalarField sf("co_2pi_x.cub", ScalarFieldInputFileType::SFF_CUB); + sf.read(); + + // perform marching cubes algorithm + IsoSurface is(&sf); + is.marching_cubes(0.01); + + // construct mesh + IsoSurfaceMesh ism(&sf, &is); + ism.construct_mesh(true); + + // create file + ism.write_to_file("test.ply", "co molecule 2pi_x orbital test", "molecule"); + + // test md5sum + CPPUNIT_ASSERT_EQUAL(this->md5("test.ply"), std::string("ec143f6ebf9b72761803c3b091f54bf3")); +} + +void TestFileCreation::test_stl_file() { + // set number of threads to 1 + omp_set_num_threads(1); + + // read scalar field + ScalarField sf("co_2pi_x.cub", ScalarFieldInputFileType::SFF_CUB); + sf.read(); + + // perform marching cubes algorithm + IsoSurface is(&sf); + is.marching_cubes(0.01); + + // construct mesh + IsoSurfaceMesh ism(&sf, &is); + ism.construct_mesh(true); + + // create file + ism.write_to_file("test.stl", "co molecule 2pi_x orbital test", "molecule"); + + // test md5sum + CPPUNIT_ASSERT_EQUAL(this->md5("test.stl"), std::string("c2194ba639caf5092654862bb9f93298")); +} + +void TestFileCreation::test_obj_file() { + // set number of threads to 1 + omp_set_num_threads(1); + + // read scalar field + ScalarField sf("co_2pi_x.cub", ScalarFieldInputFileType::SFF_CUB); + sf.read(); + + // perform marching cubes algorithm + IsoSurface is(&sf); + is.marching_cubes(0.01); + + // construct mesh + IsoSurfaceMesh ism(&sf, &is); + ism.construct_mesh(true); + + // create file + ism.write_to_file("test.obj", "co molecule 2pi_x orbital test", "molecule"); + + // test md5sum + CPPUNIT_ASSERT_EQUAL(this->md5("test.obj"), std::string("e2b3e09f9c010dac99a7bc0137c187ec")); +} + +/** + * @brief Calculate MD5 checksum of a file + * + * @param[in] name Path to the file + * + * @return 32 byte string containing md5 checksum + */ +std::string TestFileCreation::md5(const std::string& filename) { + // read the file + std::ifstream mfile(filename, std::ios::binary | std::ios::ate); + std::streamsize size = mfile.tellg(); + mfile.seekg(0, std::ios::beg); + char buffer[size]; + mfile.read(buffer, size); + mfile.close(); + + // output variable for hash + unsigned char hash[MD5_DIGEST_LENGTH]; + + // calculate the md5 hash + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + EVP_MD_CTX_init(ctx); + const EVP_MD *md_type = EVP_md5(); + EVP_DigestInit_ex(ctx, md_type, NULL); + EVP_DigestUpdate(ctx, buffer, size); + EVP_DigestFinal_ex(ctx, hash, NULL); + EVP_MD_CTX_destroy(ctx); + + // output as a 32-byte hex-string + std::stringstream ss; + for(int i = 0; i < MD5_DIGEST_LENGTH; i++){ + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast( hash[i] ); + } + return ss.str(); +} \ No newline at end of file diff --git a/src/test/test_file_creation.h b/src/test/test_file_creation.h new file mode 100644 index 0000000..11c01ca --- /dev/null +++ b/src/test/test_file_creation.h @@ -0,0 +1,53 @@ +/************************************************************************** + * * + * Author: Ivo Filot * + * * + * DEN2OBJ is free software: * + * you can redistribute it and/or modify it under the terms of the * + * GNU General Public License as published by the Free Software * + * Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * DEN2OBJ is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see http://www.gnu.org/licenses/. * + * * + **************************************************************************/ + +#ifndef _TEST_FILE_CREATION +#define _TEST_FILE_CREATION + +#include + +// we need these for the MD5 checksums +#include +#include +#include + +#include "scalar_field.h" +#include "isosurface.h" +#include "isosurface_mesh.h" + +class TestFileCreation : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE( TestFileCreation ); + CPPUNIT_TEST( test_ply_file ); + CPPUNIT_TEST( test_stl_file ); + CPPUNIT_TEST( test_obj_file ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void test_ply_file(); + void test_stl_file(); + void test_obj_file(); + void tearDown(); + +private: + std::string md5(const std::string &str); +}; + +#endif \ No newline at end of file diff --git a/src/test/testinput/.gitignore b/src/test/testinput/.gitignore new file mode 100644 index 0000000..b64ee73 --- /dev/null +++ b/src/test/testinput/.gitignore @@ -0,0 +1,5 @@ +CHGCAR* +PARCHG* +LOCPOT* +*.d2o +*.cub