Reduced use of raw pointers.
[alexxy/gromacs.git] / src / gromacs / analysisdata / tests / analysisdata.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Tests for analysis data functionality.
34  *
35  * These tests check the functionality of gmx::AnalysisData, as well as classes
36  * used in its implementation: gmx::AbstractAnalysisData and
37  * gmx::AnalysisDataStorage.
38  * Most checking is done using gmx::test::AnalysisDataTestFixture and mock
39  * modules that implement gmx::AnalysisDataModuleInterface.
40  *
41  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
42  * \ingroup module_analysisdata
43  */
44 #include <memory>
45
46 #include <gmock/gmock.h>
47 #include <gtest/gtest.h>
48
49 #include "gromacs/analysisdata/analysisdata.h"
50 #include "gromacs/analysisdata/paralleloptions.h"
51 #include "gromacs/fatalerror/exceptions.h"
52
53 #include "datatest.h"
54 #include "mock_module.h"
55
56 using gmx::test::MockAnalysisModule;
57
58 namespace
59 {
60
61 /********************************************************************
62  * Tests for gmx::AnalysisData.
63  */
64
65 /*
66  * Tests that simple initialization works.
67  */
68 TEST(AnalysisDataInitializationTest, BasicInitialization)
69 {
70     gmx::AnalysisData data;
71     EXPECT_EQ(0, data.columnCount());
72     EXPECT_FALSE(data.isMultipoint());
73     EXPECT_EQ(0, data.frameCount());
74
75     data.setColumns(1);
76     EXPECT_EQ(1, data.columnCount());
77     EXPECT_FALSE(data.isMultipoint());
78
79     data.setColumns(3, true);
80     EXPECT_EQ(3, data.columnCount());
81     EXPECT_TRUE(data.isMultipoint());
82
83     data.setColumns(1);
84     EXPECT_EQ(1, data.columnCount());
85     EXPECT_FALSE(data.isMultipoint());
86 }
87
88 /*
89  * Tests that checking for compatibility of modules with multicolumn data
90  * works.
91  */
92 TEST(AnalysisDataInitializationTest, ChecksMultiColumnModules)
93 {
94     gmx::AnalysisData data;
95     data.setColumns(2);
96
97     std::auto_ptr<MockAnalysisModule> mod(new MockAnalysisModule(0));
98     EXPECT_THROW(data.addModule(mod.release()), gmx::APIError);
99
100     mod.reset(new MockAnalysisModule(gmx::AnalysisDataModuleInterface::efAllowMulticolumn));
101     EXPECT_NO_THROW(data.addModule(mod.release()));
102 }
103
104 /*
105  * Tests that checking for compatibility of modules with multipoint data
106  * works.
107  */
108 TEST(AnalysisDataInitializationTest, ChecksMultiPointModules)
109 {
110     gmx::AnalysisData data;
111     data.setColumns(1, true);
112
113     std::auto_ptr<MockAnalysisModule> mod(new MockAnalysisModule(0));
114     EXPECT_THROW(data.addModule(mod.release()), gmx::APIError);
115
116     mod.reset(new MockAnalysisModule(gmx::AnalysisDataModuleInterface::efAllowMultipoint));
117     EXPECT_NO_THROW(data.addModule(mod.release()));
118 }
119
120
121 typedef gmx::test::AnalysisDataTestFixture AnalysisDataTest;
122
123 // Input data for the tests below.
124 using gmx::test::END_OF_DATA;
125 using gmx::test::END_OF_FRAME;
126 using gmx::test::MPSTOP;
127 static const real inputdata[] = {
128     1.0,  0.0, 1.0, 2.0, END_OF_FRAME,
129     2.0,  1.0, 1.0, 1.0, END_OF_FRAME,
130     3.0,  2.0, 0.0, 0.0, END_OF_FRAME,
131     END_OF_DATA
132 };
133
134 /*
135  * Tests that data is forwarded correctly to modules using two independent
136  * modules.
137  */
138 TEST_F(AnalysisDataTest, CallsModuleCorrectly)
139 {
140     gmx::test::AnalysisDataTestInput input(inputdata);
141     gmx::AnalysisData data;
142     data.setColumns(input.columnCount());
143
144     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
145     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
146     ASSERT_NO_THROW(presentAllData(input, &data));
147 }
148
149 /*
150  * Tests that data is forwarded correctly to modules that are added using
151  * addColumnModule().
152  * Uses two independent modules.
153  */
154 TEST_F(AnalysisDataTest, CallsColumnModuleCorrectly)
155 {
156     gmx::test::AnalysisDataTestInput input(inputdata);
157     gmx::AnalysisData data;
158     data.setColumns(input.columnCount());
159
160     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 0, 2, &data));
161     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 2, 1, &data));
162     ASSERT_NO_THROW(presentAllData(input, &data));
163 }
164
165 /*
166  * Tests that data is forwarded correctly (in frame order) to modules when the
167  * data is added through multiple handles in non-increasing order.
168  */
169 TEST_F(AnalysisDataTest, CallsModuleCorrectlyWithOutOfOrderFrames)
170 {
171     gmx::test::AnalysisDataTestInput input(inputdata);
172     gmx::AnalysisData data;
173     data.setColumns(input.columnCount());
174
175     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
176     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 1, 2, &data));
177     gmx::AnalysisDataHandle handle1;
178     gmx::AnalysisDataHandle handle2;
179     gmx::AnalysisDataParallelOptions options(2);
180     ASSERT_NO_THROW(handle1 = data.startData(options));
181     ASSERT_NO_THROW(handle2 = data.startData(options));
182     ASSERT_NO_THROW(presentDataFrame(input, 1, handle1));
183     ASSERT_NO_THROW(presentDataFrame(input, 0, handle2));
184     ASSERT_NO_THROW(presentDataFrame(input, 2, handle1));
185     ASSERT_NO_THROW(handle1.finishData());
186     ASSERT_NO_THROW(handle2.finishData());
187 }
188
189 /*
190  * Tests that data can be accessed correctly from a module that requests
191  * storage using AbstractAnalysisData::requestStorage() with parameter -1.
192  */
193 TEST_F(AnalysisDataTest, FullStorageWorks)
194 {
195     gmx::test::AnalysisDataTestInput input(inputdata);
196     gmx::AnalysisData data;
197     data.setColumns(input.columnCount());
198
199     ASSERT_NO_THROW(addStaticStorageCheckerModule(input, -1, &data));
200     ASSERT_NO_THROW(presentAllData(input, &data));
201 }
202
203 /*
204  * Tests that a data module can be added to an AnalysisData object after data
205  * has been added if all data is still available in storage.
206  */
207 TEST_F(AnalysisDataTest, CanAddModuleAfterStoredData)
208 {
209     gmx::test::AnalysisDataTestInput input(inputdata);
210     gmx::AnalysisData data;
211     data.setColumns(input.columnCount());
212     ASSERT_TRUE(data.requestStorage(-1));
213
214     ASSERT_NO_THROW(presentAllData(input, &data));
215     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
216 }
217
218 /*
219  * Tests that data can be accessed correctly from a module that requests
220  * storage using AbstractAnalysisData::requestStorage() only for one frame.
221  */
222 TEST_F(AnalysisDataTest, LimitedStorageWorks)
223 {
224     gmx::test::AnalysisDataTestInput input(inputdata);
225     gmx::AnalysisData data;
226     data.setColumns(input.columnCount());
227
228     ASSERT_NO_THROW(addStaticStorageCheckerModule(input, 1, &data));
229     ASSERT_NO_THROW(presentAllData(input, &data));
230 }
231
232 // Input data for the tests below.
233 static const real multipointinputdata[] = {
234     1.0,  0.0, 1.0, 2.0, MPSTOP, 1.1, 2.1, 1.1, MPSTOP, 2.2, 1.2, 0.2, END_OF_FRAME,
235     2.0,  1.0, 1.0, 1.0, MPSTOP, 2.1, 1.1, 0.1, MPSTOP, 1.2, 0.2, 1.2, END_OF_FRAME,
236     3.0,  2.0, 0.0, 0.0, MPSTOP, 3.1, 2.1, 1.1, MPSTOP, 0.2, 2.2, 1.2, END_OF_FRAME,
237     END_OF_DATA
238 };
239
240 /*
241  * Tests that multipoint data is forwarded correctly to modules using two
242  * independent modules.
243  */
244 TEST_F(AnalysisDataTest, MultipointCallsModuleCorrectly)
245 {
246     gmx::test::AnalysisDataTestInput input(multipointinputdata);
247     gmx::AnalysisData data;
248     data.setColumns(input.columnCount(), true);
249
250     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
251     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
252     ASSERT_NO_THROW(presentAllData(input, &data));
253 }
254
255 /*
256  * Tests that multipoint data is forwarded correctly to modules that are added
257  * using addColumnModule().
258  * Uses two independent modules.
259  */
260 TEST_F(AnalysisDataTest, MultipointCallsColumnModuleCorrectly)
261 {
262     gmx::test::AnalysisDataTestInput input(multipointinputdata);
263     gmx::AnalysisData data;
264     data.setColumns(input.columnCount(), true);
265
266     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 0, 2, &data));
267     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 2, 1, &data));
268     ASSERT_NO_THROW(presentAllData(input, &data));
269 }
270
271 } // namespace