diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 97716a67d1..ab45858f88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,10 @@ jobs: windows-unit-tests: needs: linux-unit-tests uses: salesforcecli/github-workflows/.github/workflows/unitTestsWindows.yml@main + nuts: + needs: linux-unit-tests + uses: salesforcecli/github-workflows/.github/workflows/nut.yml@main + xNuts: needs: linux-unit-tests uses: salesforcecli/github-workflows/.github/workflows/externalNut.yml@main @@ -40,6 +44,8 @@ jobs: command: 'yarn test:nuts' os: ${{ matrix.os }} useCache: false + # remove the test folder for sfdx-core + preBuildCommands: 'shx rm -rf test' preSwapCommands: 'yarn upgrade @jsforce/jsforce-node@latest; npx yarn-deduplicate; yarn install' preExternalBuildCommands: 'shx rm -rf node_modules/@salesforce/core/node_modules/@jsforce/jsforce-node shx rm -rf node_modules/@salesforce/sf-plugins-core/node_modules/@salesforce/core node_modules/@salesforce/cli-plugins-testkit/node_modules/@salesforce/core node_modules/@salesforce/source-tracking/node_modules/@salesforce/core node_modules/@salesforce/source-deploy-retrieve/node_modules/@salesforce/core node_modules/@salesforce/apex-node/node_modules/@salesforce/core' secrets: inherit diff --git a/.mocharc.json b/.mocharc.json index 8bb562fc13..5adf3d90c9 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -1,5 +1,5 @@ { - "require": "test/init.js, ts-node/register, source-map-support/register", + "require": "ts-node/register, source-map-support/register", "watch-extensions": "ts", "watch-files": ["src", "test"], "recursive": true, diff --git a/.sfdevrc.json b/.sfdevrc.json index 2fba7b90c3..ca3c6b73aa 100644 --- a/.sfdevrc.json +++ b/.sfdevrc.json @@ -1,6 +1,6 @@ { "test": { - "testsPath": "test/**/*Test.ts" + "testsPath": "test/unit/**/*.test.ts" }, "wireit": { "compile": { diff --git a/package.json b/package.json index be01dd1e67..bc000c78a3 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "prepack": "sf-prepack", "prepare": "sf-install", "test": "wireit", + "test:nuts": "mocha \"test/**/*.nut.ts\" --timeout 500000", "test:only": "wireit", "test:perf": "ts-node test/perf/logger/main.test.ts" }, @@ -146,7 +147,7 @@ "output": [] }, "test:only": { - "command": "nyc mocha \"test/**/*Test.ts\"", + "command": "nyc mocha \"test/unit/**/*.test.ts\"", "env": { "FORCE_COLOR": "2" }, diff --git a/src/config/configFile.ts b/src/config/configFile.ts index 32c1302bbf..3b7e94c544 100644 --- a/src/config/configFile.ts +++ b/src/config/configFile.ts @@ -14,7 +14,7 @@ import { Global } from '../global'; import { Logger } from '../logger/logger'; import { SfError } from '../sfError'; import { resolveProjectPath, resolveProjectPathSync } from '../util/internal'; -import { lockInit, lockInitSync } from '../util/fileLocking'; +import { lockInit, lockInitSync, pollUntilUnlock, pollUntilUnlockSync } from '../util/fileLocking'; import { BaseConfigStore } from './configStore'; import { ConfigContents } from './configStackTypes'; import { stateFromContents } from './lwwMap'; @@ -167,7 +167,7 @@ export class ConfigFile< !this.hasRead ? 'hasRead is false' : 'force parameter is true' }` ); - + await pollUntilUnlock(this.getPath()); const obj = parseJsonMap

(await fs.promises.readFile(this.getPath(), 'utf8'), this.getPath()); this.setContentsFromFileContents(obj, (await fs.promises.stat(this.getPath(), { bigint: true })).mtimeNs); } @@ -203,6 +203,7 @@ export class ConfigFile< // Only need to read config files once. They are kept up to date // internally and updated persistently via write(). if (!this.hasRead || force) { + pollUntilUnlockSync(this.getPath()); this.logger.debug(`Reading config file: ${this.getPath()}`); const obj = parseJsonMap

(fs.readFileSync(this.getPath(), 'utf8')); this.setContentsFromFileContents(obj, fs.statSync(this.getPath(), { bigint: true }).mtimeNs); diff --git a/src/util/fileLocking.ts b/src/util/fileLocking.ts index db955221b0..ee90d3f74f 100644 --- a/src/util/fileLocking.ts +++ b/src/util/fileLocking.ts @@ -6,7 +6,9 @@ */ import * as fs from 'node:fs'; import { dirname } from 'node:path'; -import { lock, lockSync } from 'proper-lockfile'; +import { lock, lockSync, check, checkSync } from 'proper-lockfile'; +import { Duration } from '@salesforce/kit'; +import { retryDecorator } from 'ts-retry-promise'; import { SfError } from '../sfError'; import { Logger } from '../logger/logger'; import { lockOptions, lockRetryOptions } from './lockRetryOptions'; @@ -95,3 +97,37 @@ export const lockInitSync = (filePath: string): LockInitSyncResponse => { unlock, }; }; + +/** + * Poll until the file is unlocked. + * + * @param filePath file path to check + */ +export const pollUntilUnlock = async (filePath: string): Promise => { + try { + await retryDecorator(check, { + timeout: Duration.minutes(1).milliseconds, + delay: 10, + until: (locked) => locked === false, + // don't retry errors (typically enoent or access on the lockfile, therefore not locked) + retryIf: () => false, + })(filePath, lockRetryOptions); + } catch (e) { + // intentionally swallow the error, same reason as above + } +}; + +export const pollUntilUnlockSync = (filePath: string): void => { + // Set a counter to ensure that the while loop does not run indefinitely + let counter = 0; + let locked = true; + while (locked && counter < 100) { + try { + locked = checkSync(filePath, lockOptions); + counter++; + } catch { + // Likely a file not found error, which means the file is not locked + locked = false; + } + } +}; diff --git a/test/init.js b/test/init.js deleted file mode 100644 index d314a8fd4f..0000000000 --- a/test/init.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2018, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -const path = require('path'); -process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json'); diff --git a/test/nut/concurrencyConfig.ts b/test/nut/concurrencyConfig.ts new file mode 100644 index 0000000000..8d79b39002 --- /dev/null +++ b/test/nut/concurrencyConfig.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import { tmpdir } from 'node:os'; +import { ConfigFile } from '../../src'; + +export const FILENAME = 'concurrency.json'; + +export class TestConfig extends ConfigFile { + public static getOptions( + filename: string, + isGlobal: boolean, + isState?: boolean, + filePath?: string + ): ConfigFile.Options { + return { + rootFolder: tmpdir(), + filename, + isGlobal, + isState, + filePath, + }; + } + + public static getFileName() { + return FILENAME; + } +} diff --git a/test/nut/concurrencyReadWrite.ts b/test/nut/concurrencyReadWrite.ts new file mode 100644 index 0000000000..82d773ca49 --- /dev/null +++ b/test/nut/concurrencyReadWrite.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import { join } from 'node:path'; +import { expect } from 'chai'; // Add this line to import the expect function +import { TestConfig } from './concurrencyConfig'; + +const sharedLocation = join('sfdx-core-ut', 'test', 'configFile'); + +/** ex: `yarn ts-node test/nut/concurrencyReadWrite.ts 1` */ +(async function (i: number = parseInt(process.argv[2], 10)) { + const config = new TestConfig(TestConfig.getOptions('test', true, true, sharedLocation)); + config.set('x', i); + await config.write(); + const readConfig = await config.read(true, true); + expect(readConfig.x).to.be.a('number'); +})().catch((err) => { + throw err; +}); diff --git a/test/unit/config/configFileConcurrency.test.ts b/test/nut/configFileConcurrency.nut.ts similarity index 91% rename from test/unit/config/configFileConcurrency.test.ts rename to test/nut/configFileConcurrency.nut.ts index 8314b8a879..5b6c7af78f 100644 --- a/test/unit/config/configFileConcurrency.test.ts +++ b/test/nut/configFileConcurrency.nut.ts @@ -7,33 +7,15 @@ import { join } from 'node:path'; import { tmpdir } from 'node:os'; import { rm } from 'node:fs/promises'; +import { exec } from 'node:child_process'; +import { promisify } from 'node:util'; import { expect } from 'chai'; import { sleep } from '@salesforce/kit'; -import { ConfigFile } from '../../../src'; +import { TestConfig, FILENAME } from './concurrencyConfig'; -const FILENAME = 'concurrency.json'; -const sharedLocation = join('sfdx-core-ut', 'test', 'configFile'); +const execProm = promisify(exec); -class TestConfig extends ConfigFile { - public static getOptions( - filename: string, - isGlobal: boolean, - isState?: boolean, - filePath?: string - ): ConfigFile.Options { - return { - rootFolder: tmpdir(), - filename, - isGlobal, - isState, - filePath, - }; - } - - public static getFileName() { - return FILENAME; - } -} +const sharedLocation = join('sfdx-core-ut', 'test', 'configFile'); /* file and node - clock timestamps aren't precise enough to run in a UT. * the goal of this and the `sleep` is to put a bit of space between operations @@ -190,4 +172,15 @@ describe('concurrency', () => { expect(config4.get('x')).to.be.greaterThanOrEqual(7).and.lessThanOrEqual(9); } }); + + it('safe reads on parallel writes', async () => { + const configOriginal = new TestConfig(TestConfig.getOptions('test', true, true, sharedLocation)); + configOriginal.set('x', 0); + await configOriginal.write(); + await sleep(SLEEP_FUDGE_MS); + + await Promise.all( + Array.from({ length: 50 }).map((_, i) => execProm(`yarn ts-node test/nut/concurrencyReadWrite.ts ${i}`)) + ); + }); }); diff --git a/test/tsconfig.json b/test/tsconfig.json index d1a7d129dd..ad28147f51 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@salesforce/dev-config/tsconfig-test-strict", - "include": ["unit/**/*.ts", "perf/**/*.ts"], + "include": ["nut/**/*.ts", "unit/**/*.ts", "perf/**/*.ts"], "compilerOptions": { "noEmit": true, "skipLibCheck": true, diff --git a/test/unit/config/configTest.ts b/test/unit/config/config.test.ts similarity index 100% rename from test/unit/config/configTest.ts rename to test/unit/config/config.test.ts diff --git a/test/unit/config/configAggregatorTest.ts b/test/unit/config/configAggregator.test.ts similarity index 100% rename from test/unit/config/configAggregatorTest.ts rename to test/unit/config/configAggregator.test.ts diff --git a/test/unit/config/configFileTest.ts b/test/unit/config/configFile.test.ts similarity index 100% rename from test/unit/config/configFileTest.ts rename to test/unit/config/configFile.test.ts diff --git a/test/unit/config/configStoreTest.ts b/test/unit/config/configStore.test.ts similarity index 100% rename from test/unit/config/configStoreTest.ts rename to test/unit/config/configStore.test.ts diff --git a/test/unit/config/envVarsTest.ts b/test/unit/config/envVars.test.ts similarity index 100% rename from test/unit/config/envVarsTest.ts rename to test/unit/config/envVars.test.ts diff --git a/test/unit/config/lwwMapTest.ts b/test/unit/config/lwwMap.test.ts similarity index 100% rename from test/unit/config/lwwMapTest.ts rename to test/unit/config/lwwMap.test.ts diff --git a/test/unit/config/ttlConfigTest.ts b/test/unit/config/ttlConfig.test.ts similarity index 98% rename from test/unit/config/ttlConfigTest.ts rename to test/unit/config/ttlConfig.test.ts index 59bf3823e9..ccfa870f17 100644 --- a/test/unit/config/ttlConfigTest.ts +++ b/test/unit/config/ttlConfig.test.ts @@ -51,7 +51,7 @@ describe('TTLConfig', () => { it('should return the latest entry', async () => { const config = await TestConfig.create(); config.set('1', { one: 'one' }); - await sleep(1000); + await sleep(200); config.set('2', { two: 'two' }); const latest = config.getLatestEntry(); expect(latest).to.deep.equal(['2', config.get('2')]); @@ -68,7 +68,7 @@ describe('TTLConfig', () => { it('should return the key of the latest entry', async () => { const config = await TestConfig.create(); config.set('1', { one: 'one' }); - await sleep(1000); + await sleep(200); config.set('2', { two: 'two' }); const latest = config.getLatestKey(); expect(latest).to.equal('2'); diff --git a/test/unit/crypto/cryptoKeyFailuresTest.ts b/test/unit/crypto/cryptoKeyFailures.test.ts similarity index 100% rename from test/unit/crypto/cryptoKeyFailuresTest.ts rename to test/unit/crypto/cryptoKeyFailures.test.ts diff --git a/test/unit/crypto/cryptoTest.ts b/test/unit/crypto/cryptoTest.test.ts similarity index 100% rename from test/unit/crypto/cryptoTest.ts rename to test/unit/crypto/cryptoTest.test.ts diff --git a/test/unit/crypto/keyChainTest.ts b/test/unit/crypto/keyChain.test.ts similarity index 100% rename from test/unit/crypto/keyChainTest.ts rename to test/unit/crypto/keyChain.test.ts diff --git a/test/unit/crypto/keyChainImplTest.ts b/test/unit/crypto/keyChainImpl.test.ts similarity index 100% rename from test/unit/crypto/keyChainImplTest.ts rename to test/unit/crypto/keyChainImpl.test.ts diff --git a/test/unit/crypto/secureStringTest.ts b/test/unit/crypto/secureString.test.ts similarity index 100% rename from test/unit/crypto/secureStringTest.ts rename to test/unit/crypto/secureString.test.ts diff --git a/test/unit/deviceOauthServiceTest.ts b/test/unit/deviceOauthService.test.ts similarity index 100% rename from test/unit/deviceOauthServiceTest.ts rename to test/unit/deviceOauthService.test.ts diff --git a/test/unit/globalTest.ts b/test/unit/global.test.ts similarity index 100% rename from test/unit/globalTest.ts rename to test/unit/global.test.ts diff --git a/test/unit/lifecycleEventsTest.ts b/test/unit/lifecycleEvents.test.ts similarity index 100% rename from test/unit/lifecycleEventsTest.ts rename to test/unit/lifecycleEvents.test.ts diff --git a/test/unit/logger/cleanupTest.ts b/test/unit/logger/cleanup.test.ts similarity index 100% rename from test/unit/logger/cleanupTest.ts rename to test/unit/logger/cleanup.test.ts diff --git a/test/unit/logger/filterTest.ts b/test/unit/logger/filter.test.ts similarity index 100% rename from test/unit/logger/filterTest.ts rename to test/unit/logger/filter.test.ts diff --git a/test/unit/loggerTest.ts b/test/unit/logger/logger.test.ts similarity index 98% rename from test/unit/loggerTest.ts rename to test/unit/logger/logger.test.ts index cfac7013cd..b231539fac 100644 --- a/test/unit/loggerTest.ts +++ b/test/unit/logger/logger.test.ts @@ -10,8 +10,8 @@ import { expect, config as chaiConfig } from 'chai'; import { isString } from '@salesforce/ts-types'; -import { Logger, LoggerLevel, computeLevel } from '../../src/logger/logger'; -import { shouldThrowSync, TestContext } from '../../src/testSetup'; +import { Logger, LoggerLevel, computeLevel } from '../../../src/logger/logger'; +import { shouldThrowSync, TestContext } from '../../../src/testSetup'; // NOTE: These tests still use 'await' which is how it use to work and were left to make // sure we didn't regress the way they were used. diff --git a/test/unit/messagesTest.ts b/test/unit/messages.test.ts similarity index 100% rename from test/unit/messagesTest.ts rename to test/unit/messages.test.ts diff --git a/test/unit/org/authInfoTest.ts b/test/unit/org/authInfo.test.ts similarity index 100% rename from test/unit/org/authInfoTest.ts rename to test/unit/org/authInfo.test.ts diff --git a/test/unit/org/authRemoverTest.ts b/test/unit/org/authRemover.test.ts similarity index 100% rename from test/unit/org/authRemoverTest.ts rename to test/unit/org/authRemover.test.ts diff --git a/test/unit/org/connectionTest.ts b/test/unit/org/connection.test.ts similarity index 100% rename from test/unit/org/connectionTest.ts rename to test/unit/org/connection.test.ts diff --git a/test/unit/org/orgTest.ts b/test/unit/org/org.test.ts similarity index 100% rename from test/unit/org/orgTest.ts rename to test/unit/org/org.test.ts diff --git a/test/unit/org/permissionSetAssignmentTest.ts b/test/unit/org/permissionSetAssignment.test.ts similarity index 100% rename from test/unit/org/permissionSetAssignmentTest.ts rename to test/unit/org/permissionSetAssignment.test.ts diff --git a/test/unit/org/scratchOrgCreateTest.ts b/test/unit/org/scratchOrgCreate.test.ts similarity index 100% rename from test/unit/org/scratchOrgCreateTest.ts rename to test/unit/org/scratchOrgCreate.test.ts diff --git a/test/unit/org/scratchOrgErrorCodesTest.ts b/test/unit/org/scratchOrgErrorCodes.test.ts similarity index 100% rename from test/unit/org/scratchOrgErrorCodesTest.ts rename to test/unit/org/scratchOrgErrorCodes.test.ts diff --git a/test/unit/org/scratchOrgFeatureDeprecationTest.ts b/test/unit/org/scratchOrgFeatureDeprecation.test.ts similarity index 100% rename from test/unit/org/scratchOrgFeatureDeprecationTest.ts rename to test/unit/org/scratchOrgFeatureDeprecation.test.ts diff --git a/test/unit/org/scratchOrgInfoApiTest.ts b/test/unit/org/scratchOrgInfoApi.test.ts similarity index 100% rename from test/unit/org/scratchOrgInfoApiTest.ts rename to test/unit/org/scratchOrgInfoApi.test.ts diff --git a/test/unit/org/scratchOrgInfoGeneratorTest.ts b/test/unit/org/scratchOrgInfoGenerator.test.ts similarity index 100% rename from test/unit/org/scratchOrgInfoGeneratorTest.ts rename to test/unit/org/scratchOrgInfoGenerator.test.ts diff --git a/test/unit/org/scratchOrgSettingsGeneratorTest.ts b/test/unit/org/scratchOrgSettingsGenerator.test.ts similarity index 100% rename from test/unit/org/scratchOrgSettingsGeneratorTest.ts rename to test/unit/org/scratchOrgSettingsGenerator.test.ts diff --git a/test/unit/org/userTest.ts b/test/unit/org/user.test.ts similarity index 100% rename from test/unit/org/userTest.ts rename to test/unit/org/user.test.ts diff --git a/test/unit/projectTest.ts b/test/unit/project.test.ts similarity index 100% rename from test/unit/projectTest.ts rename to test/unit/project.test.ts diff --git a/test/unit/schema/validatorTest.ts b/test/unit/schema/validator.test.ts similarity index 100% rename from test/unit/schema/validatorTest.ts rename to test/unit/schema/validator.test.ts diff --git a/test/unit/sfErrorTest.ts b/test/unit/sfError.test.ts similarity index 98% rename from test/unit/sfErrorTest.ts rename to test/unit/sfError.test.ts index ae0576d5e8..082badf242 100644 --- a/test/unit/sfErrorTest.ts +++ b/test/unit/sfError.test.ts @@ -79,7 +79,7 @@ describe('SfError', () => { it('returned `name:message` when no cause', () => { const err = new SfError('test'); expect(inspect(err)).to.include('SfError: test'); - expect(inspect(err)).to.include('sfErrorTest.ts'); + expect(inspect(err)).to.include('sfError.test.ts'); // there's always 1 cause from the `cause:` property, even if undefined expect(inspect(err)?.match(causeRegex)).to.have.lengthOf(1); }); @@ -87,7 +87,7 @@ describe('SfError', () => { const nestedError = new Error('nested'); const err = new SfError('test', undefined, undefined, nestedError); expect(inspect(err)).to.include('SfError: test'); - expect(inspect(err)).to.include('sfErrorTest.ts'); + expect(inspect(err)).to.include('sfError.test.ts'); expect(inspect(err)).to.include('nested'); expect(inspect(err)?.match(causeRegex)).to.have.lengthOf(1); expect(inspect(err)?.match(nestedCauseRegex)).to.be.null; @@ -97,7 +97,7 @@ describe('SfError', () => { const nestedError2 = new Error('nested2', { cause: nestedError }); const err = new SfError('test', undefined, undefined, nestedError2); expect(inspect(err)).to.include('SfError: test'); - expect(inspect(err)).to.include('sfErrorTest.ts'); + expect(inspect(err)).to.include('sfError.test.ts'); expect(inspect(err)).to.include('nested'); expect(inspect(err)).to.include('nested2'); expect(inspect(err)?.match(causeRegex)).to.have.lengthOf(1); diff --git a/test/unit/stateAggregator/accessors/aliasAccessorTest.ts b/test/unit/stateAggregator/accessors/aliasAccessor.test.ts similarity index 100% rename from test/unit/stateAggregator/accessors/aliasAccessorTest.ts rename to test/unit/stateAggregator/accessors/aliasAccessor.test.ts diff --git a/test/unit/stateAggregator/accessors/orgAccessorTest.ts b/test/unit/stateAggregator/accessors/orgAccessor.test.ts similarity index 100% rename from test/unit/stateAggregator/accessors/orgAccessorTest.ts rename to test/unit/stateAggregator/accessors/orgAccessor.test.ts diff --git a/test/unit/stateAggregator/accessors/sandboxAccessorTest.ts b/test/unit/stateAggregator/accessors/sandboxAccessor.test.ts similarity index 100% rename from test/unit/stateAggregator/accessors/sandboxAccessorTest.ts rename to test/unit/stateAggregator/accessors/sandboxAccessor.test.ts diff --git a/test/unit/status/myDomainResolverTest.ts b/test/unit/status/myDomainResolver.test.ts similarity index 100% rename from test/unit/status/myDomainResolverTest.ts rename to test/unit/status/myDomainResolver.test.ts diff --git a/test/unit/status/pollingClientTest.ts b/test/unit/status/pollingClient.test.ts similarity index 100% rename from test/unit/status/pollingClientTest.ts rename to test/unit/status/pollingClient.test.ts diff --git a/test/unit/status/streamingClientTest.ts b/test/unit/status/streamingClient.test.ts similarity index 100% rename from test/unit/status/streamingClientTest.ts rename to test/unit/status/streamingClient.test.ts diff --git a/test/unit/testSetupTest.ts b/test/unit/testSetup.test.ts similarity index 100% rename from test/unit/testSetupTest.ts rename to test/unit/testSetup.test.ts diff --git a/test/unit/util/cacheTest.ts b/test/unit/util/cache.test.ts similarity index 100% rename from test/unit/util/cacheTest.ts rename to test/unit/util/cache.test.ts diff --git a/test/unit/util/directoryWriterTest.ts b/test/unit/util/directoryWriter.test.ts similarity index 100% rename from test/unit/util/directoryWriterTest.ts rename to test/unit/util/directoryWriter.test.ts diff --git a/test/unit/util/fileLockingTest.ts b/test/unit/util/fileLocking.test.ts similarity index 100% rename from test/unit/util/fileLockingTest.ts rename to test/unit/util/fileLocking.test.ts diff --git a/test/unit/util/findUppercaseKeysTest.ts b/test/unit/util/findUppercaseKeys.test.ts similarity index 100% rename from test/unit/util/findUppercaseKeysTest.ts rename to test/unit/util/findUppercaseKeys.test.ts diff --git a/test/unit/util/getJwtAudienceUrlTest.ts b/test/unit/util/getJwtAudienceUrl.test.ts similarity index 100% rename from test/unit/util/getJwtAudienceUrlTest.ts rename to test/unit/util/getJwtAudienceUrl.test.ts diff --git a/test/unit/util/internalTest.ts b/test/unit/util/internal.test.ts similarity index 100% rename from test/unit/util/internalTest.ts rename to test/unit/util/internal.test.ts diff --git a/test/unit/util/mapKeysTest.ts b/test/unit/util/mapKeys.test.ts similarity index 100% rename from test/unit/util/mapKeysTest.ts rename to test/unit/util/mapKeys.test.ts diff --git a/test/unit/util/sfdcTest.ts b/test/unit/util/sfdc.test.ts similarity index 100% rename from test/unit/util/sfdcTest.ts rename to test/unit/util/sfdc.test.ts diff --git a/test/unit/util/sfdcUrlTest.ts b/test/unit/util/sfdcUrl.test.ts similarity index 100% rename from test/unit/util/sfdcUrlTest.ts rename to test/unit/util/sfdcUrl.test.ts diff --git a/test/unit/util/unwrapArrayTest.ts b/test/unit/util/unwrapArray.test.ts similarity index 100% rename from test/unit/util/unwrapArrayTest.ts rename to test/unit/util/unwrapArray.test.ts diff --git a/test/unit/util/zipWriterTest.ts b/test/unit/util/zipWriter.test.ts similarity index 100% rename from test/unit/util/zipWriterTest.ts rename to test/unit/util/zipWriter.test.ts diff --git a/test/unit/webOauthServerTest.ts b/test/unit/webOauthServer.test.ts similarity index 100% rename from test/unit/webOauthServerTest.ts rename to test/unit/webOauthServer.test.ts