Skip to content

Commit 4117a04

Browse files
authored
Merge pull request #391 from MatrixAI/feature-pkg_integration_tests
Packaged executable integration tests - initial integration tests with docker
2 parents ce07c78 + 88b37bc commit 4117a04

119 files changed

Lines changed: 4802 additions & 4405 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,9 @@ AWS_SECRET_ACCESS_KEY=
3131

3232
# Authenticate to GitHub with `gh`
3333
# GITHUB_TOKEN=
34+
35+
# To allow testing different executables in the bin tests
36+
# Both PK_TEST_COMMAND and PK_TEST_PLATFORM must be set at the same time
37+
# PK_TEST_COMMAND= #Specify the shell command we want to test against
38+
# PK_TEST_PLATFORM=docker #Overrides the auto set `testPlatform` variable used for enabling platform specific tests
39+
# PK_TEST_TMPDIR= #Sets the `global.tmpDir` variable to allow overriding the temp directory used for tests

.gitlab-ci.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,20 @@ integration:docker:
330330
- integration:builds
331331
- job: integration:deployment
332332
optional: true
333-
image: docker:20.10.11
334333
services:
335-
- docker:20.10.11-dind
334+
- docker:20.10.16-dind
336335
variables:
337336
DOCKER_TLS_CERTDIR: "/certs"
337+
FF_NETWORK_PER_BUILD: "true"
338338
script:
339339
- docker info
340-
- image="$(docker load --input ./builds/*docker* | cut -d' ' -f3)"
341-
- docker run "$image"
340+
- >
341+
nix-shell --run $'
342+
PK_TEST_COMMAND="docker run \${DOCKER_OPTIONS} $(docker load --input ./builds/*docker* | cut -d\' \' -f3) polykey" \
343+
PK_TEST_PLATFORM=docker \
344+
PK_TEST_TMPDIR=/builds/$CI_PROJECT_PATH/tmp \
345+
exec npm run test -- tests/bin
346+
'
342347
rules:
343348
# Runs on staging commits and ignores version commits
344349
- if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/

jest.config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ moduleNameMapper['^jose/(.*)$'] = "<rootDir>/node_modules/jose/dist/node/cjs/$1"
1515

1616
// Global variables that are shared across the jest worker pool
1717
// These variables must be static and serializable
18+
if ((process.env.PK_TEST_PLATFORM != null) !== (process.env.PK_TEST_COMMAND != null)) throw Error('Both PK_TEST_PLATFORM and PK_TEST_COMMAND must be set together.')
1819
const globals = {
1920
// Absolute directory to the project root
2021
projectDir: __dirname,
@@ -31,7 +32,8 @@ const globals = {
3132
// Timeouts rely on setTimeout which takes 32 bit numbers
3233
maxTimeout: Math.pow(2, 31) - 1,
3334
testCmd: process.env.PK_TEST_COMMAND,
34-
testPlatform: process.env.PK_TEST_COMMAND_DOCKER,
35+
testPlatform: process.env.PK_TEST_PLATFORM,
36+
tmpDir: process.env.PK_TEST_TMPDIR ?? os.tmpdir(),
3537
};
3638

3739
// The `globalSetup` and `globalTeardown` cannot access the `globals`

scripts/docker-run.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/PolykeyAgent.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { FileSystem } from './types';
22
import type { PolykeyWorkerManagerInterface } from './workers/types';
33
import type { ConnectionData, Host, Port } from './network/types';
44
import type { SeedNodes } from './nodes/types';
5-
import type { KeyManagerChangeData } from './keys/types';
5+
import type { KeyManagerChangeData, PrivateKeyPem } from './keys/types';
66
import path from 'path';
77
import process from 'process';
88
import Logger from '@matrixai/logger';
@@ -108,6 +108,7 @@ class PolykeyAgent {
108108
rootCertDuration?: number;
109109
dbKeyBits?: number;
110110
recoveryCode?: string;
111+
privateKeyPemOverride?: PrivateKeyPem;
111112
};
112113
proxyConfig?: {
113114
authToken?: string;

src/bin/agent/CommandStart.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class CommandStart extends CommandPolykey {
3737
this.addOption(binOptions.backgroundOutFile);
3838
this.addOption(binOptions.backgroundErrFile);
3939
this.addOption(binOptions.fresh);
40+
this.addOption(binOptions.rootKeyFile);
4041
this.action(async (options) => {
4142
options.clientHost =
4243
options.clientHost ?? config.defaults.networkConfig.clientHost;
@@ -88,12 +89,16 @@ class CommandStart extends CommandPolykey {
8889
const [seedNodes, defaults] = options.seedNodes;
8990
let seedNodes_ = seedNodes;
9091
if (defaults) seedNodes_ = { ...options.network, ...seedNodes };
92+
const privateKeyPem = await binProcessors.processRootKey(
93+
options.rootKeyFile,
94+
);
9195
const agentConfig = {
9296
password,
9397
nodePath: options.nodePath,
9498
keysConfig: {
9599
rootKeyPairBits: options.rootKeyPairBits,
96100
recoveryCode: recoveryCodeIn,
101+
privateKeyPemOverride: privateKeyPem,
97102
},
98103
proxyConfig: {
99104
connConnectTime: options.connectionTimeout,

src/bin/bootstrap/CommandBootstrap.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class CommandBootstrap extends CommandPolykey {
1111
this.addOption(binOptions.recoveryCodeFile);
1212
this.addOption(binOptions.rootKeyPairBits);
1313
this.addOption(binOptions.fresh);
14+
this.addOption(binOptions.rootKeyFile);
1415
this.action(async (options) => {
1516
const bootstrapUtils = await import('../../bootstrap/utils');
1617
const password = await binProcessors.processNewPassword(
@@ -21,19 +22,23 @@ class CommandBootstrap extends CommandPolykey {
2122
options.recoveryCodeFile,
2223
this.fs,
2324
);
25+
const privateKeyPem = await binProcessors.processRootKey(
26+
options.rootKeyFile,
27+
);
2428
const recoveryCodeOut = await bootstrapUtils.bootstrapState({
2529
password,
2630
nodePath: options.nodePath,
2731
keysConfig: {
2832
rootKeyPairBits: options.rootKeyPairBits,
2933
recoveryCode: recoveryCodeIn,
34+
privateKeyPemOverride: privateKeyPem,
3035
},
3136
fresh: options.fresh,
3237
fs: this.fs,
3338
logger: this.logger,
3439
});
3540
this.logger.info(`Bootstrapped ${options.nodePath}`);
36-
process.stdout.write(recoveryCodeOut + '\n');
41+
if (recoveryCodeOut != null) process.stdout.write(recoveryCodeOut + '\n');
3742
});
3843
}
3944
}

src/bin/errors.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class ErrorCLIRecoveryCodeFileRead<T> extends ErrorCLI<T> {
2929
exitCode = sysexits.NOINPUT;
3030
}
3131

32+
class ErrorCLIPrivateKeyFileRead<T> extends ErrorCLI<T> {
33+
static description = 'Failed to read private key Pem file';
34+
exitCode = sysexits.NOINPUT;
35+
}
36+
3237
class ErrorCLIFileRead<T> extends ErrorCLI<T> {
3338
static description = 'Failed to read file';
3439
exitCode = sysexits.NOINPUT;
@@ -61,6 +66,7 @@ export {
6166
ErrorCLIPasswordMissing,
6267
ErrorCLIPasswordFileRead,
6368
ErrorCLIRecoveryCodeFileRead,
69+
ErrorCLIPrivateKeyFileRead,
6470
ErrorCLIFileRead,
6571
ErrorCLIPolykeyAgentStatus,
6672
ErrorCLIPolykeyAgentProcess,

src/bin/utils/options.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ const noPing = new commander.Option('--no-ping', 'Skip ping step').default(
163163
true,
164164
);
165165

166+
const rootKeyFile = new commander.Option(
167+
'--root-key-file <rootKeyFile>',
168+
'Override key generation with a private key Pem from a file.',
169+
);
170+
166171
export {
167172
nodePath,
168173
format,
@@ -187,4 +192,5 @@ export {
187192
pullVault,
188193
forceNodeAdd,
189194
noPing,
195+
rootKeyFile,
190196
};

src/bin/utils/processors.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { FileSystem } from '../../types';
2-
import type { RecoveryCode } from '../../keys/types';
2+
import type { RecoveryCode, PrivateKeyPem } from '../../keys/types';
33
import type { NodeId } from '../../nodes/types';
44
import type { Host, Port } from '../../network/types';
55
import type {
@@ -403,6 +403,29 @@ async function processAuthentication(
403403
return meta;
404404
}
405405

406+
async function processRootKey(
407+
privateKeyFile: string | undefined,
408+
fs: FileSystem = require('fs'),
409+
): Promise<PrivateKeyPem | undefined> {
410+
if (privateKeyFile != null) {
411+
try {
412+
return (await fs.promises.readFile(privateKeyFile, 'utf-8')).trim();
413+
} catch (e) {
414+
throw new binErrors.ErrorCLIPrivateKeyFileRead(e.message, {
415+
data: {
416+
errno: e.errno,
417+
syscall: e.syscall,
418+
code: e.code,
419+
path: e.path,
420+
},
421+
cause: e,
422+
});
423+
}
424+
} else if (typeof process.env['PK_ROOT_KEY'] === 'string') {
425+
return process.env['PK_ROOT_KEY'];
426+
}
427+
}
428+
406429
export {
407430
promptPassword,
408431
promptNewPassword,
@@ -412,4 +435,5 @@ export {
412435
processClientOptions,
413436
processClientStatus,
414437
processAuthentication,
438+
processRootKey,
415439
};

0 commit comments

Comments
 (0)