From 875f0e98651892d77aabdc23296b5edf4e05a712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Thu, 15 Sep 2022 16:01:41 +0200 Subject: [PATCH] fix: upgrade go-httpauth to support basic auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge and add proxy and proxy auth related tests Signed-off-by: Peter Schäfer <101886095+PeterSchafer@users.noreply.github.com> Signed-off-by: Peter Schäfer <101886095+PeterSchafer@users.noreply.github.com> --- cliv2/Makefile | 6 +- cliv2/go.mod | 2 +- cliv2/go.sum | 4 +- .../acceptance/proxy_authentication.spec.ts | 270 ---------------- .../fixtures/squid_environment/Dockerfile | 0 .../squid_environment/docker-compose.yml | 0 .../squid_environment/scripts/setup.sh | 0 test/jest/acceptance/proxy-behavior.spec.ts | 289 ++++++++++++++++++ 8 files changed, 293 insertions(+), 278 deletions(-) delete mode 100644 cliv2/test/acceptance/proxy_authentication.spec.ts rename {cliv2/test => test}/fixtures/squid_environment/Dockerfile (100%) rename {cliv2/test => test}/fixtures/squid_environment/docker-compose.yml (100%) rename {cliv2/test => test}/fixtures/squid_environment/scripts/setup.sh (100%) diff --git a/cliv2/Makefile b/cliv2/Makefile index 4859d7ba16..846f0b446c 100644 --- a/cliv2/Makefile +++ b/cliv2/Makefile @@ -190,12 +190,8 @@ whiteboxtest: @echo "$(LOG_PREFIX) Running $@" @$(GOCMD) test -cover ./... -.PHONY: acceptancetest -acceptancetest: build - TEST_SNYK_COMMAND="$(BUILD_DIR)/$(V2_EXECUTABLE_NAME)" npx jest - .PHONY: test -test: whiteboxtest blackboxtest acceptancetest +test: whiteboxtest blackboxtest .PHONY: lint lint: diff --git a/cliv2/go.mod b/cliv2/go.mod index 548439b1b8..1a0bb789ed 100644 --- a/cliv2/go.mod +++ b/cliv2/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/elazarl/goproxy v0.0.0-20220328115640-894aeddb713e github.com/hashicorp/go-uuid v1.0.3 - github.com/snyk/go-httpauth v0.0.0-20220912133144-d51219ca664d + github.com/snyk/go-httpauth v0.0.0-20220915135832-0edf62cf8cdd github.com/spf13/viper v1.13.0 github.com/stretchr/testify v1.8.0 ) diff --git a/cliv2/go.sum b/cliv2/go.sum index d8458b29b9..34b23561ca 100644 --- a/cliv2/go.sum +++ b/cliv2/go.sum @@ -174,8 +174,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/snyk/go-httpauth v0.0.0-20220912133144-d51219ca664d h1:dT2rfoDxGDWeplsnXWajWZcZ7zo8R6Hif3jufvkXcUE= -github.com/snyk/go-httpauth v0.0.0-20220912133144-d51219ca664d/go.mod h1:v6t6wKizOcHXT3p4qKn6Bda7yNIjCQ54Xyl31NjgXkY= +github.com/snyk/go-httpauth v0.0.0-20220915135832-0edf62cf8cdd h1:zjDhcQ642rIVI8aIjfG5uVcw+OGotQtX2l9VHe7IqCQ= +github.com/snyk/go-httpauth v0.0.0-20220915135832-0edf62cf8cdd/go.mod h1:v6t6wKizOcHXT3p4qKn6Bda7yNIjCQ54Xyl31NjgXkY= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= diff --git a/cliv2/test/acceptance/proxy_authentication.spec.ts b/cliv2/test/acceptance/proxy_authentication.spec.ts deleted file mode 100644 index 1753911092..0000000000 --- a/cliv2/test/acceptance/proxy_authentication.spec.ts +++ /dev/null @@ -1,270 +0,0 @@ -import * as path from 'path'; -import { fakeServer, FakeServer } from '../../../test/acceptance/fake-server'; -import { - createProjectFromWorkspace, - TestProject, -} from '../../../test/jest/util/createProject'; -import { - startCommand, - TestCLI, - startSnykCLI, -} from '../../../test/jest/util/startSnykCLI'; -import { isCLIV2 } from '../../../test/jest/util/isCLIV2'; -import { unlink } from 'fs'; -import { execSync } from 'child_process'; -import * as os from 'os'; - -jest.setTimeout(1000 * 60); - -// Global test configuration -const rootDir = path.resolve(path.join(__dirname, '..', '..')); -const squidEnvironmentPath = path.resolve( - path.join(rootDir, 'test', 'fixtures', 'squid_environment'), -); -const dockerComposeFile = path.resolve( - path.join(squidEnvironmentPath, 'docker-compose.yml'), -); -const scriptsPath = path.resolve(path.join(squidEnvironmentPath, 'scripts')); -const containerName = 'proxy_authentication_container'; -const hostnameFakeServer = 'host.docker.internal'; -const hostnameProxy = 'proxy.snyk.local'; -const proxyPort = '3128'; -const port = process.env.PORT || process.env.SNYK_PORT || '12345'; -const baseApi = '/api/v1'; -const SNYK_API = 'http://' + hostnameFakeServer + ':' + port + baseApi; -const HTTP_PROXY = 'http://localhost:' + proxyPort; -const KRB5_CACHE_FILE = 'krb5_cache'; -const KRB5_CONFIG_FILE = 'krb5.conf'; - -function getDockerOptions() { - const dockerOptions = { - env: { - ...process.env, - HTTP_PROXY_PORT: proxyPort, - PROXY_HOSTNAME: hostnameProxy, - SNYK_API: SNYK_API, - CONTAINER_NAME: containerName, - SCRIPTS_PATH: scriptsPath, - }, - }; - return dockerOptions; -} - -function isDockerAvailable(): boolean { - let result = false; - - try { - execSync('docker --version'); - execSync('docker-compose --version'); - result = true; - } catch (error) { - result = false; - console.debug(error); - } - - return result; -} - -async function startProxyEnvironment(): Promise { - // Stop any orphaned containers from previous runs. - await stopProxyEnvironment(); - - const dockerUp = await startCommand( - 'docker-compose', - ['--file', dockerComposeFile, 'up', '--build'], - getDockerOptions(), - ); - await expect(dockerUp).toDisplay('Kerberos setup complete.', { - timeout: 60_000, - }); -} - -async function stopProxyEnvironment(): Promise { - const dockerDown = await startCommand( - 'docker-compose', - ['--file', dockerComposeFile, 'down'], - getDockerOptions(), - ); - await expect(dockerDown).toExitWith(0, { timeout: 30_000 }); -} - -async function getProxyAccessLog(): Promise { - const check = await startCommand('docker', [ - 'exec', - containerName, - 'cat', - '/var/log/squid/access.log', - ]); - await expect(check).toExitWith(0); - return check.stdout.get(); -} - -async function runCliWithProxy( - env: Record, - args: string[] = [], - cmd = 'test', -): Promise { - let temp: string[] = [cmd, '--debug']; - temp = temp.concat(args); - - if (env['KRB5CCNAME'] == undefined) { - env['KRB5CCNAME'] = 'FILE:' + path.join(scriptsPath, KRB5_CACHE_FILE); - env['KRB5_CONFIG'] = path.join(scriptsPath, KRB5_CONFIG_FILE); - } - - const cli = await startSnykCLI(temp.join(' '), { - env: { - ...env, - SNYK_HTTP_PROTOCOL_UPGRADE: '0', - }, - }); - return cli; -} - -function canTestRun(): boolean { - if (!isCLIV2() || !isDockerAvailable()) { - // eslint-disable-next-line jest/no-focused-tests - it.only('These tests are currently limited to certain environments.', () => { - console.warn( - 'Skipping CLIv2 test. These tests are limited to environments that have docker and docker-compose installed.', - ); - }); - return false; - } - return true; -} - -describe('Proxy Authentication (all platforms)', () => { - if (canTestRun()) { - let server: FakeServer; - let env: Record; - let project: TestProject; - - beforeAll(async () => { - project = await createProjectFromWorkspace('npm-package'); - await startProxyEnvironment(); - - env = { - ...process.env, - SNYK_API: SNYK_API, - SNYK_TOKEN: '123456789', - HTTP_PROXY: HTTP_PROXY, - HTTPS_PROXY: HTTP_PROXY, - }; - server = fakeServer(baseApi, env.SNYK_TOKEN); - await server.listenPromise(port); - }); - - afterEach(() => { - server.restore(); - }); - - afterAll(async () => { - await server.closePromise(); - await stopProxyEnvironment(); - unlink(path.join(scriptsPath, KRB5_CACHE_FILE), () => {}); - unlink(path.join(scriptsPath, KRB5_CONFIG_FILE), () => {}); - }); - - it('fails to run snyk test due to disabled proxy authentication', async () => { - const logOnEntry = await getProxyAccessLog(); - - // run snyk test - const args: string[] = ['--proxy-noauth', project.path()]; - const cli = await runCliWithProxy(env, args); - await expect(cli).toExitWith(2); - - const logOnExit = await getProxyAccessLog(); - const additionalLogEntries = logOnExit.substring(logOnEntry.length); - expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); - expect( - additionalLogEntries.includes( - 'CONNECT ' + hostnameFakeServer + ':' + port, - ), - ).toBeFalsy(); - }); - - it('successfully runs snyk test with proxy', async () => { - const logOnEntry = await getProxyAccessLog(); - - // run snyk test - const args: string[] = [project.path()]; - const cli = await runCliWithProxy(env, args); - await expect(cli).toExitWith(0); - - const logOnExit = await getProxyAccessLog(); - const additionalLogEntries = logOnExit.substring(logOnEntry.length); - expect(additionalLogEntries.includes('TCP_TUNNEL/200')).toBeTruthy(); - expect( - additionalLogEntries.includes( - 'CONNECT ' + hostnameFakeServer + ':' + port, - ), - ).toBeTruthy(); - }); - } -}); - -describe('Proxy Authentication (Non-Windows)', () => { - if (canTestRun() && !os.platform().includes('win32')) { - let server: FakeServer; - let env: Record; - let project: TestProject; - - beforeAll(async () => { - project = await createProjectFromWorkspace('npm-package'); - await startProxyEnvironment(); - - env = { - ...process.env, - SNYK_API: SNYK_API, - SNYK_TOKEN: '123456789', - HTTP_PROXY: HTTP_PROXY, - HTTPS_PROXY: HTTP_PROXY, - }; - server = fakeServer(baseApi, env.SNYK_TOKEN); - await server.listenPromise(port); - }); - - afterEach(() => { - server.restore(); - }); - - afterAll(async () => { - await server.closePromise(); - await stopProxyEnvironment(); - unlink(path.join(scriptsPath, KRB5_CACHE_FILE), () => {}); - unlink(path.join(scriptsPath, KRB5_CONFIG_FILE), () => {}); - }); - - it('fail to run snyk test with proxy due to incorrect cache configuration', async () => { - const logOnEntry = await getProxyAccessLog(); - - // run snyk test - const args: string[] = [project.path()]; - env['KRB5CCNAME'] = 'MEMORY:' + path.join(scriptsPath, KRB5_CACHE_FILE); // specifying incorrect cache type memory - env['KRB5_CONFIG'] = path.join(scriptsPath, KRB5_CONFIG_FILE); - const cli = await runCliWithProxy(env, args); - await expect(cli).toExitWith(2); - - const logOnExit = await getProxyAccessLog(); - const additionalLogEntries = logOnExit.substring(logOnEntry.length); - expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); - }); - - it('fail to run snyk test with proxy due to incorrect config file', async () => { - const logOnEntry = await getProxyAccessLog(); - - // run snyk test - const args: string[] = [project.path()]; - env['KRB5CCNAME'] = 'FILE:' + path.join(scriptsPath, KRB5_CACHE_FILE); - env['KRB5_CONFIG'] = - path.join(scriptsPath, KRB5_CONFIG_FILE) + '_not_existing'; // specifying incorrect config location - const cli = await runCliWithProxy(env, args); - await expect(cli).toExitWith(2); - - const logOnExit = await getProxyAccessLog(); - const additionalLogEntries = logOnExit.substring(logOnEntry.length); - expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); - }); - } -}); diff --git a/cliv2/test/fixtures/squid_environment/Dockerfile b/test/fixtures/squid_environment/Dockerfile similarity index 100% rename from cliv2/test/fixtures/squid_environment/Dockerfile rename to test/fixtures/squid_environment/Dockerfile diff --git a/cliv2/test/fixtures/squid_environment/docker-compose.yml b/test/fixtures/squid_environment/docker-compose.yml similarity index 100% rename from cliv2/test/fixtures/squid_environment/docker-compose.yml rename to test/fixtures/squid_environment/docker-compose.yml diff --git a/cliv2/test/fixtures/squid_environment/scripts/setup.sh b/test/fixtures/squid_environment/scripts/setup.sh similarity index 100% rename from cliv2/test/fixtures/squid_environment/scripts/setup.sh rename to test/fixtures/squid_environment/scripts/setup.sh diff --git a/test/jest/acceptance/proxy-behavior.spec.ts b/test/jest/acceptance/proxy-behavior.spec.ts index fe94b87412..66290069c3 100644 --- a/test/jest/acceptance/proxy-behavior.spec.ts +++ b/test/jest/acceptance/proxy-behavior.spec.ts @@ -1,5 +1,19 @@ import { runSnykCLI } from '../util/runSnykCLI'; import { isCLIV2 } from '../util/isCLIV2'; +import { fakeServer, FakeServer } from '../../../test/acceptance/fake-server'; +import * as path from 'path'; +import { + createProjectFromWorkspace, + TestProject, +} from '../../../test/jest/util/createProject'; +import { + startCommand, + TestCLI, + startSnykCLI, +} from '../../../test/jest/util/startSnykCLI'; +import { unlink } from 'fs'; +import { execSync } from 'child_process'; +import * as os from 'os'; const fakeServerPort = 12345; const SNYK_API_HTTPS = 'https://snyk.io/api/v1'; @@ -24,6 +38,125 @@ function getConnectionRefusedRegExp(): string | RegExp { return expectedMessageRegex; } +// Global test configuration +const rootDir = path.resolve(path.join(__dirname, '..', '..')); +const squidEnvironmentPath = path.resolve( + path.join(rootDir, 'fixtures', 'squid_environment'), +); +const dockerComposeFile = path.resolve( + path.join(squidEnvironmentPath, 'docker-compose.yml'), +); +const scriptsPath = path.resolve(path.join(squidEnvironmentPath, 'scripts')); +const containerName = 'proxy_authentication_container'; +const hostnameFakeServer = 'host.docker.internal'; +const hostnameProxy = 'proxy.snyk.local'; +const proxyPort = '3128'; +const port = process.env.PORT || process.env.SNYK_PORT || '12345'; +const baseApi = '/api/v1'; +const SNYK_API = 'http://' + hostnameFakeServer + ':' + port + baseApi; +const HTTP_PROXY_WITH_USER = 'http://patch:dogsrule@localhost:' + proxyPort; +const HTTP_PROXY = 'http://localhost:' + proxyPort; +const KRB5_CACHE_FILE = 'krb5_cache'; +const KRB5_CONFIG_FILE = 'krb5.conf'; + +function getDockerOptions() { + const dockerOptions = { + env: { + ...process.env, + HTTP_PROXY_PORT: proxyPort, + PROXY_HOSTNAME: hostnameProxy, + SNYK_API: SNYK_API, + CONTAINER_NAME: containerName, + SCRIPTS_PATH: scriptsPath, + }, + }; + return dockerOptions; +} + +function isDockerAvailable(): boolean { + let result = false; + + try { + execSync('docker ps'); + execSync('docker-compose --version'); + result = true; + } catch (error) { + result = false; + console.debug(error); + } + + return result; +} + +async function startProxyEnvironment(): Promise { + // Stop any orphaned containers from previous runs. + await stopProxyEnvironment(); + + const dockerUp = await startCommand( + 'docker-compose', + ['--file', dockerComposeFile, 'up', '--build'], + getDockerOptions(), + ); + await expect(dockerUp).toDisplay('Kerberos setup complete.', { + timeout: 60_000, + }); +} + +async function stopProxyEnvironment(): Promise { + const dockerDown = await startCommand( + 'docker-compose', + ['--file', dockerComposeFile, 'down'], + getDockerOptions(), + ); + await expect(dockerDown).toExitWith(0, { timeout: 30_000 }); +} + +async function getProxyAccessLog(): Promise { + const check = await startCommand('docker', [ + 'exec', + containerName, + 'cat', + '/var/log/squid/access.log', + ]); + await expect(check).toExitWith(0); + return check.stdout.get(); +} + +async function runCliWithProxy( + env: Record, + args: string[] = [], + cmd = 'test', +): Promise { + let temp: string[] = [cmd, '--debug']; + temp = temp.concat(args); + + if (env['KRB5CCNAME'] == undefined) { + env['KRB5CCNAME'] = 'FILE:' + path.join(scriptsPath, KRB5_CACHE_FILE); + env['KRB5_CONFIG'] = path.join(scriptsPath, KRB5_CONFIG_FILE); + } + + const cli = await startSnykCLI(temp.join(' '), { + env: { + ...env, + SNYK_HTTP_PROTOCOL_UPGRADE: '0', + }, + }); + return cli; +} + +function canTestRun(): boolean { + if (!isDockerAvailable()) { + // eslint-disable-next-line jest/no-focused-tests + it('These tests are currently limited to certain environments.', () => { + console.warn( + 'Skipping CLIv2 test. These tests are limited to environments that have docker and docker-compose installed.', + ); + }); + return false; + } + return true; +} + jest.setTimeout(1000 * 60 * 1); describe('Proxy configuration behavior', () => { describe('*_PROXY against HTTPS host', () => { @@ -116,3 +249,159 @@ describe('Proxy configuration behavior', () => { } }); }); + +describe('Proxy Authentication (all platforms)', () => { + if (canTestRun()) { + let server: FakeServer; + let env: Record; + let project: TestProject; + + beforeAll(async () => { + project = await createProjectFromWorkspace('npm-package'); + await startProxyEnvironment(); + + env = { + ...process.env, + SNYK_API: SNYK_API, + SNYK_TOKEN: '123456789', + HTTP_PROXY: HTTP_PROXY, + HTTPS_PROXY: HTTP_PROXY, + }; + server = fakeServer(baseApi, env.SNYK_TOKEN); + await server.listenPromise(port); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll(async () => { + await server.closePromise(); + await stopProxyEnvironment(); + unlink(path.join(scriptsPath, KRB5_CACHE_FILE), () => {}); + unlink(path.join(scriptsPath, KRB5_CONFIG_FILE), () => {}); + }); + + if (isCLIV2()) { + it('fails to run snyk test due to disabled proxy authentication', async () => { + const logOnEntry = await getProxyAccessLog(); + + // run snyk test + const args: string[] = ['--proxy-noauth', project.path()]; + const cli = await runCliWithProxy(env, args); + await expect(cli).toExitWith(2); + + const logOnExit = await getProxyAccessLog(); + const additionalLogEntries = logOnExit.substring(logOnEntry.length); + expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); + expect( + additionalLogEntries.includes( + 'CONNECT ' + hostnameFakeServer + ':' + port, + ), + ).toBeFalsy(); + }); + + it('successfully runs snyk test with proxy (AnyAuth)', async () => { + const logOnEntry = await getProxyAccessLog(); + + // run snyk test + const args: string[] = [project.path()]; + const cli = await runCliWithProxy(env, args); + await expect(cli).toExitWith(0); + + const logOnExit = await getProxyAccessLog(); + const additionalLogEntries = logOnExit.substring(logOnEntry.length); + expect(additionalLogEntries.includes('TCP_TUNNEL/200')).toBeTruthy(); + expect( + additionalLogEntries.includes( + 'CONNECT ' + hostnameFakeServer + ':' + port, + ), + ).toBeTruthy(); + }); + } + + it('successfully runs snyk test with proxy (Basic)', async () => { + const logOnEntry = await getProxyAccessLog(); + + const localEnv = env; + localEnv['HTTP_PROXY'] = HTTP_PROXY_WITH_USER; + localEnv['HTTPS_PROXY'] = HTTP_PROXY_WITH_USER; + localEnv['SNYK_API'] = SNYK_API_HTTPS; + + // run snyk test + const args: string[] = [project.path(), '-d']; + const cli = await runCliWithProxy(localEnv, args, 'woof'); + await expect(cli).toExitWith(0); + + const logOnExit = await getProxyAccessLog(); + const additionalLogEntries = logOnExit.substring(logOnEntry.length); + expect(additionalLogEntries.includes('TCP_TUNNEL/200')).toBeTruthy(); + expect(additionalLogEntries.includes('CONNECT snyk.io:443')).toBeTruthy(); + }); + } +}); + +describe('Proxy Authentication (Non-Windows)', () => { + if (canTestRun() && !os.platform().includes('win32') && isCLIV2()) { + let server: FakeServer; + let env: Record; + let project: TestProject; + + beforeAll(async () => { + project = await createProjectFromWorkspace('npm-package'); + await startProxyEnvironment(); + + env = { + ...process.env, + SNYK_API: SNYK_API, + SNYK_TOKEN: '123456789', + HTTP_PROXY: HTTP_PROXY, + HTTPS_PROXY: HTTP_PROXY, + }; + server = fakeServer(baseApi, env.SNYK_TOKEN); + await server.listenPromise(port); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll(async () => { + await server.closePromise(); + await stopProxyEnvironment(); + unlink(path.join(scriptsPath, KRB5_CACHE_FILE), () => {}); + unlink(path.join(scriptsPath, KRB5_CONFIG_FILE), () => {}); + }); + + it('fail to run snyk test with proxy due to incorrect cache configuration', async () => { + const logOnEntry = await getProxyAccessLog(); + + // run snyk test + const args: string[] = [project.path()]; + env['KRB5CCNAME'] = 'MEMORY:' + path.join(scriptsPath, KRB5_CACHE_FILE); // specifying incorrect cache type memory + env['KRB5_CONFIG'] = path.join(scriptsPath, KRB5_CONFIG_FILE); + const cli = await runCliWithProxy(env, args); + await expect(cli).toExitWith(2); + + const logOnExit = await getProxyAccessLog(); + const additionalLogEntries = logOnExit.substring(logOnEntry.length); + expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); + }); + + it('fail to run snyk test with proxy due to incorrect config file', async () => { + const logOnEntry = await getProxyAccessLog(); + + // run snyk test + const args: string[] = [project.path()]; + env['KRB5CCNAME'] = 'FILE:' + path.join(scriptsPath, KRB5_CACHE_FILE); + env['KRB5_CONFIG'] = + path.join(scriptsPath, KRB5_CONFIG_FILE) + '_not_existing'; // specifying incorrect config location + const cli = await runCliWithProxy(env, args); + await expect(cli).toExitWith(2); + + const logOnExit = await getProxyAccessLog(); + const additionalLogEntries = logOnExit.substring(logOnEntry.length); + expect(additionalLogEntries.includes('TCP_DENIED/407')).toBeTruthy(); + }); + } +});