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