1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package convwatch;
29 
30 // imports
31 import java.util.ArrayList;
32 import java.io.File;
33 import java.io.FileFilter;
34 
35 import convwatch.EnhancedComplexTestCase;
36 import com.sun.star.lang.XMultiServiceFactory;
37 
38 import convwatch.ConvWatchException;
39 import convwatch.DirectoryHelper;
40 import convwatch.GraphicalTestArguments;
41 import convwatch.HTMLOutputter;
42 import helper.OfficeProvider;
43 import helper.OfficeWatcher;
44 import helper.OSHelper;
45 import convwatch.PerformanceContainer;
46 
47 /**
48  * The following Complex Test will test
49  * an already created document and it's postscript output (by an older office version)
50  * with a new office version.
51  * This test use Ghostscript for the jpeg export and graphically compare tools from ImageMagick.
52  * Read the manual for more information.
53  *
54  * this is only the starter program
55  * more is found in qadevOOo/runner/convwatch/*
56  */
57 
58 public class ConvWatchStarter extends EnhancedComplexTestCase
59 {
60     // The first of the mandatory functions:
61     /**
62      * Return the name of the test.
63      * In this case it is the actual name of the service.
64      * @return The tested service.
65      */
66     // public String getTestObjectName() {
67     //     return "ConvWatch runner";
68     // }
69 
70     // The second of the mandatory functions: return all test methods as an
71     // array. There is only one test function in this example.
72     /**
73      * Return all test methods.
74      * @return The test methods.
75      */
76     public String[] getTestMethodNames() {
77         return new String[]{"compareGraphicalDiffs"};
78     }
79 
80     String m_sInputPath = "";
81     String m_sReferencePath = "";
82     String m_sOutputPath = "";
83     String m_sDiffPath = null;
84 
85     private void initMember()
86         {
87             // MUST PARAMETER
88             // INPUTFILE ----------
89             String sINPATH = (String)param.get( PropertyName.DOC_COMPARATOR_INPUT_PATH );
90             boolean bQuit = false;
91             if (sINPATH == null || sINPATH.length() == 0)
92             {
93                 log.println("Please set input path (path to documents) " + PropertyName.DOC_COMPARATOR_INPUT_PATH + "=path.");
94                 bQuit = true;
95             }
96             else
97             {
98                 log.println("found " + PropertyName.DOC_COMPARATOR_INPUT_PATH + " " + sINPATH);
99                 m_sInputPath = sINPATH;
100             }
101 
102             // REFERENCE_PATH ----------
103             String sREF = (String)param.get( PropertyName.DOC_COMPARATOR_REFERENCE_PATH );
104             if (sREF == null || sREF.length() == 0)
105             {
106                 // log.println("Please set reference file (path to good documents) REFERENCEFILE=path.");
107                 log.println("Assumtion, reference directory and input directory are the same.");
108                 m_sReferencePath = m_sInputPath;
109             }
110             else
111             {
112                 log.println("found " + PropertyName.DOC_COMPARATOR_REFERENCE_PATH + " " + sREF);
113                 m_sReferencePath = sREF;
114             }
115 
116             // OUTPUT_PATH ----------
117             String sOUT = (String)param.get( PropertyName.DOC_COMPARATOR_OUTPUT_PATH );
118             if (sOUT == null || sOUT.length() == 0)
119             {
120                 log.println("Please set output path (path to a temp directory) " + PropertyName.DOC_COMPARATOR_OUTPUT_PATH + "=path.");
121                 bQuit = true;
122             }
123             else
124             {
125                 log.println("found " + PropertyName.DOC_COMPARATOR_OUTPUT_PATH + " " + sOUT);
126                 m_sOutputPath = sOUT;
127             }
128 
129             if (bQuit == true)
130             {
131                 // log.println("must quit.");
132                 assure("Must quit", false);
133             }
134 
135 
136             // DIFF_PATH ----------
137             String sDIFF = (String)param.get( PropertyName.DOC_COMPARATOR_DIFF_PATH );
138             if (sDIFF == null || sDIFF.length() == 0)
139             {
140             }
141             else
142             {
143                 log.println("found " + PropertyName.DOC_COMPARATOR_DIFF_PATH + " " + sDIFF);
144                 m_sDiffPath = sDIFF;
145             }
146 
147             if (m_sInputPath.startsWith("file:") ||
148                 m_sReferencePath.startsWith("file:") ||
149                 m_sOutputPath.startsWith("file:"))
150             {
151                 assure("We can't handle file: URL right, use system path instead.", false);
152             }
153 
154         }
155 
156 
157     /**
158      *
159      * @return a List of software which must accessable as an external executable
160      */
161     protected Object[] mustInstalledSoftware()
162         {
163             ArrayList aList = new ArrayList();
164             // Tools from ImageMagick
165             if (! OSHelper.isWindows())
166             {
167             aList.add( "composite -version" );
168             aList.add( "identify -version" );
169 
170             // Ghostscript
171             aList.add( "gs -version" );
172             }
173             else
174             {
175                 aList.add( "composite.exe -version" );
176                 aList.add( "identify.exe -version" );
177 
178                 // Ghostscript
179                 aList.add( "gswin32c.exe -version" );
180             }
181 
182             return aList.toArray();
183         }
184 
185 
186     /**
187      * The test method itself.
188      * Don't try to call it from outside, it is started only from qadevOOo runner
189      */
190 
191     /* protected */
192     public void compareGraphicalDiffs()
193         {
194             GlobalLogWriter.set(log);
195             String sDBConnection = (String)param.get( PropertyName.DB_CONNECTION_STRING );
196             // check if all need software is installed and accessable
197             checkEnvironment(mustInstalledSoftware());
198 
199             GraphicalTestArguments aGTA = getGraphicalTestArguments();
200             if (aGTA == null)
201             {
202                 assure("Must quit", false);
203             }
204             if (aGTA.cancelRequest())
205             {
206                 return;
207             }
208 
209             initMember();
210 
211             aGTA.allowStore();
212 
213             String sBuildID = aGTA.getBuildID();
214             log.println("Current Office has buildid: " + sBuildID);
215 
216             // LLA: sample code, how to access all parameters
217             // for (Enumeration e = param.keys() ; e.hasMoreElements() ;)
218             // {
219             //     System.out.println(e.nextElement());
220             // }
221 
222             String fs = System.getProperty("file.separator");
223 
224             String sHTMLName = "index.html";
225             File aInputPathTest = new File(m_sInputPath);
226             if (!aInputPathTest.isDirectory())
227             {
228                 int n = m_sInputPath.lastIndexOf(fs);
229                 sHTMLName = m_sInputPath.substring(n + 1);
230                 sHTMLName += ".html";
231             }
232             HTMLOutputter HTMLoutput = HTMLOutputter.create(m_sOutputPath, sHTMLName, "", "");
233             HTMLoutput.header( m_sOutputPath );
234             HTMLoutput.indexSection( m_sOutputPath );
235             LISTOutputter LISToutput = LISTOutputter.create(m_sOutputPath, "allfiles.txt");
236 
237             DB.init(aGTA.getDBInfoString() + "," + sDBConnection);
238 
239             File aInputPath = new File(m_sInputPath);
240             if (aInputPath.isDirectory())
241             {
242                 // check a whole directory
243                 // a whole directory
244                 FileFilter aFileFilter = FileHelper.getFileFilter();
245 
246                 Object[] aList = DirectoryHelper.traverse(m_sInputPath, aFileFilter, aGTA.includeSubDirectories());
247                 if (aList.length == 0)
248                 {
249                     log.println("Nothing to do, there are no document files found.");
250                 }
251                 else
252                 {
253                     for (int i=0;i<aList.length;i++)
254                     {
255                         String sEntry = (String)aList[i];
256                         log.println("- next file is: ------------------------------");
257                         log.println(sEntry);
258 
259                         String sNewSubDir = FileHelper.removeFirstDirectorysAndBasenameFrom(sEntry, m_sInputPath);
260 
261                         String sNewReferencePath = m_sReferencePath;
262                         String sNewOutputPath = m_sOutputPath;
263                         String sNewDiffPath = m_sDiffPath;
264                         if (sNewSubDir.length() > 0)
265                         {
266                             if (sNewReferencePath != null)
267                                 sNewReferencePath = sNewReferencePath + fs + sNewSubDir;
268                             // String sNameNoSuffix = FileHelper.getNameNoSuffix(FileHelper.getBasename(sEntry));
269                             // sNewReferenceFile = sNewReferencePath + fs + sNameNoSuffix + ".prn";
270 
271                             sNewOutputPath = sNewOutputPath + fs + sNewSubDir;
272                             if (sNewDiffPath != null)
273                                 sNewDiffPath = sNewDiffPath + fs + sNewSubDir;
274                         }
275 
276                         // NameHelper aNameContainer = new NameHelper(m_sOutputPath, sNewSubDir, FileHelper.getBasename(sEntry));
277                         // aNameContainer.print();
278 
279                         if (aGTA.checkIfUsableDocumentType(sEntry))
280                         {
281                             runGDCWithStatus(HTMLoutput, LISToutput, sEntry, sNewOutputPath, sNewReferencePath, sNewDiffPath, sNewSubDir);
282                         }
283                         if (aGTA.cancelRequest())
284                         {
285                             break;
286                         }
287                     }
288                 }
289             }
290             else
291             {
292                 // check exact name
293                 if (aGTA.checkIfUsableDocumentType(m_sInputPath))
294                 {
295                     runGDCWithStatus(HTMLoutput, LISToutput, m_sInputPath, m_sOutputPath, m_sReferencePath, m_sDiffPath, "");
296                 }
297             }
298 
299             LISToutput.close();
300             HTMLoutput.close();
301             log.println("The file '" + HTMLoutput.getFilename() + "' shows a html based status.");
302             DB.writeHTMLFile(HTMLoutput.getFilename());
303         }
304 
305 
306     // -----------------------------------------------------------------------------
307     void runGDCWithStatus(HTMLOutputter _aHTMLoutput, LISTOutputter _aLISToutput, String _sInputFile, String _sOutputPath, String _sReferencePath, String _sDiffPath, String _sNewSubDir )
308         {
309             // start a fresh Office
310             GraphicalTestArguments aGTA = getGraphicalTestArguments();
311 
312             OfficeProvider aProvider = null;
313             // SimpleFileSemaphore aSemaphore = new SimpleFileSemaphore();
314             if (aGTA.shouldOfficeStart())
315             {
316                 // if (OSHelper.isWindows())
317                 // {
318                 //     aSemaphore.P(aSemaphore.getSemaphoreFile());
319                 // }
320 
321                 aGTA.getPerformance().startTime(PerformanceContainer.OfficeStart);
322                 aProvider = new OfficeProvider();
323                 XMultiServiceFactory xMSF = (XMultiServiceFactory) aProvider.getManager(param);
324                 param.put("ServiceFactory", xMSF);
325                 aGTA.getPerformance().stopTime(PerformanceContainer.OfficeStart);
326 
327                 long nStartTime = aGTA.getPerformance().getTime(PerformanceContainer.OfficeStart);
328                 aGTA = getGraphicalTestArguments(); // get new TestArguments
329                 aGTA.getPerformance().setTime(PerformanceContainer.OfficeStart, nStartTime);
330             }
331 
332             // Watcher Object is need in log object to give a simple way to say if a running office is alive.
333             // As long as a log comes, it pings the Watcher and says the office is alive, if not an
334             // internal counter increase and at a given point (300 seconds) the office is killed.
335             GlobalLogWriter.get().println("Set office watcher");
336             OfficeWatcher aWatcher = (OfficeWatcher)param.get("Watcher");
337             GlobalLogWriter.get().setWatcher(aWatcher);
338             // initializeWatcher(param);
339 
340             String sStatusRunThrough = "";
341             String sStatusMessage = "";
342             try
343             {
344                 DB.destination_start();
345                 // better was:
346                 // load document
347                 // create postscript from document
348                 // check file
349                 GraphicalDifferenceCheck.checkOneFile(_sInputFile, _sOutputPath, _sReferencePath, _sDiffPath, aGTA);
350                 sStatusRunThrough = "PASSED, OK";
351                 DB.destination_finished();
352             }
353             catch(ConvWatchCancelException e)
354             {
355                 assure(e.getMessage(), false, true);
356                 sStatusRunThrough = "CANCELLED, FAILED";
357                 sStatusMessage = e.getMessage();
358                 DB.destination_failed(sStatusRunThrough, sStatusMessage);
359             }
360             catch(ConvWatchException e)
361             {
362                 assure(e.getMessage(), false, true);
363                 sStatusMessage = e.getMessage();
364                 sStatusRunThrough = "PASSED, FAILED";
365                 DB.destination_failed(sStatusRunThrough, sStatusMessage);
366             }
367             catch(com.sun.star.lang.DisposedException e)
368             {
369                 assure(e.getMessage(), false, true);
370                 sStatusMessage = e.getMessage();
371                 sStatusRunThrough = "FAILED, FAILED";
372                 DB.destination_failed(sStatusRunThrough, sStatusMessage);
373             }
374 
375             GlobalLogWriter.get().println("Watcher count is: " + aWatcher.getPing());
376 
377             // Office shutdown
378             if (aProvider != null)
379             {
380                 aProvider.closeExistingOffice(param, true);
381                 // if (OSHelper.isWindows())
382                 // {
383                 //     aSemaphore.V(aSemaphore.getSemaphoreFile());
384                 //     aSemaphore.sleep(2);
385                 //     // wait some time maybe an other process will take the semaphore
386                 //     // I know, this is absolutly dirty, but the whole convwatch is dirty and need a big cleanup.
387                 // }
388             }
389 
390             // -------------------- Status --------------------
391             String fs = System.getProperty("file.separator");
392             String sBasename = FileHelper.getBasename(_sInputFile);
393             String sFilenameNoSuffix = FileHelper.getNameNoSuffix(sBasename);
394 
395             // -------------------- List of all files -----------------
396             String sListFile;
397             if (_sNewSubDir.length() > 0)
398             {
399                 sListFile = _sNewSubDir + fs + sFilenameNoSuffix + ".ini";
400             }
401             else
402             {
403                 sListFile = sFilenameNoSuffix + ".ini";
404             }
405             _aLISToutput.writeValue(sListFile);
406 
407             // -------------------- HTML --------------------
408             String sLink;
409             String sLinkDD;
410             String sLinkName;
411             String sLinkDDName;
412             String sHTMLPrefix = aGTA.getHTMLOutputPrefix();
413 
414             GlobalLogWriter.get().println("----------------------------------------------------------------------");
415             GlobalLogWriter.get().println(" OutputPath: " + _sOutputPath);
416             GlobalLogWriter.get().println("    NewPath: " + _sNewSubDir);
417             GlobalLogWriter.get().println("----------------------------------------------------------------------");
418 
419 //             if (_sNewSubDir.length() > 0)
420 //             {
421 //                 sLink   = sHTMLPrefix /* + "/cw.php?inifile=" */ + _sOutputPath + fs + _sNewSubDir + fs + sFilenameNoSuffix + ".ini";
422 //                 sLinkDD = sHTMLPrefix /* + "/cw.php?inifile=" */ + _sOutputPath + fs + _sNewSubDir + fs + "DiffDiff_" + sFilenameNoSuffix + ".ini";
423 //             }
424 //             else
425 //             {
426             sLink = sHTMLPrefix   /* + "/cw.php?inifile=" */ + _sOutputPath + fs + sFilenameNoSuffix + ".ini";
427                 // sLinkDD = sHTMLPrefix /* + "/cw.php?inifile=" */ + _sOutputPath + fs + _sNewSubDir + fs + "DiffDiff_" + sFilenameNoSuffix + ".ini";
428             sLinkDD = sHTMLPrefix /* + "/cw.php?inifile=" */ + _sOutputPath + fs + "DiffDiff_" + sFilenameNoSuffix + ".ini";
429 //             }
430             sLinkName = sFilenameNoSuffix;
431             sLinkDDName = sFilenameNoSuffix + " (DiffDiff)";
432 
433             if (_sDiffPath != null && _sDiffPath.length() > 0)
434             {
435                 _aHTMLoutput.indexLine( sLinkDD, sLinkDDName, sLink, sLinkName, sStatusRunThrough, sStatusMessage );
436             }
437             else
438             {
439                 _aHTMLoutput.indexLine( sLink, sLinkName, "", "", sStatusRunThrough, sStatusMessage );
440             }
441 
442         }
443 
444 
445 }
446