Skip to content

Commit de09244

Browse files
committed
e2e: allow external bundle URI testing
Testing performance via localhost may be a bit of a cheat, in some views. The existing performance test also constructs a fresh bundle containing all of the existing objects, without needing incremental bundles and the creationToken heuristic. To get a possibly more accurate result, we can test across a real network boundary and on a machine that has been updating bundles based on our existing bundle schedule, demonstrating performance for a bundle server after some time in use. To promote this, add a performance test (marked @slow) but with a "Given" that expects a TEST_BUNDLE_SERVER_URI environment variable. If this variable does not exist, the test will fail quickly. But, if it exists, it will append one of the 'route' values for the test so we can compare cloning with that bundle URI versus without. Here is the output I got for my machines (testing on a Linux machine connected over LAN to the bundle URI Linux machine): Clone execution time for https://github.com/git/git.git: 13.045381171941758s (bundle URI) vs. 17.917231523036957s (no bundle URI) Clone execution time for https://github.com/kubernetes/kubernetes.git: 46.17043500101566s (bundle URI) vs. 41.95928572797775s (no bundle URI) Clone execution time for https://github.com/homebrew/homebrew-core: 36.88277485907078s (bundle URI) vs. 358.64118642401695s (no bundle URI) Clone execution time for https://github.com/torvalds/linux.git: 203.00328045904635s (bundle URI) vs. 292.6792869710922s (no bundle URI) It is interesting to me that in this test _and_ the existing performance test that bundle URIs do not do as good of a job on kubernetes/kubernetes as cloning completely from GitHub. Perhaps there is something with our pack-objects settings that could be improved during bundle creation that would make it easier to unpack the bundle. Some investigation is worthwhile for that case. However, there are also interesting cases like homebrew/homebrew-core that are substantially slower from GitHub. There are definitely a few trees that are particularly difficult to parse in that repo, so there could be more time computing the reachability on the server _or_ it could be worse deltas for those big trees.
1 parent e098adf commit de09244

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

test/e2e/features/performance.feature

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ Feature: Bundle server performance
1414
Examples:
1515
| repo |
1616
| https://github.com/git/git.git | # takes ~2 minutes
17-
| https://github.com/git-for-windows/git.git | # takes ~2 minutes
1817
| https://github.com/kubernetes/kubernetes.git | # takes ~3 minutes
18+
| https://github.com/homebrew/homebrew-core | # takes ~15(!) minutes
1919
| https://github.com/torvalds/linux.git | # takes ~30(!) minutes
20+
21+
@slow
22+
Scenario Outline: Comparing clone performance with external bundle server
23+
Given a remote repository '<repo>'
24+
Given a bundle URI from TEST_BUNDLE_SERVER_URI
25+
Given a bundle route '<route>'
26+
When I clone from the remote repo with a bundle URI
27+
When another developer clones from the remote repo without a bundle URI
28+
Then I compare the clone execution times
29+
30+
Examples:
31+
| repo | route |
32+
| https://github.com/git/git.git | git/git |
33+
| https://github.com/kubernetes/kubernetes.git | kubernetes/kubernetes |
34+
| https://github.com/homebrew/homebrew-core | homebrew/homebrew-core |
35+
| https://github.com/torvalds/linux.git | torvalds/linux |

test/e2e/features/step_definitions/remote.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Given, } from '@cucumber/cucumber'
22
import { RemoteRepo } from '../classes/remote'
33
import { BundleServerWorld } from '../support/world'
44
import * as path from 'path'
5+
import { env } from 'process'
56

67
/**
78
* Steps relating to the setup of the remote repository users will clone from.
@@ -11,6 +12,18 @@ Given('a remote repository {string}', async function (this: BundleServerWorld, u
1112
this.remote = new RemoteRepo(false, url)
1213
})
1314

15+
Given('a bundle URI from TEST_BUNDLE_SERVER_URI', async function (this: BundleServerWorld) {
16+
this.bundleURIBase = env["TEST_BUNDLE_SERVER_URI"]
17+
18+
if (this.bundleURIBase == "") {
19+
throw new Error("This test requires TEST_BUNDLE_SERVER_URI")
20+
}
21+
})
22+
23+
Given('a bundle route {string}', async function (this: BundleServerWorld, route: string) {
24+
this.bundleURI = this.bundleURIBase + route
25+
})
26+
1427
Given('a new remote repository with main branch {string}', async function (this: BundleServerWorld, mainBranch: string) {
1528
this.remote = new RemoteRepo(true, path.join(this.trashDirectory, "server"), mainBranch)
1629
})

test/e2e/features/step_definitions/repository.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,20 @@ Given('another user removed {int} commits and added {int} commits to {string}',
4242

4343
Given('I cloned from the remote repo with a bundle URI', async function (this: BundleServerWorld) {
4444
const user = User.Me
45-
this.cloneRepositoryFor(user, this.bundleServer.bundleUri())
45+
if (this.bundleURI !== undefined) {
46+
this.cloneRepositoryFor(User.Me, this.bundleURI)
47+
} else {
48+
this.cloneRepositoryFor(User.Me, this.bundleServer.bundleUri())
49+
}
4650
utils.assertStatus(0, this.getRepo(user).cloneResult)
4751
})
4852

4953
When('I clone from the remote repo with a bundle URI', async function (this: BundleServerWorld) {
50-
this.cloneRepositoryFor(User.Me, this.bundleServer.bundleUri())
54+
if (this.bundleURI !== undefined) {
55+
this.cloneRepositoryFor(User.Me, this.bundleURI)
56+
} else {
57+
this.cloneRepositoryFor(User.Me, this.bundleServer.bundleUri())
58+
}
5159
})
5260

5361
When('another developer clones from the remote repo without a bundle URI', async function (this: BundleServerWorld) {
@@ -76,7 +84,12 @@ Then('bundles are downloaded and used', async function (this: BundleServerWorld)
7684
let result = clonedRepo.runGit("config", "--get", "fetch.bundleURI")
7785
utils.assertStatus(0, result, "'fetch.bundleURI' is not set after clone")
7886
const actualURI = result.stdout.toString().trim()
79-
assert.strictEqual(actualURI, this.bundleServer.bundleUri())
87+
88+
if (this.bundleURI !== undefined) {
89+
assert.strictEqual(actualURI, this.bundleURI)
90+
} else {
91+
assert.strictEqual(actualURI, this.bundleServer.bundleUri())
92+
}
8093

8194
result = clonedRepo.runGit("for-each-ref", "--format=%(refname)")
8295
utils.assertStatus(0, result, "git for-each-ref failed")

test/e2e/features/support/world.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export class BundleServerWorld extends World<BundleServerParameters> {
2525
// Bundle server
2626
bundleServer: BundleServer
2727
remote: RemoteRepo | undefined
28+
bundleURIBase: string | undefined
29+
bundleURI: string | undefined
2830

2931
// Users
3032
repoMap: Map<User, ClonedRepository>

0 commit comments

Comments
 (0)