ic-mops 0.45.4-pre.0 → 1.0.0
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/CHANGELOG.md +19 -1
- package/README.md +1 -1
- package/api/actors.ts +1 -1
- package/bundle/cli.tgz +0 -0
- package/cache.ts +15 -10
- package/cli.ts +27 -27
- package/commands/add.ts +4 -0
- package/commands/bench/bench-canister.mo +34 -8
- package/commands/bench-replica.ts +11 -6
- package/commands/bench.ts +29 -3
- package/commands/publish.ts +1 -1
- package/commands/replica.ts +239 -0
- package/commands/sources.ts +2 -3
- package/commands/test/mmf1.ts +10 -6
- package/commands/test/reporters/compact-reporter.ts +2 -1
- package/commands/test/reporters/files-reporter.ts +3 -2
- package/commands/test/reporters/reporter.ts +2 -1
- package/commands/test/reporters/silent-reporter.ts +2 -1
- package/commands/test/reporters/verbose-reporter.ts +14 -4
- package/commands/test/test.ts +214 -81
- package/commands/user.ts +71 -1
- package/declarations/bench/bench.did +6 -2
- package/declarations/bench/bench.did.d.ts +6 -2
- package/declarations/bench/bench.did.js +6 -2
- package/dist/cache.js +14 -10
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +23 -27
- package/dist/commands/add.js +3 -0
- package/dist/commands/bench/bench-canister.mo +34 -8
- package/dist/commands/bench-replica.d.ts +2 -1
- package/dist/commands/bench-replica.js +10 -6
- package/dist/commands/bench.js +27 -3
- package/dist/commands/publish.js +1 -1
- package/dist/commands/replica.d.ts +59 -0
- package/dist/commands/replica.js +195 -0
- package/dist/commands/sources.d.ts +2 -2
- package/dist/commands/sources.js +2 -3
- package/dist/commands/test/mmf1.d.ts +2 -2
- package/dist/commands/test/mmf1.js +9 -5
- package/dist/commands/test/reporters/compact-reporter.d.ts +2 -1
- package/dist/commands/test/reporters/compact-reporter.js +1 -1
- package/dist/commands/test/reporters/files-reporter.d.ts +2 -1
- package/dist/commands/test/reporters/files-reporter.js +2 -2
- package/dist/commands/test/reporters/reporter.d.ts +2 -1
- package/dist/commands/test/reporters/silent-reporter.d.ts +2 -1
- package/dist/commands/test/reporters/silent-reporter.js +1 -1
- package/dist/commands/test/reporters/verbose-reporter.d.ts +3 -1
- package/dist/commands/test/reporters/verbose-reporter.js +12 -4
- package/dist/commands/test/test.d.ts +10 -8
- package/dist/commands/test/test.js +171 -78
- package/dist/commands/user.d.ts +6 -0
- package/dist/commands/user.js +59 -1
- package/dist/declarations/bench/bench.did +6 -2
- package/dist/declarations/bench/bench.did.d.ts +6 -2
- package/dist/declarations/bench/bench.did.js +6 -2
- package/dist/mops.d.ts +1 -1
- package/dist/mops.js +5 -29
- package/dist/package.json +20 -21
- package/dist/release-cli.js +5 -2
- package/dist/resolve-packages.d.ts +2 -2
- package/dist/resolve-packages.js +29 -7
- package/dist/types.d.ts +1 -0
- package/dist/vessel.js +1 -1
- package/mops.ts +5 -32
- package/package.json +24 -24
- package/release-cli.ts +7 -2
- package/resolve-packages.ts +39 -8
- package/types.ts +3 -1
- package/vessel.ts +1 -1
- package/DEVELOPMENT.md +0 -25
- package/commands/import-identity.ts +0 -62
- package/commands/whoami.ts +0 -12
- package/dist/commands/import-identity.d.ts +0 -5
- package/dist/commands/import-identity.js +0 -51
- package/dist/commands/whoami.d.ts +0 -1
- package/dist/commands/whoami.js +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 1.0.0
|
|
4
4
|
- `mops cache clean` now cleans local cache too (`.mops` folder)
|
|
5
|
+
- Conflicting dependencies are now reported on `mops add/install/sources`
|
|
6
|
+
- New `--conflicts <action>` option in `mops sources` command ([docs](https://docs.mops.one/cli/mops-sources#--conflicts))
|
|
7
|
+
- New "Stable Memory" and "Garbage Collection" metrics are now reported in the `mops bench` command
|
|
8
|
+
- `mops test` command now supports `replica` mode for running actor tests ([docs](https://docs.mops.one/cli/mops-test#--mode))
|
|
9
|
+
- New `--replica` option in `mops test` command
|
|
10
|
+
- Updated npm dependencies
|
|
11
|
+
- Fixed bug with GitHub dependency with branch name containing `/`
|
|
12
|
+
|
|
13
|
+
**Breaking changes**:
|
|
14
|
+
- Default replica in `mops bench` and `mops test` commands now is `pocket-ic` if `pocket-ic` is specified in `mops.toml` in `[toolchain]` section and `dfx` otherwise
|
|
15
|
+
- The only supported version of `pocket-ic` is `4.0.0`
|
|
16
|
+
- Dropped support for `wasmtime` version `< 14.0.0`
|
|
17
|
+
- Default reporter in `mops test` command is now `files` if test file count is > 1 and `verbose` otherwise.
|
|
18
|
+
- Renamed `mops import-identity` command to `mops user import`
|
|
19
|
+
- Renamed `mops whoami` command to `mops user get-principal`
|
|
20
|
+
- Removed the ability to install a specific package with `mops install <pkg>` command. Use `mops add <pkg>` instead.
|
|
21
|
+
- Removed legacy folders migration code. If you are using Mops CLI `<= 0.21.0`, you need first to run `npm i -g ic-mops@0.45.3` to migrate your legacy folders. After that, you can run `mops self update` to update your Mops CLI to the latest version.
|
|
22
|
+
- Removed `--verbose` flag from `mops sources` command
|
|
5
23
|
|
|
6
24
|
## 0.45.3
|
|
7
25
|
- Fixed bug with missing `tar` package
|
package/README.md
CHANGED
package/api/actors.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {_SERVICE as _STORAGE_SERVICE} from '../declarations/storage/storage.did.
|
|
|
8
8
|
import {getEndpoint} from './network.js';
|
|
9
9
|
import {getNetwork} from './network.js';
|
|
10
10
|
|
|
11
|
-
let agentPromiseByPrincipal = new Map
|
|
11
|
+
let agentPromiseByPrincipal = new Map<string, Promise<HttpAgent>>();
|
|
12
12
|
|
|
13
13
|
let getAgent = async (identity ?: Identity) : Promise<HttpAgent> => {
|
|
14
14
|
let principal = identity ? identity?.getPrincipal().toText() : '';
|
package/bundle/cli.tgz
ADDED
|
Binary file
|
package/cache.ts
CHANGED
|
@@ -3,15 +3,20 @@ import path from 'node:path';
|
|
|
3
3
|
import ncp from 'ncp';
|
|
4
4
|
import getFolderSize from 'get-folder-size';
|
|
5
5
|
|
|
6
|
-
import {getDependencyType, getRootDir, globalCacheDir, parseGithubURL} from './mops.js';
|
|
6
|
+
import {getDependencyType, getNetwork, getRootDir, globalCacheDir, parseGithubURL} from './mops.js';
|
|
7
7
|
import {getPackageId} from './helpers/get-package-id.js';
|
|
8
8
|
|
|
9
|
+
let getGlobalCacheDir = () => {
|
|
10
|
+
let network = getNetwork();
|
|
11
|
+
return path.join(globalCacheDir, network === 'ic' ? '' : network);
|
|
12
|
+
};
|
|
13
|
+
|
|
9
14
|
export let show = () => {
|
|
10
|
-
return
|
|
15
|
+
return getGlobalCacheDir();
|
|
11
16
|
};
|
|
12
17
|
|
|
13
18
|
export let getDepCacheDir = (cacheName : string) => {
|
|
14
|
-
return path.join(
|
|
19
|
+
return path.join(getGlobalCacheDir(), 'packages', cacheName);
|
|
15
20
|
};
|
|
16
21
|
|
|
17
22
|
export let isDepCached = (cacheName : string) => {
|
|
@@ -30,11 +35,11 @@ export function getMopsDepCacheName(name : string, version : string) {
|
|
|
30
35
|
|
|
31
36
|
export function getGithubDepCacheName(name : string, repo : string) {
|
|
32
37
|
const {branch, commitHash} = parseGithubURL(repo);
|
|
33
|
-
return `_github/${name}#${branch}` + (commitHash ? `@${commitHash}` : '');
|
|
38
|
+
return `_github/${name}#${branch.replaceAll('/', '___')}` + (commitHash ? `@${commitHash}` : '');
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
export let addCache = (cacheName : string, source : string) => {
|
|
37
|
-
let dest = path.join(
|
|
42
|
+
let dest = path.join(getGlobalCacheDir(), 'packages', cacheName);
|
|
38
43
|
fs.mkdirSync(dest, {recursive: true});
|
|
39
44
|
|
|
40
45
|
return new Promise<void>((resolve, reject) => {
|
|
@@ -48,7 +53,7 @@ export let addCache = (cacheName : string, source : string) => {
|
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
export let copyCache = (cacheName : string, dest : string) => {
|
|
51
|
-
let source = path.join(
|
|
56
|
+
let source = path.join(getGlobalCacheDir(), 'packages', cacheName);
|
|
52
57
|
fs.mkdirSync(dest, {recursive: true});
|
|
53
58
|
|
|
54
59
|
return new Promise<void>((resolve, reject) => {
|
|
@@ -62,7 +67,7 @@ export let copyCache = (cacheName : string, dest : string) => {
|
|
|
62
67
|
};
|
|
63
68
|
|
|
64
69
|
export let cacheSize = async () => {
|
|
65
|
-
let dir = path.join(
|
|
70
|
+
let dir = path.join(getGlobalCacheDir());
|
|
66
71
|
fs.mkdirSync(dir, {recursive: true});
|
|
67
72
|
|
|
68
73
|
let size = await getFolderSize.strict(dir);
|
|
@@ -73,13 +78,13 @@ export let cacheSize = async () => {
|
|
|
73
78
|
};
|
|
74
79
|
|
|
75
80
|
export let cleanCache = async () => {
|
|
76
|
-
if (!
|
|
77
|
-
throw new Error('Invalid cache directory: ' +
|
|
81
|
+
if (!getGlobalCacheDir().endsWith('mops/cache') && !getGlobalCacheDir().endsWith('/mops') && !getGlobalCacheDir().endsWith('/mops/' + getNetwork())) {
|
|
82
|
+
throw new Error('Invalid cache directory: ' + getGlobalCacheDir());
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
// local cache
|
|
81
86
|
fs.rmSync(path.join(getRootDir(), '.mops'), {recursive: true, force: true});
|
|
82
87
|
|
|
83
88
|
// global cache
|
|
84
|
-
fs.rmSync(
|
|
89
|
+
fs.rmSync(getGlobalCacheDir(), {recursive: true, force: true});
|
|
85
90
|
};
|
package/cli.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import {Command, Argument, Option} from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
4
|
|
|
6
5
|
import {init} from './commands/init.js';
|
|
7
6
|
import {publish} from './commands/publish.js';
|
|
8
|
-
import {importPem} from './commands/import-identity.js';
|
|
9
7
|
import {sources} from './commands/sources.js';
|
|
10
8
|
import {checkApiCompatibility, setNetwork, apiVersion, checkConfigFile, getNetworkFile, version} from './mops.js';
|
|
11
9
|
import {getNetwork} from './api/network.js';
|
|
12
|
-
import {whoami} from './commands/whoami.js';
|
|
13
10
|
import {installAll} from './commands/install/install-all.js';
|
|
14
11
|
import {search} from './commands/search.js';
|
|
15
12
|
import {add} from './commands/add.js';
|
|
@@ -17,7 +14,7 @@ import {cacheSize, cleanCache, show} from './cache.js';
|
|
|
17
14
|
import {test} from './commands/test/test.js';
|
|
18
15
|
import {template} from './commands/template.js';
|
|
19
16
|
import {remove} from './commands/remove.js';
|
|
20
|
-
import {getUserProp, setUserProp} from './commands/user.js';
|
|
17
|
+
import {importPem, getPrincipal, getUserProp, setUserProp} from './commands/user.js';
|
|
21
18
|
import {bump} from './commands/bump.js';
|
|
22
19
|
import {sync} from './commands/sync.js';
|
|
23
20
|
import {outdated} from './commands/outdated.js';
|
|
@@ -27,11 +24,14 @@ import {transferOwnership} from './commands/transfer-ownership.js';
|
|
|
27
24
|
import {toolchain} from './commands/toolchain/index.js';
|
|
28
25
|
import {Tool} from './types.js';
|
|
29
26
|
import * as self from './commands/self.js';
|
|
27
|
+
import {resolvePackages} from './resolve-packages.js';
|
|
30
28
|
// import {docs} from './commands/docs.js';
|
|
31
29
|
|
|
32
30
|
declare global {
|
|
33
31
|
// eslint-disable-next-line no-var
|
|
34
32
|
var MOPS_NETWORK : string;
|
|
33
|
+
// eslint-disable-next-line no-var
|
|
34
|
+
var mopsReplicaTestRunning : boolean;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
let networkFile = getNetworkFile();
|
|
@@ -87,12 +87,12 @@ program
|
|
|
87
87
|
|
|
88
88
|
// install
|
|
89
89
|
program
|
|
90
|
-
.command('install
|
|
90
|
+
.command('install')
|
|
91
91
|
.alias('i')
|
|
92
92
|
.description('Install all dependencies specified in mops.toml')
|
|
93
93
|
.option('--verbose')
|
|
94
94
|
.addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
|
|
95
|
-
.action(async (
|
|
95
|
+
.action(async (options) => {
|
|
96
96
|
if (!checkConfigFile()) {
|
|
97
97
|
process.exit(1);
|
|
98
98
|
}
|
|
@@ -104,17 +104,14 @@ program
|
|
|
104
104
|
|
|
105
105
|
await toolchain.ensureToolchainInited({strict: false});
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!ok) {
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
107
|
+
let ok = await installAll(options);
|
|
108
|
+
await toolchain.installAll(options);
|
|
109
|
+
|
|
110
|
+
// check conflicts
|
|
111
|
+
await resolvePackages({conflicts: 'warning'});
|
|
112
|
+
|
|
113
|
+
if (!ok) {
|
|
114
|
+
process.exit(1);
|
|
118
115
|
}
|
|
119
116
|
});
|
|
120
117
|
|
|
@@ -155,14 +152,14 @@ program
|
|
|
155
152
|
console.log(getNetwork());
|
|
156
153
|
});
|
|
157
154
|
|
|
158
|
-
// import
|
|
155
|
+
// user import
|
|
159
156
|
program
|
|
160
|
-
.command('import
|
|
157
|
+
.command('mops user import <data>')
|
|
161
158
|
.description('Import .pem file data to use as identity')
|
|
162
159
|
.addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
|
|
163
160
|
.action(async (data, options) => {
|
|
164
161
|
await importPem(data, options);
|
|
165
|
-
await
|
|
162
|
+
await getPrincipal();
|
|
166
163
|
});
|
|
167
164
|
|
|
168
165
|
// sources
|
|
@@ -170,7 +167,7 @@ program
|
|
|
170
167
|
.command('sources')
|
|
171
168
|
.description('for dfx packtool')
|
|
172
169
|
.option('--no-install', 'Do not install dependencies before running sources')
|
|
173
|
-
.
|
|
170
|
+
.addOption(new Option('--conflicts <action>', 'What to do with dependency version conflicts').choices(['ignore', 'warning', 'error']).default('warning'))
|
|
174
171
|
.action(async (options) => {
|
|
175
172
|
if (!checkConfigFile()) {
|
|
176
173
|
process.exit(1);
|
|
@@ -183,12 +180,12 @@ program
|
|
|
183
180
|
console.log(sourcesArr.join('\n'));
|
|
184
181
|
});
|
|
185
182
|
|
|
186
|
-
//
|
|
183
|
+
// get-principal
|
|
187
184
|
program
|
|
188
|
-
.command('
|
|
185
|
+
.command('get-principal')
|
|
189
186
|
.description('Print your principal')
|
|
190
187
|
.action(async () => {
|
|
191
|
-
await
|
|
188
|
+
await getPrincipal();
|
|
192
189
|
});
|
|
193
190
|
|
|
194
191
|
// search
|
|
@@ -222,10 +219,12 @@ program
|
|
|
222
219
|
program
|
|
223
220
|
.command('test [filter]')
|
|
224
221
|
.description('Run tests')
|
|
225
|
-
.addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent'])
|
|
226
|
-
.addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi']).default('interpreter'))
|
|
222
|
+
.addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent']))
|
|
223
|
+
.addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi', 'replica']).default('interpreter'))
|
|
224
|
+
.addOption(new Option('--replica <replica>', 'Which replica to use to run tests in replica mode').choices(['dfx', 'pocket-ic']))
|
|
227
225
|
.option('-w, --watch', 'Enable watch mode')
|
|
228
226
|
.action(async (filter, options) => {
|
|
227
|
+
checkConfigFile(true);
|
|
229
228
|
await installAll({silent: true, lock: 'ignore'});
|
|
230
229
|
await test(filter, options);
|
|
231
230
|
});
|
|
@@ -234,13 +233,14 @@ program
|
|
|
234
233
|
program
|
|
235
234
|
.command('bench [filter]')
|
|
236
235
|
.description('Run benchmarks')
|
|
237
|
-
.addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic'])
|
|
236
|
+
.addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic']))
|
|
238
237
|
.addOption(new Option('--gc <gc>', 'Garbage collector').choices(['copying', 'compacting', 'generational', 'incremental']).default('copying'))
|
|
239
238
|
.addOption(new Option('--save', 'Save benchmark results to .bench/<filename>.json'))
|
|
240
239
|
.addOption(new Option('--compare', 'Run benchmark and compare results with .bench/<filename>.json'))
|
|
241
240
|
// .addOption(new Option('--force-gc', 'Force GC'))
|
|
242
241
|
.addOption(new Option('--verbose', 'Show more information'))
|
|
243
242
|
.action(async (filter, options) => {
|
|
243
|
+
checkConfigFile(true);
|
|
244
244
|
await installAll({silent: true, lock: 'ignore'});
|
|
245
245
|
await bench(filter, options);
|
|
246
246
|
});
|
package/commands/add.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {checkIntegrity} from '../integrity.js';
|
|
|
10
10
|
import {checkRequirements} from '../check-requirements.js';
|
|
11
11
|
import {syncLocalCache} from './install/sync-local-cache.js';
|
|
12
12
|
import {notifyInstalls} from '../notify-installs.js';
|
|
13
|
+
import {resolvePackages} from '../resolve-packages.js';
|
|
13
14
|
|
|
14
15
|
type AddOptions = {
|
|
15
16
|
verbose ?: boolean;
|
|
@@ -127,4 +128,7 @@ export async function add(name : string, {verbose = false, dev = false, lock} :
|
|
|
127
128
|
await checkRequirements({verbose});
|
|
128
129
|
|
|
129
130
|
console.log(chalk.green('Package installed ') + `${pkgDetails.name} = "${pkgDetails.repo || pkgDetails.path || pkgDetails.version}"`);
|
|
131
|
+
|
|
132
|
+
// check conflicts
|
|
133
|
+
await resolvePackages({conflicts: 'warning'});
|
|
130
134
|
}
|
|
@@ -2,17 +2,35 @@ import Nat64 "mo:base/Nat64";
|
|
|
2
2
|
import Nat "mo:base/Nat";
|
|
3
3
|
import Debug "mo:base/Debug";
|
|
4
4
|
import ExperimentalInternetComputer "mo:base/ExperimentalInternetComputer";
|
|
5
|
+
import ExperimentalStableMemory "mo:base/ExperimentalStableMemory";
|
|
6
|
+
import Int64 "mo:base/Int64";
|
|
7
|
+
import Region "mo:base/Region";
|
|
5
8
|
import Prim "mo:prim";
|
|
6
9
|
import Bench "mo:bench";
|
|
7
10
|
|
|
8
11
|
import UserBench "./user-bench"; // file path will be replaced with the *.bench.mo file path
|
|
9
12
|
|
|
10
13
|
actor class() {
|
|
14
|
+
type BenchResult = {
|
|
15
|
+
instructions : Int;
|
|
16
|
+
rts_mutator_instructions : Int;
|
|
17
|
+
stable_memory_size : Int;
|
|
18
|
+
rts_stable_memory_size : Int;
|
|
19
|
+
rts_logical_stable_memory_size : Int;
|
|
20
|
+
rts_collector_instructions : Int;
|
|
21
|
+
rts_heap_size : Int;
|
|
22
|
+
rts_memory_size : Int;
|
|
23
|
+
rts_total_allocation : Int;
|
|
24
|
+
rts_reclaimed : Int;
|
|
25
|
+
};
|
|
26
|
+
|
|
11
27
|
var benchOpt : ?Bench.Bench = null;
|
|
12
28
|
|
|
13
29
|
public func init() : async Bench.BenchSchema {
|
|
14
30
|
let bench = UserBench.init();
|
|
15
31
|
benchOpt := ?bench;
|
|
32
|
+
// ignore ExperimentalStableMemory.grow(1);
|
|
33
|
+
ignore Region.grow(Region.new(), 1);
|
|
16
34
|
bench.getSchema();
|
|
17
35
|
};
|
|
18
36
|
|
|
@@ -21,29 +39,37 @@ actor class() {
|
|
|
21
39
|
bench.getSchema();
|
|
22
40
|
};
|
|
23
41
|
|
|
24
|
-
func _getStats() :
|
|
42
|
+
func _getStats() : BenchResult {
|
|
25
43
|
{
|
|
26
44
|
instructions = 0;
|
|
27
45
|
rts_heap_size = Prim.rts_heap_size();
|
|
46
|
+
stable_memory_size = Int64.toInt(Int64.fromNat64(ExperimentalStableMemory.size())) * 65536;
|
|
47
|
+
rts_stable_memory_size = Prim.rts_stable_memory_size();
|
|
48
|
+
rts_logical_stable_memory_size = Prim.rts_logical_stable_memory_size();
|
|
28
49
|
rts_memory_size = Prim.rts_memory_size();
|
|
29
50
|
rts_total_allocation = Prim.rts_total_allocation();
|
|
51
|
+
rts_reclaimed = Prim.rts_reclaimed();
|
|
30
52
|
rts_mutator_instructions = Prim.rts_mutator_instructions();
|
|
31
53
|
rts_collector_instructions = Prim.rts_collector_instructions();
|
|
32
54
|
}
|
|
33
55
|
};
|
|
34
56
|
|
|
35
|
-
func _diffStats(before :
|
|
57
|
+
func _diffStats(before : BenchResult, after : BenchResult) : BenchResult {
|
|
36
58
|
{
|
|
37
59
|
instructions = after.instructions - before.instructions;
|
|
38
60
|
rts_heap_size = after.rts_heap_size - before.rts_heap_size;
|
|
61
|
+
stable_memory_size = after.stable_memory_size - before.stable_memory_size;
|
|
62
|
+
rts_stable_memory_size = after.rts_stable_memory_size - before.rts_stable_memory_size;
|
|
63
|
+
rts_logical_stable_memory_size = after.rts_logical_stable_memory_size - before.rts_logical_stable_memory_size;
|
|
39
64
|
rts_memory_size = after.rts_memory_size - before.rts_memory_size;
|
|
40
65
|
rts_total_allocation = after.rts_total_allocation - before.rts_total_allocation;
|
|
66
|
+
rts_reclaimed = after.rts_reclaimed - before.rts_reclaimed;
|
|
41
67
|
rts_mutator_instructions = after.rts_mutator_instructions - before.rts_mutator_instructions;
|
|
42
68
|
rts_collector_instructions = after.rts_collector_instructions - before.rts_collector_instructions;
|
|
43
69
|
}
|
|
44
70
|
};
|
|
45
71
|
|
|
46
|
-
func _runCell(rowIndex : Nat, colIndex : Nat) :
|
|
72
|
+
func _runCell(rowIndex : Nat, colIndex : Nat) : BenchResult {
|
|
47
73
|
let ?bench = benchOpt else Debug.trap("bench not initialized");
|
|
48
74
|
let statsBefore = _getStats();
|
|
49
75
|
|
|
@@ -55,7 +81,7 @@ actor class() {
|
|
|
55
81
|
_diffStats(statsBefore, { statsAfter with instructions });
|
|
56
82
|
};
|
|
57
83
|
|
|
58
|
-
func _runCellAwait(rowIndex : Nat, colIndex : Nat) : async
|
|
84
|
+
func _runCellAwait(rowIndex : Nat, colIndex : Nat) : async BenchResult {
|
|
59
85
|
let ?bench = benchOpt else Debug.trap("bench not initialized");
|
|
60
86
|
let statsBefore = _getStats();
|
|
61
87
|
|
|
@@ -69,19 +95,19 @@ actor class() {
|
|
|
69
95
|
_diffStats(statsBefore, { statsAfter with instructions });
|
|
70
96
|
};
|
|
71
97
|
|
|
72
|
-
public query func getStats() : async
|
|
98
|
+
public query func getStats() : async BenchResult {
|
|
73
99
|
_getStats();
|
|
74
100
|
};
|
|
75
101
|
|
|
76
|
-
public query func runCellQuery(rowIndex : Nat, colIndex : Nat) : async
|
|
102
|
+
public query func runCellQuery(rowIndex : Nat, colIndex : Nat) : async BenchResult {
|
|
77
103
|
_runCell(rowIndex, colIndex);
|
|
78
104
|
};
|
|
79
105
|
|
|
80
|
-
public func runCellUpdate(rowIndex : Nat, colIndex : Nat) : async
|
|
106
|
+
public func runCellUpdate(rowIndex : Nat, colIndex : Nat) : async BenchResult {
|
|
81
107
|
_runCell(rowIndex, colIndex);
|
|
82
108
|
};
|
|
83
109
|
|
|
84
|
-
public func runCellUpdateAwait(rowIndex : Nat, colIndex : Nat) : async
|
|
110
|
+
public func runCellUpdateAwait(rowIndex : Nat, colIndex : Nat) : async BenchResult {
|
|
85
111
|
await _runCellAwait(rowIndex, colIndex);
|
|
86
112
|
};
|
|
87
113
|
};
|
|
@@ -3,7 +3,7 @@ import {execSync} from 'node:child_process';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import {execaCommand} from 'execa';
|
|
6
|
-
import {PocketIc} from 'pic-ic';
|
|
6
|
+
import {PocketIc, PocketIcServer} from 'pic-ic';
|
|
7
7
|
import {getRootDir, readConfig} from '../mops.js';
|
|
8
8
|
import {createActor, idlFactory} from '../declarations/bench/index.js';
|
|
9
9
|
import {toolchain} from './toolchain/index.js';
|
|
@@ -12,6 +12,7 @@ export class BenchReplica {
|
|
|
12
12
|
type : 'dfx' | 'pocket-ic';
|
|
13
13
|
verbose = false;
|
|
14
14
|
canisters : Record<string, {cwd : string; canisterId : string; actor : any;}> = {};
|
|
15
|
+
pocketIcServer ?: PocketIcServer;
|
|
15
16
|
pocketIc ?: PocketIc;
|
|
16
17
|
|
|
17
18
|
constructor(type : 'dfx' | 'pocket-ic', verbose = false) {
|
|
@@ -31,11 +32,14 @@ export class BenchReplica {
|
|
|
31
32
|
else {
|
|
32
33
|
let pocketIcBin = await toolchain.bin('pocket-ic');
|
|
33
34
|
let config = readConfig();
|
|
34
|
-
if (config.toolchain?.['pocket-ic'] !== '
|
|
35
|
-
console.error('
|
|
35
|
+
if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
|
|
36
|
+
console.error('Current Mops CLI only supports pocket-ic 4.0.0');
|
|
36
37
|
process.exit(1);
|
|
37
38
|
}
|
|
38
|
-
this.
|
|
39
|
+
this.pocketIcServer = await PocketIcServer.start({
|
|
40
|
+
binPath: pocketIcBin,
|
|
41
|
+
});
|
|
42
|
+
this.pocketIc = await PocketIc.create(this.pocketIcServer.getUrl());
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -44,8 +48,9 @@ export class BenchReplica {
|
|
|
44
48
|
let dir = path.join(getRootDir(), '.mops/.bench');
|
|
45
49
|
execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
|
|
46
50
|
}
|
|
47
|
-
else if (this.pocketIc) {
|
|
51
|
+
else if (this.pocketIc && this.pocketIcServer) {
|
|
48
52
|
await this.pocketIc.tearDown();
|
|
53
|
+
await this.pocketIcServer.stop();
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -61,7 +66,7 @@ export class BenchReplica {
|
|
|
61
66
|
this.canisters[name] = {cwd, canisterId, actor};
|
|
62
67
|
}
|
|
63
68
|
else if (this.pocketIc) {
|
|
64
|
-
let {canisterId, actor} = await this.pocketIc.setupCanister(idlFactory, wasm);
|
|
69
|
+
let {canisterId, actor} = await this.pocketIc.setupCanister({idlFactory, wasm});
|
|
65
70
|
this.canisters[name] = {
|
|
66
71
|
cwd,
|
|
67
72
|
canisterId: canisterId.toText(),
|
package/commands/bench.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {sources} from './sources.js';
|
|
|
20
20
|
import {Benchmark, Benchmarks} from '../declarations/main/main.did.js';
|
|
21
21
|
import {BenchResult, _SERVICE} from '../declarations/bench/bench.did.js';
|
|
22
22
|
import {BenchReplica} from './bench-replica.js';
|
|
23
|
+
import {filesize} from 'filesize';
|
|
23
24
|
|
|
24
25
|
let ignore = [
|
|
25
26
|
'**/node_modules/**',
|
|
@@ -48,8 +49,10 @@ type BenchOptions = {
|
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}) : Promise<Benchmarks> {
|
|
52
|
+
let config = readConfig();
|
|
53
|
+
|
|
51
54
|
let defaultOptions : BenchOptions = {
|
|
52
|
-
replica: 'dfx',
|
|
55
|
+
replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
|
|
53
56
|
replicaVersion: '',
|
|
54
57
|
compiler: 'moc',
|
|
55
58
|
compilerVersion: getMocVersion(),
|
|
@@ -67,7 +70,6 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
67
70
|
options.replicaVersion = getDfxVersion();
|
|
68
71
|
}
|
|
69
72
|
else if (options.replica == 'pocket-ic') {
|
|
70
|
-
let config = readConfig();
|
|
71
73
|
options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -219,11 +221,17 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
219
221
|
|
|
220
222
|
let instructionsCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
|
|
221
223
|
let heapCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
|
|
224
|
+
let logicalStableMemoryCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
|
|
225
|
+
let reclaimedCells : bigint[][] = Array.from({length: schema.rows.length}, () => []);
|
|
222
226
|
|
|
223
227
|
let formatNumber = (n : bigint | number) : string => {
|
|
224
228
|
return n.toLocaleString('en-US').replaceAll(',', '_');
|
|
225
229
|
};
|
|
226
230
|
|
|
231
|
+
let formatSize = (n : bigint | number) : string => {
|
|
232
|
+
return filesize(n, {standard: 'iec', round: 2});
|
|
233
|
+
};
|
|
234
|
+
|
|
227
235
|
let getTable = (prop : keyof BenchResult) : string => {
|
|
228
236
|
let resArr = [['', ...schema.cols]];
|
|
229
237
|
|
|
@@ -251,7 +259,17 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
251
259
|
}
|
|
252
260
|
|
|
253
261
|
// add to table
|
|
254
|
-
|
|
262
|
+
let value = '';
|
|
263
|
+
if (prop == 'rts_logical_stable_memory_size') {
|
|
264
|
+
value = formatSize(res[prop] * 65536n);
|
|
265
|
+
}
|
|
266
|
+
else if (prop === 'rts_heap_size' || prop == 'rts_reclaimed') {
|
|
267
|
+
value = formatSize(res[prop]);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
value = formatNumber(res[prop]);
|
|
271
|
+
}
|
|
272
|
+
curRow.push(value + diff);
|
|
255
273
|
}
|
|
256
274
|
else {
|
|
257
275
|
curRow.push('');
|
|
@@ -272,6 +290,8 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
272
290
|
${schema.description ? '\n' + chalk.gray(schema.description) : ''}
|
|
273
291
|
\n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
|
|
274
292
|
\n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
|
|
293
|
+
\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
|
|
294
|
+
\n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
|
|
275
295
|
`);
|
|
276
296
|
};
|
|
277
297
|
|
|
@@ -289,6 +309,10 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
289
309
|
instructionsCells[rowIndex][colIndex] = res.instructions;
|
|
290
310
|
// @ts-ignore
|
|
291
311
|
heapCells[rowIndex][colIndex] = res.rts_heap_size;
|
|
312
|
+
// @ts-ignore
|
|
313
|
+
logicalStableMemoryCells[rowIndex][colIndex] = res.rts_logical_stable_memory_size;
|
|
314
|
+
// @ts-ignore
|
|
315
|
+
reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
|
|
292
316
|
|
|
293
317
|
if (!process.env.CI && !options.silent) {
|
|
294
318
|
printResults();
|
|
@@ -340,6 +364,8 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
340
364
|
metrics: [
|
|
341
365
|
['instructions', instructionsCells],
|
|
342
366
|
['rts_heap_size', heapCells],
|
|
367
|
+
['rts_logical_stable_memory_size', logicalStableMemoryCells],
|
|
368
|
+
['rts_reclaimed', reclaimedCells],
|
|
343
369
|
],
|
|
344
370
|
};
|
|
345
371
|
}
|
package/commands/publish.ts
CHANGED
|
@@ -271,7 +271,7 @@ export async function publish(options : {docs ?: boolean, test ?: boolean, bench
|
|
|
271
271
|
let reporter = new SilentReporter;
|
|
272
272
|
if (options.test) {
|
|
273
273
|
console.log('Running tests...');
|
|
274
|
-
await testWithReporter(reporter);
|
|
274
|
+
await testWithReporter(reporter, '', 'interpreter', config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx');
|
|
275
275
|
if (reporter.failed > 0) {
|
|
276
276
|
console.log(chalk.red('Error: ') + 'tests failed');
|
|
277
277
|
process.exit(1);
|