1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.potential.groovy;
39
40 import static java.lang.String.format;
41 import static org.apache.commons.io.FileUtils.copyFile;
42 import static org.junit.Assert.assertEquals;
43 import static org.junit.Assert.assertTrue;
44 import static org.junit.Assert.fail;
45
46 import ffx.potential.utils.PotentialTest;
47 import ffx.utilities.DirectoryUtils;
48 import java.io.BufferedReader;
49 import java.io.File;
50 import java.io.FileReader;
51 import java.io.IOException;
52 import java.nio.file.Files;
53 import java.util.ArrayList;
54 import java.util.Arrays;
55 import java.util.Collection;
56 import java.util.Collections;
57 import java.util.HashMap;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.logging.Level;
61 import java.util.regex.Pattern;
62 import java.util.stream.Collectors;
63 import org.apache.commons.configuration2.Configuration;
64 import org.apache.commons.configuration2.MapConfiguration;
65 import org.apache.commons.io.FilenameUtils;
66 import org.apache.commons.io.IOUtils;
67 import org.junit.After;
68 import org.junit.Test;
69 import org.junit.runner.RunWith;
70 import org.junit.runners.Parameterized;
71
72 @RunWith(Parameterized.class)
73 public class SolvatorTest extends PotentialTest {
74
75
76
77
78
79 private static final Map<String, String> DEFAULT_OPTIONS;
80
81 static {
82 String[] opts = {
83 "-b", "2.5",
84 "-p", "7.0",
85 };
86
87 int nOpts = opts.length;
88 Map<String, String> optMap = new HashMap<>(nOpts);
89 for (int i = 0; i < nOpts; i += 2) {
90 optMap.put(opts[i], opts[i + 1]);
91 }
92 DEFAULT_OPTIONS = Collections.unmodifiableMap(optMap);
93 }
94
95 private final String info;
96 private final SolvatorTestMode mode;
97 private final File solvatedTestFile;
98 private final Map<String, String> opts;
99
100
101
102 private final Configuration algorithmConfig;
103
104 private final List<String> flags;
105 private final File tempDir;
106 private final List<File> copiedFiles = new ArrayList<>();
107 Solvator solvator;
108
109 public SolvatorTest(
110 String info,
111 SolvatorTestMode mode,
112 String soluteFile,
113 String solvatedTestFileName,
114 String solventFileName,
115 String ionFileName,
116 String[] options,
117 String[] properties,
118 String[] flagArray)
119 throws IOException {
120 this.info = info;
121 this.mode = mode;
122 this.solvatedTestFile = getResourceFile(solvatedTestFileName);
123 if (mode == SolvatorTestMode.HELP) {
124 opts = Collections.emptyMap();
125 algorithmConfig = null;
126 flags = Collections.emptyList();
127 tempDir = null;
128 } else {
129 File temp = null;
130 try {
131 temp = Files.createTempDirectory("Solvator").toFile();
132 } catch (IOException e) {
133 fail(" Could not create a temporary directory.");
134 }
135 tempDir = temp;
136 logger.fine(format(" Running test %s in directory %s", info, tempDir));
137 String[] copiedExtensions = new String[] {"key", "properties", "ions"};
138 String[] filesUsed;
139 if (ionFileName == null) {
140 filesUsed = new String[] {soluteFile, solventFileName};
141 } else {
142 filesUsed = new String[] {soluteFile, solventFileName, ionFileName};
143 }
144 for (String fname : filesUsed) {
145 File srcFile = getResourceFile(fname);
146 File tempFile = new File(tempDir.getAbsolutePath() + "/" + FilenameUtils.getName(fname));
147
148 copyFile(srcFile, tempFile);
149 copiedFiles.add(tempFile);
150 logger.info(format(" Copied file %s to %s", srcFile, tempFile));
151
152 for (String ext : copiedExtensions) {
153 srcFile = new File(format("%s.%s", FilenameUtils.removeExtension(srcFile.getPath()), ext));
154 if (srcFile.exists()) {
155 logger.fine(" Copying extension " + ext);
156 tempFile = new File(format("%s.%s", FilenameUtils.removeExtension(tempFile.getPath()), ext));
157 logger.fine(format(" Copied file %s to %s", srcFile, tempFile));
158 copyFile(srcFile, tempFile);
159 }
160 }
161 }
162
163 int nOpts = options.length;
164 int nProps = properties.length;
165 int nFlags = flagArray.length;
166
167 if (nOpts > 0) {
168 assertEquals(format("Unmatched option key %s for test %s", options[nOpts - 1], info),
169 0, options.length % 2);
170 }
171 if (nProps > 0) {
172 assertEquals(format("Unmatched property key %s for test %s", properties[nProps - 1], info),
173 0, properties.length % 2);
174 }
175
176 Pattern validOption = Pattern.compile("^--?[^D]");
177 Pattern validProperty = Pattern.compile("^[^-]");
178
179 Map<String, String> groovyOpts = new HashMap<>(DEFAULT_OPTIONS);
180 for (int i = 0; i < nOpts; i += 2) {
181 String opti = options[i];
182 assertTrue(
183 format(" Option %s for test %s does not look like a Groovy option!", opti, info),
184 validOption.matcher(opti).find());
185 groovyOpts.put(opti, options[i + 1]);
186 }
187 groovyOpts.put("--sFi", copiedFiles.get(1).getPath());
188 if (ionFileName != null) {
189 groovyOpts.put("--iFi", copiedFiles.get(2).getPath());
190 }
191 this.opts = Collections.unmodifiableMap(groovyOpts);
192
193 Map<String, String> addedProps = new HashMap<>();
194 for (int i = 0; i < nProps; i += 2) {
195 String propi = properties[i];
196 assertTrue(
197 format(" Property %s for test %s does not look like a property!", propi, info),
198 validProperty.matcher(propi).find());
199 addedProps.put(propi, properties[i + 1]);
200 }
201 algorithmConfig = new MapConfiguration(addedProps);
202
203 Map<String, Boolean> addedFlags = new HashMap<>();
204 for (int i = 0; i < nFlags; i += 2) {
205 String flagi = flagArray[i];
206 assertTrue(
207 format(" Flag %s for test %s does not look like a flag!", flagi, info),
208 validOption.matcher(flagi).find());
209 String vali = flagArray[i + 1];
210 assertTrue(
211 format(
212 " Value %s for flag %s in test %s is not a true/false value!", vali, flagi, info),
213 vali.equalsIgnoreCase("TRUE") || vali.equalsIgnoreCase("FALSE"));
214 addedFlags.put(flagi, Boolean.parseBoolean(vali));
215 }
216 this.flags =
217 Collections.unmodifiableList(
218 addedFlags.entrySet().stream()
219 .filter(Map.Entry::getValue)
220 .map(Map.Entry::getKey)
221 .collect(Collectors.toList()));
222 }
223 }
224
225 @Parameterized.Parameters
226 public static Collection<Object[]> data() {
227 return Arrays.asList(
228 new Object[][] {
229 {
230 "Solvator Help Message Test",
231 SolvatorTestMode.HELP,
232 "",
233 null,
234 null,
235 null,
236 new String[] {},
237 new String[] {},
238 new String[] {"-h"}
239 },
240 {
241 "Aspartate Pure Water Solvation",
242 SolvatorTestMode.SOLVATE,
243 "capAsp.xyz",
244 "capAsp.pureWater.pdb",
245 "watertiny.xyz",
246 null,
247 new String[] {"-b", "2.5", "-p", "8.0", "-s", "42"},
248 new String[] {},
249 new String[] {}
250 },
251 {
252 "Aspartate Neutralizing NaCl (+200 mM) Solvation",
253 SolvatorTestMode.SOLVATE,
254 "capAsp.xyz",
255 "capAsp.neutNaCl.pdb",
256 "watertiny.xyz",
257 "nacl.pdb",
258 new String[] {"-b", "2.5", "-p", "8.0", "-s", "42"},
259 new String[] {},
260 new String[] {}
261 },
262 {
263 "Aspartate Charged NaCl (200 mM) Solvation",
264 SolvatorTestMode.SOLVATE,
265 "capAsp.xyz",
266 "capAsp.chargedNaCl.pdb",
267 "watertiny.xyz",
268 "naclCharged.pdb",
269 new String[] {"-b", "2.5", "-p", "8.0", "-s", "42"},
270 new String[] {},
271 new String[] {}
272 }
273 });
274 }
275
276 @After
277 public void after() {
278 if (mode != SolvatorTestMode.HELP) {
279
280
281 try {
282 DirectoryUtils.deleteDirectoryTree(tempDir.toPath());
283 } catch (IOException e) {
284 System.out.println(e);
285 fail(" Exception deleting files created by Cart2Frac.");
286 }
287 }
288 }
289
290 @Test
291 public void testSolvator() {
292 switch (mode) {
293 case HELP:
294 testHelp();
295 break;
296 case SOLVATE:
297 testSolvate();
298 break;
299 }
300 }
301
302 @Override
303 public String toString() {
304 return info;
305 }
306
307 private void testHelp() {
308 String[] args = {"-h"};
309 binding.setVariable("args", args);
310 solvator = new Solvator(binding).run();
311 potentialScript = solvator;
312 }
313
314 private void testSolvate() {
315
316 List<String> argList = new ArrayList<>(flags);
317 opts.forEach(
318 (String k, String v) -> {
319 argList.add(k);
320 argList.add(v);
321 });
322 argList.add(copiedFiles.get(0).getPath());
323 String[] args = argList.toArray(new String[0]);
324 binding.setVariable("args", args);
325 solvator = new Solvator(binding);
326 solvator.setProperties(algorithmConfig);
327
328 solvator.run();
329 potentialScript = solvator;
330
331 File written = solvator.getWrittenFile();
332
333 logger.log(Level.INFO, " Written file {0}", written.getAbsolutePath());
334 logger.log(Level.INFO, " Expected file {0}", solvatedTestFile.getAbsolutePath());
335
336 try (BufferedReader expectedReader = new BufferedReader(new FileReader(solvatedTestFile));
337 BufferedReader writtenReader = new BufferedReader(new FileReader(written))) {
338 boolean same = IOUtils.contentEqualsIgnoreEOL(expectedReader, writtenReader);
339 assertTrue(" File written by test did not match the expected file!", same);
340 } catch (IOException ex) {
341 fail(format(" Exception %s in attempting to compare expected file %s to written file %s",
342 ex, solvatedTestFile, written));
343 }
344 }
345
346 private enum SolvatorTestMode {
347 HELP,
348 SOLVATE
349 }
350 }