Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid network ops in tests #564

Merged
merged 6 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@types/tar": "^6.1.2",
"byline": "^5.0.0",
"cross-env": "^5.2.0",
"find-git-exec": "0.0.1-alpha.2",
"find-git-exec": "^0.0.4",
"jest": "^28.1.3",
"prettier": "^2.7.1",
"rimraf": "^2.5.4",
Expand Down
47 changes: 16 additions & 31 deletions test/external/git-process-external-test.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,31 @@
import { dirname } from 'path'
import { default as findGit, Git } from 'find-git-exec'
import { resolve } from 'path'
import findGit from 'find-git-exec'

import { GitProcess } from '../../lib'
import { verify } from '../helpers'

const temp = require('temp').track()

async function setupGitEnvironment(): Promise<Git | null> {
let git: Git | undefined = undefined

try {
git = await findGit()
} catch {
return null
}
if (!git || !git.path || !git.execPath) {
return null
} else {
const { path, execPath } = git
// Set the environment variable to be able to use an external Git.
process.env.GIT_EXEC_PATH = execPath
process.env.LOCAL_GIT_DIRECTORY = dirname(dirname(path))
return git
}
}
const getExternalGitEnvironment = () =>
findGit().then(({ path, execPath }) => ({
GIT_EXEC_PATH: execPath,
LOCAL_GIT_DIRECTORY: resolve(path, '../../'),
}))

describe('git-process [with external Git executable]', () => {
describe('clone', () => {
describe('--exec-path', () => {
it('returns exit code when successful', async () => {
const git = await setupGitEnvironment()
if (git == null) {
throw new Error('External Git was not found on the host system.')
}
const env = await getExternalGitEnvironment()

const testRepoPath = temp.mkdirSync('desktop-git-clone-valid-external')
const result = await GitProcess.exec(
['clone', '--', 'https://github.com/TypeFox/find-git-exec.git', '.'],
testRepoPath
)
verify(result, r => {
expect(r.exitCode).toEqual(0)
const result = await GitProcess.exec(['--exec-path'], testRepoPath, {
env,
})

verify(result, r => expect(r.exitCode).toEqual(0))
verify(result, r =>
expect(resolve(r.stdout.trim())).toEqual(resolve(env.GIT_EXEC_PATH))
)
})
})
})
15 changes: 12 additions & 3 deletions test/fast/git-process-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,27 @@ import {

import { gitVersion } from '../helpers'
import { setupNoAuth } from '../slow/auth'
import { pathToFileURL } from 'url'

const temp = require('temp').track()

describe('git-process', () => {
it('can cancel in-progress git command', async () => {
const testRepoPath = temp.mkdirSync('desktop-git-clone-valid')
const sourceRepoPath = temp.mkdirSync('desktop-git-clone-source')
const destinationRepoPath = temp.mkdirSync('desktop-git-clone-destination')
const options = {
env: setupNoAuth(),
}

await GitProcess.exec(['init'], sourceRepoPath)
await GitProcess.exec(
['commit', '--allow-empty', '-m', 'Init'],
sourceRepoPath
)

const task = GitProcess.execTask(
['clone', '--', 'https://github.com/shiftkey/friendly-bassoon.git', '.'],
testRepoPath,
['clone', '--', pathToFileURL(sourceRepoPath).toString(), '.'],
destinationRepoPath,
options
)

Expand Down
142 changes: 36 additions & 106 deletions test/slow/git-process-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import * as Path from 'path'
import { GitProcess, GitError } from '../../lib'
import { initialize, verify } from '../helpers'
import { setupAskPass, setupNoAuth } from './auth'
import { pathToFileURL } from 'url'
import { resolve } from 'path'
import { createServer } from 'http'

const temp = require('temp').track()

Expand All @@ -15,18 +18,11 @@ describe('git-process', () => {
env: setupNoAuth(),
}

// GitHub will prompt for (and validate) credentials for non-public
// repositories, to prevent leakage of information.
// Bitbucket will not prompt for credentials, and will immediately
// return whether this non-public repository exists.
//
// This is an easier to way to test for the specific error than to
// pass live account credentials to Git.
const result = await GitProcess.exec(
[
'clone',
'--',
'https://bitbucket.org/shiftkey/testing-non-existent.git',
pathToFileURL(resolve('i-for-sure-donut-exist')).toString(),
'.',
],
testRepoPath,
Expand All @@ -43,61 +39,53 @@ describe('git-process', () => {
const options = {
env: setupAskPass('error', 'error'),
}
const result = await GitProcess.exec(
[
'clone',
'--',
'https://github.com/shiftkey/repository-private.git',
'.',
],
testRepoPath,
options
)
verify(result, r => {
expect(r.exitCode).toBe(128)

const server = createServer((req, res) => {
res.writeHead(401, {
'Content-Type': 'text/plain',
'WWW-Authenticate': 'Basic realm="foo"',
})
res.end()
})
const error = GitProcess.parseError(result.stderr)
expect(error).toBe(GitError.HTTPSAuthenticationFailed)
})

it('returns exit code when successful', async () => {
const testRepoPath = temp.mkdirSync('desktop-git-clone-valid')
const options = {
env: setupNoAuth(),
}
const result = await GitProcess.exec(
[
'clone',
'--',
'https://github.com/shiftkey/friendly-bassoon.git',
'.',
],
testRepoPath,
options
)
verify(result, r => {
expect(r.exitCode).toBe(0)
const port = await new Promise<number>((resolve, reject) => {
server.listen(0, () => {
const addr = server.address()
if (addr === null || typeof addr === 'string') {
reject(new Error('invalid server address'))
} else {
resolve(addr.port)
}
})
})

try {
const result = await GitProcess.exec(
['clone', '--', `http://127.0.0.1:${port}/`, '.'],
testRepoPath,
options
)
verify(result, r => {
expect(r.exitCode).toBe(128)
})
const error = GitProcess.parseError(result.stderr)
expect(error).toBe(GitError.HTTPSAuthenticationFailed)
} finally {
server.close()
}
})
})

describe('fetch', () => {
it("returns exit code when repository doesn't exist", async () => {
const testRepoPath = await initialize('desktop-git-fetch-failure')

// GitHub will prompt for (and validate) credentials for non-public
// repositories, to prevent leakage of information.
// Bitbucket will not prompt for credentials, and will immediately
// return whether this non-public repository exists.
//
// This is an easier to way to test for the specific error than to
// pass live account credentials to Git.
const addRemote = await GitProcess.exec(
[
'remote',
'add',
'origin',
'https://bitbucket.org/shiftkey/testing-non-existent.git',
pathToFileURL(resolve('i-for-sure-donut-exist')).toString(),
],
testRepoPath
)
Expand All @@ -117,64 +105,6 @@ describe('git-process', () => {
expect(r.exitCode).toBe(128)
})
})

it('returns exit code and error when repository requires credentials', async () => {
const testRepoPath = await initialize('desktop-git-fetch-failure')
const addRemote = await GitProcess.exec(
[
'remote',
'add',
'origin',
'https://github.com/shiftkey/repository-private.git',
],
testRepoPath
)
verify(addRemote, r => {
expect(r.exitCode).toBe(0)
})

const options = {
env: setupAskPass('error', 'error'),
}
const result = await GitProcess.exec(
['fetch', 'origin'],
testRepoPath,
options
)
verify(result, r => {
expect(r.exitCode).toBe(128)
})
const error = GitProcess.parseError(result.stderr)
expect(error).toBe(GitError.HTTPSAuthenticationFailed)
})

it('returns exit code when successful', async () => {
const testRepoPath = await initialize('desktop-git-fetch-valid')
const addRemote = await GitProcess.exec(
[
'remote',
'add',
'origin',
'https://github.com/shiftkey/friendly-bassoon.git',
],
testRepoPath
)
verify(addRemote, r => {
expect(r.exitCode).toBe(0)
})

const options = {
env: setupNoAuth(),
}
const result = await GitProcess.exec(
['fetch', 'origin'],
testRepoPath,
options
)
verify(result, r => {
expect(r.exitCode).toBe(0)
})
})
})

describe('checkout', () => {
Expand Down
27 changes: 17 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -650,16 +650,16 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83"
integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A==

"@types/node@^10.14.22":
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==

"@types/node@^11.9.0":
version "11.15.54"
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.15.54.tgz#59ed60e7b0d56905a654292e8d73275034eb6283"
integrity sha512-1RWYiq+5UfozGsU6MwJyFX6BtktcT10XRjvcAQmskCtMcW3tPske88lM/nHv7BQG1w9KBXI1zPGuu5PnNCX14g==

"@types/node@^8.0.26":
version "8.10.66"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==

"@types/prettier@^2.1.5":
version "2.7.0"
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc"
Expand Down Expand Up @@ -693,6 +693,11 @@
"@types/node" "*"
minipass "^3.3.5"

"@types/which@^1.3.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.3.2.tgz#9c246fc0c93ded311c8512df2891fb41f6227fdf"
integrity sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==

"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
Expand Down Expand Up @@ -1123,12 +1128,14 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"

find-git-exec@0.0.1-alpha.2:
version "0.0.1-alpha.2"
resolved "https://registry.yarnpkg.com/find-git-exec/-/find-git-exec-0.0.1-alpha.2.tgz#02c266b3be6e411c19aa5fd6f813c96a73286fac"
integrity sha512-Vr4UEPeqQQmTv8EPHff1VyRpT/xIB8VdJ+JdKol0TpbdBg5fNBowdd6La8aBtkdYYWLg6BfpCqezwddmB0gZkA==
find-git-exec@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/find-git-exec/-/find-git-exec-0.0.4.tgz#f1d0d35f93ad99bc81aacd357388d00ae902bc92"
integrity sha512-klzQwno+dpdeahtHhvZZ5Yn6K+zme1Aj+YJ4ZD+DywSLrQoyCywTrsubUZa1hHRehmfwBThoeKjS7fsaxhpfNA==
dependencies:
"@types/node" "^8.0.26"
"@types/node" "^10.14.22"
"@types/which" "^1.3.2"
which "^2.0.1"

find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
Expand Down
Loading