diff options
Diffstat (limited to 'org.eclipse.jgit.test/exttst')
4 files changed, 528 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/SpeedTestBase.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/SpeedTestBase.java new file mode 100644 index 0000000000..b53a4e4304 --- /dev/null +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/SpeedTestBase.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2008, Google Inc. + * Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com> + * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.lib; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.TestCase; + +/** + * Base class for performance unit test. + */ +public abstract class SpeedTestBase extends TestCase { + + /** + * The time used by native git as this is our reference. + */ + protected long nativeTime; + + /** + * Reference to the location of the Linux kernel repo. + */ + protected String kernelrepo; + + /** + * Prepare test by running a test against the Linux kernel repo first. + * + * @param refcmd + * git command to execute + * + * @throws Exception + */ + protected void prepare(String[] refcmd) throws Exception { + try { + BufferedReader bufferedReader = new BufferedReader(new FileReader("kernel.ref")); + try { + kernelrepo = bufferedReader.readLine(); + } finally { + bufferedReader.close(); + } + timeNativeGit(kernelrepo, refcmd); + nativeTime = timeNativeGit(kernelrepo, refcmd); + } catch (Exception e) { + System.out.println("Create a file named kernel.ref and put the path to the Linux kernels repository there"); + throw e; + } + } + + private static long timeNativeGit(String kernelrepo, String[] refcmd) throws IOException, + InterruptedException, Exception { + long start = System.currentTimeMillis(); + Process p = Runtime.getRuntime().exec(refcmd, null, new File(kernelrepo,"..")); + InputStream inputStream = p.getInputStream(); + InputStream errorStream = p.getErrorStream(); + byte[] buf=new byte[1024*1024]; + for (;;) + if (inputStream.read(buf) < 0) + break; + if (p.waitFor()!=0) { + int c; + while ((c=errorStream.read())!=-1) + System.err.print((char)c); + throw new Exception("git log failed"); + } + inputStream.close(); + errorStream.close(); + long stop = System.currentTimeMillis(); + return stop - start; + } +} diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0005_ShallowSpeedTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0005_ShallowSpeedTest.java new file mode 100644 index 0000000000..97b1cf97d7 --- /dev/null +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0005_ShallowSpeedTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com> + * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.lib; + +import java.io.File; +import java.io.IOException; + +import junit.textui.TestRunner; + +public class T0005_ShallowSpeedTest extends SpeedTestBase { + + protected void setUp() throws Exception { + prepare(new String[] { "git", "rev-list", "365bbe0d0caaf2ba74d56556827babf0bc66965d" }); + } + + public void testShallowHistoryScan() throws IOException { + long start = System.currentTimeMillis(); + Repository db = new Repository(new File(kernelrepo)); + Commit commit = db.mapCommit("365bbe0d0caaf2ba74d56556827babf0bc66965d"); + int n = 1; + for (;;) { + ObjectId[] parents = commit.getParentIds(); + if (parents.length == 0) + break; + ObjectId parentId = parents[0]; + commit = db.mapCommit(parentId); + commit.getCommitId().name(); + ++n; + } + assertEquals(12275, n); + long stop = System.currentTimeMillis(); + long time = stop - start; + System.out.println("native="+nativeTime); + System.out.println("jgit="+time); + // ~0.750s (hot cache), ok + /* +native=1795 +jgit=722 + */ + // native git seems to run SLOWER than jgit here, at roughly half the speed + // creating the git process is not the issue here, btw. + long factor10 = (nativeTime*150/time+50)/100; + assertEquals(3, factor10); + } + + public static void main(String[] args) { + TestRunner.run(T0005_ShallowSpeedTest.class); + } +} diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0006_DeepSpeedTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0006_DeepSpeedTest.java new file mode 100644 index 0000000000..8843ae35b3 --- /dev/null +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/lib/T0006_DeepSpeedTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com> + * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.lib; + +import java.io.File; +import java.io.IOException; + +import junit.textui.TestRunner; + +public class T0006_DeepSpeedTest extends SpeedTestBase { + + protected void setUp() throws Exception { + prepare(new String[] { "git", "rev-list", "365bbe0d0caaf2ba74d56556827babf0bc66965d","--","net/netfilter/nf_queue.c" }); + } + + public void testDeepHistoryScan() throws IOException { + long start = System.currentTimeMillis(); + Repository db = new Repository(new File(kernelrepo)); + Commit commit = db.mapCommit("365bbe0d0caaf2ba74d56556827babf0bc66965d"); + int n = 1; + for (;;) { + ObjectId[] parents = commit.getParentIds(); + if (parents.length == 0) + break; + ObjectId parentId = parents[0]; + commit = db.mapCommit(parentId); + TreeEntry m = commit.getTree().findBlobMember("net/netfilter/nf_queue.c"); + if (m != null) + commit.getCommitId().name(); + ++n; + } + + assertEquals(12275, n); + long stop = System.currentTimeMillis(); + long time = stop - start; + System.out.println("native="+nativeTime); + System.out.println("jgit="+time); + /* + native=1355 + jgit=5449 + */ + // This is not an exact factor, but we'd expect native git to perform this + // about 4 times quicker. If for some reason we find jgit to be faster than + // this the cause should be found and secured. + long factor = (time*110/nativeTime+50)/100; + assertEquals(4, factor); + } + + public static void main(String[] args) { + TestRunner.run(T0006_DeepSpeedTest.class); + } +} diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java new file mode 100644 index 0000000000..60d3853d85 --- /dev/null +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2008, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.patch; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.HashSet; + +import junit.framework.TestCase; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.util.MutableInteger; +import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.TemporaryBuffer; + +public class EGitPatchHistoryTest extends TestCase { + public void testParseHistory() throws Exception { + final NumStatReader numstat = new NumStatReader(); + numstat.read(); + + final HashMap<String, HashMap<String, StatInfo>> stats = numstat.stats; + assertEquals(1211, stats.size()); + + new PatchReader(stats).read(); + } + + static class StatInfo { + int added, deleted; + } + + static class PatchReader extends CommitReader { + final HashSet<String> offBy1; + + final HashMap<String, HashMap<String, StatInfo>> stats; + + int errors; + + PatchReader(final HashMap<String, HashMap<String, StatInfo>> s) + throws IOException { + super(new String[] { "-p" }); + stats = s; + + offBy1 = new HashSet<String>(); + offBy1.add("9bda5ece6806cd797416eaa47c7b927cc6e9c3b2"); + } + + @Override + void onCommit(String cid, byte[] buf) { + final HashMap<String, StatInfo> files = stats.remove(cid); + assertNotNull("No files for " + cid, files); + + final Patch p = new Patch(); + p.parse(buf, 0, buf.length - 1); + assertEquals("File count " + cid, files.size(), p.getFiles().size()); + if (!p.getErrors().isEmpty()) { + for (final FormatError e : p.getErrors()) { + System.out.println("error " + e.getMessage()); + System.out.println(" at " + e.getLineText()); + } + dump(buf); + fail("Unexpected error in " + cid); + } + + for (final FileHeader fh : p.getFiles()) { + final String fileName; + if (fh.getChangeType() != FileHeader.ChangeType.DELETE) + fileName = fh.getNewName(); + else + fileName = fh.getOldName(); + final StatInfo s = files.remove(fileName); + final String nid = fileName + " in " + cid; + assertNotNull("No " + nid, s); + int added = 0, deleted = 0; + for (final HunkHeader h : fh.getHunks()) { + added += h.getOldImage().getLinesAdded(); + deleted += h.getOldImage().getLinesDeleted(); + } + + if (s.added == added) { + // + } else if (s.added == added + 1 && offBy1.contains(cid)) { + // + } else { + dump(buf); + assertEquals("Added diff in " + nid, s.added, added); + } + + if (s.deleted == deleted) { + // + } else if (s.deleted == deleted + 1 && offBy1.contains(cid)) { + // + } else { + dump(buf); + assertEquals("Deleted diff in " + nid, s.deleted, deleted); + } + } + assertTrue("Missed files in " + cid, files.isEmpty()); + } + + private static void dump(final byte[] buf) { + String str; + try { + str = new String(buf, 0, buf.length - 1, "ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + System.out.println("<<" + str + ">>"); + } + } + + static class NumStatReader extends CommitReader { + final HashMap<String, HashMap<String, StatInfo>> stats = new HashMap<String, HashMap<String, StatInfo>>(); + + NumStatReader() throws IOException { + super(new String[] { "--numstat" }); + } + + @Override + void onCommit(String commitId, byte[] buf) { + final HashMap<String, StatInfo> files = new HashMap<String, StatInfo>(); + final MutableInteger ptr = new MutableInteger(); + while (ptr.value < buf.length) { + if (buf[ptr.value] == '\n') + break; + final StatInfo i = new StatInfo(); + i.added = RawParseUtils.parseBase10(buf, ptr.value, ptr); + i.deleted = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr); + final int eol = RawParseUtils.nextLF(buf, ptr.value); + final String name = RawParseUtils.decode(Constants.CHARSET, + buf, ptr.value + 1, eol - 1); + files.put(name, i); + ptr.value = eol; + } + stats.put(commitId, files); + } + } + + static abstract class CommitReader { + private Process proc; + + CommitReader(final String[] args) throws IOException { + final String[] realArgs = new String[3 + args.length + 1]; + realArgs[0] = "git"; + realArgs[1] = "log"; + realArgs[2] = "--pretty=format:commit %H"; + System.arraycopy(args, 0, realArgs, 3, args.length); + realArgs[3 + args.length] = "a4b98ed15ea5f165a7aa0f2fd2ea6fcce6710925"; + + proc = Runtime.getRuntime().exec(realArgs); + proc.getOutputStream().close(); + proc.getErrorStream().close(); + } + + void read() throws IOException, InterruptedException { + final BufferedReader in = new BufferedReader(new InputStreamReader( + proc.getInputStream(), "ISO-8859-1")); + String commitId = null; + TemporaryBuffer buf = null; + for (;;) { + String line = in.readLine(); + if (line == null) + break; + if (line.startsWith("commit ")) { + if (buf != null) { + buf.close(); + onCommit(commitId, buf.toByteArray()); + buf.destroy(); + } + commitId = line.substring("commit ".length()); + buf = new TemporaryBuffer(); + } else if (buf != null) { + buf.write(line.getBytes("ISO-8859-1")); + buf.write('\n'); + } + } + in.close(); + assertEquals(0, proc.waitFor()); + proc = null; + } + + abstract void onCommit(String commitId, byte[] buf); + } +} |