Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcvs2svn2004-11-03 12:04:42 -0500
committercvs2svn2004-11-03 12:04:42 -0500
commit94843f77c21e0f2621012aa48225fb6c99da9e9d (patch)
tree53a75ed040f107dbc3f776b41940458a6c250af1
parent94791b73765c2e7d04f31505b583af45468fdf2e (diff)
downloadeclipse.platform.team-94843f77c21e0f2621012aa48225fb6c99da9e9d.tar.gz
eclipse.platform.team-94843f77c21e0f2621012aa48225fb6c99da9e9d.tar.xz
eclipse.platform.team-94843f77c21e0f2621012aa48225fb6c99da9e9d.zip
This commit was manufactured by cvs2svn to create branch 'R3_0_maintenance'.
Cherrypick from master 2004-11-03 17:04:40 UTC Jean Michel-Lemieux <jlemieux> 'Removed tests that didn't run long enough and fixed the tagAsSummary tests.': tests/org.eclipse.team.tests.cvs.core/launchConfigurations/Performance - SyncTests.launch tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTest.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTestSetup.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkUtils.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SequenceGenerator.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/ShareAndCheckoutTest.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SyncTests.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/Util.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/WorkflowTests.java
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/launchConfigurations/Performance - SyncTests.launch26
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTest.java218
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTestSetup.java59
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkUtils.java552
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SequenceGenerator.java63
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/ShareAndCheckoutTest.java45
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SyncTests.java98
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/Util.java46
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/WorkflowTests.java169
9 files changed, 1276 insertions, 0 deletions
diff --git a/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/Performance - SyncTests.launch b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/Performance - SyncTests.launch
new file mode 100644
index 000000000..fe114363a
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/Performance - SyncTests.launch
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
+<stringAttribute key="product" value="org.eclipse.jabber.standalone1.product"/>
+<booleanAttribute key="clearws" value="true"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.team.tests.ccvs.ui.benchmark.SyncTests"/>
+<booleanAttribute key="useProduct" value="false"/>
+<booleanAttribute key="tracing" value="false"/>
+<stringAttribute key="location1" value="C:\Eclipse\Latest\eclipse-0924\runtime-test-workspace"/>
+<stringAttribute key="vmargs" value="-Declipse.cvs.properties=c:\eclipse\repository.properties -DInternalPrintPerformanceResults"/>
+<booleanAttribute key="default" value="true"/>
+<booleanAttribute key="clearConfig" value="false"/>
+<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<stringAttribute key="progargs" value="-os win32 -ws win32 -arch x86 -nl en_US -clean"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<booleanAttribute key="automaticAdd" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.team.tests.cvs.core"/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="includeFragments" value="false"/>
+<stringAttribute key="location0" value="C:\Eclipse\Latest\eclipse-0924\runtime-test-workspace"/>
+</launchConfiguration>
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTest.java
new file mode 100644
index 000000000..87521c97a
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTest.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.zip.ZipException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.subscribers.Subscriber;
+import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.tests.ccvs.core.EclipseTest;
+import org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource;
+import org.eclipse.team.tests.ccvs.ui.SynchronizeViewTestAdapter;
+import org.eclipse.test.performance.*;
+import org.eclipse.test.performance.Performance;
+import org.eclipse.test.performance.PerformanceMeter;
+
+/**
+ * Benchmark test superclass
+ */
+public abstract class BenchmarkTest extends EclipseTest {
+
+ private HashMap groups;
+ private PerformanceMeter currentMeter;
+ private static SyncInfoSource source = new SynchronizeViewTestAdapter();
+
+ protected BenchmarkTest() {
+ }
+
+ protected BenchmarkTest(String name) {
+ super(name);
+ }
+
+ protected IProject createUniqueProject(File zipFile) throws TeamException, CoreException, ZipException, IOException, InterruptedException, InvocationTargetException {
+ return createAndImportProject(getName(), zipFile);
+ }
+
+ protected IProject createAndImportProject(String prefix, File zipFile) throws TeamException, CoreException, ZipException, IOException, InterruptedException, InvocationTargetException {
+ // create a project with no contents
+ IProject project = getUniqueTestProject(prefix);
+ Util.importZip(project, zipFile);
+ return project;
+ }
+
+ /**
+ * @param string
+ */
+ protected void startTask(String string) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ *
+ */
+ protected void endTask() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Create a set of perforance meters that can be started with the
+ * startGroup method.
+ * @param performance_groups
+ */
+ protected void setupGroups(String[] performance_groups) {
+ setupGroups(performance_groups, null, false);
+ }
+
+ protected void setupGroups(String[] performance_groups, String globalName, boolean global) {
+ groups = new HashMap();
+ Performance perf = Performance.getDefault();
+ PerformanceMeter meter = null;
+ if (global) {
+ // Use one meter for all groups - provides a single timing result
+ meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
+ for (int i = 0; i < performance_groups.length; i++) {
+ String suffix = performance_groups[i];
+ groups.put(suffix, meter);
+ }
+ perf.tagAsGlobalSummary(meter, globalName, Dimension.CPU_TIME);
+ } else {
+ // Use a meter for each group, provides fine grain results
+ for (int i = 0; i < performance_groups.length; i++) {
+ String suffix = performance_groups[i];
+ meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this) + suffix);
+ groups.put(suffix, meter);
+ if (globalName != null) {
+ perf.tagAsSummary(meter, suffix, Dimension.CPU_TIME);
+ }
+ }
+ }
+ }
+
+ /**
+ * Commit the performance meters that were created by setupGroups and
+ * started and stoped using startGroup/endGroup
+ */
+ protected void commitGroups(boolean global) {
+ for (Iterator iter = groups.values().iterator(); iter.hasNext();) {
+ PerformanceMeter meter = (PerformanceMeter) iter.next();
+ meter.commit();
+ if(global)
+ break;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.tests.ccvs.core.EclipseTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ try {
+ if (groups != null) {
+ Performance perf = Performance.getDefault();
+ try {
+ for (Iterator iter = groups.values().iterator(); iter.hasNext();) {
+ PerformanceMeter meter = (PerformanceMeter) iter.next();
+ perf.assertPerformance(meter);
+ }
+ } finally {
+ for (Iterator iter = groups.values().iterator(); iter.hasNext();) {
+ PerformanceMeter meter = (PerformanceMeter) iter.next();
+ meter.dispose();
+ }
+ }
+ groups = null;
+ }
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ /**
+ * Start the meter that was created for the given key
+ * @param string
+ */
+ protected void startGroup(String key) {
+ assertNull(currentMeter);
+ currentMeter = (PerformanceMeter)groups.get(key);
+ currentMeter.start();
+ }
+
+ /**
+ * End the current meter
+ */
+ protected void endGroup() {
+ currentMeter.stop();
+ currentMeter = null;
+ }
+
+ protected void disableLog() {
+ // TODO:
+ }
+
+ protected void enableLog() {
+ // TODO:
+ }
+
+ protected void syncResources(Subscriber subscriber, IResource[] resources) throws TeamException {
+ startTask("Synchronize with Repository action");
+ getSyncInfoSource().refresh(subscriber, resources);
+ endTask();
+ }
+
+ /**
+ * @param resources
+ * @param string
+ * @throws CoreException
+ * @throws TeamException
+ */
+ protected void syncCommitResources(IResource[] resources, String comment) throws TeamException, CoreException {
+ startTask("Synchronize outgoing changes");
+ syncResources(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(), resources);
+ endTask();
+ // TODO: Commit all outgoing changes that are children of the given resource
+ // by extracting them from the subscriber sync set
+ startTask("Commit outgoing changes");
+ commitResources(resources, IResource.DEPTH_INFINITE);
+ endTask();
+ }
+
+ /**
+ * @param resources
+ * @throws TeamException
+ */
+ protected void syncUpdateResources(IResource[] resources) throws TeamException {
+ startTask("Synchronize incoming changes");
+ syncResources(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(), resources);
+ endTask();
+ // TODO: Update all incoming changes that are children of the given resource
+ // by extracting them from the subscriber sync set
+ startTask("Update incoming changes");
+ updateResources(resources, false);
+ endTask();
+ }
+
+ /**
+ * @return
+ */
+ private SyncInfoSource getSyncInfoSource() {
+ return source;
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTestSetup.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTestSetup.java
new file mode 100644
index 000000000..700ccc35a
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkTestSetup.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import junit.framework.Test;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.team.tests.ccvs.core.CVSTestSetup;
+import org.osgi.framework.Bundle;
+
+public class BenchmarkTestSetup extends CVSTestSetup {
+ public static final File BIG_ZIP_FILE;
+ public static final File SMALL_ZIP_FILE;
+ public static final File TINY_ZIP_FILE;
+ public static int LOOP_COUNT;
+
+ // Static initializer for constants
+ static {
+ try {
+ LOOP_COUNT = Integer.valueOf(System.getProperty("eclipse.cvs.loopCount", "3")).intValue();
+ } catch (NumberFormatException e1) {
+ LOOP_COUNT = 1;
+ }
+ try {
+ BIG_ZIP_FILE = getTestFile("benchmarkBig.zip");
+ SMALL_ZIP_FILE = getTestFile("benchmarkSmall.zip");
+ TINY_ZIP_FILE = getTestFile("benchmarkTiny.zip");
+ } catch (IOException e) {
+ throw new Error(e.getMessage());
+ }
+ }
+
+ public static File getTestFile(String name) throws IOException {
+ Bundle b = Platform.getBundle("org.eclipse.team.tests.cvs.core");
+ URL url = b.getEntry("resources/BenchmarkTest/" + name);
+ url = Platform.resolve(url);
+ if (url.getProtocol().equals("file")) {
+ return new File(url.getFile()).getAbsoluteFile();
+ }
+ throw new IOException("Cannot find test file: " + name);
+ }
+
+ public BenchmarkTestSetup(Test test) {
+ super(test);
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkUtils.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkUtils.java
new file mode 100644
index 000000000..c044ce9a0
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/BenchmarkUtils.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import junit.framework.Assert;
+
+import org.eclipse.compare.structuremergeviewer.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.team.internal.ccvs.core.CVSStatus;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
+
+/**
+ * Provides helpers for:
+ * <ul>
+ * <li>Resource manipulation</li>
+ * <li>Diff trees</li>
+ * <li>UI automation</li>
+ * <li>Parallel development simulation</li>
+ * </ul>
+ *
+ * Note: This class is referenced from the VCM 1.0 performance tests.
+ */
+public class BenchmarkUtils {
+ /*** RESOURCE MANIPULATION SUPPORT ***/
+
+ /**
+ * Gets a handle for a project of a given name.
+ * @param name the project name
+ * @return the project handle
+ */
+ public static IProject getProject(String name) throws CoreException {
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ }
+
+ /**
+ * Creates a new project.
+ * @param name the project name
+ * @return the project handle
+ */
+ public static IProject createProject(String name) throws CoreException {
+ IProject project = getProject(name);
+ if (!project.exists()) project.create(null);
+ if (!project.isOpen()) project.open(null);
+ return project;
+ }
+
+ /**
+ * Deletes a project.
+ * @param project the project
+ */
+ public static void deleteProject(IProject project) throws CoreException {
+ project.delete(false /*force*/, null);
+ }
+
+ /**
+ * Deletes a file and prunes empty containing folders.
+ * @param file the file to delete
+ */
+ public static void deleteFileAndPrune(IFile file) throws CoreException {
+ file.delete(false /*force*/, null);
+ IContainer container = file.getParent();
+ while (container != null && container instanceof IFolder &&
+ isFolderEmpty((IFolder) container)) {
+ deleteFolder((IFolder) container);
+ container = container.getParent();
+ }
+ }
+
+ /**
+ * Deletes a folder.
+ */
+ public static void deleteFolder(IFolder folder) throws CoreException {
+ try {
+ folder.delete(false /*force*/, null);
+ } catch (CoreException e) {
+ IStatus status = e.getStatus();
+ // ignore errors caused by attempting to delete folders that CVS needs to have around
+ if (findStatusByCode(status, CVSStatus.FOLDER_NEEDED_FOR_FILE_DELETIONS) == null) {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Finds an IStatus instance in a multi-status by status code.
+ */
+ public static IStatus findStatusByCode(IStatus status, int code) {
+ if (status.getCode() == code) return status;
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ IStatus found = findStatusByCode(children[i], code);
+ if (found != null) return found;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a uniquely named project.
+ * @param prefix a string prepended to the generated name
+ * @return the new project
+ */
+ public static IProject createUniqueProject(String prefix) throws CoreException {
+ return createProject(makeUniqueName(null, prefix, null));
+ }
+
+ /**
+ * Creates a uniquely named file in the parent folder or project with random contents.
+ * @param gen the sequence generator
+ * @param parent the parent IFolder or IProject for the new file
+ * @param meanSize the mean size of file to create (in bytes)
+ * @param variance 69% of files with be within this amount of the mean
+ * @param probBinary the probability of a new file being binary as a percentage
+ * @return the new file
+ */
+ public static IFile createUniqueFile(SequenceGenerator gen, IContainer parent,
+ int meanSize, int variance, int probBinary) throws IOException, CoreException {
+ int fileSize;
+ do {
+ fileSize = (int) Math.abs(gen.nextGaussian() * variance + meanSize);
+ } while (fileSize > meanSize + variance * 4); // avoid huge files
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ String fileName;
+ if (gen.nextInt(100) < probBinary) {
+ fileName = makeUniqueName(gen, "file", "class"); // binary
+ writeRandomBytes(gen, os, fileSize);
+ } else {
+ fileName = makeUniqueName(gen, "file", "txt"); // text
+ writeRandomText(gen, os, fileSize);
+ }
+ IFile file = parent.getFile(new Path(fileName));
+ file.create(new ByteArrayInputStream(os.toByteArray()), true, null);
+ os.close();
+ return file;
+ }
+
+ /**
+ * Creates a uniquely named folder in the parent folder.
+ * @param gen the sequence generator
+ * @param parent the parent IFolder or IProject for the new folder
+ * @return the new folder
+ */
+ public static IFolder createUniqueFolder(SequenceGenerator gen, IContainer parent) throws CoreException {
+ IFolder folder = parent.getFolder(new Path(BenchmarkUtils.makeUniqueName(gen, "folder", null)));
+ folder.create(false /*force*/, true /*local*/, null);
+ return folder;
+ }
+
+ /**
+ * Renames a resource.
+ * The resource handle becomes invalid.
+ * @param resource the existing resource
+ * @param newName the new name for the resource
+ */
+ public static void renameResource(IResource resource, String newName) throws CoreException {
+ switch (resource.getType()) {
+ case IResource.PROJECT: {
+ IProject project = (IProject) resource;
+ IProjectDescription desc = project.getDescription();
+ desc.setName(newName);
+ project.move(desc, false /*force*/, true /*keepHistory*/, null);
+ } break;
+ case IResource.FOLDER: {
+ try {
+ resource.move(new Path(newName), false /*force*/, null);
+ } catch (CoreException e) {
+ IStatus status = e.getStatus();
+ // ignore errors caused by attempting to delete folders that CVS needs to have around
+ if (findStatusByCode(status, CVSStatus.FOLDER_NEEDED_FOR_FILE_DELETIONS) == null) {
+ throw e;
+ }
+ }
+ } break;
+ default:
+ resource.move(new Path(newName), false /*force*/, null);
+ break;
+ }
+ }
+
+ /**
+ * Modified a resource.
+ * @param gen the sequence generator
+ * @param file the file to modify
+ */
+ public static void modifyFile(SequenceGenerator gen, IFile file)
+ throws IOException, CoreException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ InputStream is = file.getContents(true);
+ try {
+ byte[] buffer = new byte[8192];
+ int rsize;
+ boolean changed = false;
+ while ((rsize = is.read(buffer)) != -1) {
+ double gaussian;
+ do {
+ gaussian = gen.nextGaussian() * 0.5; // large changes are less likely than small ones
+ } while (gaussian > 1.0 || gaussian < -1.0);
+ int changeSize = (int) (gaussian * rsize);
+ changed = changed || changeSize != 0;
+ os.write(buffer, 0, changeSize < 0 ? - changeSize : rsize); // shrink file
+ writeRandomText(gen, os, changeSize); // enlarge file
+ }
+ if (! changed) os.write('!'); // make sure we actually did change the file
+ file.setContents(new ByteArrayInputStream(os.toByteArray()), false /*force*/, true /*keepHistory*/, null);
+ } finally {
+ is.close();
+ }
+ } finally {
+ os.close();
+ }
+ }
+
+ /**
+ * Creates a unique name.
+ * Ensures that a deterministic sequence of names is generated for all files
+ * and folders within a project, though not across sessions.
+ *
+ * @param gen the generator, or null if this name is to be globally unique
+ * @param prefix a string prepended to the generated name
+ * @param extension the file extension not including the period, null if none
+ * @return the new name
+ */
+ public static String makeUniqueName(SequenceGenerator gen, String prefix, String extension)
+ throws CoreException {
+ StringBuffer name = new StringBuffer(prefix);
+ name.append('-');
+ if (gen == null) {
+ name.append(SequenceGenerator.nextGloballyUniqueLong());
+ } else {
+ name.append(gen.nextUniqueInt());
+ }
+ if (extension != null) {
+ name.append('.');
+ name.append(extension);
+ }
+ return name.toString();
+ }
+
+ /**
+ * Imports a .zip file into a container's root folder.
+ * @param container the container
+ * @param file the path of the .zip file
+ */
+ public static void importZip(IContainer container, File file)
+ throws IOException, ZipException, InterruptedException, InvocationTargetException {
+ ZipFile zipFile = new ZipFile(file);
+ ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
+ ImportOperation importOperation = new ImportOperation(container.getFullPath(),
+ provider.getRoot(), provider, null);
+ importOperation.setOverwriteResources(true); // don't ask
+ importOperation.run(new NullProgressMonitor());
+ Assert.assertTrue(importOperation.getStatus().isOK());
+ }
+
+ /**
+ * Writes random text to an output stream.
+ * @param gen the sequence generator
+ */
+ public static void writeRandomText(SequenceGenerator gen, OutputStream os, int count) throws IOException {
+ while (count-- > 0) {
+ int c = gen.nextInt(99);
+ os.write((c >= 95) ? '\n' : c + ' ');
+ }
+ }
+
+ /**
+ * Writes random bytes to an output stream.
+ * @param gen the sequence generator
+ */
+ public static void writeRandomBytes(SequenceGenerator gen, OutputStream os, int count) throws IOException {
+ while (count-- > 0) {
+ os.write(gen.nextInt(256));
+ }
+ }
+
+ /**
+ * Creates a random folder deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @return the new folder
+ */
+ public static IFolder createRandomDeepFolder(SequenceGenerator gen, IContainer root) throws CoreException {
+ IContainer container = pickRandomDeepContainer(gen, root);
+ for (;;) {
+ IFolder folder = createUniqueFolder(gen, container);
+ container = folder;
+ // 12.5% chance of creating a nested folder
+ if (gen.nextInt(8) != 0) return folder;
+ }
+ }
+
+ /**
+ * Creates several random files deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @param count the number of files to create
+ * @param meanSize the mean size of file to create (in bytes)
+ * @param probBinary the probability of a new file being binary as a percentage
+ */
+ public static void createRandomDeepFiles(SequenceGenerator gen, IContainer root, int count,
+ int meanSize, int variance, int probBinary) throws IOException, CoreException {
+ while (count-- > 0) {
+ createUniqueFile(gen, pickRandomDeepContainer(gen, root), meanSize, variance, probBinary);
+ }
+ }
+
+ /**
+ * Deletes several random files deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @param count the number of files to delete
+ */
+ public static void deleteRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException {
+ while (count-- > 0) {
+ IFile file = pickRandomDeepFile(gen, root);
+ if (file == null) break;
+ deleteFileAndPrune(file);
+ }
+ }
+
+ /**
+ * Modifies several random files deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @param count the number of files to modify
+ */
+ public static void modifyRandomDeepFiles(SequenceGenerator gen, IContainer root, int count)
+ throws IOException, CoreException {
+ // perhaps we can add a parameter for the "magnitude" of the change
+ while (count-- > 0) {
+ IFile file = pickRandomDeepFile(gen, root);
+ if (file == null) break;
+ modifyFile(gen, file);
+ }
+ }
+
+ /**
+ * Touches several random files deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @param count the number of files to touch
+ */
+ public static void touchRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException {
+ while (count-- > 0) {
+ IFile file = pickRandomDeepFile(gen, root);
+ if (file == null) break;
+ file.touch(null);
+ }
+ }
+
+ /**
+ * Renames several random files deeply below the root folder.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @param count the number of files to touch
+ */
+ public static void renameRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException {
+ IProject project = root.getProject();
+ while (count-- > 0) {
+ IFile file = pickRandomDeepFile(gen, root);
+ if (file == null) break;
+ renameResource(file, makeUniqueName(gen, "file", file.getFileExtension()));
+ }
+ }
+
+ /**
+ * Picks a random file from the parent folder or project.
+ * @param gen the sequence generator
+ * @param parent the parent IFolder or IProject for the operation
+ * @return the file that was chosen, or null if no suitable files
+ */
+ public static IFile pickRandomFile(SequenceGenerator gen, IContainer parent) throws CoreException {
+ IResource[] members = filterResources(parent.members());
+ for (int size = members.length; size != 0; --size) {
+ int elem = gen.nextInt(size);
+ if (members[elem] instanceof IFile) return (IFile) members[elem];
+ System.arraycopy(members, elem + 1, members, elem, size - elem - 1);
+ }
+ return null;
+ }
+
+ /**
+ * Picks a random folder from the parent folder or project.
+ * @param gen the sequence generator
+ * @param parent the parent IFolder or IProject for the operation
+ * @return the folder, or null if no suitable folders
+ */
+ public static IFolder pickRandomFolder(SequenceGenerator gen, IContainer parent) throws CoreException {
+ IResource[] members = filterResources(parent.members());
+ for (int size = members.length; size != 0; --size) {
+ int elem = gen.nextInt(size);
+ if (members[elem] instanceof IFolder) return (IFolder) members[elem];
+ System.arraycopy(members, elem + 1, members, elem, size - elem - 1);
+ }
+ return null;
+ }
+
+ /**
+ * Picks a random file deeply from the root folder or project.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @return the file that was chosen, or null if no suitable files
+ */
+ public static IFile pickRandomDeepFile(SequenceGenerator gen, IContainer root) throws CoreException {
+ IResource[] members = filterResources(root.members());
+ for (int size = members.length; size != 0; --size) {
+ int elem = gen.nextInt(size);
+ IResource resource = members[elem];
+ if (resource instanceof IFile) return (IFile) resource;
+ if (resource instanceof IFolder) {
+ IFile file = pickRandomDeepFile(gen, (IFolder) resource);
+ if (file != null) return file;
+ }
+ System.arraycopy(members, elem + 1, members, elem, size - elem - 1);
+ }
+ return null;
+ }
+
+ /**
+ * Picks a random folder deeply from the root folder or project.
+ * May pick the project's root container.
+ * @param gen the sequence generator
+ * @param root the root IFolder or IProject for the operation
+ * @return the container that was chosen, never null
+ */
+ public static IContainer pickRandomDeepContainer(SequenceGenerator gen, IContainer root) throws CoreException {
+ if (gen.nextInt(6) == 0) {
+ IResource[] members = filterResources(root.members());
+ for (int size = members.length; size != 0; --size) {
+ int elem = gen.nextInt(size);
+ IResource resource = members[elem];
+ if (resource instanceof IFolder) {
+ return pickRandomDeepContainer(gen, (IFolder) resource);
+ }
+ System.arraycopy(members, elem + 1, members, elem, size - elem - 1);
+ }
+ }
+ Assert.assertTrue(isValidContainer(root));
+ return root;
+ }
+
+ /**
+ * Returns true if the folder does not contain any real files.
+ */
+ public static boolean isFolderEmpty(IFolder folder) throws CoreException {
+ IResource[] members = folder.members();
+ for (int i = 0; i < members.length; ++i) {
+ if (isValidFile(members[i]) || isValidFolder(members[i])) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns true iff file is a valid IFile (that should not be ignored).
+ */
+ public static boolean isValidFile(IResource file) throws CoreException {
+ String name = file.getName();
+ return file instanceof IFile
+ && ! file.isPhantom()
+ && ! name.equals(".classpath")
+ && ! name.equals(".project")
+ && ! name.equals(".vcm_meta");
+ }
+
+ /**
+ * Returns true iff folder is a valid IFolder (that should not be ignored).
+ */
+ public static boolean isValidFolder(IResource folder) throws CoreException {
+ String name = folder.getName();
+ return folder instanceof IFolder
+ && ! folder.isPhantom()
+ && ! name.equals("CVS")
+ && ! name.equals("bin");
+ }
+
+ /**
+ * Returns true iff container is a valid IFolder or IProject (that should not be ignored).
+ */
+ public static boolean isValidContainer(IResource container) throws CoreException {
+ return container instanceof IProject || isValidFolder(container);
+ }
+
+ /**
+ * Returns true iff resource is a valid IFile, IFolder or IProject (that should not be ignored).
+ */
+ public static boolean isValidResource(IResource resource) throws CoreException {
+ return isValidFile(resource) || isValidContainer(resource);
+ }
+
+ /**
+ * Filters and sorts an array of resources to ensure deterministic behaviour across
+ * sessions. The general idea is to guarantee that given a known sequence of
+ * pseudo-random numbers, we will always pick the same sequence of files and
+ * folders each time we repeat the test.
+ */
+ public static IResource[] filterResources(IResource[] resources) throws CoreException {
+ List list = new ArrayList(resources.length);
+ for (int i = 0; i < resources.length; ++i) {
+ if (isValidResource(resources[i])) list.add(resources[i]);
+ }
+ if (list.size() != resources.length) {
+ resources = (IResource[]) list.toArray(new IResource[list.size()]);
+ }
+ Arrays.sort(resources, new Comparator() {
+ public int compare(Object a, Object b) {
+ return ((IResource) a).getName().compareTo(((IResource) b).getName());
+ }
+ });
+ return resources;
+ }
+
+ /*** DIFF SUPPORT ***/
+
+ public static boolean isEmpty(IDiffContainer node) {
+ if (node == null) return true;
+ if (node.getKind() != 0) return false;
+ IDiffElement[] children = node.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ if (!isEmpty(children[i])) return false;
+ }
+ return true;
+ }
+ public static boolean isEmpty(IDiffElement element) {
+ if (element == null) return true;
+ if (element.getKind() != 0) return false;
+ if (element instanceof IDiffContainer) {
+ IDiffElement[] children = ((DiffNode)element).getChildren();
+ for (int i = 0; i < children.length; i++) {
+ if (!isEmpty(children[i])) return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SequenceGenerator.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SequenceGenerator.java
new file mode 100644
index 000000000..bdd2b1c56
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SequenceGenerator.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+
+import java.util.Random;
+
+/**
+ * Encapsulates algorithms and state for generating deterministic sequences.
+ * The sequence of numbers generated will always follow the same pattern,
+ * regardless of the time, place, or platform.
+ */
+public class SequenceGenerator {
+ private static long globalSeqNum = System.currentTimeMillis() * 1000;
+ private final Random random;
+ private int uniqueInt;
+
+ /**
+ * Constructs a new sequence generator with a known seed.
+ */
+ public SequenceGenerator() {
+ random = new Random(3141592653589793238L); // a known constant
+ uniqueInt = 1000000;
+ }
+
+ /**
+ * Returns a globally unique long integer.
+ */
+ public static long nextGloballyUniqueLong() {
+ return globalSeqNum++;
+ }
+
+ /**
+ * Returns a unique 7-digit integer.
+ */
+ public int nextUniqueInt() {
+ return uniqueInt++;
+ }
+
+ /**
+ * Returns a pseudo-random integer between 0 and n-1.
+ * @see Random#nextInt(int)
+ */
+ public int nextInt(int n) {
+ return random.nextInt(n);
+ }
+
+ /**
+ * Returns a pseudo-random real number following a gaussian distribution.
+ * @see Random#nextGaussian()
+ */
+ public double nextGaussian() {
+ return random.nextGaussian();
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/ShareAndCheckoutTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/ShareAndCheckoutTest.java
new file mode 100644
index 000000000..29d272607
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/ShareAndCheckoutTest.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.zip.ZipException;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Benchmark test which shares and checks out a large project
+ */
+public class ShareAndCheckoutTest extends BenchmarkTest {
+
+ public ShareAndCheckoutTest() {
+ super();
+ }
+
+ public ShareAndCheckoutTest(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return suite(ShareAndCheckoutTest.class);
+ }
+
+ public void testShareAndCheckout() throws TeamException, ZipException, CoreException, IOException, InterruptedException, InvocationTargetException {
+ IProject project = createUniqueProject(BenchmarkTestSetup.BIG_ZIP_FILE);
+ shareProject(project);
+ checkoutCopy(project, "-copy"); //$NON-NLS-1$
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SyncTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SyncTests.java
new file mode 100644
index 000000000..c6eea2899
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/SyncTests.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+
+import junit.framework.Test;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+public class SyncTests extends BenchmarkTest {
+ private static final int FILE_SIZE_MEAN = 16384;
+ private static final int FILE_SIZE_VARIANCE = 0;
+ private static final int PROB_BINARY = 0;
+
+ private static final String ADDED_GROUP_SUFFIX = "AddedFiles";
+ private static final String REMOVED_GROUP_SUFFIX = "RemovedFiles";
+ private static final String MODIFIED_GROUP_SUFFIX = "ModifiedFiles";
+ private static final String[] PERFORMANCE_GROUPS = new String[] {ADDED_GROUP_SUFFIX, MODIFIED_GROUP_SUFFIX, REMOVED_GROUP_SUFFIX};
+
+ public SyncTests() {
+ super();
+ }
+
+ public SyncTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return suite(SyncTests.class);
+ }
+
+ public void testSync10() throws Exception {
+ runTestSync(10, "CVS Synchronize 10", false);
+ }
+
+ public void testSync100() throws Exception {
+ runTestSync(100, "CVS Synchronize 100", false);
+ }
+
+ public void testSync100Global() throws Exception {
+ runTestSync(100, "CVS Synchronize", true);
+ }
+
+ protected IProject setupOutProject() throws Exception {
+ IProject project = createUniqueProject(BenchmarkTestSetup.SMALL_ZIP_FILE);
+ shareProject(project);
+ return project;
+ }
+
+ /**
+ * Runs a sequence of operations for the synchronizer tests.
+ * A parallel project is used to generate incoming changes.
+ */
+ protected void runTestSync(int size, String globalName, boolean global) throws Exception {
+ setupGroups(PERFORMANCE_GROUPS, globalName, global);
+ for (int i = 0; i < BenchmarkTestSetup.LOOP_COUNT; i++) {
+ final SequenceGenerator gen = new SequenceGenerator();
+
+ // setup out project then move it out of the way
+ IProject outProject = setupOutProject();
+ String moduleName = outProject.getName();
+ BenchmarkUtils.renameResource(outProject, moduleName + "out");
+ outProject = BenchmarkUtils.getProject(moduleName + "out");
+
+ // setup in project
+ IProject inProject = BenchmarkUtils.getProject(moduleName);
+ checkoutProject(inProject, moduleName, null);
+
+ /*** outgoing and incoming changes ***/
+ startGroup(ADDED_GROUP_SUFFIX);
+ BenchmarkUtils.createRandomDeepFiles(gen, outProject, size, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY);
+ syncCommitResources(new IResource[] { outProject }, "");
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ startGroup(MODIFIED_GROUP_SUFFIX);
+ BenchmarkUtils.modifyRandomDeepFiles(gen, outProject, size);
+ syncCommitResources(new IResource[] { outProject }, "");
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ startGroup(REMOVED_GROUP_SUFFIX);
+ BenchmarkUtils.deleteRandomDeepFiles(gen, outProject, size);
+ syncCommitResources(new IResource[] { outProject }, "");
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+ }
+ commitGroups(global);
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/Util.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/Util.java
new file mode 100644
index 000000000..2d46119ca
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/Util.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import junit.framework.Assert;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
+
+/**
+ * CVS Test related utility methods
+ */
+public class Util {
+
+ /**
+ * Imports a .zip file into a container's root folder.
+ * @param container the container
+ * @param file the path of the .zip file
+ */
+ public static void importZip(IContainer container, File file)
+ throws IOException, ZipException, InterruptedException, InvocationTargetException {
+ ZipFile zipFile = new ZipFile(file);
+ ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
+ ImportOperation importOperation = new ImportOperation(container.getFullPath(),
+ provider.getRoot(), provider, null);
+ importOperation.setOverwriteResources(true); // don't ask
+ importOperation.run(new NullProgressMonitor());
+ Assert.assertTrue(importOperation.getStatus().isOK());
+ }
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/WorkflowTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/WorkflowTests.java
new file mode 100644
index 000000000..25d4f3681
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/benchmark/WorkflowTests.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.tests.ccvs.ui.benchmark;
+
+import java.io.File;
+import junit.framework.Test;
+import org.eclipse.core.resources.*;
+import org.eclipse.team.internal.ccvs.core.CVSTag;
+
+public class WorkflowTests extends BenchmarkTest {
+ private int FILE_SIZE_MEAN = 16384;
+ private int FILE_SIZE_VARIANCE = 12288;
+ private int PROB_BINARY = 5;
+ private static final String SHARE_PROJECT = "Share";
+ private static final String CHECKOUT_PROJECT = "Checkout";
+ private static final String COMMIT1 = "Commit1";
+ private static final String COMMIT2 = "Commit2";
+ private static final String COMMIT3 = "Commit3";
+ private static final String COMMIT4 = "Commit4";
+ private static final String UPDATE1 = "Update1";
+ private static final String UPDATE2 = "Update2";
+ private static final String UPDATE3 = "Update3";
+ private static final String UPDATE4 = "Update4";
+ private static final String REPLACE1 = "Replace1";
+ private static final String REPLACE2 = "Replace2";
+ private static final String REPLACE3 = "Replace3";
+ private static final String TAG1 = "Tag1";
+ private static final String[] PERFORMANCE_GROUPS = new String[] {
+ SHARE_PROJECT, CHECKOUT_PROJECT, COMMIT1, COMMIT2, COMMIT3, COMMIT4,
+ UPDATE1, UPDATE2, UPDATE3, UPDATE4, REPLACE1, REPLACE2, REPLACE3, TAG1
+ };
+
+ public WorkflowTests() {
+ super();
+ }
+
+ public WorkflowTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return suite(WorkflowTests.class);
+ }
+
+ public void testBigWorkflow() throws Exception {
+ runWorkflowTests("testBig", BenchmarkTestSetup.BIG_ZIP_FILE, "CVS Big Workflow", BenchmarkTestSetup.LOOP_COUNT, false);
+ }
+
+ public void testBigWorkflowForSummary() throws Exception {
+ runWorkflowTests("testBigGlobal", BenchmarkTestSetup.BIG_ZIP_FILE, "CVS Workflow", BenchmarkTestSetup.LOOP_COUNT, true);
+ }
+
+ /**
+ * Runs a series of incoming and outgoing workflow-related tests.
+ */
+ protected void runWorkflowTests(String name, File initialContents, String globalName, int loopCount, boolean global) throws Exception {
+ setupGroups(PERFORMANCE_GROUPS, globalName, global);
+ for (int i = 0; i < loopCount; i++) {
+ final SequenceGenerator gen = new SequenceGenerator();
+ IProject outProject = createAndImportProject(name, initialContents);
+
+ // test project sharing
+ startGroup(SHARE_PROJECT);
+ shareProject(outProject);
+ endGroup();
+
+ // move the project out of the way
+ String moduleName = outProject.getName();
+ BenchmarkUtils.renameResource(outProject, moduleName + "out");
+ outProject = BenchmarkUtils.getProject(moduleName + "out");
+
+ // test initial project checkout
+ IProject inProject = BenchmarkUtils.getProject(moduleName);
+ startGroup(CHECKOUT_PROJECT);
+ checkoutProject(inProject, moduleName, null);
+ endGroup();
+
+ // Test incoming and outgoing change scenarios
+
+ // Test 1: adding a new component - localized additions and some changes
+ startGroup(COMMIT1);
+ BenchmarkUtils.modifyRandomDeepFiles(gen, outProject, 5);
+ BenchmarkUtils.touchRandomDeepFiles(gen, outProject, 2);
+ IFolder componentRoot = BenchmarkUtils.createRandomDeepFolder(gen, outProject);
+ BenchmarkUtils.createRandomDeepFiles(gen, componentRoot, 12, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY);
+ syncCommitResources(new IResource[] { outProject }, "");
+ endGroup();
+ // Test 1: catching up to a new component - localized additions and some changes
+ startGroup(UPDATE1);
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ // Test 2: fixing a bug - localized changes
+ startGroup(COMMIT2);
+ BenchmarkUtils.modifyRandomDeepFiles(gen, componentRoot, 2);
+ BenchmarkUtils.touchRandomDeepFiles(gen, componentRoot, 2);
+ syncCommitResources(new IResource[] { outProject }, "");
+ endGroup();
+ // Test 2: catching up to a bug fix - localized changes
+ startGroup(UPDATE2);
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ // Test 3: moving a package - scattered changes, files moved
+ startGroup(COMMIT3);
+ BenchmarkUtils.modifyRandomDeepFiles(gen, outProject, 5); // a few scattered changes
+ BenchmarkUtils.modifyRandomDeepFiles(gen, componentRoot, 12); // changes to "package" stmt
+ BenchmarkUtils.renameResource(componentRoot, BenchmarkUtils.makeUniqueName(gen, "folder", null));
+ syncCommitResources(new IResource[] { outProject }, "");
+ endGroup();
+ // Test 3: catching up to a moved package - scattered changes, files moved
+ startGroup(UPDATE3);
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ // Test 4: big refactoring - scattered changes, files renamed and balanced additions/deletions
+ startGroup(COMMIT4);
+ BenchmarkUtils.deleteRandomDeepFiles(gen, outProject, 4); // some stuff deleted
+ BenchmarkUtils.modifyRandomDeepFiles(gen, outProject, 20); // many scattered changes
+ BenchmarkUtils.renameRandomDeepFiles(gen, outProject, 5); // renamed some stuff
+ BenchmarkUtils.createRandomDeepFiles(gen, outProject, 4, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // some new stuff added
+ syncCommitResources(new IResource[] { outProject }, "");
+ endGroup();
+ // Test 4: catching up to a big refactoring - scattered changes, files renamed and balanced additions/deletions
+ startGroup(UPDATE4);
+ syncUpdateResources(new IResource[] { inProject });
+ endGroup();
+
+ // Test 5: test tagging a project
+ startGroup(TAG1);
+ tagProject(outProject, new CVSTag("v101", CVSTag.VERSION), false);
+ endGroup();
+
+ // replace with remote contents
+ // Test 6: no local dirty files, no remote changes
+ startGroup(REPLACE1);
+ replace(new IResource[] { inProject }, null, true);
+ endGroup();
+
+ // Test 7: abandoning some local work, no remote changes
+ startGroup(REPLACE2);
+ BenchmarkUtils.deleteRandomDeepFiles(gen, inProject, 4); // some stuff locally deleted
+ BenchmarkUtils.modifyRandomDeepFiles(gen, inProject, 6); // a few unimportant changes to forget
+ BenchmarkUtils.createRandomDeepFiles(gen, inProject, 4, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // some new work to abandon
+ replace(new IResource[] { inProject }, null, true);
+ endGroup();
+
+ // Test 8: no local dirty files, many remote changes
+ // e.g. returning from a long vacation
+ BenchmarkUtils.deleteRandomDeepFiles(gen, outProject, 10); // some components obsoleted
+ BenchmarkUtils.modifyRandomDeepFiles(gen, outProject, 42); // many changes
+ BenchmarkUtils.renameRandomDeepFiles(gen, outProject, 8); // evidence of some refactoring
+ BenchmarkUtils.createRandomDeepFiles(gen, outProject, 10, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // a few new components added
+ syncCommitResources(new IResource[] { outProject }, "");
+ startGroup(REPLACE3);
+ replace(new IResource[] { inProject }, null, true);
+ endGroup();
+ }
+ commitGroups(global);
+ }
+}

Back to the top