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.AfterTest;
38 import org.testng.annotations.BeforeClass;
39 import org.testng.annotations.Test;
41 import jalview.bin.Cache;
42 import jalview.datamodel.AlignmentI;
43 import jalview.datamodel.Sequence;
44 import jalview.datamodel.SequenceI;
45 import jalview.gui.AlignFrame;
46 import jalview.gui.JvOptionPane;
48 @Test(singleThreaded = true)
49 public class BackupFilesTest
51 @BeforeClass(alwaysRun = true)
52 public void setUpJvOptionPane()
54 JvOptionPane.setInteractiveMode(false);
55 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
58 private static boolean actuallyDeleteTmpFiles = true;
60 private static String testDir = "test/jalview/io";
62 private static String testBasename = "backupfilestest";
64 private static String testExt = ".fa";
66 private static String testFilename = testBasename + testExt;
68 private static String testFile = testDir + File.separatorChar
71 private static String newBasename = testBasename + "Temp";
73 private static String newFilename = newBasename + testExt;
75 private static String newFile = testDir + File.separatorChar
78 private static String sequenceName = "BACKUP_FILES";
80 private static String sequenceDescription = "backupfiles";
82 private static String sequenceData = "AAAARG";
84 private static String suffix = "_BACKUPTEST-%n";
86 private static int digits = 6;
88 private static int rollMax = 2;
90 private AlignFrame af;
92 // read and save with backupfiles disabled
93 @Test(groups = { "Functional" })
94 public void noBackupsEnabledTest() throws Exception
96 // set BACKUPFILES_ENABLED to false (i.e. turn off BackupFiles feature -- no
97 // backup files to be made when saving)
98 setBackupFilesOptions(false, true, true);
100 // init the newFile and backups (i.e. make sure newFile exists on its own
101 // and has no backups
102 initNewFileForTesting();
107 // check no backup files
108 File[] backupFiles = getBackupFiles();
109 Assert.assertEquals(backupFiles.length, 0, "Number of backup files is "
110 + backupFiles.length + ", not " + 0);
113 // save with no numbers in the backup file names
114 @Test(groups = { "Functional" })
115 public void backupsEnabledSingleFileBackupTest() throws Exception
117 // Enable BackupFiles and set noMax so all backupfiles get kept
118 String mysuffix = "~";
119 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(mysuffix, 1,
120 false, true, 1, false);
121 setBackupFilesOptions(true, false, true,
122 "test/jalview/io/testProps_singlefilebackup.jvprops", bfpe);
124 // init the newFile and backups (i.e. make sure newFile exists on its own
125 // and has no backups)
126 initNewFileForTesting();
127 HashMap<Integer, String> correctindexmap = new HashMap<>();
128 correctindexmap.put(0, "backupfilestestTemp.fa~");
131 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
133 // and a second time -- see JAL-3628
135 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
137 cleanupTmpFiles(newFile, "~", 1);
140 // save keeping all backup files
141 @Test(groups = { "Functional" })
142 public void backupsEnabledNoRollMaxTest() throws Exception
144 // Enable BackupFiles and set noMax so all backupfiles get kept
145 setBackupFilesOptions(true, false, true);
147 // init the newFile and backups (i.e. make sure newFile exists on its own
148 // and has no backups)
149 initNewFileForTesting();
151 // now save a few times again. No rollMax so should have more than two
154 for (int i = 0; i < numSaves; i++)
159 // check 10 backup files
160 HashMap<Integer, String> correctindexmap = new HashMap<>();
161 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
162 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
163 correctindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
164 correctindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
165 correctindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
166 correctindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
167 correctindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
168 correctindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
169 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
170 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
171 HashMap<Integer, String> wrongindexmap = new HashMap<>();
172 wrongindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-1");
173 wrongindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
174 wrongindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
175 wrongindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
176 wrongindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
177 wrongindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
178 wrongindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
179 wrongindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
180 wrongindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
181 wrongindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
182 int[] indexes2 = { 3, 4, 5, 6, 7, 8, 9, 10 };
183 int[] indexes3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
184 Assert.assertTrue(checkBackupFiles(correctindexmap));
185 Assert.assertFalse(checkBackupFiles(wrongindexmap));
186 Assert.assertFalse(checkBackupFiles(indexes2));
187 Assert.assertFalse(checkBackupFiles(indexes3));
190 // save keeping only the last rollMax (2) backup files
191 @Test(groups = { "Functional" })
192 public void backupsEnabledRollMaxTest() throws Exception
194 // Enable BackupFiles and set noMax so all backupfiles get kept
195 setBackupFilesOptions(true, false, false);
197 // init the newFile and backups (i.e. make sure newFile exists on its own
198 // and has no backups)
199 initNewFileForTesting();
201 // now save a few times again. No rollMax so should have more than two
204 for (int i = 0; i < numSaves; i++)
209 // check there are "rollMax" backup files and they are all saved correctly
210 // check 10 backup files
211 HashMap<Integer, String> correctindexmap = new HashMap<>();
212 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
213 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
214 int[] indexes2 = { 10 };
215 int[] indexes3 = { 8, 9, 10 };
216 Assert.assertTrue(checkBackupFiles(correctindexmap));
217 Assert.assertFalse(checkBackupFiles(indexes2));
218 Assert.assertFalse(checkBackupFiles(indexes3));
221 // save keeping only the last rollMax (2) backup files
222 @Test(groups = { "Functional" })
223 public void backupsEnabledReverseRollMaxTest() throws Exception
225 // Enable BackupFiles and set noMax so all backupfiles get kept
226 setBackupFilesOptions(true, true, false);
228 // init the newFile and backups (i.e. make sure newFile exists on its own
229 // and has no backups)
230 initNewFileForTesting();
232 // now save a few times again. No rollMax so should have more than two
235 for (int i = 0; i < numSaves; i++)
240 // check there are "rollMax" backup files and they are all saved correctly
241 // check 10 backup files
242 HashMap<Integer, String> correctindexmap = new HashMap<>();
243 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
244 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
245 int[] indexes2 = { 1 };
246 int[] indexes3 = { 1, 2, 3 };
247 Assert.assertTrue(checkBackupFiles(correctindexmap));
248 Assert.assertFalse(checkBackupFiles(indexes2));
249 Assert.assertFalse(checkBackupFiles(indexes3));
252 private void setBackupFilesOptions()
254 setBackupFilesOptions(true, false, false);
257 private void setBackupFilesOptions(boolean enabled, boolean reverse,
260 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
261 reverse, noMax, rollMax, false);
262 setBackupFilesOptions(enabled, reverse, noMax,
263 "test/jalview/io/testProps.jvprops", bfpe);
266 private void setBackupFilesOptions(boolean enabled, boolean reverse,
267 boolean noMax, String propsFile, BackupFilesPresetEntry bfpe)
269 Cache.loadProperties(propsFile);
271 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
272 Boolean.toString(enabled));
273 Cache.applicationProperties.setProperty(
274 BackupFilesPresetEntry.SAVEDCONFIG, bfpe.toString());
276 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
277 Boolean.toString(enabled));
278 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, suffix);
279 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS,
280 Integer.toString(digits));
281 Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER,
282 Boolean.toString(reverse));
283 Cache.applicationProperties.setProperty(BackupFiles.NO_MAX,
284 Boolean.toString(noMax));
285 Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX,
286 Integer.toString(rollMax));
287 Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD,
296 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
300 // this runs cleanTmpFiles and then writes the newFile once as a starting
301 // point for all tests
302 private void initNewFileForTesting() throws Exception
306 AppletFormatAdapter afa = new AppletFormatAdapter();
307 AlignmentI al = afa.readFile(testFile, DataSourceType.FILE,
308 jalview.io.FileFormat.Fasta);
309 List<SequenceI> l = al.getSequences();
311 // check this is right
314 throw new Exception("single sequence from '" + testFile
315 + "' not read in correctly (should be a single short sequence). List<SequenceI> size is wrong.");
317 SequenceI s = l.get(0);
318 Sequence ref = new Sequence(sequenceName, sequenceData);
319 ref.setDescription(sequenceDescription);
320 if (!sequencesEqual(s, ref))
322 throw new Exception("single sequence from '" + testFile
323 + "' not read in correctly (should be a single short sequence). SequenceI name, description or data is wrong.");
325 // save alignment file to new filename -- this doesn't test backups disabled
326 // yet as this file shouldn't already exist
327 af = new AlignFrame(al, 0, 0);
328 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
331 // this deletes the newFile (if it exists) and any saved backup file for it
332 @AfterTest(alwaysRun = true)
333 @AfterClass(alwaysRun = true)
334 private void cleanupTmpFiles()
336 cleanupTmpFiles(newFile, suffix, digits);
339 protected static void cleanupTmpFiles(String file, String mysuffix,
342 File newfile = new File(file);
343 if (newfile.exists())
347 File[] tmpFiles = getBackupFiles(file, mysuffix, mydigits);
349 for (int i = 0; i < tmpFiles.length; i++)
351 if (actuallyDeleteTmpFiles)
353 tmpFiles[i].delete();
357 System.out.println("Pretending to delete " + tmpFiles[i].getPath());
362 private static File[] getBackupFiles(String f, String s, int i)
364 TreeMap<Integer, File> bfTreeMap = BackupFiles
365 .getBackupFilesAsTreeMap(f, s, i);
366 File[] backupFiles = new File[bfTreeMap.size()];
367 bfTreeMap.values().toArray(backupFiles);
371 private static File[] getBackupFiles()
373 return getBackupFiles(newFile, suffix, digits);
376 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap)
379 return checkBackupFiles(indexmap, newFile, suffix, digits);
382 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap,
383 String file, String mysuffix, int mydigits) throws IOException
385 TreeMap<Integer, File> map = BackupFiles.getBackupFilesAsTreeMap(file,
387 Enumeration<Integer> indexesenum = Collections
388 .enumeration(indexmap.keySet());
389 while (indexesenum.hasMoreElements())
391 int i = indexesenum.nextElement();
392 String indexfilename = indexmap.get(i);
393 if (!map.containsKey(i))
398 if (!filesContentEqual(newFile, f.getPath()))
407 if (!f.getName().equals(indexfilename))
412 // should be nothing left in map
421 private static boolean checkBackupFiles(int[] indexes) throws IOException
423 TreeMap<Integer, File> map = BackupFiles
424 .getBackupFilesAsTreeMap(newFile, suffix, digits);
425 for (int m = 0; m < indexes.length; m++)
428 if (!map.containsKey(i))
433 if (!filesContentEqual(newFile, f.getPath()))
442 // check the filename -- although this uses the same code to forumulate
443 // the filename so not much of a test!
444 String filename = BackupFilenameParts.getBackupFilename(i,
445 newBasename + testExt, suffix, digits);
446 if (!filename.equals(f.getName()))
448 System.out.println("Supposed filename '" + filename
449 + "' not equal to actual filename '" + f.getName() + "'");
453 // should be nothing left in map
462 private static String[] getBackupFilesAsStrings()
464 File[] files = getBackupFiles(newFile, suffix, digits);
465 String[] filenames = new String[files.length];
466 for (int i = 0; i < files.length; i++)
468 filenames[i] = files[i].getPath();
473 public static boolean sequencesEqual(SequenceI s1, SequenceI s2)
475 if (s1 == null && s2 == null)
479 else if (s1 == null || s2 == null)
483 return (s1.getName().equals(s2.getName())
484 && s1.getDescription().equals(s2.getDescription())
485 && Arrays.equals(s1.getSequence(), s2.getSequence()));
488 public static boolean filesContentEqual(String fileName1,
489 String fileName2) throws IOException
491 Path file1 = Paths.get(fileName1);
492 Path file2 = Paths.get(fileName2);
493 byte[] bytes1 = Files.readAllBytes(file1);
494 byte[] bytes2 = Files.readAllBytes(file2);
495 return Arrays.equals(bytes1, bytes2);