2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
24 import java.io.IOException;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.Enumeration;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.TreeMap;
35 import org.testng.Assert;
36 import org.testng.annotations.AfterClass;
37 import org.testng.annotations.BeforeClass;
38 import org.testng.annotations.Test;
40 import jalview.bin.Cache;
41 import jalview.datamodel.AlignmentI;
42 import jalview.datamodel.Sequence;
43 import jalview.datamodel.SequenceI;
44 import jalview.gui.AlignFrame;
45 import jalview.gui.JvOptionPane;
47 public class BackupFilesTest
49 @BeforeClass(alwaysRun = true)
50 public void setUpJvOptionPane()
52 JvOptionPane.setInteractiveMode(false);
53 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
56 private static boolean actuallyDeleteTmpFiles = true;
58 private static String testDir = "test/jalview/io";
60 private static String testBasename = "backupfilestest";
62 private static String testExt = ".fa";
64 private static String testFilename = testBasename + testExt;
66 private static String testFile = testDir + File.separatorChar
69 private static String newBasename = testBasename + "Temp";
71 private static String newFilename = newBasename + testExt;
73 private static String newFile = testDir + File.separatorChar
76 private static String sequenceName = "BACKUP_FILES";
78 private static String sequenceDescription = "backupfiles";
80 private static String sequenceData = "AAAARG";
82 private static String suffix = "_BACKUPTEST-%n";
84 private static int digits = 6;
86 private static int rollMax = 2;
88 private AlignFrame af;
90 // read and save with backupfiles disabled
91 @Test(groups = { "Functional" })
92 public void noBackupsEnabledTest() throws Exception
94 // set BACKUPFILES_ENABLED to false (i.e. turn off BackupFiles feature -- no
95 // backup files to be made when saving)
96 setBackupFilesOptions(false, true, true);
98 // init the newFile and backups (i.e. make sure newFile exists on its own
100 initNewFileForTesting();
105 // check no backup files
106 File[] backupFiles = getBackupFiles();
107 Assert.assertEquals(backupFiles.length, 0, "Number of backup files is "
108 + backupFiles.length + ", not " + 0);
111 // save with no numbers in the backup file names
112 @Test(groups = { "Functional" })
113 public void backupsEnabledSingleFileBackupTest() throws Exception
115 // Enable BackupFiles and set noMax so all backupfiles get kept
116 String mysuffix = "~";
117 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(mysuffix, 1,
118 false, true, 1, false);
119 setBackupFilesOptions(true, false, true,
120 "test/jalview/io/testProps_singlefilebackup.jvprops", bfpe);
122 // init the newFile and backups (i.e. make sure newFile exists on its own
123 // and has no backups)
124 initNewFileForTesting();
125 HashMap<Integer, String> correctindexmap = new HashMap<>();
126 correctindexmap.put(0, "backupfilestestTemp.fa~");
129 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
131 // and a second time -- see JAL-3628
133 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
135 cleanupTmpFiles(newFile, "~", 1);
138 // save keeping all backup files
139 @Test(groups = { "Functional" })
140 public void backupsEnabledNoRollMaxTest() throws Exception
142 // Enable BackupFiles and set noMax so all backupfiles get kept
143 setBackupFilesOptions(true, false, true);
145 // init the newFile and backups (i.e. make sure newFile exists on its own
146 // and has no backups)
147 initNewFileForTesting();
149 // now save a few times again. No rollMax so should have more than two
152 for (int i = 0; i < numSaves; i++)
157 // check 10 backup files
158 HashMap<Integer, String> correctindexmap = new HashMap<>();
159 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
160 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
161 correctindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
162 correctindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
163 correctindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
164 correctindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
165 correctindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
166 correctindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
167 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
168 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
169 HashMap<Integer, String> wrongindexmap = new HashMap<>();
170 wrongindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-1");
171 wrongindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
172 wrongindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
173 wrongindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
174 wrongindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
175 wrongindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
176 wrongindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
177 wrongindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
178 wrongindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
179 wrongindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
180 int[] indexes2 = { 3, 4, 5, 6, 7, 8, 9, 10 };
181 int[] indexes3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
182 Assert.assertTrue(checkBackupFiles(correctindexmap));
183 Assert.assertFalse(checkBackupFiles(wrongindexmap));
184 Assert.assertFalse(checkBackupFiles(indexes2));
185 Assert.assertFalse(checkBackupFiles(indexes3));
188 // save keeping only the last rollMax (2) backup files
189 @Test(groups = { "Functional" })
190 public void backupsEnabledRollMaxTest() throws Exception
192 // Enable BackupFiles and set noMax so all backupfiles get kept
193 setBackupFilesOptions(true, false, false);
195 // init the newFile and backups (i.e. make sure newFile exists on its own
196 // and has no backups)
197 initNewFileForTesting();
199 // now save a few times again. No rollMax so should have more than two
202 for (int i = 0; i < numSaves; i++)
207 // check there are "rollMax" backup files and they are all saved correctly
208 // check 10 backup files
209 HashMap<Integer, String> correctindexmap = new HashMap<>();
210 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
211 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
212 int[] indexes2 = { 10 };
213 int[] indexes3 = { 8, 9, 10 };
214 Assert.assertTrue(checkBackupFiles(correctindexmap));
215 Assert.assertFalse(checkBackupFiles(indexes2));
216 Assert.assertFalse(checkBackupFiles(indexes3));
219 // save keeping only the last rollMax (2) backup files
220 @Test(groups = { "Functional" })
221 public void backupsEnabledReverseRollMaxTest() throws Exception
223 // Enable BackupFiles and set noMax so all backupfiles get kept
224 setBackupFilesOptions(true, true, false);
226 // init the newFile and backups (i.e. make sure newFile exists on its own
227 // and has no backups)
228 initNewFileForTesting();
230 // now save a few times again. No rollMax so should have more than two
233 for (int i = 0; i < numSaves; i++)
238 // check there are "rollMax" backup files and they are all saved correctly
239 // check 10 backup files
240 HashMap<Integer, String> correctindexmap = new HashMap<>();
241 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
242 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
243 int[] indexes2 = { 1 };
244 int[] indexes3 = { 1, 2, 3 };
245 Assert.assertTrue(checkBackupFiles(correctindexmap));
246 Assert.assertFalse(checkBackupFiles(indexes2));
247 Assert.assertFalse(checkBackupFiles(indexes3));
250 private void setBackupFilesOptions()
252 setBackupFilesOptions(true, false, false);
255 private void setBackupFilesOptions(boolean enabled, boolean reverse,
258 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
259 reverse, noMax, rollMax, false);
260 setBackupFilesOptions(enabled, reverse, noMax,
261 "test/jalview/io/testProps.jvprops", bfpe);
264 private void setBackupFilesOptions(boolean enabled, boolean reverse,
265 boolean noMax, String propsFile, BackupFilesPresetEntry bfpe)
267 Cache.loadProperties(propsFile);
269 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
270 Boolean.toString(enabled));
271 Cache.applicationProperties.setProperty(
272 BackupFilesPresetEntry.SAVEDCONFIG, bfpe.toString());
274 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
275 Boolean.toString(enabled));
276 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, suffix);
277 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS,
278 Integer.toString(digits));
279 Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER,
280 Boolean.toString(reverse));
281 Cache.applicationProperties.setProperty(BackupFiles.NO_MAX,
282 Boolean.toString(noMax));
283 Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX,
284 Integer.toString(rollMax));
285 Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD,
294 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
298 // this runs cleanTmpFiles and then writes the newFile once as a starting
299 // point for all tests
300 private void initNewFileForTesting() throws Exception
304 AppletFormatAdapter afa = new AppletFormatAdapter();
305 AlignmentI al = afa.readFile(testFile, DataSourceType.FILE,
306 jalview.io.FileFormat.Fasta);
307 List<SequenceI> l = al.getSequences();
309 // check this is right
312 throw new Exception("single sequence from '" + testFile
313 + "' not read in correctly (should be a single short sequence). List<SequenceI> size is wrong.");
315 SequenceI s = l.get(0);
316 Sequence ref = new Sequence(sequenceName, sequenceData);
317 ref.setDescription(sequenceDescription);
318 if (!sequencesEqual(s, ref))
320 throw new Exception("single sequence from '" + testFile
321 + "' not read in correctly (should be a single short sequence). SequenceI name, description or data is wrong.");
323 // save alignment file to new filename -- this doesn't test backups disabled
324 // yet as this file shouldn't already exist
325 af = new AlignFrame(al, 0, 0);
326 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
329 // this deletes the newFile (if it exists) and any saved backup file for it
330 @AfterClass(alwaysRun = true)
331 private void cleanupTmpFiles()
333 cleanupTmpFiles(newFile, suffix, digits);
336 protected static void cleanupTmpFiles(String file, String mysuffix,
339 File newfile = new File(file);
340 if (newfile.exists())
344 File[] tmpFiles = getBackupFiles(file, mysuffix, mydigits);
345 for (int i = 0; i < tmpFiles.length; i++)
347 if (actuallyDeleteTmpFiles)
349 tmpFiles[i].delete();
353 System.out.println("Pretending to delete " + tmpFiles[i].getPath());
358 private static File[] getBackupFiles(String f, String s, int i)
360 TreeMap<Integer, File> bfTreeMap = BackupFiles
361 .getBackupFilesAsTreeMap(f, s, i);
362 File[] backupFiles = new File[bfTreeMap.size()];
363 bfTreeMap.values().toArray(backupFiles);
367 private static File[] getBackupFiles()
369 return getBackupFiles(newFile, suffix, digits);
372 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap)
375 return checkBackupFiles(indexmap, newFile, suffix, digits);
378 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap,
379 String file, String mysuffix, int mydigits) throws IOException
381 TreeMap<Integer, File> map = BackupFiles.getBackupFilesAsTreeMap(file,
383 Enumeration<Integer> indexesenum = Collections
384 .enumeration(indexmap.keySet());
385 while (indexesenum.hasMoreElements())
387 int i = indexesenum.nextElement();
388 String indexfilename = indexmap.get(i);
389 if (!map.containsKey(i))
394 if (!filesContentEqual(newFile, f.getPath()))
403 if (!f.getName().equals(indexfilename))
408 // should be nothing left in map
417 private static boolean checkBackupFiles(int[] indexes) throws IOException
419 TreeMap<Integer, File> map = BackupFiles
420 .getBackupFilesAsTreeMap(newFile, suffix, digits);
421 for (int m = 0; m < indexes.length; m++)
424 if (!map.containsKey(i))
429 if (!filesContentEqual(newFile, f.getPath()))
438 // check the filename -- although this uses the same code to forumulate
439 // the filename so not much of a test!
440 String filename = BackupFilenameParts.getBackupFilename(i,
441 newBasename + testExt, suffix, digits);
442 if (!filename.equals(f.getName()))
444 System.out.println("Supposed filename '" + filename
445 + "' not equal to actual filename '" + f.getName() + "'");
449 // should be nothing left in map
458 private static String[] getBackupFilesAsStrings()
460 File[] files = getBackupFiles(newFile, suffix, digits);
461 String[] filenames = new String[files.length];
462 for (int i = 0; i < files.length; i++)
464 filenames[i] = files[i].getPath();
469 public static boolean sequencesEqual(SequenceI s1, SequenceI s2)
471 if (s1 == null && s2 == null)
475 else if (s1 == null || s2 == null)
479 return (s1.getName().equals(s2.getName())
480 && s1.getDescription().equals(s2.getDescription())
481 && Arrays.equals(s1.getSequence(), s2.getSequence()));
484 public static boolean filesContentEqual(String fileName1,
485 String fileName2) throws IOException
487 Path file1 = Paths.get(fileName1);
488 Path file2 = Paths.get(fileName2);
489 byte[] bytes1 = Files.readAllBytes(file1);
490 byte[] bytes2 = Files.readAllBytes(file2);
491 return Arrays.equals(bytes1, bytes2);