@digicatapult/sqnc-process-management 2.2.128 → 2.2.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/build/package.json +2 -1
- package/build/src/lib/process/api.d.ts +1 -0
- package/build/src/lib/process/api.js +89 -15
- package/build/src/lib/process/index.d.ts +2 -2
- package/build/src/lib/process/index.js +120 -44
- package/build/src/lib/types/validation.d.ts +4 -4
- package/build/src/lib/utils/polkadot.d.ts +6 -1
- package/build/src/lib/utils/polkadot.js +3 -0
- package/build/tests/helpers/containers.d.ts +7 -0
- package/build/tests/helpers/containers.js +40 -0
- package/build/tests/helpers/substrateHelper.d.ts +2 -2
- package/build/tests/helpers/substrateHelper.js +86 -11
- package/build/tests/integration/command-functions.test.js +114 -44
- package/build/tests/integration/without-manual-seal.test.d.ts +1 -0
- package/build/tests/integration/without-manual-seal.test.js +52 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -200,14 +200,14 @@ Unit tests can be run without docker using:
|
|
|
200
200
|
npm run test:unit
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
Running the integration test suite requires docker to be installed. Tests can then be executed with:
|
|
204
204
|
|
|
205
205
|
```shell
|
|
206
|
-
|
|
206
|
+
npm run test
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
If you want to see output from the `sqnc-node` container brought up with `testcontainers` run:
|
|
210
210
|
|
|
211
211
|
```shell
|
|
212
|
-
npm run test
|
|
212
|
+
DEBUG=testcontainers* npm run test
|
|
213
213
|
```
|
package/build/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digicatapult/sqnc-process-management",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.129",
|
|
4
4
|
"description": "SQNC Process Management Flow",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"mocha": "^10.8.2",
|
|
52
52
|
"nodemon": "^3.1.7",
|
|
53
53
|
"prettier": "^3.3.3",
|
|
54
|
+
"testcontainers": "^10.14.0",
|
|
54
55
|
"ts-mocha": "^10.0.0",
|
|
55
56
|
"ts-node": "^10.9.2"
|
|
56
57
|
},
|
|
@@ -7,6 +7,58 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
11
|
+
if (value !== null && value !== void 0) {
|
|
12
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
13
|
+
var dispose, inner;
|
|
14
|
+
if (async) {
|
|
15
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.asyncDispose];
|
|
17
|
+
}
|
|
18
|
+
if (dispose === void 0) {
|
|
19
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
20
|
+
dispose = value[Symbol.dispose];
|
|
21
|
+
if (async) inner = dispose;
|
|
22
|
+
}
|
|
23
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
24
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
25
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
26
|
+
}
|
|
27
|
+
else if (async) {
|
|
28
|
+
env.stack.push({ async: true });
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
};
|
|
32
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
33
|
+
return function (env) {
|
|
34
|
+
function fail(e) {
|
|
35
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
36
|
+
env.hasError = true;
|
|
37
|
+
}
|
|
38
|
+
var r, s = 0;
|
|
39
|
+
function next() {
|
|
40
|
+
while (r = env.stack.pop()) {
|
|
41
|
+
try {
|
|
42
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
43
|
+
if (r.dispose) {
|
|
44
|
+
var result = r.dispose.call(r.value);
|
|
45
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
46
|
+
}
|
|
47
|
+
else s |= 1;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
fail(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
54
|
+
if (env.hasError) throw env.error;
|
|
55
|
+
}
|
|
56
|
+
return next();
|
|
57
|
+
};
|
|
58
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
59
|
+
var e = new Error(message);
|
|
60
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
61
|
+
});
|
|
10
62
|
import { ProgramError } from '../types/error.js';
|
|
11
63
|
import * as api from '../utils/polkadot.js';
|
|
12
64
|
import { hexToUtf8 } from './hex.js';
|
|
@@ -18,6 +70,10 @@ const isProgramValid = (program, out = { ops: 0, restrictions: -1 }) => {
|
|
|
18
70
|
});
|
|
19
71
|
return out.ops === out.restrictions;
|
|
20
72
|
};
|
|
73
|
+
let lastSubmittedNonce = -1;
|
|
74
|
+
export function resetLastSubmittedNonce() {
|
|
75
|
+
lastSubmittedNonce = -1;
|
|
76
|
+
}
|
|
21
77
|
// TODO refactor since api.ts other should be a util
|
|
22
78
|
// since createNodeApi, set's all routes we could use in process.index.ts
|
|
23
79
|
export const createProcessTransaction = (polkadot, processId, program, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -32,9 +88,12 @@ export const createProcessTransaction = (polkadot, processId, program, options)
|
|
|
32
88
|
reject = rej;
|
|
33
89
|
});
|
|
34
90
|
try {
|
|
91
|
+
const nextTxPoolNonce = (yield polkadot.api.rpc.system.accountNextIndex(sudo.publicKey)).toNumber();
|
|
92
|
+
const nonce = Math.max(nextTxPoolNonce, lastSubmittedNonce + 1);
|
|
93
|
+
lastSubmittedNonce = nonce;
|
|
35
94
|
const unsub = yield polkadot.api.tx.sudo
|
|
36
95
|
.sudo(polkadot.api.tx.processValidation.createProcess(processId, program))
|
|
37
|
-
.signAndSend(sudo, { nonce
|
|
96
|
+
.signAndSend(sudo, { nonce }, (result) => {
|
|
38
97
|
if (result.status.isFinalized) {
|
|
39
98
|
const { event } = result.events.find(({ event: { method } }) => method === 'ProcessCreated');
|
|
40
99
|
const data = event.data;
|
|
@@ -64,9 +123,12 @@ export const disableProcessTransaction = (polkadot, processId, version, options)
|
|
|
64
123
|
const supportsManualSeal = !!polkadot.api.rpc.engine.createBlock;
|
|
65
124
|
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
125
|
try {
|
|
126
|
+
const nextTxPoolNonce = (yield polkadot.api.rpc.system.accountNextIndex(sudo.publicKey)).toNumber();
|
|
127
|
+
const nonce = Math.max(nextTxPoolNonce, lastSubmittedNonce + 1);
|
|
128
|
+
lastSubmittedNonce = nonce;
|
|
67
129
|
const unsub = yield polkadot.api.tx.sudo
|
|
68
130
|
.sudo(polkadot.api.tx.processValidation.disableProcess(processId, version))
|
|
69
|
-
.signAndSend(sudo, (result) => {
|
|
131
|
+
.signAndSend(sudo, { nonce }, (result) => {
|
|
70
132
|
if (result.status.isFinalized) {
|
|
71
133
|
const { event } = result.events.find(({ event: { method } }) => method === 'ProcessDisabled');
|
|
72
134
|
const data = event.data;
|
|
@@ -89,19 +151,31 @@ export const disableProcessTransaction = (polkadot, processId, version, options)
|
|
|
89
151
|
}));
|
|
90
152
|
});
|
|
91
153
|
export const getAll = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
return {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
154
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
155
|
+
try {
|
|
156
|
+
const polkadot = __addDisposableResource(env_1, yield api.createNodeApi(options), true);
|
|
157
|
+
const processesRaw = yield polkadot.api.query.processValidation.processModel.entries();
|
|
158
|
+
return processesRaw.map(([idRaw, data]) => {
|
|
159
|
+
const id = idRaw.toHuman();
|
|
160
|
+
return {
|
|
161
|
+
name: id[0],
|
|
162
|
+
version: parseInt(id[1]),
|
|
163
|
+
status: data.status.toString(),
|
|
164
|
+
program: data.program.toJSON(),
|
|
165
|
+
createdAtHash: data.createdAtHash.toHuman(),
|
|
166
|
+
initialU8aLength: data.initialU8aLength,
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (e_1) {
|
|
171
|
+
env_1.error = e_1;
|
|
172
|
+
env_1.hasError = true;
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
const result_1 = __disposeResources(env_1);
|
|
176
|
+
if (result_1)
|
|
177
|
+
yield result_1;
|
|
178
|
+
}
|
|
105
179
|
});
|
|
106
180
|
export const getVersion = (polkadot, processId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
107
181
|
const id = yield polkadot.api.query.processValidation.versionModel(processId);
|
|
@@ -5,7 +5,7 @@ export declare const sanitizeInput: (data: string) => Process.Result<{
|
|
|
5
5
|
}[], CliInputParseError>;
|
|
6
6
|
export declare const loadProcesses: ({ data, options, dryRun, verbose, }: {
|
|
7
7
|
data: string;
|
|
8
|
-
options
|
|
8
|
+
options: Polkadot.Options;
|
|
9
9
|
dryRun?: boolean;
|
|
10
10
|
verbose?: boolean;
|
|
11
11
|
}) => Promise<Process.Response>;
|
|
@@ -16,7 +16,7 @@ export declare const listTransforming: (res: Process.RawPayload[], options: Proc
|
|
|
16
16
|
status: "Enabled" | "Disabled" | "Enabled (dry-run)" | "Disabled (dry-run)";
|
|
17
17
|
}[];
|
|
18
18
|
export declare const handleVerbose: (res: Process.Payload, verbose: boolean) => Process.Payload;
|
|
19
|
-
export declare const createProcess: (processRaw: Process.CliProcessInput, dryRun
|
|
19
|
+
export declare const createProcess: (processRaw: Process.CliProcessInput, dryRun: boolean | undefined, polkadot: Polkadot.Polkadot, options?: Polkadot.Options, verbose?: boolean) => Promise<{
|
|
20
20
|
waitForFinalised: Promise<Process.ProcessResponse>;
|
|
21
21
|
}>;
|
|
22
22
|
export declare const disableProcess: (name: string, processVersion: number, dryRun?: boolean, options?: Polkadot.Options) => Promise<Process.ProcessResponse>;
|
|
@@ -7,6 +7,58 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
11
|
+
if (value !== null && value !== void 0) {
|
|
12
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
13
|
+
var dispose, inner;
|
|
14
|
+
if (async) {
|
|
15
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.asyncDispose];
|
|
17
|
+
}
|
|
18
|
+
if (dispose === void 0) {
|
|
19
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
20
|
+
dispose = value[Symbol.dispose];
|
|
21
|
+
if (async) inner = dispose;
|
|
22
|
+
}
|
|
23
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
24
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
25
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
26
|
+
}
|
|
27
|
+
else if (async) {
|
|
28
|
+
env.stack.push({ async: true });
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
};
|
|
32
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
33
|
+
return function (env) {
|
|
34
|
+
function fail(e) {
|
|
35
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
36
|
+
env.hasError = true;
|
|
37
|
+
}
|
|
38
|
+
var r, s = 0;
|
|
39
|
+
function next() {
|
|
40
|
+
while (r = env.stack.pop()) {
|
|
41
|
+
try {
|
|
42
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
43
|
+
if (r.dispose) {
|
|
44
|
+
var result = r.dispose.call(r.value);
|
|
45
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
46
|
+
}
|
|
47
|
+
else s |= 1;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
fail(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
54
|
+
if (env.hasError) throw env.error;
|
|
55
|
+
}
|
|
56
|
+
return next();
|
|
57
|
+
};
|
|
58
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
59
|
+
var e = new Error(message);
|
|
60
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
61
|
+
});
|
|
10
62
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
63
|
var t = {};
|
|
12
64
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -67,32 +119,45 @@ export const sanitizeInput = (data) => {
|
|
|
67
119
|
}
|
|
68
120
|
};
|
|
69
121
|
export const loadProcesses = (_a) => __awaiter(void 0, [_a], void 0, function* ({ data, options, dryRun, verbose, }) {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
let successCount = 0;
|
|
83
|
-
for (const [key, processTxProm] of processTxs) {
|
|
84
|
-
let response = yield processTxProm;
|
|
85
|
-
result[key] = response;
|
|
86
|
-
if (response.type === 'ok') {
|
|
87
|
-
successCount = successCount + 1;
|
|
122
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
123
|
+
try {
|
|
124
|
+
const parsedRes = sanitizeInput(data);
|
|
125
|
+
if (parsedRes.type === 'error') {
|
|
126
|
+
return parsedRes;
|
|
127
|
+
}
|
|
128
|
+
const processes = parsedRes.result;
|
|
129
|
+
const processTxs = new Map();
|
|
130
|
+
const polkadot = __addDisposableResource(env_1, yield createNodeApi(options), true);
|
|
131
|
+
for (const process of processes) {
|
|
132
|
+
const { waitForFinalised } = yield createProcess(process, dryRun, polkadot, options, verbose);
|
|
133
|
+
processTxs.set(process.name, waitForFinalised);
|
|
88
134
|
}
|
|
135
|
+
yield Promise.all(processTxs.values());
|
|
136
|
+
const result = {};
|
|
137
|
+
let successCount = 0;
|
|
138
|
+
for (const [key, processTxProm] of processTxs) {
|
|
139
|
+
let response = yield processTxProm;
|
|
140
|
+
result[key] = response;
|
|
141
|
+
if (response.type === 'ok') {
|
|
142
|
+
successCount = successCount + 1;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// calculate the result and successCount
|
|
146
|
+
return {
|
|
147
|
+
type: 'ok',
|
|
148
|
+
result,
|
|
149
|
+
message: `Successfully loaded ${successCount}/${processes.length} processes`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
catch (e_1) {
|
|
153
|
+
env_1.error = e_1;
|
|
154
|
+
env_1.hasError = true;
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
const result_1 = __disposeResources(env_1);
|
|
158
|
+
if (result_1)
|
|
159
|
+
yield result_1;
|
|
89
160
|
}
|
|
90
|
-
// calculate the result and successCount
|
|
91
|
-
return {
|
|
92
|
-
type: 'ok',
|
|
93
|
-
result,
|
|
94
|
-
message: `Successfully loaded ${successCount}/${processes.length} processes`,
|
|
95
|
-
};
|
|
96
161
|
});
|
|
97
162
|
export const listTransforming = (res, options) => {
|
|
98
163
|
let processes;
|
|
@@ -124,7 +189,7 @@ export const handleVerbose = (res, verbose) => {
|
|
|
124
189
|
const { program } = res, rest = __rest(res, ["program"]);
|
|
125
190
|
return rest;
|
|
126
191
|
};
|
|
127
|
-
export const createProcess = (processRaw_1, ...args_1) => __awaiter(void 0, [processRaw_1, ...args_1], void 0, function* (processRaw, dryRun = false, options = defaultOptions, verbose = false) {
|
|
192
|
+
export const createProcess = (processRaw_1, ...args_1) => __awaiter(void 0, [processRaw_1, ...args_1], void 0, function* (processRaw, dryRun = false, polkadot, options = defaultOptions, verbose = false) {
|
|
128
193
|
const handleErr = (err) => {
|
|
129
194
|
// err is basically from errors.ts or any exception
|
|
130
195
|
// process errors will contain specific messages and/or process
|
|
@@ -154,7 +219,6 @@ export const createProcess = (processRaw_1, ...args_1) => __awaiter(void 0, [pro
|
|
|
154
219
|
try {
|
|
155
220
|
const { name, version, program } = processValidation.parse(processRaw);
|
|
156
221
|
const processId = utf8ToHex(name);
|
|
157
|
-
const polkadot = yield createNodeApi(options);
|
|
158
222
|
const currentVersion = yield getVersion(polkadot, processId);
|
|
159
223
|
const expectedVersion = currentVersion + 1;
|
|
160
224
|
if (version > expectedVersion || version < currentVersion)
|
|
@@ -210,26 +274,38 @@ export const createProcess = (processRaw_1, ...args_1) => __awaiter(void 0, [pro
|
|
|
210
274
|
}
|
|
211
275
|
});
|
|
212
276
|
export const disableProcess = (name_1, processVersion_1, ...args_1) => __awaiter(void 0, [name_1, processVersion_1, ...args_1], void 0, function* (name, processVersion, dryRun = false, options = defaultOptions) {
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
277
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
278
|
+
try {
|
|
279
|
+
const processId = utf8ToHex(name);
|
|
280
|
+
const polkadot = __addDisposableResource(env_2, yield createNodeApi(options), true);
|
|
281
|
+
const currentProcess = yield getProcess(polkadot, processId, processVersion);
|
|
282
|
+
if (currentProcess.status === 'Disabled') {
|
|
283
|
+
throw new DisableError(`${name} with version ${processVersion} doesn't exist or is already disabled`);
|
|
284
|
+
}
|
|
285
|
+
if (dryRun) {
|
|
286
|
+
return {
|
|
287
|
+
type: 'ok',
|
|
288
|
+
message: `This will DISABLE the following process ${name}`,
|
|
289
|
+
result: {
|
|
290
|
+
name,
|
|
291
|
+
version: processVersion,
|
|
292
|
+
status: 'Disabled (dry-run)',
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
220
296
|
return {
|
|
221
297
|
type: 'ok',
|
|
222
|
-
message:
|
|
223
|
-
result:
|
|
224
|
-
name,
|
|
225
|
-
version: processVersion,
|
|
226
|
-
status: 'Disabled (dry-run)',
|
|
227
|
-
},
|
|
298
|
+
message: 'Process has been disabled',
|
|
299
|
+
result: yield disableProcessTransaction(polkadot, processId, processVersion, options),
|
|
228
300
|
};
|
|
229
301
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
302
|
+
catch (e_2) {
|
|
303
|
+
env_2.error = e_2;
|
|
304
|
+
env_2.hasError = true;
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
const result_2 = __disposeResources(env_2);
|
|
308
|
+
if (result_2)
|
|
309
|
+
yield result_2;
|
|
310
|
+
}
|
|
235
311
|
});
|
|
@@ -2479,6 +2479,7 @@ export declare const processValidation: z.ZodObject<{
|
|
|
2479
2479
|
};
|
|
2480
2480
|
}>]>, "many">;
|
|
2481
2481
|
}, "strip", z.ZodTypeAny, {
|
|
2482
|
+
name: string;
|
|
2482
2483
|
version: number;
|
|
2483
2484
|
program: ({
|
|
2484
2485
|
Op: "Identity" | "TransferL" | "TransferR" | "NotL" | "NotR" | "And" | "Nand" | "Or" | "Nor" | "Xor" | "Xnor" | "ImplicationL" | "ImplicationR" | "InhibitionL" | "InhibitionR";
|
|
@@ -2583,8 +2584,8 @@ export declare const processValidation: z.ZodObject<{
|
|
|
2583
2584
|
};
|
|
2584
2585
|
};
|
|
2585
2586
|
})[];
|
|
2586
|
-
name: string;
|
|
2587
2587
|
}, {
|
|
2588
|
+
name: string;
|
|
2588
2589
|
version: number;
|
|
2589
2590
|
program: ({
|
|
2590
2591
|
Op: "Identity" | "TransferL" | "TransferR" | "NotL" | "NotR" | "And" | "Nand" | "Or" | "Nor" | "Xor" | "Xnor" | "ImplicationL" | "ImplicationR" | "InhibitionL" | "InhibitionR";
|
|
@@ -2689,7 +2690,6 @@ export declare const processValidation: z.ZodObject<{
|
|
|
2689
2690
|
};
|
|
2690
2691
|
};
|
|
2691
2692
|
})[];
|
|
2692
|
-
name: string;
|
|
2693
2693
|
}>;
|
|
2694
2694
|
export declare const simpleProcesssValidation: z.ZodArray<z.ZodObject<{
|
|
2695
2695
|
name: z.ZodString;
|
|
@@ -3373,6 +3373,7 @@ export declare const processesValidation: z.ZodArray<z.ZodObject<{
|
|
|
3373
3373
|
};
|
|
3374
3374
|
}>]>, "many">;
|
|
3375
3375
|
}, "strip", z.ZodTypeAny, {
|
|
3376
|
+
name: string;
|
|
3376
3377
|
version: number;
|
|
3377
3378
|
program: ({
|
|
3378
3379
|
Op: "Identity" | "TransferL" | "TransferR" | "NotL" | "NotR" | "And" | "Nand" | "Or" | "Nor" | "Xor" | "Xnor" | "ImplicationL" | "ImplicationR" | "InhibitionL" | "InhibitionR";
|
|
@@ -3477,8 +3478,8 @@ export declare const processesValidation: z.ZodArray<z.ZodObject<{
|
|
|
3477
3478
|
};
|
|
3478
3479
|
};
|
|
3479
3480
|
})[];
|
|
3480
|
-
name: string;
|
|
3481
3481
|
}, {
|
|
3482
|
+
name: string;
|
|
3482
3483
|
version: number;
|
|
3483
3484
|
program: ({
|
|
3484
3485
|
Op: "Identity" | "TransferL" | "TransferR" | "NotL" | "NotR" | "And" | "Nand" | "Or" | "Nor" | "Xor" | "Xnor" | "ImplicationL" | "ImplicationR" | "InhibitionL" | "InhibitionR";
|
|
@@ -3583,7 +3584,6 @@ export declare const processesValidation: z.ZodArray<z.ZodObject<{
|
|
|
3583
3584
|
};
|
|
3584
3585
|
};
|
|
3585
3586
|
})[];
|
|
3586
|
-
name: string;
|
|
3587
3587
|
}>, "many">;
|
|
3588
3588
|
export type ValidationRestriction = z.infer<typeof restrictionValidation>;
|
|
3589
3589
|
export type ValidationProgramStep = z.infer<typeof stepValidation>;
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { ApiPromise, Keyring } from '@polkadot/api';
|
|
2
|
+
export declare const createNodeApi: (options: Polkadot.Options) => Promise<{
|
|
3
|
+
api: ApiPromise;
|
|
4
|
+
keyring: Keyring;
|
|
5
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
6
|
+
}>;
|
|
@@ -21,5 +21,8 @@ export const createNodeApi = (options) => __awaiter(void 0, void 0, void 0, func
|
|
|
21
21
|
return {
|
|
22
22
|
api,
|
|
23
23
|
keyring: new Keyring({ type: 'sr25519' }),
|
|
24
|
+
[Symbol.asyncDispose]: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
yield api.disconnect();
|
|
26
|
+
}),
|
|
24
27
|
};
|
|
25
28
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { GenericContainer, Wait } from 'testcontainers';
|
|
11
|
+
import { resetLastSubmittedNonce } from '../../src/lib/process/api.js';
|
|
12
|
+
export const withSubstrateNode = (config, context) => {
|
|
13
|
+
before(function () {
|
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
this.timeout(60000);
|
|
16
|
+
resetLastSubmittedNonce();
|
|
17
|
+
context.nodeContainer = yield new GenericContainer('digicatapult/sqnc-node')
|
|
18
|
+
.withName('sqnc-node')
|
|
19
|
+
.withExposedPorts(30333, 9944, 9933)
|
|
20
|
+
.withCommand([
|
|
21
|
+
'--base-path',
|
|
22
|
+
'/data/',
|
|
23
|
+
'--dev',
|
|
24
|
+
'--unsafe-rpc-external',
|
|
25
|
+
'--rpc-cors',
|
|
26
|
+
'all',
|
|
27
|
+
...(config.manualSeal ? ['--manual-seal'] : []),
|
|
28
|
+
])
|
|
29
|
+
.withWaitStrategy(Wait.forHealthCheck())
|
|
30
|
+
.withReuse()
|
|
31
|
+
.start();
|
|
32
|
+
context.polkadotOptions.API_PORT = context.nodeContainer.getMappedPort(9944);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
after(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
var _a;
|
|
37
|
+
yield ((_a = context.nodeContainer) === null || _a === void 0 ? void 0 : _a.stop({ remove: true }));
|
|
38
|
+
resetLastSubmittedNonce();
|
|
39
|
+
}));
|
|
40
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const getVersionHelper: (name: string) => Promise<number>;
|
|
2
|
-
export declare const Helper: (processId: Process.Hex, version: number) => Promise<Process.Payload>;
|
|
1
|
+
export declare const getVersionHelper: (name: string, options: Polkadot.Options) => Promise<number>;
|
|
2
|
+
export declare const Helper: (processId: Process.Hex, version: number, options: Polkadot.Options) => Promise<Process.Payload>;
|
|
@@ -7,19 +7,94 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
11
|
+
if (value !== null && value !== void 0) {
|
|
12
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
13
|
+
var dispose, inner;
|
|
14
|
+
if (async) {
|
|
15
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.asyncDispose];
|
|
17
|
+
}
|
|
18
|
+
if (dispose === void 0) {
|
|
19
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
20
|
+
dispose = value[Symbol.dispose];
|
|
21
|
+
if (async) inner = dispose;
|
|
22
|
+
}
|
|
23
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
24
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
25
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
26
|
+
}
|
|
27
|
+
else if (async) {
|
|
28
|
+
env.stack.push({ async: true });
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
};
|
|
32
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
33
|
+
return function (env) {
|
|
34
|
+
function fail(e) {
|
|
35
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
36
|
+
env.hasError = true;
|
|
37
|
+
}
|
|
38
|
+
var r, s = 0;
|
|
39
|
+
function next() {
|
|
40
|
+
while (r = env.stack.pop()) {
|
|
41
|
+
try {
|
|
42
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
43
|
+
if (r.dispose) {
|
|
44
|
+
var result = r.dispose.call(r.value);
|
|
45
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
46
|
+
}
|
|
47
|
+
else s |= 1;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
fail(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
54
|
+
if (env.hasError) throw env.error;
|
|
55
|
+
}
|
|
56
|
+
return next();
|
|
57
|
+
};
|
|
58
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
59
|
+
var e = new Error(message);
|
|
60
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
61
|
+
});
|
|
10
62
|
import { createNodeApi } from '../../src/lib/utils/polkadot.js';
|
|
11
63
|
import { getVersion, getProcess } from '../../src/lib/process/api.js';
|
|
12
|
-
import { defaultOptions } from '../../src/lib/process/index.js';
|
|
13
64
|
import { utf8ToHex } from '../../src/lib/process/hex.js';
|
|
14
|
-
export const getVersionHelper = (name) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
65
|
+
export const getVersionHelper = (name, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
67
|
+
try {
|
|
68
|
+
const polkadot = __addDisposableResource(env_1, yield createNodeApi(options), true);
|
|
69
|
+
const version = yield getVersion(polkadot, utf8ToHex(name));
|
|
70
|
+
yield polkadot.api.disconnect();
|
|
71
|
+
return version;
|
|
72
|
+
}
|
|
73
|
+
catch (e_1) {
|
|
74
|
+
env_1.error = e_1;
|
|
75
|
+
env_1.hasError = true;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
const result_1 = __disposeResources(env_1);
|
|
79
|
+
if (result_1)
|
|
80
|
+
yield result_1;
|
|
81
|
+
}
|
|
19
82
|
});
|
|
20
|
-
export const Helper = (processId, version) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
83
|
+
export const Helper = (processId, version, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
85
|
+
try {
|
|
86
|
+
const polkadot = __addDisposableResource(env_2, yield createNodeApi(options), true);
|
|
87
|
+
const process = yield getProcess(polkadot, processId, version);
|
|
88
|
+
yield polkadot.api.disconnect();
|
|
89
|
+
return process;
|
|
90
|
+
}
|
|
91
|
+
catch (e_2) {
|
|
92
|
+
env_2.error = e_2;
|
|
93
|
+
env_2.hasError = true;
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
const result_2 = __disposeResources(env_2);
|
|
97
|
+
if (result_2)
|
|
98
|
+
yield result_2;
|
|
99
|
+
}
|
|
25
100
|
});
|
|
@@ -7,6 +7,58 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
11
|
+
if (value !== null && value !== void 0) {
|
|
12
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
13
|
+
var dispose, inner;
|
|
14
|
+
if (async) {
|
|
15
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.asyncDispose];
|
|
17
|
+
}
|
|
18
|
+
if (dispose === void 0) {
|
|
19
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
20
|
+
dispose = value[Symbol.dispose];
|
|
21
|
+
if (async) inner = dispose;
|
|
22
|
+
}
|
|
23
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
24
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
25
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
26
|
+
}
|
|
27
|
+
else if (async) {
|
|
28
|
+
env.stack.push({ async: true });
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
};
|
|
32
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
33
|
+
return function (env) {
|
|
34
|
+
function fail(e) {
|
|
35
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
36
|
+
env.hasError = true;
|
|
37
|
+
}
|
|
38
|
+
var r, s = 0;
|
|
39
|
+
function next() {
|
|
40
|
+
while (r = env.stack.pop()) {
|
|
41
|
+
try {
|
|
42
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
43
|
+
if (r.dispose) {
|
|
44
|
+
var result = r.dispose.call(r.value);
|
|
45
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
46
|
+
}
|
|
47
|
+
else s |= 1;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
fail(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
54
|
+
if (env.hasError) throw env.error;
|
|
55
|
+
}
|
|
56
|
+
return next();
|
|
57
|
+
};
|
|
58
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
59
|
+
var e = new Error(message);
|
|
60
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
61
|
+
});
|
|
10
62
|
import { expect } from 'chai';
|
|
11
63
|
import { createProcess, disableProcess, loadProcesses } from '../../src/lib/process/index.js';
|
|
12
64
|
import { validAllRestrictions, invalidPOSIX, multiple, simple2, simple, invalidRestrictionKey, invalidRestrictionValue, } from '../fixtures/programs.js';
|
|
@@ -17,13 +69,31 @@ import { DisableError, ProgramError, VersionError } from '../../src/lib/types/er
|
|
|
17
69
|
import { getAll } from '../../src/lib/process/api.js';
|
|
18
70
|
/* fixtures */
|
|
19
71
|
import processesExample from '../fixtures/processes.js';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
72
|
+
import { withSubstrateNode } from '../helpers/containers.js';
|
|
73
|
+
import { createNodeApi } from '../../src/lib/utils/polkadot.js';
|
|
74
|
+
const createProcessAndWait = (processRaw, options, dryRun, verbose) => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
76
|
+
try {
|
|
77
|
+
const polkadot = __addDisposableResource(env_1, yield createNodeApi(options), true);
|
|
78
|
+
const { waitForFinalised } = yield createProcess(processRaw, dryRun, polkadot, options, verbose);
|
|
79
|
+
const result = yield waitForFinalised;
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
catch (e_1) {
|
|
83
|
+
env_1.error = e_1;
|
|
84
|
+
env_1.hasError = true;
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
const result_1 = __disposeResources(env_1);
|
|
88
|
+
if (result_1)
|
|
89
|
+
yield result_1;
|
|
90
|
+
}
|
|
25
91
|
});
|
|
26
92
|
describe('Process creation and deletion, listing', () => {
|
|
93
|
+
const context = {
|
|
94
|
+
polkadotOptions: { API_HOST: 'localhost', API_PORT: 0, USER_URI: '//Alice', MANUAL_SEAL: true },
|
|
95
|
+
};
|
|
96
|
+
withSubstrateNode({ manualSeal: true }, context);
|
|
27
97
|
describe('Happy path', () => {
|
|
28
98
|
describe('Multiple processes', () => {
|
|
29
99
|
it('skips already created processes and creates new ones', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -31,11 +101,11 @@ describe('Process creation and deletion, listing', () => {
|
|
|
31
101
|
name: 'existing-process-test',
|
|
32
102
|
version: 1,
|
|
33
103
|
program: simple2,
|
|
34
|
-
},
|
|
104
|
+
}, context.polkadotOptions, false);
|
|
35
105
|
const process2Name = 'process-to-be-created';
|
|
36
|
-
const process2BumpedV = (yield getVersionHelper(process2Name)) + 1;
|
|
106
|
+
const process2BumpedV = (yield getVersionHelper(process2Name, context.polkadotOptions)) + 1;
|
|
37
107
|
const newProcesses = yield loadProcesses({
|
|
38
|
-
options: polkadotOptions,
|
|
108
|
+
options: context.polkadotOptions,
|
|
39
109
|
data: multiple('existing-process-test', 1, process2Name, process2BumpedV),
|
|
40
110
|
});
|
|
41
111
|
if (newProcesses.type !== 'ok') {
|
|
@@ -62,11 +132,11 @@ describe('Process creation and deletion, listing', () => {
|
|
|
62
132
|
}));
|
|
63
133
|
it('creates multiple processes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
134
|
const process1Name = 'process-1';
|
|
65
|
-
const process1BumpedV = (yield getVersionHelper(process1Name)) + 1;
|
|
135
|
+
const process1BumpedV = (yield getVersionHelper(process1Name, context.polkadotOptions)) + 1;
|
|
66
136
|
const process2Name = 'process-2';
|
|
67
|
-
const process2BumpedV = (yield getVersionHelper(process2Name)) + 1;
|
|
137
|
+
const process2BumpedV = (yield getVersionHelper(process2Name, context.polkadotOptions)) + 1;
|
|
68
138
|
const newProcesses = yield loadProcesses({
|
|
69
|
-
options: polkadotOptions,
|
|
139
|
+
options: context.polkadotOptions,
|
|
70
140
|
data: multiple(process1Name, process1BumpedV, process2Name, process2BumpedV),
|
|
71
141
|
});
|
|
72
142
|
if (newProcesses.type !== 'ok') {
|
|
@@ -92,8 +162,8 @@ describe('Process creation and deletion, listing', () => {
|
|
|
92
162
|
});
|
|
93
163
|
}));
|
|
94
164
|
it('loads and skips multiple processes using number values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
-
yield loadProcesses({ options: polkadotOptions, data: JSON.stringify(processesExample) });
|
|
96
|
-
const res = yield loadProcesses({ options: polkadotOptions, data: JSON.stringify(processesExample) });
|
|
165
|
+
yield loadProcesses({ options: context.polkadotOptions, data: JSON.stringify(processesExample) });
|
|
166
|
+
const res = yield loadProcesses({ options: context.polkadotOptions, data: JSON.stringify(processesExample) });
|
|
97
167
|
if (res.type !== 'ok') {
|
|
98
168
|
expect.fail('Expected process create to succeed');
|
|
99
169
|
}
|
|
@@ -116,9 +186,9 @@ describe('Process creation and deletion, listing', () => {
|
|
|
116
186
|
});
|
|
117
187
|
it('creates then disables a process', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
118
188
|
const processName = '0';
|
|
119
|
-
const currentVersion = yield getVersionHelper(processName);
|
|
189
|
+
const currentVersion = yield getVersionHelper(processName, context.polkadotOptions);
|
|
120
190
|
const bumpedVersion = currentVersion + 1;
|
|
121
|
-
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: simple },
|
|
191
|
+
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: simple }, context.polkadotOptions, false);
|
|
122
192
|
if (newProcess.type !== 'ok') {
|
|
123
193
|
expect.fail('Expected process creation to succeed');
|
|
124
194
|
}
|
|
@@ -127,7 +197,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
127
197
|
version: bumpedVersion,
|
|
128
198
|
status: 'Enabled',
|
|
129
199
|
});
|
|
130
|
-
const disabledProcess = yield disableProcess(processName, bumpedVersion, false, polkadotOptions);
|
|
200
|
+
const disabledProcess = yield disableProcess(processName, bumpedVersion, false, context.polkadotOptions);
|
|
131
201
|
if (disabledProcess.type !== 'ok') {
|
|
132
202
|
expect.fail('Expected process disable to succeed');
|
|
133
203
|
}
|
|
@@ -140,9 +210,9 @@ describe('Process creation and deletion, listing', () => {
|
|
|
140
210
|
}));
|
|
141
211
|
it('does not create process if dry run', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
142
212
|
const processName = '0';
|
|
143
|
-
const currentVersion = yield getVersionHelper(processName);
|
|
213
|
+
const currentVersion = yield getVersionHelper(processName, context.polkadotOptions);
|
|
144
214
|
const bumpedVersion = currentVersion + 1;
|
|
145
|
-
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: validAllRestrictions },
|
|
215
|
+
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: validAllRestrictions }, context.polkadotOptions, true);
|
|
146
216
|
if (newProcess.type !== 'ok') {
|
|
147
217
|
expect.fail('Expected process create to succeed');
|
|
148
218
|
}
|
|
@@ -155,11 +225,11 @@ describe('Process creation and deletion, listing', () => {
|
|
|
155
225
|
}));
|
|
156
226
|
it('does not disable process if dry run', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
227
|
const processName = '0';
|
|
158
|
-
const currentVersion = yield getVersionHelper(processName);
|
|
228
|
+
const currentVersion = yield getVersionHelper(processName, context.polkadotOptions);
|
|
159
229
|
const bumpedVersion = currentVersion + 1;
|
|
160
|
-
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: validAllRestrictions },
|
|
230
|
+
const newProcess = yield createProcessAndWait({ name: processName, version: bumpedVersion, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
161
231
|
expect(newProcess.type).to.equal('ok');
|
|
162
|
-
const disabledProcess = yield disableProcess(processName, bumpedVersion, true, polkadotOptions);
|
|
232
|
+
const disabledProcess = yield disableProcess(processName, bumpedVersion, true, context.polkadotOptions);
|
|
163
233
|
if (disabledProcess.type !== 'ok') {
|
|
164
234
|
expect.fail('Expected disable process to succeed');
|
|
165
235
|
}
|
|
@@ -173,7 +243,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
173
243
|
}));
|
|
174
244
|
// it('returns a list of raw processes when with --verbose flag', () => {
|
|
175
245
|
it('returns a list of processes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
-
const res = yield getAll(polkadotOptions);
|
|
246
|
+
const res = yield getAll(context.polkadotOptions);
|
|
177
247
|
expect(res).to.be.an('array');
|
|
178
248
|
expect(res[0])
|
|
179
249
|
.to.be.an('object')
|
|
@@ -184,18 +254,18 @@ describe('Process creation and deletion, listing', () => {
|
|
|
184
254
|
const validProcessName = '0';
|
|
185
255
|
let validVersionNumber;
|
|
186
256
|
before(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
-
const currentVersion = yield getVersionHelper(validProcessName);
|
|
257
|
+
const currentVersion = yield getVersionHelper(validProcessName, context.polkadotOptions);
|
|
188
258
|
validVersionNumber = currentVersion + 1;
|
|
189
259
|
}));
|
|
190
260
|
describe('If process already exists', () => {
|
|
191
261
|
describe('Multiple uploads', () => {
|
|
192
262
|
// TODO could prestage in before if more scenarios
|
|
193
263
|
it('skips and notifies if process programs are different', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
194
|
-
yield createProcessAndWait({ name: 'existing-length', version: 1, program: validAllRestrictions },
|
|
264
|
+
yield createProcessAndWait({ name: 'existing-length', version: 1, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
195
265
|
const process2Name = 'should-create-1';
|
|
196
|
-
const process2BumpedV = (yield getVersionHelper(process2Name)) + 1;
|
|
266
|
+
const process2BumpedV = (yield getVersionHelper(process2Name, context.polkadotOptions)) + 1;
|
|
197
267
|
const res = yield loadProcesses({
|
|
198
|
-
options: polkadotOptions,
|
|
268
|
+
options: context.polkadotOptions,
|
|
199
269
|
data: multiple('existing-length', 1, process2Name, process2BumpedV),
|
|
200
270
|
});
|
|
201
271
|
if (res.type !== 'ok') {
|
|
@@ -213,11 +283,11 @@ describe('Process creation and deletion, listing', () => {
|
|
|
213
283
|
expect(process2Res.message).to.equal('Transaction for new process should-create-1 has been successfully submitted');
|
|
214
284
|
}));
|
|
215
285
|
it('also fails if number of steps matches but POSTFIX does not', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
216
|
-
yield createProcessAndWait({ name: 'existing-steps', version: 1, program: simple },
|
|
286
|
+
yield createProcessAndWait({ name: 'existing-steps', version: 1, program: simple }, context.polkadotOptions, false);
|
|
217
287
|
const process2Name = 'should-create-2';
|
|
218
|
-
const process2BumpedV = (yield getVersionHelper(process2Name)) + 1;
|
|
288
|
+
const process2BumpedV = (yield getVersionHelper(process2Name, context.polkadotOptions)) + 1;
|
|
219
289
|
const res = yield loadProcesses({
|
|
220
|
-
options: polkadotOptions,
|
|
290
|
+
options: context.polkadotOptions,
|
|
221
291
|
data: multiple('existing-steps', 1, process2Name, process2BumpedV),
|
|
222
292
|
});
|
|
223
293
|
// TODO: should this fail
|
|
@@ -229,8 +299,8 @@ describe('Process creation and deletion, listing', () => {
|
|
|
229
299
|
}));
|
|
230
300
|
});
|
|
231
301
|
it('does not create new one and notifies if programs are different length', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
232
|
-
yield createProcessAndWait({ name: 'existing-single', version: 1, program: validAllRestrictions },
|
|
233
|
-
const res = yield createProcessAndWait({ name: 'existing-single', version: 1, program: simple },
|
|
302
|
+
yield createProcessAndWait({ name: 'existing-single', version: 1, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
303
|
+
const res = yield createProcessAndWait({ name: 'existing-single', version: 1, program: simple }, context.polkadotOptions, false);
|
|
234
304
|
if (res.type !== 'error') {
|
|
235
305
|
expect.fail('Expected program create with different lengths to fail');
|
|
236
306
|
}
|
|
@@ -238,8 +308,8 @@ describe('Process creation and deletion, listing', () => {
|
|
|
238
308
|
expect(res.error).to.instanceOf(ProgramError);
|
|
239
309
|
}));
|
|
240
310
|
it('does not create new one and notifies if programs same are length but do not match', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
241
|
-
yield createProcessAndWait({ name: 'existing-steps-single', version: 1, program: simple2 },
|
|
242
|
-
const res = yield createProcessAndWait({ name: 'existing-steps-single', version: 1, program: [{ Restriction: 'None' }] },
|
|
311
|
+
yield createProcessAndWait({ name: 'existing-steps-single', version: 1, program: simple2 }, context.polkadotOptions, false);
|
|
312
|
+
const res = yield createProcessAndWait({ name: 'existing-steps-single', version: 1, program: [{ Restriction: 'None' }] }, context.polkadotOptions, false);
|
|
243
313
|
if (res.type !== 'error') {
|
|
244
314
|
expect.fail('Expected program create with different lengths to fail');
|
|
245
315
|
}
|
|
@@ -254,7 +324,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
254
324
|
}));
|
|
255
325
|
});
|
|
256
326
|
it('fails for invalid POSTFIX notation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
-
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: invalidPOSIX },
|
|
327
|
+
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: invalidPOSIX }, context.polkadotOptions, false);
|
|
258
328
|
if (res.type !== 'error') {
|
|
259
329
|
expect.fail('Expected process create to fail');
|
|
260
330
|
}
|
|
@@ -266,7 +336,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
266
336
|
name: validProcessName,
|
|
267
337
|
version: validVersionNumber,
|
|
268
338
|
program: invalidRestrictionKey,
|
|
269
|
-
},
|
|
339
|
+
}, context.polkadotOptions, false);
|
|
270
340
|
if (res.type !== 'error') {
|
|
271
341
|
expect.fail('Expected process create to fail');
|
|
272
342
|
}
|
|
@@ -278,14 +348,14 @@ describe('Process creation and deletion, listing', () => {
|
|
|
278
348
|
});
|
|
279
349
|
}));
|
|
280
350
|
it('fails for invalid restriction value', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
281
|
-
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: invalidRestrictionValue },
|
|
351
|
+
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: invalidRestrictionValue }, context.polkadotOptions, false);
|
|
282
352
|
if (res.type !== 'error') {
|
|
283
353
|
expect.fail('Expected process create to fail');
|
|
284
354
|
}
|
|
285
355
|
expect(res.error).to.be.instanceOf(ZodError);
|
|
286
356
|
}));
|
|
287
357
|
it('fails for invalid json', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
288
|
-
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: 'invalidJson' },
|
|
358
|
+
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: 'invalidJson' }, context.polkadotOptions, false);
|
|
289
359
|
if (res.type !== 'error') {
|
|
290
360
|
expect.fail('Expected process create to fail');
|
|
291
361
|
}
|
|
@@ -293,7 +363,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
293
363
|
}));
|
|
294
364
|
it('fails to create for too low version', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
295
365
|
// - 2 because -1 would make current = valid
|
|
296
|
-
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber - 2, program: validAllRestrictions },
|
|
366
|
+
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber - 2, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
297
367
|
if (res.type !== 'error') {
|
|
298
368
|
expect.fail('Expected process create to fail');
|
|
299
369
|
}
|
|
@@ -301,7 +371,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
301
371
|
expect(res.error).to.be.instanceOf(VersionError);
|
|
302
372
|
}));
|
|
303
373
|
it('fails to create for too high version', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
304
|
-
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber + 1, program: validAllRestrictions },
|
|
374
|
+
const res = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber + 1, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
305
375
|
if (res.type !== 'error') {
|
|
306
376
|
expect.fail('Expected process create to fail');
|
|
307
377
|
}
|
|
@@ -310,7 +380,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
310
380
|
}));
|
|
311
381
|
it('fails to create with too long process id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
312
382
|
const processName = '0'.repeat(Constants.PROCESS_ID_LENGTH + 1);
|
|
313
|
-
const res = yield createProcessAndWait({ name: processName, version: 1, program: validAllRestrictions },
|
|
383
|
+
const res = yield createProcessAndWait({ name: processName, version: 1, program: validAllRestrictions }, context.polkadotOptions, false);
|
|
314
384
|
if (res.type !== 'error') {
|
|
315
385
|
expect.fail('Expected process create to fail');
|
|
316
386
|
}
|
|
@@ -319,7 +389,7 @@ describe('Process creation and deletion, listing', () => {
|
|
|
319
389
|
it('fails to disable process that does not exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
320
390
|
let err = null;
|
|
321
391
|
try {
|
|
322
|
-
yield disableProcess('incorrectProcessName', 1, false, polkadotOptions);
|
|
392
|
+
yield disableProcess('incorrectProcessName', 1, false, context.polkadotOptions);
|
|
323
393
|
}
|
|
324
394
|
catch (error) {
|
|
325
395
|
err = error;
|
|
@@ -327,13 +397,13 @@ describe('Process creation and deletion, listing', () => {
|
|
|
327
397
|
expect(err).instanceOf(DisableError);
|
|
328
398
|
}));
|
|
329
399
|
it('fails to disable process a second time', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
330
|
-
const newProcess = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: simple },
|
|
400
|
+
const newProcess = yield createProcessAndWait({ name: validProcessName, version: validVersionNumber, program: simple }, context.polkadotOptions, false);
|
|
331
401
|
expect(newProcess.type).to.equal('ok');
|
|
332
|
-
const firstDisable = yield disableProcess(validProcessName, validVersionNumber, false, polkadotOptions);
|
|
402
|
+
const firstDisable = yield disableProcess(validProcessName, validVersionNumber, false, context.polkadotOptions);
|
|
333
403
|
expect(firstDisable.type).to.equal('ok');
|
|
334
404
|
let err = null;
|
|
335
405
|
try {
|
|
336
|
-
yield disableProcess(validProcessName, validVersionNumber, false, polkadotOptions);
|
|
406
|
+
yield disableProcess(validProcessName, validVersionNumber, false, context.polkadotOptions);
|
|
337
407
|
}
|
|
338
408
|
catch (error) {
|
|
339
409
|
err = error;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { expect } from 'chai';
|
|
11
|
+
import { loadProcesses } from '../../src/lib/process/index.js';
|
|
12
|
+
import { multiple } from '../fixtures/programs.js';
|
|
13
|
+
import { getVersionHelper } from '../helpers/substrateHelper.js';
|
|
14
|
+
import { withSubstrateNode } from '../helpers/containers.js';
|
|
15
|
+
describe('Transactions without manual seal', function () {
|
|
16
|
+
this.timeout(60000);
|
|
17
|
+
const context = {
|
|
18
|
+
polkadotOptions: { API_HOST: 'localhost', API_PORT: 0, USER_URI: '//Alice', MANUAL_SEAL: false },
|
|
19
|
+
};
|
|
20
|
+
withSubstrateNode({ manualSeal: false }, context);
|
|
21
|
+
it('creates multiple processes', () => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const process1Name = 'process-1';
|
|
23
|
+
const process1BumpedV = (yield getVersionHelper(process1Name, context.polkadotOptions)) + 1;
|
|
24
|
+
const process2Name = 'process-2';
|
|
25
|
+
const process2BumpedV = (yield getVersionHelper(process2Name, context.polkadotOptions)) + 1;
|
|
26
|
+
const newProcesses = yield loadProcesses({
|
|
27
|
+
options: context.polkadotOptions,
|
|
28
|
+
data: multiple(process1Name, process1BumpedV, process2Name, process2BumpedV),
|
|
29
|
+
});
|
|
30
|
+
if (newProcesses.type !== 'ok') {
|
|
31
|
+
expect.fail('Expected new process creation to succeed');
|
|
32
|
+
}
|
|
33
|
+
expect(newProcesses.result[process1Name].message).to.deep.equal('Transaction for new process process-1 has been successfully submitted');
|
|
34
|
+
const process1Result = newProcesses.result[process1Name];
|
|
35
|
+
if (process1Result.type !== 'ok') {
|
|
36
|
+
expect.fail('Expected process1 creation to succeed');
|
|
37
|
+
}
|
|
38
|
+
expect(process1Result.result).to.deep.contain({
|
|
39
|
+
version: process1BumpedV,
|
|
40
|
+
status: 'Enabled',
|
|
41
|
+
});
|
|
42
|
+
const process2Result = newProcesses.result[process2Name];
|
|
43
|
+
if (process2Result.type !== 'ok') {
|
|
44
|
+
expect.fail('Expected process2 creation to succeed');
|
|
45
|
+
}
|
|
46
|
+
expect(process2Result.message).to.deep.equal('Transaction for new process process-2 has been successfully submitted');
|
|
47
|
+
expect(process2Result.result).to.deep.contain({
|
|
48
|
+
version: process2BumpedV,
|
|
49
|
+
status: 'Enabled',
|
|
50
|
+
});
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/version.ts","../src/lib/process/api.ts","../src/lib/process/constants.ts","../src/lib/process/hex.ts","../src/lib/process/index.ts","../src/lib/process/_tests_/unit.test.ts","../src/lib/types/error.ts","../src/lib/types/polkadot.d.ts","../src/lib/types/process.d.ts","../src/lib/types/validation.ts","../src/lib/utils/polkadot.ts","../tests/fixtures/processes.ts","../tests/fixtures/programs.ts","../tests/helpers/substrateHelper.ts","../tests/integration/command-functions.test.ts"],"version":"5.6.3"}
|
|
1
|
+
{"root":["../src/index.ts","../src/version.ts","../src/lib/process/api.ts","../src/lib/process/constants.ts","../src/lib/process/hex.ts","../src/lib/process/index.ts","../src/lib/process/_tests_/unit.test.ts","../src/lib/types/error.ts","../src/lib/types/polkadot.d.ts","../src/lib/types/process.d.ts","../src/lib/types/validation.ts","../src/lib/utils/polkadot.ts","../tests/fixtures/processes.ts","../tests/fixtures/programs.ts","../tests/helpers/containers.ts","../tests/helpers/substrateHelper.ts","../tests/integration/command-functions.test.ts","../tests/integration/without-manual-seal.test.ts"],"version":"5.6.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digicatapult/sqnc-process-management",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.129",
|
|
4
4
|
"description": "SQNC Process Management Flow",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"mocha": "^10.8.2",
|
|
52
52
|
"nodemon": "^3.1.7",
|
|
53
53
|
"prettier": "^3.3.3",
|
|
54
|
+
"testcontainers": "^10.14.0",
|
|
54
55
|
"ts-mocha": "^10.0.0",
|
|
55
56
|
"ts-node": "^10.9.2"
|
|
56
57
|
},
|