JAL-3141 Fixed tests
[jalview.git] / test / jalview / io / BackupFilesTest.java
1 package jalview.io;
2
3 import jalview.bin.Cache;
4 import jalview.datamodel.AlignmentI;
5 import jalview.datamodel.Sequence;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.AlignFrame;
8 import jalview.gui.JvOptionPane;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.nio.file.Files;
13 import java.nio.file.Path;
14 import java.nio.file.Paths;
15 import java.util.Arrays;
16 import java.util.Collections;
17 import java.util.Enumeration;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.TreeMap;
21
22 import org.testng.Assert;
23 import org.testng.annotations.AfterClass;
24 import org.testng.annotations.BeforeClass;
25 import org.testng.annotations.Test;
26
27 public class BackupFilesTest
28 {
29   @BeforeClass(alwaysRun = true)
30   public void setUpJvOptionPane()
31   {
32     JvOptionPane.setInteractiveMode(false);
33     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
34   }
35
36   private static boolean actuallyDeleteTmpFiles = true;
37   private static String testDir = "examples";
38
39   private static String testBasename = "backupfilestest";
40
41   private static String testExt = ".fa";
42
43   private static String testFilename = testBasename + testExt;
44
45
46   private static String testFile = testDir + File.separatorChar
47           + testFilename;
48
49   private static String newBasename = testBasename + "Temp";
50
51   private static String newFilename = newBasename + testExt;
52
53   private static String newFile = testDir + File.separatorChar
54           + newFilename;
55
56   private static String sequenceName = "BACKUP_FILES";
57
58   private static String sequenceDescription = "backupfiles";
59
60   private static String sequenceData = "AAAARG";
61
62   private static String suffix = "_BACKUPTEST-%n";
63
64   private static int digits = 6;
65
66   private static int rollMax = 2;
67
68   private AlignFrame af;
69
70   // read and save with backupfiles disabled
71   @Test(groups = { "Functional" })
72   public void noBackupsEnabledTest() throws Exception
73   {
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);
77
78     // init the newFile and backups (i.e. make sure newFile exists on its own
79     // and has no backups
80     initNewFileForTesting();
81
82     // now save again
83     save();
84
85     // check no backup files
86     File[] backupFiles = getBackupFiles();
87     Assert.assertTrue(backupFiles.length == 0);
88   }
89
90   // save keeping all backup files
91   @Test(groups = { "Functional" })
92   public void backupsEnabledNoRollMaxTest() throws Exception
93   {
94     // Enable BackupFiles and set noMax so all backupfiles get kept
95     setBackupFilesOptions(true, false, true);
96
97     // init the newFile and backups (i.e. make sure newFile exists on its own
98     // and has no backups)
99     initNewFileForTesting();
100
101     // now save a few times again. No rollMax so should have more than two
102     // backup files
103     int numSaves = 10;
104     for (int i = 0; i < numSaves; i++)
105     {
106       save();
107     }
108
109     // check 10 backup files
110     HashMap<Integer, String> correctindexmap = new HashMap<>();
111     correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
112     correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
113     correctindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
114     correctindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
115     correctindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
116     correctindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
117     correctindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
118     correctindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
119     correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
120     correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
121     HashMap<Integer, String> wrongindexmap = new HashMap<>();
122     wrongindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-1");
123     wrongindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
124     wrongindexmap.put(3, "backupfilestestTemp.fa_BACKUPTEST-000003");
125     wrongindexmap.put(4, "backupfilestestTemp.fa_BACKUPTEST-000004");
126     wrongindexmap.put(5, "backupfilestestTemp.fa_BACKUPTEST-000005");
127     wrongindexmap.put(6, "backupfilestestTemp.fa_BACKUPTEST-000006");
128     wrongindexmap.put(7, "backupfilestestTemp.fa_BACKUPTEST-000007");
129     wrongindexmap.put(8, "backupfilestestTemp.fa_BACKUPTEST-000008");
130     wrongindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
131     wrongindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
132     int[] indexes2 = { 3, 4, 5, 6, 7, 8, 9, 10 };
133     int[] indexes3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
134     Assert.assertTrue(checkBackupFiles(correctindexmap));
135     Assert.assertFalse(checkBackupFiles(wrongindexmap));
136     Assert.assertFalse(checkBackupFiles(indexes2));
137     Assert.assertFalse(checkBackupFiles(indexes3));
138   }
139
140   // save keeping only the last rollMax (2) backup files
141   @Test(groups = { "Functional" })
142   public void backupsEnabledRollMaxTest() throws Exception
143   {
144     // Enable BackupFiles and set noMax so all backupfiles get kept
145     setBackupFilesOptions(true, false, false);
146
147     // init the newFile and backups (i.e. make sure newFile exists on its own
148     // and has no backups)
149     initNewFileForTesting();
150
151     // now save a few times again. No rollMax so should have more than two
152     // backup files
153     int numSaves = 10;
154     for (int i = 0; i < numSaves; i++)
155     {
156       save();
157     }
158
159     // check there are "rollMax" backup files and they are all saved correctly
160     // check 10 backup files
161     HashMap<Integer, String> correctindexmap = new HashMap<>();
162     correctindexmap.put(9, "backupfilestestTemp.fa_BACKUPTEST-000009");
163     correctindexmap.put(10, "backupfilestestTemp.fa_BACKUPTEST-000010");
164     int[] indexes2 = { 10 };
165     int[] indexes3 = { 8, 9, 10 };
166     Assert.assertTrue(checkBackupFiles(correctindexmap));
167     Assert.assertFalse(checkBackupFiles(indexes2));
168     Assert.assertFalse(checkBackupFiles(indexes3));
169   }
170
171   // save keeping only the last rollMax (2) backup files
172   @Test(groups = { "Functional" })
173   public void backupsEnabledReverseRollMaxTest() throws Exception
174   {
175     // Enable BackupFiles and set noMax so all backupfiles get kept
176     setBackupFilesOptions(true, true, false);
177
178     // init the newFile and backups (i.e. make sure newFile exists on its own
179     // and has no backups)
180     initNewFileForTesting();
181
182     // now save a few times again. No rollMax so should have more than two
183     // backup files
184     int numSaves = 10;
185     for (int i = 0; i < numSaves; i++)
186     {
187       save();
188     }
189
190     // check there are "rollMax" backup files and they are all saved correctly
191     // check 10 backup files
192     HashMap<Integer, String> correctindexmap = new HashMap<>();
193     correctindexmap.put(1, "backupfilestestTemp.fa_BACKUPTEST-000001");
194     correctindexmap.put(2, "backupfilestestTemp.fa_BACKUPTEST-000002");
195     int[] indexes2 = { 1 };
196     int[] indexes3 = { 1, 2, 3 };
197     Assert.assertTrue(checkBackupFiles(correctindexmap));
198     Assert.assertFalse(checkBackupFiles(indexes2));
199     Assert.assertFalse(checkBackupFiles(indexes3));
200   }
201
202   private void setBackupFilesOptions()
203   {
204     setBackupFilesOptions(true, false, false);
205   }
206
207   private void setBackupFilesOptions(boolean enabled, boolean reverse,
208           boolean noMax)
209   {
210     Cache.loadProperties("test/jalview/io/testProps.jvprops");
211
212     BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
213             reverse, noMax, rollMax, false);
214
215     Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
216             Boolean.toString(enabled));
217     Cache.applicationProperties.setProperty(
218             BackupFilesPresetEntry.SAVEDCONFIG, bfpe.toString());
219     /*
220     Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
221             Boolean.toString(enabled));
222     Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, suffix);
223     Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS,
224             Integer.toString(digits));
225     Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER,
226             Boolean.toString(reverse));
227     Cache.applicationProperties.setProperty(BackupFiles.NO_MAX,
228             Boolean.toString(noMax));
229     Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX,
230             Integer.toString(rollMax));
231     Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD,
232             "false");
233             */
234   }
235
236   private void save()
237   {
238     if (af != null)
239     {
240     af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
241     }
242   }
243
244   // this runs cleanTmpFiles and then writes the newFile once as a starting
245   // point for all tests
246   private void initNewFileForTesting() throws Exception
247   {
248     cleanupTmpFiles();
249
250     AppletFormatAdapter afa = new AppletFormatAdapter();
251     AlignmentI al = afa.readFile(testFile, DataSourceType.FILE,
252             jalview.io.FileFormat.Fasta);
253     List<SequenceI> l = al.getSequences();
254
255     // check this is right
256     if (l.size() != 1)
257     {
258       throw new Exception("single sequence from '" + testFile
259               + "' not read in correctly (should be a single short sequence). List<SequenceI> size is wrong.");
260     }
261     SequenceI s = l.get(0);
262     Sequence ref = new Sequence(sequenceName, sequenceData);
263     ref.setDescription(sequenceDescription);
264     if (!sequencesEqual(s, ref))
265     {
266       throw new Exception("single sequence from '" + testFile
267               + "' not read in correctly (should be a single short sequence). SequenceI name, description or data is wrong.");
268     }
269     // save alignment file to new filename -- this doesn't test backups disabled
270     // yet as this file shouldn't already exist
271     af = new AlignFrame(al, 0, 0);
272     af.saveAlignment(newFile, jalview.io.FileFormat.Fasta);
273   }
274
275   // this deletes the newFile (if it exists) and any saved backup file for it
276   @AfterClass(alwaysRun = true)
277   private void cleanupTmpFiles()
278   {
279     File newfile = new File(newFile);
280     if (newfile.exists())
281     {
282       newfile.delete();
283     }
284     File[] tmpFiles = getBackupFiles(newFile, suffix, digits);
285     for (int i = 0; i < tmpFiles.length; i++)
286     {
287       if (actuallyDeleteTmpFiles)
288       {
289         tmpFiles[i].delete();
290       }
291       else
292       {
293         System.out.println("Pretending to delete " + tmpFiles[i].getPath());
294       }
295     }
296   }
297
298   private static File[] getBackupFiles(String f, String s, int i)
299   {
300     TreeMap<Integer, File> bfTreeMap = BackupFiles.getBackupFilesAsTreeMap(f,
301             s, i);
302     File[] backupFiles = new File[bfTreeMap.size()];
303     bfTreeMap.values().toArray(backupFiles);
304     return backupFiles;
305   }
306
307   private static File[] getBackupFiles()
308   {
309     return getBackupFiles(newFile, suffix, digits);
310   }
311
312   private static boolean checkBackupFiles(HashMap<Integer, String> indexmap)
313           throws IOException
314   {
315     TreeMap<Integer, File> map = BackupFiles.getBackupFilesAsTreeMap(newFile,
316             suffix, digits);
317     Enumeration<Integer> indexesenum = Collections
318             .enumeration(indexmap.keySet());
319     while (indexesenum.hasMoreElements())
320     {
321       int i = indexesenum.nextElement();
322       String indexfilename = indexmap.get(i);
323       if (!map.containsKey(i))
324       {
325         return false;
326       }
327       File f = map.get(i);
328       if (!filesContentEqual(newFile, f.getPath()))
329       {
330         return false;
331       }
332       map.remove(i);
333       if (f == null)
334       {
335         return false;
336       }
337       if (!f.getName().equals(indexfilename))
338       {
339         return false;
340       }
341     }
342     // should be nothing left in map
343     if (map.size() > 0)
344     {
345       return false;
346     }
347
348     return true;
349   }
350
351   private static boolean checkBackupFiles(int[] indexes) throws IOException
352   {
353     TreeMap<Integer, File> map = BackupFiles.getBackupFilesAsTreeMap(newFile,
354             suffix, digits);
355     for (int m = 0; m < indexes.length; m++)
356     {
357       int i = indexes[m];
358       if (!map.containsKey(i))
359       {
360         return false;
361       }
362       File f = map.get(i);
363       if (!filesContentEqual(newFile, f.getPath()))
364       {
365         return false;
366       }
367       map.remove(i);
368       if (f == null)
369       {
370         return false;
371       }
372       // check the filename -- although this uses the same code to forumulate the filename so not much of a test!
373       String filename = BackupFilenameParts.getBackupFilename(i,
374               newBasename + testExt, suffix, digits);
375       if (!filename.equals(f.getName()))
376       {
377         System.out.println("Supposed filename '" + filename
378                 + "' not equal to actual filename '" + f.getName() + "'");
379         return false;
380       }
381     }
382     // should be nothing left in map
383     if (map.size() > 0)
384     {
385       return false;
386     }
387
388     return true;
389   }
390
391   private static String[] getBackupFilesAsStrings()
392   {
393     File[] files = getBackupFiles(newFile, suffix, digits);
394     String[] filenames = new String[files.length];
395     for (int i = 0; i < files.length; i++)
396     {
397       filenames[i] = files[i].getPath();
398     }
399     return filenames;
400   }
401
402   public static boolean sequencesEqual(SequenceI s1, SequenceI s2) {
403     if (s1 == null && s2 == null) {
404       return true;
405     } else if (s1 == null || s2 == null) {
406       return false;
407     }
408     return (s1.getName().equals(s2.getName())
409             && s1.getDescription().equals(s2.getDescription())
410             && Arrays.equals(s1.getSequence(), s2.getSequence()));
411   }
412
413   public static boolean filesContentEqual(String fileName1,
414           String fileName2) throws IOException
415   {
416     Path file1 = Paths.get(fileName1);
417     Path file2 = Paths.get(fileName2);
418     byte[] bytes1 = Files.readAllBytes(file1);
419     byte[] bytes2 = Files.readAllBytes(file2);
420     return Arrays.equals(bytes1, bytes2);
421   }
422
423 }