diff options
Diffstat (limited to 'vcl/qa/complex')
-rw-r--r-- | vcl/qa/complex/memCheck/CheckMemoryUsage.java | 343 | ||||
-rw-r--r-- | vcl/qa/complex/memCheck/CheckMemoryUsage.props | 14 | ||||
-rwxr-xr-x | vcl/qa/complex/memCheck/makefile.mk | 93 | ||||
-rw-r--r-- | vcl/qa/complex/persistent_window_states/DocumentHandle.java | 172 | ||||
-rw-r--r-- | vcl/qa/complex/persistent_window_states/PersistentWindowTest.java | 396 | ||||
-rw-r--r-- | vcl/qa/complex/persistent_window_states/PersistentWindowTest.props | 10 | ||||
-rw-r--r-- | vcl/qa/complex/persistent_window_states/makefile.mk | 85 |
7 files changed, 1113 insertions, 0 deletions
diff --git a/vcl/qa/complex/memCheck/CheckMemoryUsage.java b/vcl/qa/complex/memCheck/CheckMemoryUsage.java new file mode 100644 index 000000000000..c374c7d4229a --- /dev/null +++ b/vcl/qa/complex/memCheck/CheckMemoryUsage.java @@ -0,0 +1,343 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CheckMemoryUsage.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package complex.memCheck; + +import com.sun.star.beans.PropertyValue; +import com.sun.star.frame.XStorable; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.util.XCloseable; +import complexlib.ComplexTestCase; +import helper.ProcessHandler; +import java.io.File; +import java.io.FilePermission; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; +import util.DesktopTools; +import util.WriterTools; +import util.utils; + +/** + * Documents are opened and exported with StarOffice. The memory usage of + * StarOffice is monitored and if the usage exceeds the allowed kilobytes, + * the test is failed. Used for monitoring the StarOffice process is the + * command line tool 'pmap', available on Solaris or Linux. This test will not + * run on Windows.<br>Test procedure: every given document type is searched in + * the source directory + * Needed paramters: + * <ul> + * <li>"TestDocumentPath" - the path where test documents are located.</li> + * <li>"AllowMemoryIncrease" (optional) - the allowed memory increase measured in kByte per exported document. The default is 10 kByte.</li> + * <li>"ExportDocCount" (optional) - the amount of exports for each document that is loaded. Is defaulted to 25. + * <li>"FileExportFilter" (optional) - a relation between loaded document type and used export filter. Is defaulted to + * writer, calc and impress. This parameter can be set with a number to give more than one relation. Example:<br> + * "FileExportFilter1=sxw,writer_pdf_Export"<br> + * "FileExportFilter2=sxc,calc_pdf_Export"<br> + * "FileExportFilter3=sxi,impress_pdf_Export"<br></li> + * All parameters are used for iteration over the test document path. + * </ul> + */ +public class CheckMemoryUsage extends ComplexTestCase { + private final String sWriterDoc = "sxw,writer_pdf_Export"; + private final String sCalcDoc = "sxc,calc_pdf_Export"; + private final String sImpressDoc = "sxi,impress_pdf_Export"; + private String sProcessId = "ps -ef | grep $USER | grep soffice | grep -v grep"; + private String sMemoryMonitor = "pmap <processID> | grep total"; + private String sChmod = "chmod 777 "; + private String sProcessIdCommand = null; + private String sOfficeMemoryCommand = null; + private String sTempDir = null; + private String sFS = null; + private String sMemoryMap1 = null; + private String sMemoryMap2 = null; + private String bash = "#!/bin/bash"; + private String sDocumentPath = ""; + private String[][] sDocTypeExportFilter; + private String[][] sDocuments; + private int iAllowMemoryIncrease = 10; + private int iExportDocCount = 25; + + /** + * Get all test methods + * @return The test methods. + */ + public String[] getTestMethodNames() { + return new String[] {"loadAndSaveDocuments"}; + } + + /** + * Collect all documnets to load and all filters used for export. + */ + public void before() { + // test does definitely not run on Windows. + if (param.get("OperatingSystem").equals("wntmsci")) { + log.println("Test can only reasonably be executed with a tool that " + + "displays the memory usage of StarOffice."); + failed("Test does not run on Windows, only on Solaris or Linux."); + } + + // how many times is every document exported. + int count = param.getInt("ExportDocCount"); + if (count != 0) + iExportDocCount = count; + + // get the temp dir for creating the command scripts. + sTempDir = System.getProperty("java.io.tmpdir"); + sProcessIdCommand = sTempDir + "getPS"; + sOfficeMemoryCommand = sTempDir + "getPmap"; + + // get the file extension, export filter connection + Enumeration keys = param.keys(); + Vector v = new Vector(); + while(keys.hasMoreElements()) { + String key = (String)keys.nextElement(); + if (key.startsWith("FileExportFilter")) { + v.add(param.get(key)); + } + } + // if no param given, set defaults. + if (v.size() == 0){ + v.add(sWriterDoc); + v.add(sCalcDoc); + v.add(sImpressDoc); + } + // store a file extension + sDocTypeExportFilter = new String[v.size()][2]; + for (int i=0; i<v.size(); i++) { + // 2do: error routine for wrong given params + StringTokenizer t = new StringTokenizer((String)v.get(i), ","); + sDocTypeExportFilter[i][0] = t.nextToken(); + sDocTypeExportFilter[i][1] = t.nextToken(); + } + + // get files to load and export + sDocumentPath = (String)param.get("TestDocumentPath"); + File f = new File(sDocumentPath); + sDocumentPath = f.getAbsolutePath(); + String sFS = System.getProperty("file.separator"); + sDocuments = new String[sDocTypeExportFilter.length][]; + for (int j=0; j<sDocTypeExportFilter.length; j++) { + FileFilter filter = new FileFilter(sDocTypeExportFilter[j][0]); + String[] doc = f.list(filter); + sDocuments[j] = new String[doc.length]; + for (int i=0; i<doc.length; i++) { + if (sDocumentPath.endsWith(sFS)) + sDocuments[j][i] = sDocumentPath + doc[i]; + else + sDocuments[j][i] = sDocumentPath + sFS + doc[i]; + sDocuments[j][i] = utils.getFullURL(sDocuments[j][i]); + } + } + } + + /** + * delete all created files on disk + */ + public void after() { + // delete the constructed files. + for (int i=0; i<iExportDocCount; i++) { + File f = new File(sTempDir + "DocExport" + i + ".pdf"); + f.delete(); + } + File f = new File(sProcessIdCommand); + f.delete(); + f = new File(sOfficeMemoryCommand); + f.delete(); + } + + /** + * Thet etst function: load documents and save them using the given filters + * for each given document type. + */ + public void loadAndSaveDocuments() { + int storageBefore = getOfficeMemoryUsage(); + + XMultiServiceFactory xMSF = (XMultiServiceFactory)param.getMSF(); + + // iterate over all document types + for (int k=0; k<sDocTypeExportFilter.length; k++) { + // iterate over all documents of this type + for (int i=0; i<sDocuments[k].length; i++) { + System.out.println("Document: "+ sDocuments[k][i]); + XComponent xComponent = DesktopTools.loadDoc(xMSF, sDocuments[k][i], null); + XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xComponent); + if (xStorable != null) { + // export each document iExportDocCount times + for (int j=0; j<iExportDocCount; j++) { + String url = utils.getFullURL(sTempDir + "DocExport" + j + ".pdf"); + try { + PropertyValue[] props = new PropertyValue[1]; + props[0] = new PropertyValue(); + props[0].Name = "FilterName"; + // use export filter for this doc type + props[0].Value = sDocTypeExportFilter[k][1]; + xStorable.storeToURL(url, props); + } + catch(com.sun.star.io.IOException e) { + failed("Could not store to '" + url + "'", true); + } + } + // close the doc + XCloseable xCloseable = (XCloseable)UnoRuntime.queryInterface(XCloseable.class, xStorable); + try { + xCloseable.close(true); + } + catch(com.sun.star.util.CloseVetoException e) { + e.printStackTrace((java.io.PrintWriter)log); + failed("Cannot close document: test is futile, Office will surely use more space."); + } + } + else { + log.println("Cannot query for XStorable interface on document '" + sDocuments[i] + "'"); + log.println(" -> Skipping storage."); + } + } + } + // short wait for the office to 'calm down' and free some memory + shortWait(5000); + // wait util memory is not freed anymore. + int storageAfter = getOfficeMemoryUsage(); + int mem = 0; + int count = 0; + while (storageAfter != mem && count < 10) { + count++; + mem = storageAfter; + storageAfter = getOfficeMemoryUsage(); + shortWait(1000); + } + assure("The Office consumes now " + (storageAfter - storageBefore) + + "K more memory than at the start of the test; allowed were " + + iAllowMemoryIncrease * iExportDocCount + "K.", + storageAfter - storageBefore < iAllowMemoryIncrease * iExportDocCount); + + } + + /** + * Get the process ID from the Office + * @return the Id as String + */ + private String getOfficeProcessID() { + writeExecutableFile(sProcessIdCommand, sProcessId); + ProcessHandler processID = new ProcessHandler(sProcessIdCommand); + processID.executeSynchronously(); + String text = processID.getOutputText(); + if (text == null || text.equals("") || text.indexOf(' ') == -1) + failed("Could not determine Office process ID. Check " + sProcessIdCommand); + StringTokenizer aToken = new StringTokenizer(text); + // this is not nice, but ps gives the same output on every machine + aToken.nextToken(); + String id = aToken.nextToken(); + return id; + } + + /** + * Get the memory usage of the Office in KByte. + * @return The memory used by the Office. + */ + private int getOfficeMemoryUsage() { + String command = sMemoryMonitor.replaceAll("<processID>", getOfficeProcessID()); + writeExecutableFile(sOfficeMemoryCommand, command); + ProcessHandler processID = new ProcessHandler(sOfficeMemoryCommand); + processID.executeSynchronously(); + String text = processID.getOutputText(); + if (text == null || text.equals("") || text.indexOf(' ') == -1) { + failed("Could not determine Office memory usage. Check " + sOfficeMemoryCommand); + } + StringTokenizer aToken = new StringTokenizer(text); + // this works, because the output of pmap is quite standardized. + aToken.nextToken(); + String mem = aToken.nextToken(); + mem = mem.substring(0, mem.indexOf('K')); + Integer memory = new Integer(mem); + return memory.intValue(); + } + + /** + * Write a script file and set its rights to rwxrwxrwx. + * @param fileName The name of the created file + * @param line The commandline that has to be written inside of the file. + */ + private void writeExecutableFile(String fileName, String line) { + try { + PrintWriter fWriter = new PrintWriter(new FileWriter(fileName)); + fWriter.println(bash); + fWriter.println(line); + fWriter.close(); + // change rights to rwxrwxrwx + ProcessHandler processID = new ProcessHandler(sChmod + fileName); + processID.executeSynchronously(); + } + catch(java.io.IOException e) { + } + } + + /** + * Let this thread sleep for some time + * @param milliSeconds time to wait in milliseconds. + */ + private void shortWait(int milliSeconds) { + try { + Thread.sleep(milliSeconds); + } + catch(java.lang.InterruptedException e) { // ignore + } + } + + /** + * Own file filter, will just return ok for all files that end with a given + * suffix + */ + private class FileFilter implements FilenameFilter { + private String suffix = null; + /** + * C'tor. + * @param suffix The suffix each filename should end with. + */ + public FileFilter(String suffix) { + this.suffix = suffix; + } + /** + * Returns true, if the name of the file has the suffix given to the + * c'tor. + * @param name The filename that is tested. + * @param file Not used. + * @return True, if name ends with suffix. + */ + public boolean accept(File file, String name) { + return name.endsWith(suffix); + } + }; + +} diff --git a/vcl/qa/complex/memCheck/CheckMemoryUsage.props b/vcl/qa/complex/memCheck/CheckMemoryUsage.props new file mode 100644 index 000000000000..5d1333186950 --- /dev/null +++ b/vcl/qa/complex/memCheck/CheckMemoryUsage.props @@ -0,0 +1,14 @@ +# the path to the test documents +TestDocumentPath=../../testdocuments + +# the allowed memory increase per exported document: if the memory increase is higher than this number, the test will fail +AllowMemoryIncrease=20 + +# the amount of exported documents: each loaded document will be written 'ExportDocCount' times +ExportDocCount=25 + +# the import and export filters, separated by comma; further relations can be added with increasing numbers, like +#'FileExportFilter4=sxd,draw_pdf_Export' +FileExportFilter1=sxw,writer_pdf_Export +FileExportFilter2=sxc,calc_pdf_Export +FileExportFilter3=sxi,impress_pdf_Export diff --git a/vcl/qa/complex/memCheck/makefile.mk b/vcl/qa/complex/memCheck/makefile.mk new file mode 100755 index 000000000000..5b1837540c51 --- /dev/null +++ b/vcl/qa/complex/memCheck/makefile.mk @@ -0,0 +1,93 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.5.124.1 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ = ..$/..$/.. +TARGET = MemoryCheck +PRJNAME = $(TARGET) +PACKAGE = complex$/memCheck + +# --- Settings ----------------------------------------------------- +.INCLUDE: settings.mk + + +#----- compile .java files ----------------------------------------- + +JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar +JAVAFILES = CheckMemoryUsage.java + +#----- make a jar from compiled files ------------------------------ + +MAXLINELENGTH = 100000 + +JARCLASSDIRS = $(PACKAGE) +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE + +# --- Parameters for the test -------------------------------------- + +# start an office if the parameter is set for the makefile +.IF "$(OFFICE)" == "" +CT_APPEXECCOMMAND = +.ELSE +CT_APPEXECCOMMAND = -AppExecutionCommand \ + "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" +.ENDIF + +# test base is java complex +CT_TESTBASE = -TestBase java_complex + +# replace $/ with . in package name +CT_PACKAGE = -o $(PACKAGE:s\$/\.\) + +# start the runner application +CT_APP = org.openoffice.Runner + +# --- Targets ------------------------------------------------------ + +.IF "$(depend)" == "" +$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR +.ELSE +$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR +.ENDIF + +.INCLUDE : target.mk + + + +$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : CheckMemoryUsage.props + cp $(@:f) $@ + jar uf $(CLASSDIR)$/$(JARTARGET) -C $(CLASSDIR) $(PACKAGE)$/$(@:f) + + +RUN: run + +run: + java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_PACKAGE).CheckMemoryUsage diff --git a/vcl/qa/complex/persistent_window_states/DocumentHandle.java b/vcl/qa/complex/persistent_window_states/DocumentHandle.java new file mode 100644 index 000000000000..38b8f75f0cfe --- /dev/null +++ b/vcl/qa/complex/persistent_window_states/DocumentHandle.java @@ -0,0 +1,172 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentHandle.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package complex.persistent_window_states; + + +import com.sun.star.awt.Rectangle; +import com.sun.star.awt.PosSize; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.lang.XComponent; +import com.sun.star.awt.XWindow; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.PropertyState; +import com.sun.star.frame.XController; +import com.sun.star.frame.FrameSearchFlag; +import com.sun.star.text.XTextDocument; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.frame.XFrame; +import com.sun.star.frame.FrameSearchFlag; +import com.sun.star.frame.XFramesSupplier; +import helper.WindowListener; + +/** + * Load and resize a document. + * + */ +public class DocumentHandle { + // the component loader to load a document + XComponentLoader xCompLoader = null; + // the document + XComponent xComp = null; + // the current window + XWindow xWin = null; + // a own window listener + WindowListener wl = null; + + /** + * Constructor + * @param xComponentLoader A loader to load a document + */ + public DocumentHandle(XComponentLoader xCompLoader) { + this.xCompLoader = xCompLoader; + wl = new WindowListener(); + } + + /** + * Load/Create a document. + * @param docName The name of a document as file URL + * @param hidden If true, the document is loaded hidden. + * @return The size of the opened/created document. + */ + public Rectangle loadDocument(String docName, boolean hidden) + throws Exception{ + wl.resetTrigger(); + try { + PropertyValue [] szArgs = null; + if (hidden) { + szArgs = new PropertyValue [1]; + PropertyValue Arg = new PropertyValue(); + Arg.Name = "Hidden"; + Arg.Value = hidden?"True":"False"; + Arg.Handle = -1; + Arg.State = PropertyState.DEFAULT_VALUE; + szArgs[0] = Arg; + } + else { + szArgs = new PropertyValue [0]; + } + + // get the current active window + XFrame xCurFrame = (XFrame)UnoRuntime.queryInterface(XFrame.class, xCompLoader); + + // create a new frame + XFrame xFrame = xCurFrame.findFrame("_blank", FrameSearchFlag.CREATE); + + // load document in this frame + XComponentLoader xFrameLoader = (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, xFrame); + xComp = xFrameLoader.loadComponentFromURL( + docName, "_self", 0, szArgs); + // wait for the document to load. + try { + Thread.sleep(10000); + } + catch(java.lang.InterruptedException e) {} + + xWin = xFrame.getContainerWindow(); + xWin.addWindowListener(wl); + } + catch(com.sun.star.io.IOException e) { + e.printStackTrace(); + return null; + } + catch(com.sun.star.lang.IllegalArgumentException e) { + e.printStackTrace(); + return null; + } + catch(java.lang.Exception e) { + System.out.println("DH3"); + e.printStackTrace(); + throw e; + } + return xWin.getPosSize(); + + } + + /** + * Get the size of the current window. + * @return The size of the window as Rectangle. + */ + public Rectangle getDocumentPosSize() { + return xWin.getPosSize(); + } + + /** + * Resize the window in defined steps: + * width -10 pixel; + * height -10 pixel; + * X-Position +10 pixel; + * Y-Position +10 pixel + * @return True if resize worked. + */ + public boolean resizeDocument() { + Rectangle newPosSize = xWin.getPosSize(); + newPosSize.Width = newPosSize.Width - 20; + newPosSize.Height = newPosSize.Height - 20; + newPosSize.X = newPosSize.X + 80; + newPosSize.Y = newPosSize.Y + 80; + return resizeDocument(newPosSize); + } + + /** + * Resize window to the given Rectangle + * @param newPosSize The new position and size of the window. + * @return True if resize worked. + */ + public boolean resizeDocument(Rectangle newPosSize){ + wl.resetTrigger(); + xWin.setPosSize(newPosSize.X, newPosSize.Y, newPosSize.Width, + newPosSize.Height, PosSize.POSSIZE); + try { + Thread.sleep(3000); + } + catch(java.lang.InterruptedException e) {} + return wl.resizedTrigger; + } +} diff --git a/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java new file mode 100644 index 000000000000..6b7804697e2f --- /dev/null +++ b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java @@ -0,0 +1,396 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PersistentWindowTest.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package complex.persistent_window_states; + + +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XInitialization; +import com.sun.star.uno.Type; +import com.sun.star.uno.Any; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XComponent; +import com.sun.star.frame.XDesktop; +import com.sun.star.frame.XFramesSupplier; +import com.sun.star.frame.XFrames; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.container.XIndexAccess; +import com.sun.star.beans.XPropertySet; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.AnyConverter; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.awt.Rectangle; +import com.sun.star.util.XCloseable; +import helper.ConfigurationRead; +import complexlib.ComplexTestCase; +import helper.OfficeProvider; +import complex.persistent_window_states.DocumentHandle; + +/** + * Parameters: + * <ul> + * <li>NoOffice=yes - StarOffice is not started initially.</li> + * </ul> + */ +public class PersistentWindowTest extends ComplexTestCase { + + private XMultiServiceFactory xMSF; + private OfficeProvider oProvider; + private int iOfficeCloseTime = 0; + + /** + * A frunction to tell the framework, which test functions are available. + * Right now, it's only 'checkPersistentWindowState'. + * @return All test methods. + */ + public String[] getTestMethodNames() { + return new String[]{"checkPersistentWindowState"}; + } + + /** + * Test if all available document types change the + * persistent Window Attributes + * + * The test follows basically these steps: + * - Create a configuration reader and a componentloader + * - Look for all document types in the configuration + * - Do for every doc type + * - start office + * - read configuration attibute settings + * - create a new document + * - resize the document and close it + * - close office + * - start office + * - read configuration attribute settings + * - create another new document + * - compare old settings with new ones: should be different + * - compare the document size with the resized document: should be equal + * - close office + * - Test finished + */ + public void checkPersistentWindowState() + { + try { + + log.println("Connect the first time."); + log.println("AppExecCommand: " + (String)param.get("AppExecutionCommand")); + log.println("ConnString: " + (String)param.get("ConnectionString")); + oProvider = new OfficeProvider(); + iOfficeCloseTime = param.getInt("OfficeCloseTime"); + if ( iOfficeCloseTime == 0 ) { + iOfficeCloseTime = 1000; + } + + if (!connect()) return; + + // create the configuration provider + Object o = null; + try { + o = xMSF.createInstance( + "com.sun.star.configuration.ConfigurationProvider"); + } + catch(com.sun.star.uno.Exception e) { + failed("Cannot create \"com.sun.star.configuration."+ + "ConfigurationProvider\""); + return; + } + + // fetch the multi service factory for setup + XMultiServiceFactory xCP = (XMultiServiceFactory) + UnoRuntime.queryInterface(XMultiServiceFactory.class, o); + + // create the configuration reader + ConfigurationRead cfgRead = new ConfigurationRead(xCP); + + // just test the wrong ones, not all. + String [] els = new String[]{ + "Office/Factories/com.sun.star.drawing.DrawingDocument", + "Office/Factories/com.sun.star.formula.FormulaProperties", + //"Office/Factories/com.sun.star.presentation.PresentationDocument", + "Office/Factories/com.sun.star.sheet.SpreadsheetDocument", + "Office/Factories/com.sun.star.text.GlobalDocument", + "Office/Factories/com.sun.star.text.TextDocument", + "Office/Factories/com.sun.star.text.WebDocument", + }; + // uncomment the following line for all doc types +// String [] els = cfgRead.getSubNodeNames("Office/Factories"); + + log.println("Found "+ els.length + " document types to test.\n"); + if (!disconnect()) return; + + // for all types + for(int i=0; i<els.length; i++) { + log.println("\tStart test for document type " + i + ": " + els[i]); + // exclude chart documents: cannot be created this way. + if ( els[i].indexOf("ChartDocument") != -1) { + log.println("Skipping chart document: cannot be create like this."); + continue; + } + + // start an office + if (!connect()) return; + + // get configuration + String[] settings = getConfigurationAndLoader(xMSF, els[i]); + if (settings == null) { + log.println("Skipping document type " + els[i]); + disconnect(); + continue; + } + String cfg = settings[1]; + + // load a document + DocumentHandle handle = loadDocument(xMSF, settings[0]); + + // first size + Rectangle rect1 = handle.getDocumentPosSize(); + + // resize + handle.resizeDocument(); + // after resize + Rectangle rect2 = handle.getDocumentPosSize(); + + // disposeManager and start a new office + if (!disconnect()) return; + + if (!connect()) return; + + // get configuration + settings = getConfigurationAndLoader(xMSF, els[i]); + + String newCfg = settings[1]; + + // load a document + handle = loadDocument(xMSF, settings[0]); + + Rectangle newRect = handle.getDocumentPosSize(); + + // print the settings and window sizes + log.println("----------------------------"); + log.println("Initial Config String : " + cfg); + log.println("Config String after restart: " + newCfg); + + log.println("----------------------------"); + log.println("Initial window (X,Y,Width,Height): " + +rect1.X+";"+rect1.Y+";"+ rect1.Width+";"+rect1.Height); + log.println("Window after resize (X,Y,Width,Height): " + +rect2.X+";"+rect2.Y+";"+ rect2.Width+";"+rect2.Height); + log.println("Window after restart (X,Y,Width,Height): " + +newRect.X+";"+newRect.Y+";"+newRect.Width+";" + +newRect.Height); + + // compare to see if resize worked + log.println("----------------------------"); + assure("Resize values for "+ els[i] + + " are equal.", !compareRectangles(rect1, rect2), true); + // compare settings and sizes + assure("Config settings for "+ els[i] + + " were not changed.", !cfg.equals(newCfg), true); + assure("Resized and restarted window for "+ els[i] + + " are not equal.", compareRectangles(rect2, newRect), true); + log.println("----------------------------"); + + // disposeManager + if (!disconnect()) return; + + log.println("\tFinish test for document type " + i + ": " + els[i]); + + } + } + catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * Get the configuration settings and the document loader + * @param xMSF A MultiServiceFactory from an office + * @param cfgString A configuration string + * @return Settings and Loader + */ + private static String[] getConfigurationAndLoader(XMultiServiceFactory xMSF, + String cfgString) { + String[] conf = new String[2]; + + try { + Object o = xMSF.createInstance( + "com.sun.star.configuration.ConfigurationProvider"); + + // fetch the multi service factory for setup + XMultiServiceFactory xCP = (XMultiServiceFactory) + UnoRuntime.queryInterface(XMultiServiceFactory.class, o); + + // create the configuration reader + ConfigurationRead cfgRead = new ConfigurationRead(xCP); + + // get the document loader + String loader = getStringFromObject( + cfgRead.getByHierarchicalName(cfgString + "/ooSetupFactoryEmptyDocumentURL")); + + if (loader == null) return null; + log.println("\tLoader: " + loader); + + // read attributes + String hierchName = cfgString + "/ooSetupFactoryWindowAttributes"; + String setupSettings = getStringFromObject(cfgRead.getByHierarchicalName(hierchName)); + // remove slots: just plain document types have to start + if ( loader.indexOf("?slot") != -1 ) { + loader = loader.substring(0, loader.indexOf("?slot")); + System.out.println("Loader: "+loader); + } + + conf[0] = loader; + conf[1] = setupSettings; + } + catch(com.sun.star.uno.Exception e) {} + return conf; + } + + /** + * Load a document + * @param xMSF A MultiServiceFactory from an office + * @param docLoader A documet loader + * @return A handle to the document + */ + private DocumentHandle loadDocument(XMultiServiceFactory xMSF, + String docLoader) { + DocumentHandle docHandle = null; + try { + // create component loaader + XComponentLoader xCompLoader = (XComponentLoader) + UnoRuntime.queryInterface( + XComponentLoader.class, xMSF.createInstance( + "com.sun.star.frame.Desktop")); + XFramesSupplier xFrameSupp = (XFramesSupplier)UnoRuntime.queryInterface(XFramesSupplier.class, xCompLoader); + // close all existing frames + XFrames xFrames = xFrameSupp.getFrames(); + XIndexAccess xAcc = (XIndexAccess)UnoRuntime.queryInterface(XIndexAccess.class, xFrames); + for ( int i=0; i<xAcc.getCount(); i++ ) { + XCloseable xClose = (XCloseable)UnoRuntime.queryInterface(XCloseable.class, xAcc.getByIndex(i)); + try { + if ( xClose != null ) { + xClose.close(false); + } + else { + failed("Could not query frame for XCloseable!"); + } + } + catch( com.sun.star.uno.Exception e ) { + e.printStackTrace((java.io.PrintWriter)log); + failed("Could not query frame for XCloseable!"); + } + } + docHandle = new DocumentHandle(xCompLoader); + docHandle.loadDocument(docLoader, false); + } + catch(com.sun.star.uno.Exception e) { + e.printStackTrace(); + } + catch(java.lang.Exception e) { + e.printStackTrace(); + } + return docHandle; + } + + private boolean connect() { + try { + xMSF = (XMultiServiceFactory)oProvider.getManager(param); + try { + Thread.sleep(10000); + } + catch(java.lang.InterruptedException e) {} + } + catch (java.lang.Exception e) { + log.println(e.getClass().getName()); + log.println("Message: " + e.getMessage()); + failed("Cannot connect the Office."); + return false; + } + return true; + } + + private boolean disconnect() { + try { + XDesktop desk = null; + desk = (XDesktop) UnoRuntime.queryInterface( + XDesktop.class, xMSF.createInstance( + "com.sun.star.frame.Desktop")); + xMSF = null; + desk.terminate(); + log.println("Waiting " + iOfficeCloseTime + " milliseconds for the Office to close down"); + try { + Thread.sleep(iOfficeCloseTime); + } + catch(java.lang.InterruptedException e) {} + } + catch (java.lang.Exception e) { + e.printStackTrace(); + failed("Cannot dispose the Office."); + return false; + } + return true; + } + + private static String getStringFromObject(Object oName) { + if (oName instanceof String) + return (String)oName; + String value = null; + if (oName instanceof Any) { + try { + value = AnyConverter.toString(oName); + if (value == null) { + log.println("Got a void css.uno.Any as loading string."); + } + } + catch(Exception e) { + log.println("This document type cannot be opened directly."); + } + } + return value; + } + + /** + * Compare two rectangles. Return true, if both are equal, false + * otherwise. + * @param rect1 First Rectangle. + * @param rect2 Second Rectangle. + * @return True, if the rectangles are equal. + */ + private boolean compareRectangles(Rectangle rect1, Rectangle rect2) { + boolean result = true; + result &= (rect1.X==rect2.X); + result &= (rect1.Y==rect2.Y); + result &= (rect1.Width==rect2.Width); + result &= (rect1.Height==rect2.Height); + return result; + } +} diff --git a/vcl/qa/complex/persistent_window_states/PersistentWindowTest.props b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.props new file mode 100644 index 000000000000..df96e1592834 --- /dev/null +++ b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.props @@ -0,0 +1,10 @@ +# test can be long: so increase the time until the test is interrupted +# time in milliseconds +ThreadTimeOut=50000000 + +# wait for the Office to close: may be increased on slower machines +# time in milliseconds +OfficeCloseTime=5000 + +# do not start an Office initially +NoOffice=yes diff --git a/vcl/qa/complex/persistent_window_states/makefile.mk b/vcl/qa/complex/persistent_window_states/makefile.mk new file mode 100644 index 000000000000..1be4474651e9 --- /dev/null +++ b/vcl/qa/complex/persistent_window_states/makefile.mk @@ -0,0 +1,85 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.5.124.1 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ = ..$/..$/.. +TARGET = PersistentWindowTest +PRJNAME = $(TARGET) +PACKAGE = complex$/persistent_window_states + +# --- Settings ----------------------------------------------------- +.INCLUDE: settings.mk + +#----- compile .java files ----------------------------------------- + +JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar +JAVAFILES = PersistentWindowTest.java DocumentHandle.java + +#----- make a jar from compiled files ------------------------------ + +MAXLINELENGTH = 100000 + +JARCLASSDIRS = $(PACKAGE) +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE + +# --- Parameters for the test -------------------------------------- + +# test base is java complex +CT_TESTBASE = -TestBase java_complex + +# test looks something like the.full.package.TestName +CT_TEST = -o $(PACKAGE:s\$/\.\).$(TARGET) + +# start the runner application +CT_APP = org.openoffice.Runner + +# --- Targets ------------------------------------------------------ + +$(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props : ALLTAR + +.INCLUDE : target.mk + +$(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props : $(TARGET).props + cp $(TARGET).props $@ + jar uf $(CLASSDIR)$/$(JARTARGET) -C $(CLASSDIR) $(PACKAGE)$/$(TARGET).props + +RUN: run + +# start an office if the parameter is set for the makefile +.IF "$(OFFICE)" == "" +run: + @echo "Execute this test with 'dmake run OFFICE=/system/path/to/office/program'." + @echo "The office will be started by the test with a socket connection on port 8100" +.ELSE +run: $(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props + java -cp $(CLASSPATH) $(CT_APP) -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" $(CT_TESTBASE) $(CT_TEST) +.ENDIF + |