update dev300-m58
[ooovba.git] / vcl / qa / complex / memCheck / CheckMemoryUsage.java
blob90d82dd99f7925ffce05679010cb025c38a66665
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CheckMemoryUsage.java,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 package complex.memCheck;
32 import com.sun.star.beans.PropertyValue;
33 import com.sun.star.frame.XStorable;
34 import com.sun.star.lang.XComponent;
35 import com.sun.star.lang.XMultiServiceFactory;
36 import com.sun.star.uno.UnoRuntime;
37 import com.sun.star.util.XCloseable;
38 import complexlib.ComplexTestCase;
39 import helper.ProcessHandler;
40 import java.io.File;
41 import java.io.FilePermission;
42 import java.io.FileWriter;
43 import java.io.FilenameFilter;
44 import java.io.PrintWriter;
45 import java.util.Enumeration;
46 import java.util.StringTokenizer;
47 import java.util.Vector;
48 import util.DesktopTools;
49 import util.WriterTools;
50 import util.utils;
52 /**
53 * Documents are opened and exported with StarOffice. The memory usage of
54 * StarOffice is monitored and if the usage exceeds the allowed kilobytes,
55 * the test is failed. Used for monitoring the StarOffice process is the
56 * command line tool 'pmap', available on Solaris or Linux. This test will not
57 * run on Windows.<br>Test procedure: every given document type is searched in
58 * the source directory
59 * Needed paramters:
60 * <ul>
61 * <li>"TestDocumentPath" - the path where test documents are located.</li>
62 * <li>"AllowMemoryIncrease" (optional) - the allowed memory increase measured in kByte per exported document. The default is 10 kByte.</li>
63 * <li>"ExportDocCount" (optional) - the amount of exports for each document that is loaded. Is defaulted to 25.
64 * <li>"FileExportFilter" (optional) - a relation between loaded document type and used export filter. Is defaulted to
65 * writer, calc and impress. This parameter can be set with a number to give more than one relation. Example:<br>
66 * "FileExportFilter1=sxw,writer_pdf_Export"<br>
67 * "FileExportFilter2=sxc,calc_pdf_Export"<br>
68 * "FileExportFilter3=sxi,impress_pdf_Export"<br></li>
69 * All parameters are used for iteration over the test document path.
70 * </ul>
72 public class CheckMemoryUsage extends ComplexTestCase {
73 private final String sWriterDoc = "sxw,writer_pdf_Export";
74 private final String sCalcDoc = "sxc,calc_pdf_Export";
75 private final String sImpressDoc = "sxi,impress_pdf_Export";
76 private String sProcessId = "ps -ef | grep $USER | grep soffice | grep -v grep";
77 private String sMemoryMonitor = "pmap <processID> | grep total";
78 private String sChmod = "chmod 777 ";
79 private String sProcessIdCommand = null;
80 private String sOfficeMemoryCommand = null;
81 private String sTempDir = null;
82 private String sFS = null;
83 private String sMemoryMap1 = null;
84 private String sMemoryMap2 = null;
85 private String bash = "#!/bin/bash";
86 private String sDocumentPath = "";
87 private String[][] sDocTypeExportFilter;
88 private String[][] sDocuments;
89 private int iAllowMemoryIncrease = 10;
90 private int iExportDocCount = 25;
92 /**
93 * Get all test methods
94 * @return The test methods.
96 public String[] getTestMethodNames() {
97 return new String[] {"loadAndSaveDocuments"};
101 * Collect all documnets to load and all filters used for export.
103 public void before() {
104 // test does definitely not run on Windows.
105 if (param.get("OperatingSystem").equals("wntmsci")) {
106 log.println("Test can only reasonably be executed with a tool that "
107 + "displays the memory usage of StarOffice.");
108 failed("Test does not run on Windows, only on Solaris or Linux.");
111 // how many times is every document exported.
112 int count = param.getInt("ExportDocCount");
113 if (count != 0)
114 iExportDocCount = count;
116 // get the temp dir for creating the command scripts.
117 sTempDir = System.getProperty("java.io.tmpdir");
118 sProcessIdCommand = sTempDir + "getPS";
119 sOfficeMemoryCommand = sTempDir + "getPmap";
121 // get the file extension, export filter connection
122 Enumeration keys = param.keys();
123 Vector v = new Vector();
124 while(keys.hasMoreElements()) {
125 String key = (String)keys.nextElement();
126 if (key.startsWith("FileExportFilter")) {
127 v.add(param.get(key));
130 // if no param given, set defaults.
131 if (v.size() == 0){
132 v.add(sWriterDoc);
133 v.add(sCalcDoc);
134 v.add(sImpressDoc);
136 // store a file extension
137 sDocTypeExportFilter = new String[v.size()][2];
138 for (int i=0; i<v.size(); i++) {
139 // 2do: error routine for wrong given params
140 StringTokenizer t = new StringTokenizer((String)v.get(i), ",");
141 sDocTypeExportFilter[i][0] = t.nextToken();
142 sDocTypeExportFilter[i][1] = t.nextToken();
145 // get files to load and export
146 sDocumentPath = (String)param.get("TestDocumentPath");
147 File f = new File(sDocumentPath);
148 sDocumentPath = f.getAbsolutePath();
149 String sFS = System.getProperty("file.separator");
150 sDocuments = new String[sDocTypeExportFilter.length][];
151 for (int j=0; j<sDocTypeExportFilter.length; j++) {
152 FileFilter filter = new FileFilter(sDocTypeExportFilter[j][0]);
153 String[] doc = f.list(filter);
154 sDocuments[j] = new String[doc.length];
155 for (int i=0; i<doc.length; i++) {
156 if (sDocumentPath.endsWith(sFS))
157 sDocuments[j][i] = sDocumentPath + doc[i];
158 else
159 sDocuments[j][i] = sDocumentPath + sFS + doc[i];
160 sDocuments[j][i] = utils.getFullURL(sDocuments[j][i]);
166 * delete all created files on disk
168 public void after() {
169 // delete the constructed files.
170 for (int i=0; i<iExportDocCount; i++) {
171 File f = new File(sTempDir + "DocExport" + i + ".pdf");
172 f.delete();
174 File f = new File(sProcessIdCommand);
175 f.delete();
176 f = new File(sOfficeMemoryCommand);
177 f.delete();
181 * Thet etst function: load documents and save them using the given filters
182 * for each given document type.
184 public void loadAndSaveDocuments() {
185 int storageBefore = getOfficeMemoryUsage();
187 XMultiServiceFactory xMSF = (XMultiServiceFactory)param.getMSF();
189 // iterate over all document types
190 for (int k=0; k<sDocTypeExportFilter.length; k++) {
191 // iterate over all documents of this type
192 for (int i=0; i<sDocuments[k].length; i++) {
193 System.out.println("Document: "+ sDocuments[k][i]);
194 XComponent xComponent = DesktopTools.loadDoc(xMSF, sDocuments[k][i], null);
195 XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xComponent);
196 if (xStorable != null) {
197 // export each document iExportDocCount times
198 for (int j=0; j<iExportDocCount; j++) {
199 String url = utils.getFullURL(sTempDir + "DocExport" + j + ".pdf");
200 try {
201 PropertyValue[] props = new PropertyValue[1];
202 props[0] = new PropertyValue();
203 props[0].Name = "FilterName";
204 // use export filter for this doc type
205 props[0].Value = sDocTypeExportFilter[k][1];
206 xStorable.storeToURL(url, props);
208 catch(com.sun.star.io.IOException e) {
209 failed("Could not store to '" + url + "'", true);
212 // close the doc
213 XCloseable xCloseable = (XCloseable)UnoRuntime.queryInterface(XCloseable.class, xStorable);
214 try {
215 xCloseable.close(true);
217 catch(com.sun.star.util.CloseVetoException e) {
218 e.printStackTrace((java.io.PrintWriter)log);
219 failed("Cannot close document: test is futile, Office will surely use more space.");
222 else {
223 log.println("Cannot query for XStorable interface on document '" + sDocuments[i] + "'");
224 log.println(" -> Skipping storage.");
228 // short wait for the office to 'calm down' and free some memory
229 shortWait(5000);
230 // wait util memory is not freed anymore.
231 int storageAfter = getOfficeMemoryUsage();
232 int mem = 0;
233 int count = 0;
234 while (storageAfter != mem && count < 10) {
235 count++;
236 mem = storageAfter;
237 storageAfter = getOfficeMemoryUsage();
238 shortWait(1000);
240 assure("The Office consumes now " + (storageAfter - storageBefore)
241 + "K more memory than at the start of the test; allowed were "
242 + iAllowMemoryIncrease * iExportDocCount + "K.",
243 storageAfter - storageBefore < iAllowMemoryIncrease * iExportDocCount);
248 * Get the process ID from the Office
249 * @return the Id as String
251 private String getOfficeProcessID() {
252 writeExecutableFile(sProcessIdCommand, sProcessId);
253 ProcessHandler processID = new ProcessHandler(sProcessIdCommand);
254 processID.executeSynchronously();
255 String text = processID.getOutputText();
256 if (text == null || text.equals("") || text.indexOf(' ') == -1)
257 failed("Could not determine Office process ID. Check " + sProcessIdCommand);
258 StringTokenizer aToken = new StringTokenizer(text);
259 // this is not nice, but ps gives the same output on every machine
260 aToken.nextToken();
261 String id = aToken.nextToken();
262 return id;
266 * Get the memory usage of the Office in KByte.
267 * @return The memory used by the Office.
269 private int getOfficeMemoryUsage() {
270 String command = sMemoryMonitor.replaceAll("<processID>", getOfficeProcessID());
271 writeExecutableFile(sOfficeMemoryCommand, command);
272 ProcessHandler processID = new ProcessHandler(sOfficeMemoryCommand);
273 processID.executeSynchronously();
274 String text = processID.getOutputText();
275 if (text == null || text.equals("") || text.indexOf(' ') == -1) {
276 failed("Could not determine Office memory usage. Check " + sOfficeMemoryCommand);
278 StringTokenizer aToken = new StringTokenizer(text);
279 // this works, because the output of pmap is quite standardized.
280 aToken.nextToken();
281 String mem = aToken.nextToken();
282 mem = mem.substring(0, mem.indexOf('K'));
283 Integer memory = new Integer(mem);
284 return memory.intValue();
288 * Write a script file and set its rights to rwxrwxrwx.
289 * @param fileName The name of the created file
290 * @param line The commandline that has to be written inside of the file.
292 private void writeExecutableFile(String fileName, String line) {
293 try {
294 PrintWriter fWriter = new PrintWriter(new FileWriter(fileName));
295 fWriter.println(bash);
296 fWriter.println(line);
297 fWriter.close();
298 // change rights to rwxrwxrwx
299 ProcessHandler processID = new ProcessHandler(sChmod + fileName);
300 processID.executeSynchronously();
302 catch(java.io.IOException e) {
307 * Let this thread sleep for some time
308 * @param milliSeconds time to wait in milliseconds.
310 private void shortWait(int milliSeconds) {
311 try {
312 Thread.sleep(milliSeconds);
314 catch(java.lang.InterruptedException e) { // ignore
319 * Own file filter, will just return ok for all files that end with a given
320 * suffix
322 private class FileFilter implements FilenameFilter {
323 private String suffix = null;
325 * C'tor.
326 * @param suffix The suffix each filename should end with.
328 public FileFilter(String suffix) {
329 this.suffix = suffix;
332 * Returns true, if the name of the file has the suffix given to the
333 * c'tor.
334 * @param name The filename that is tested.
335 * @param file Not used.
336 * @return True, if name ends with suffix.
338 public boolean accept(File file, String name) {
339 return name.endsWith(suffix);