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