2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Tests for gmx::FileIOXdrSerializer.
39 * \author Mark Abraham <mark.j.abraham@gmail.com>
40 * \ingroup module_fileio
45 #include <gtest/gtest.h>
47 #include "gromacs/fileio/gmxfio.h"
48 #include "gromacs/fileio/gmxfio_xdr.h"
49 #include "gromacs/utility/futil.h"
51 #include "testutils/testfilemanager.h"
61 std::int32_t int32Value_;
67 std::int64_t int64Value_;
71 //! Constants used for testing endian swap operations
73 constexpr std::int16_t c_int16Value = static_cast<std::int16_t>(0x7A2B);
74 constexpr std::int32_t c_int32Value = static_cast<std::int32_t>(0x78ABCDEF);
75 constexpr std::int64_t c_int64Value = static_cast<std::int64_t>(0x78ABCDEF12345678);
77 constexpr const IntAndFloat32 c_intAndFloat32{ c_int32Value };
78 constexpr const IntAndFloat64 c_intAndFloat64{ c_int64Value };
81 //! Return the integer used for testing, depending on the size of int.
82 constexpr int integerSizeDependentTestingValue()
84 return sizeof(int) == 4 ? c_int32Value : sizeof(int) == 8 ? c_int64Value : c_int16Value;
87 class FileIOXdrSerializerTest : public ::testing::Test
90 ~FileIOXdrSerializerTest() override
97 struct SerializerValues
99 bool boolValue_ = true;
100 unsigned char unsignedCharValue_ = 0x78;
101 char charValue_ = 0x78;
102 unsigned short unsignedShortValue_ = static_cast<unsigned short>(c_int16Value);
103 std::int32_t int32Value_ = c_int32Value;
104 float floatValue_ = c_intAndFloat32.floatValue_;
105 std::int64_t int64Value_ = c_int64Value;
106 double doubleValue_ = c_intAndFloat64.doubleValue_;
107 int intValue_ = integerSizeDependentTestingValue();
108 real realValue_ = std::is_same_v<real, double>
109 ? static_cast<real>(c_intAndFloat64.doubleValue_)
110 : static_cast<real>(c_intAndFloat32.floatValue_);
113 TestFileManager fileManager_;
114 // Make sure the file extension is one that gmx_fio_open will
115 // recognize to open as binary, even though we're just abusing it
116 // to write arbitrary XDR output.
117 std::string filename_ = fileManager_.getTemporaryFilePath("data.edr");
118 t_fileio* file_ = nullptr;
121 TEST_F(FileIOXdrSerializerTest, SizeIsCorrect)
123 file_ = gmx_fio_open(filename_.c_str(), "w");
124 FileIOXdrSerializer serializer(file_);
125 // These types all have well-defined widths in bytes AFTER XDR serialization,
126 // which we can test below.
127 serializer.doBool(&defaultValues_.boolValue_); // 4 bytes
128 serializer.doChar(&defaultValues_.charValue_); // 4 bytes
129 serializer.doInt32(&defaultValues_.int32Value_); // 4 bytes
130 serializer.doInt64(&defaultValues_.int64Value_); // 8 bytes
131 serializer.doFloat(&defaultValues_.floatValue_); // 4 bytes
132 serializer.doDouble(&defaultValues_.doubleValue_); // 8 bytes
133 std::vector<char> charBuffer = { 'a', 'b', 'c' };
134 serializer.doCharArray(charBuffer.data(), charBuffer.size()); // 12 bytes
135 serializer.doOpaque(charBuffer.data(), charBuffer.size()); // 4 bytes
136 std::vector<int32_t> int32Buffer = { 0x1BCDEF78, 0x654321FE };
137 serializer.doInt32Array(int32Buffer.data(), int32Buffer.size()); // 8 bytes
138 std::vector<int64_t> int64Buffer = { 0x1BCDEF78654321FE, 0x3726ABFEAB34716C };
139 serializer.doInt64Array(int64Buffer.data(), int64Buffer.size()); // 16 bytes
140 gmx_fio_close(file_);
142 file_ = gmx_fio_open(filename_.c_str(), "r");
144 // Determine file size
145 gmx_fseek(gmx_fio_getfp(file_), 0, SEEK_END);
146 gmx_off_t fileSize = gmx_fio_ftell(file_);
147 EXPECT_EQ(fileSize, 72);