4 import java.io.IOException;
5 import java.nio.file.Files;
6 import java.nio.file.Path;
7 import java.nio.file.Paths;
8 import java.util.Arrays;
9 import java.util.Collections;
10 import java.util.Enumeration;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.TreeMap;
15 import org.testng.Assert;
16 import org.testng.annotations.AfterClass;
17 import org.testng.annotations.BeforeClass;
18 import org.testng.annotations.Test;
20 import jalview.bin.Cache;
21 import jalview.datamodel.AlignmentI;
22 import jalview.datamodel.Sequence;
23 import jalview.datamodel.SequenceI;
24 import jalview.gui.AlignFrame;
25 import jalview.gui.JvOptionPane;
27 public class BackupFilesTest
29 @BeforeClass(alwaysRun = true)
30 public void setUpJvOptionPane()
32 JvOptionPane.setInteractiveMode(false);
33 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
36 private static boolean actuallyDeleteTmpFiles = true;
38 private static String testDir = "test/jalview/io";
40 private static String testBasename = "backupfilestest";
42 private static String testExt = ".fa";
44 private static String testFilename = testBasename + testExt;
46 private static String testFile = testDir + File.separatorChar
49 private static String newBasename = testBasename + "Temp";
51 private static String newFilename = newBasename + testExt;
53 private static String newFile = testDir + File.separatorChar
56 private static String sequenceName = "BACKUP_FILES";
58 private static String sequenceDescription = "backupfiles";
60 private static String sequenceData = "AAAARG";
62 private static String suffix = "_BACKUPTEST-%n";
64 private static int digits = 6;
66 private static int rollMax = 2;
68 private AlignFrame af;
70 // read and save with backupfiles disabled
71 @Test(groups = { "Functional" })
72 public void noBackupsEnabledTest() throws Exception
74 // set BACKUPFILES_ENABLED to false (i.e. turn off BackupFiles feature -- no
75 // backup files to be made when saving)
76 setBackupFilesOptions(false, true, true);
78 // init the newFile and backups (i.e. make sure newFile exists on its own
80 initNewFileForTesting();
85 // check no backup files
86 File[] backupFiles = getBackupFiles();
87 Assert.assertTrue(backupFiles.length == 0);
90 // save with no numbers in the backup file names
91 @Test(groups = { "Functional" })
92 public void backupsEnabledSingleFileBackupTest() throws Exception
94 // Enable BackupFiles and set noMax so all backupfiles get kept
95 String mysuffix = "~";
96 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(mysuffix, 1,
97 false, true, 1, false);
98 setBackupFilesOptions(true, false, true,
99 "test/jalview/io/testProps_singlefilebackup.jvprops", bfpe);
101 // init the newFile and backups (i.e. make sure newFile exists on its own
102 // and has no backups)
103 initNewFileForTesting();
104 HashMap<Integer, String> correctindexmap = new HashMap<>();
105 correctindexmap.put(0, "backupfilestestTemp.fa~");
108 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
110 // and a second time -- see JAL-3628
112 Assert.assertTrue(checkBackupFiles(correctindexmap, newFile, "~", 1));
114 cleanupTmpFiles(newFile, "~", 1);
117 // save keeping all backup files
118 @Test(groups = { "Functional" })
119 public void backupsEnabledNoRollMaxTest() throws Exception
121 // Enable BackupFiles and set noMax so all backupfiles get kept
122 setBackupFilesOptions(true, false, true);
124 // init the newFile and backups (i.e. make sure newFile exists on its own
125 // and has no backups)
126 initNewFileForTesting();
128 // now save a few times again. No rollMax so should have more than two
131 for (int i = 0; i < numSaves; i++)
136 // check 10 backup files
137 HashMap<Integer, String> correctindexmap = new HashMap<>();
138 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
139 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
140 correctindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
141 correctindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
142 correctindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
143 correctindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
144 correctindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
145 correctindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
146 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
147 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
148 HashMap<Integer, String> wrongindexmap = new HashMap<>();
149 wrongindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-1");
150 wrongindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
151 wrongindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
152 wrongindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
153 wrongindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
154 wrongindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
155 wrongindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
156 wrongindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
157 wrongindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
158 wrongindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
159 int[] indexes2 = { 3, 4, 5, 6, 7, 8, 9, 10 };
160 int[] indexes3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
161 Assert.assertTrue(checkBackupFiles(correctindexmap));
162 Assert.assertFalse(checkBackupFiles(wrongindexmap));
163 Assert.assertFalse(checkBackupFiles(indexes2));
164 Assert.assertFalse(checkBackupFiles(indexes3));
167 // save keeping only the last rollMax (2) backup files
168 @Test(groups = { "Functional" })
169 public void backupsEnabledRollMaxTest() throws Exception
171 // Enable BackupFiles and set noMax so all backupfiles get kept
172 setBackupFilesOptions(true, false, false);
174 // init the newFile and backups (i.e. make sure newFile exists on its own
175 // and has no backups)
176 initNewFileForTesting();
178 // now save a few times again. No rollMax so should have more than two
181 for (int i = 0; i < numSaves; i++)
186 // check there are "rollMax" backup files and they are all saved correctly
187 // check 10 backup files
188 HashMap<Integer, String> correctindexmap = new HashMap<>();
189 correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
190 correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
191 int[] indexes2 = { 10 };
192 int[] indexes3 = { 8, 9, 10 };
193 Assert.assertTrue(checkBackupFiles(correctindexmap));
194 Assert.assertFalse(checkBackupFiles(indexes2));
195 Assert.assertFalse(checkBackupFiles(indexes3));
198 // save keeping only the last rollMax (2) backup files
199 @Test(groups = { "Functional" })
200 public void backupsEnabledReverseRollMaxTest() throws Exception
202 // Enable BackupFiles and set noMax so all backupfiles get kept
203 setBackupFilesOptions(true, true, false);
205 // init the newFile and backups (i.e. make sure newFile exists on its own
206 // and has no backups)
207 initNewFileForTesting();
209 // now save a few times again. No rollMax so should have more than two
212 for (int i = 0; i < numSaves; i++)
217 // check there are "rollMax" backup files and they are all saved correctly
218 // check 10 backup files
219 HashMap<Integer, String> correctindexmap = new HashMap<>();
220 correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
221 correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
222 int[] indexes2 = { 1 };
223 int[] indexes3 = { 1, 2, 3 };
224 Assert.assertTrue(checkBackupFiles(correctindexmap));
225 Assert.assertFalse(checkBackupFiles(indexes2));
226 Assert.assertFalse(checkBackupFiles(indexes3));
229 private void setBackupFilesOptions()
231 setBackupFilesOptions(true, false, false);
234 private void setBackupFilesOptions(boolean enabled, boolean reverse,
237 BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
238 reverse, noMax, rollMax, false);
239 setBackupFilesOptions(enabled, reverse, noMax,
240 "test/jalview/io/testProps.jvprops", bfpe);
243 private void setBackupFilesOptions(boolean enabled, boolean reverse,
244 boolean noMax, String propsFile, BackupFilesPresetEntry bfpe)
246 Cache.loadProperties(propsFile);
248 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
249 Boolean.toString(enabled));
250 Cache.applicationProperties.setProperty(
251 BackupFilesPresetEntry.SAVEDCONFIG, bfpe.toString());
253 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
254 Boolean.toString(enabled));
255 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, suffix);
256 Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS,
257 Integer.toString(digits));
258 Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER,
259 Boolean.toString(reverse));
260 Cache.applicationProperties.setProperty(BackupFiles.NO_MAX,
261 Boolean.toString(noMax));
262 Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX,
263 Integer.toString(rollMax));
264 Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD,
273 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
277 // this runs cleanTmpFiles and then writes the newFile once as a starting
278 // point for all tests
279 private void initNewFileForTesting() throws Exception
283 AppletFormatAdapter afa = new AppletFormatAdapter();
284 AlignmentI al = afa.readFile(testFile, DataSourceType.FILE,
285 jalview.io.FileFormat.Fasta);
286 List<SequenceI> l = al.getSequences();
288 // check this is right
291 throw new Exception("single sequence from '" + testFile
292 + "' not read in correctly (should be a single short sequence). List<SequenceI> size is wrong.");
294 SequenceI s = l.get(0);
295 Sequence ref = new Sequence(sequenceName, sequenceData);
296 ref.setDescription(sequenceDescription);
297 if (!sequencesEqual(s, ref))
299 throw new Exception("single sequence from '" + testFile
300 + "' not read in correctly (should be a single short sequence). SequenceI name, description or data is wrong.");
302 // save alignment file to new filename -- this doesn't test backups disabled
303 // yet as this file shouldn't already exist
304 af = new AlignFrame(al, 0, 0);
305 af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
308 // this deletes the newFile (if it exists) and any saved backup file for it
309 @AfterClass(alwaysRun = true)
310 private void cleanupTmpFiles()
312 cleanupTmpFiles(newFile, suffix, digits);
315 private void cleanupTmpFiles(String file, String mysuffix, int mydigits)
317 File newfile = new File(file);
318 if (newfile.exists())
322 File[] tmpFiles = getBackupFiles(file, mysuffix, mydigits);
323 for (int i = 0; i < tmpFiles.length; i++)
325 if (actuallyDeleteTmpFiles)
327 tmpFiles[i].delete();
331 System.out.println("Pretending to delete " + tmpFiles[i].getPath());
336 private static File[] getBackupFiles(String f, String s, int i)
338 TreeMap<Integer, File> bfTreeMap = BackupFiles
339 .getBackupFilesAsTreeMap(f, s, i);
340 File[] backupFiles = new File[bfTreeMap.size()];
341 bfTreeMap.values().toArray(backupFiles);
345 private static File[] getBackupFiles()
347 return getBackupFiles(newFile, suffix, digits);
350 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap)
353 return checkBackupFiles(indexmap, newFile, suffix, digits);
356 private static boolean checkBackupFiles(HashMap<Integer, String> indexmap,
357 String file, String mysuffix, int mydigits) throws IOException
359 TreeMap<Integer, File> map = BackupFiles.getBackupFilesAsTreeMap(file,
361 Enumeration<Integer> indexesenum = Collections
362 .enumeration(indexmap.keySet());
363 while (indexesenum.hasMoreElements())
365 int i = indexesenum.nextElement();
366 String indexfilename = indexmap.get(i);
367 if (!map.containsKey(i))
372 if (!filesContentEqual(newFile, f.getPath()))
381 if (!f.getName().equals(indexfilename))
386 // should be nothing left in map
395 private static boolean checkBackupFiles(int[] indexes) throws IOException
397 TreeMap<Integer, File> map = BackupFiles
398 .getBackupFilesAsTreeMap(newFile, suffix, digits);
399 for (int m = 0; m < indexes.length; m++)
402 if (!map.containsKey(i))
407 if (!filesContentEqual(newFile, f.getPath()))
416 // check the filename -- although this uses the same code to forumulate
417 // the filename so not much of a test!
418 String filename = BackupFilenameParts.getBackupFilename(i,
419 newBasename + testExt, suffix, digits);
420 if (!filename.equals(f.getName()))
422 System.out.println("Supposed filename '" + filename
423 + "' not equal to actual filename '" + f.getName() + "'");
427 // should be nothing left in map
436 private static String[] getBackupFilesAsStrings()
438 File[] files = getBackupFiles(newFile, suffix, digits);
439 String[] filenames = new String[files.length];
440 for (int i = 0; i < files.length; i++)
442 filenames[i] = files[i].getPath();
447 public static boolean sequencesEqual(SequenceI s1, SequenceI s2)
449 if (s1 == null && s2 == null)
453 else if (s1 == null || s2 == null)
457 return (s1.getName().equals(s2.getName())
458 && s1.getDescription().equals(s2.getDescription())
459 && Arrays.equals(s1.getSequence(), s2.getSequence()));
462 public static boolean filesContentEqual(String fileName1,
463 String fileName2) throws IOException
465 Path file1 = Paths.get(fileName1);
466 Path file2 = Paths.get(fileName2);
467 byte[] bytes1 = Files.readAllBytes(file1);
468 byte[] bytes2 = Files.readAllBytes(file2);
469 return Arrays.equals(bytes1, bytes2);