Merge branch 'release-4-6', adds the nbnxn functionality
[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 <gmock/gmock.h>
45 #include <gtest/gtest.h>
46
47 #include "gromacs/analysisdata/analysisdata.h"
48 #include "gromacs/analysisdata/paralleloptions.h"
49 #include "gromacs/utility/exceptions.h"
50
51 #include "testutils/datatest.h"
52 #include "testutils/mock_datamodule.h"
53
54 using gmx::test::MockAnalysisDataModule;
55 using gmx::test::MockAnalysisDataModulePointer;
56
57 namespace
58 {
59
60 /********************************************************************
61  * Tests for gmx::AnalysisData.
62  */
63
64 /*
65  * Tests that simple initialization works.
66  */
67 TEST(AnalysisDataInitializationTest, BasicInitialization)
68 {
69     gmx::AnalysisData data;
70     EXPECT_EQ(0, data.columnCount());
71     EXPECT_FALSE(data.isMultipoint());
72     EXPECT_EQ(0, data.frameCount());
73
74     data.setColumnCount(1);
75     EXPECT_EQ(1, data.columnCount());
76     EXPECT_FALSE(data.isMultipoint());
77
78     data.setColumnCount(3);
79     data.setMultipoint(true);
80     EXPECT_EQ(3, data.columnCount());
81     EXPECT_TRUE(data.isMultipoint());
82
83     data.setColumnCount(1);
84     EXPECT_EQ(1, data.columnCount());
85     EXPECT_TRUE(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.setColumnCount(2);
96
97     MockAnalysisDataModulePointer mod1(new MockAnalysisDataModule(0));
98     EXPECT_THROW(data.addModule(mod1), gmx::APIError);
99
100     MockAnalysisDataModulePointer mod2(
101             new MockAnalysisDataModule(gmx::AnalysisDataModuleInterface::efAllowMulticolumn));
102     EXPECT_NO_THROW(data.addModule(mod2));
103 }
104
105 /*
106  * Tests that checking for compatibility of modules with multipoint data
107  * works.
108  */
109 TEST(AnalysisDataInitializationTest, ChecksMultiPointModules)
110 {
111     gmx::AnalysisData data;
112     data.setColumnCount(1);
113     data.setMultipoint(true);
114
115     MockAnalysisDataModulePointer mod1(new MockAnalysisDataModule(0));
116     EXPECT_THROW(data.addModule(mod1), gmx::APIError);
117
118     MockAnalysisDataModulePointer mod2(
119             new MockAnalysisDataModule(gmx::AnalysisDataModuleInterface::efAllowMultipoint));
120     EXPECT_NO_THROW(data.addModule(mod2));
121 }
122
123
124 //! Test fixture for gmx::AnalysisData.
125 typedef gmx::test::AnalysisDataTestFixture AnalysisDataTest;
126
127 using gmx::test::END_OF_FRAME;
128 using gmx::test::MPSTOP;
129 //! Input data for gmx::AnalysisData tests.
130 const real inputdata[] = {
131     1.0,  0.0, 1.0, 2.0, END_OF_FRAME,
132     2.0,  1.0, 1.0, 1.0, END_OF_FRAME,
133     3.0,  2.0, 0.0, 0.0, END_OF_FRAME
134 };
135
136 /*
137  * Tests that data is forwarded correctly to modules using two independent
138  * modules.
139  */
140 TEST_F(AnalysisDataTest, CallsModuleCorrectly)
141 {
142     gmx::test::AnalysisDataTestInput input(inputdata);
143     gmx::AnalysisData data;
144     data.setColumnCount(input.columnCount());
145
146     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
147     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
148     ASSERT_NO_THROW(presentAllData(input, &data));
149 }
150
151 /*
152  * Tests that data is forwarded correctly to modules that are added using
153  * addColumnModule().
154  * Uses two independent modules.
155  */
156 TEST_F(AnalysisDataTest, CallsColumnModuleCorrectly)
157 {
158     gmx::test::AnalysisDataTestInput input(inputdata);
159     gmx::AnalysisData data;
160     data.setColumnCount(input.columnCount());
161
162     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 0, 2, &data));
163     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 2, 1, &data));
164     ASSERT_NO_THROW(presentAllData(input, &data));
165 }
166
167 /*
168  * Tests that data is forwarded correctly (in frame order) to modules when the
169  * data is added through multiple handles in non-increasing order.
170  */
171 TEST_F(AnalysisDataTest, CallsModuleCorrectlyWithOutOfOrderFrames)
172 {
173     gmx::test::AnalysisDataTestInput input(inputdata);
174     gmx::AnalysisData data;
175     data.setColumnCount(input.columnCount());
176
177     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
178     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 1, 2, &data));
179     gmx::AnalysisDataHandle handle1;
180     gmx::AnalysisDataHandle handle2;
181     gmx::AnalysisDataParallelOptions options(2);
182     ASSERT_NO_THROW(handle1 = data.startData(options));
183     ASSERT_NO_THROW(handle2 = data.startData(options));
184     ASSERT_NO_THROW(presentDataFrame(input, 1, handle1));
185     ASSERT_NO_THROW(presentDataFrame(input, 0, handle2));
186     ASSERT_NO_THROW(presentDataFrame(input, 2, handle1));
187     ASSERT_NO_THROW(handle1.finishData());
188     ASSERT_NO_THROW(handle2.finishData());
189 }
190
191 /*
192  * Tests that data can be accessed correctly from a module that requests
193  * storage using AbstractAnalysisData::requestStorage() with parameter -1.
194  */
195 TEST_F(AnalysisDataTest, FullStorageWorks)
196 {
197     gmx::test::AnalysisDataTestInput input(inputdata);
198     gmx::AnalysisData data;
199     data.setColumnCount(input.columnCount());
200
201     ASSERT_NO_THROW(addStaticStorageCheckerModule(input, -1, &data));
202     ASSERT_NO_THROW(presentAllData(input, &data));
203 }
204
205 /*
206  * Tests that a data module can be added to an AnalysisData object after data
207  * has been added if all data is still available in storage.
208  */
209 TEST_F(AnalysisDataTest, CanAddModuleAfterStoredData)
210 {
211     gmx::test::AnalysisDataTestInput input(inputdata);
212     gmx::AnalysisData data;
213     data.setColumnCount(input.columnCount());
214     ASSERT_TRUE(data.requestStorage(-1));
215
216     ASSERT_NO_THROW(presentAllData(input, &data));
217     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
218 }
219
220 /*
221  * Tests that data can be accessed correctly from a module that requests
222  * storage using AbstractAnalysisData::requestStorage() only for one frame.
223  */
224 TEST_F(AnalysisDataTest, LimitedStorageWorks)
225 {
226     gmx::test::AnalysisDataTestInput input(inputdata);
227     gmx::AnalysisData data;
228     data.setColumnCount(input.columnCount());
229
230     ASSERT_NO_THROW(addStaticStorageCheckerModule(input, 1, &data));
231     ASSERT_NO_THROW(presentAllData(input, &data));
232 }
233
234 //! Input data for multipoint gmx::AnalysisData tests.
235 const real multipointinputdata[] = {
236     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,
237     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,
238     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
239 };
240
241 /*
242  * Tests that multipoint data is forwarded correctly to modules using two
243  * independent modules.
244  */
245 TEST_F(AnalysisDataTest, MultipointCallsModuleCorrectly)
246 {
247     gmx::test::AnalysisDataTestInput input(multipointinputdata);
248     gmx::AnalysisData data;
249     data.setColumnCount(input.columnCount());
250     data.setMultipoint(true);
251
252     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
253     ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
254     ASSERT_NO_THROW(presentAllData(input, &data));
255 }
256
257 /*
258  * Tests that multipoint data is forwarded correctly to modules that are added
259  * using addColumnModule().
260  * Uses two independent modules.
261  */
262 TEST_F(AnalysisDataTest, MultipointCallsColumnModuleCorrectly)
263 {
264     gmx::test::AnalysisDataTestInput input(multipointinputdata);
265     gmx::AnalysisData data;
266     data.setColumnCount(input.columnCount());
267     data.setMultipoint(true);
268
269     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 0, 2, &data));
270     ASSERT_NO_THROW(addStaticColumnCheckerModule(input, 2, 1, &data));
271     ASSERT_NO_THROW(presentAllData(input, &data));
272 }
273
274 } // namespace