/******************************************************************************* * Copyright (c) 2007 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.seam.core.test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.List; import junit.framework.TestCase; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.jboss.tools.common.util.FileUtil; import org.jboss.tools.seam.core.ISeamComponent; import org.jboss.tools.seam.core.ISeamProject; import org.jboss.tools.seam.internal.core.SeamProject; import org.jboss.tools.test.util.JUnitUtils; import org.jboss.tools.test.util.JobUtils; import org.jboss.tools.test.util.ResourcesUtils; import org.jboss.tools.test.util.TestProjectProvider; import org.osgi.framework.Bundle; /** * Test checks that loading Seam model does not depend as N*N on the number of components N. * It works as follows: * 1. Copy project template to workspace and import it. * 2. Create N=1000 java files with seam components in the project and refresh it. * 3. Reload Seam model and compute times T1 and T2 needed * to process first K=200 files and last K=200 files. * 4. Test fails if T2 is 3 or more times larger than T1, * which positively implies N*N dependency. * * @author Viacheslav Kabanovich * */ public class SeamBigProjectTest extends TestCase { static String BUNDLE = "org.jboss.tools.seam.base.test"; IProject project; TestProjectProvider provider; @Override protected void setUp() throws Exception { provider = new TestProjectProvider(BUNDLE,"/projects/bigProject" , "bigProject", true); project = provider.getProject(); IFolder folder = project.getFolder(new Path("src/action/p")); InputStream template = getTemplateFile(); boolean saveAutoBuild = ResourcesUtils.setBuildAutomatically(false); SeamBigProjectGenerator g = new SeamBigProjectGenerator(); g.generate(folder, template); //To ensure that the project is built. project.build(IncrementalProjectBuilder.CLEAN_BUILD, new NullProgressMonitor()); project.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor()); ResourcesUtils.setBuildAutomatically(saveAutoBuild); } private InputStream getTemplateFile() { String entry = "/projects/template.txt"; Bundle bundle = Platform.getBundle(BUNDLE); URL url = null; try { url = FileLocator.resolve(bundle.getEntry(entry)); } catch (IOException e) { return null; } try { return url.openStream(); } catch (IOException e) { fail("Cannot find entry " + entry + " in " + BUNDLE); return null; } } public void testBigProject() throws IOException { ISeamProject sp = getSeamProject(); ISeamComponent[] cs = sp.getComponents(); int components = cs.length; if(components < 500) { fail("Found only " + components + " components. Must be more than 500."); } SeamProject impl = (SeamProject)sp; System.out.println("Full build of " + components + " components completed in " + impl.fullBuildTime + "ms"); impl.store(); long time = impl.reload(); System.out.println("Reloaded " + sp.getComponents().length + " components in " + time + "ms"); List<Long> statistics = impl.statistics; impl.statistics = null; assertTrue("Statistics contains less than 500 items", statistics.size() >= 500); long t1 = 0, t2 = 0; for (int i = 0; i < 200; i++) { t1 += statistics.get(i); t2 += statistics.get(statistics.size() - 1 - i); } System.out.println("First 200 paths are loaded in " + t1 + "ms"); System.out.println("Last 200 paths are loaded in " + t2 + "ms"); double d = 1d * t2 / t1; if(d > 5d) { fail("It takes " + d + " times longer to load path in the end " + "of seam model loading than in the beginning.\n" + "That implies that time depends as N*N on the number of components N."); } generateLongXHTML(cs); } private ISeamProject getSeamProject() { ISeamProject seamProject = null; try { seamProject = (ISeamProject)project.getNature(SeamProject.NATURE_ID); } catch (Exception e) { JUnitUtils.fail("Cannot get seam nature.",e); } assertNotNull("Seam project is null", seamProject); return seamProject; } @Override protected void tearDown() throws Exception { ISeamProject sp = getSeamProject(); SeamProject impl = (SeamProject)sp; if(impl != null) impl.clearStorage(); provider.dispose(); } private void generateLongXHTML(ISeamComponent[] cs) { StringBuffer sb = new StringBuffer(); IFolder webContent = project.getFolder("WebContent"); IFile tmpl = webContent.getFile("login.xhtml"); String s = FileUtil.readFile(tmpl.getLocation().toFile()); int i = s.indexOf("<h:form"); int j = s.indexOf(">", i) + 1; sb.append(s.substring(0, j)); int k = 0; for (ISeamComponent c: cs) { k++; String n = c.getName(); if(!n.startsWith("x")) continue; String q = "\n<h:inputText id=\"k" + k + "\" " + "value=\"#{" + n + ".value}\"/>\n"; sb.append(q); } sb.append(s.substring(j)); IFile file = webContent.getFile("long.xhtml"); try { // boolean save = ResourcesUtils.setBuildAutomatically(false); file.create(new ByteArrayInputStream(sb.toString().getBytes()), true, new NullProgressMonitor()); long time = System.currentTimeMillis(); // project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new NullProgressMonitor()); JobUtils.waitForIdle(); long dt = System.currentTimeMillis() - time; System.out.println("validated in " + dt); // ResourcesUtils.setBuildAutomatically(save); assertTrue("Validator takes more than 5s (" + ((dt-500)/1000d) + ") for validating generated long.xhtml", ((dt-500)/1000d) < 5); } catch (CoreException e) { JUnitUtils.fail("", e); } } }