ic-mops 0.45.4-pre.0 → 1.0.0-pre.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/api/actors.ts +1 -1
  4. package/cache.ts +14 -9
  5. package/cli.ts +28 -27
  6. package/commands/add.ts +4 -0
  7. package/commands/bench/bench-canister.mo +34 -8
  8. package/commands/bench-replica.ts +11 -6
  9. package/commands/bench.ts +31 -5
  10. package/commands/publish.ts +1 -1
  11. package/commands/replica.ts +237 -0
  12. package/commands/sources.ts +2 -3
  13. package/commands/test/mmf1.ts +5 -5
  14. package/commands/test/reporters/compact-reporter.ts +2 -1
  15. package/commands/test/reporters/files-reporter.ts +3 -2
  16. package/commands/test/reporters/reporter.ts +2 -1
  17. package/commands/test/reporters/silent-reporter.ts +2 -1
  18. package/commands/test/reporters/verbose-reporter.ts +14 -4
  19. package/commands/test/test.ts +213 -74
  20. package/commands/user.ts +71 -1
  21. package/declarations/bench/bench.did +8 -4
  22. package/declarations/bench/bench.did.d.ts +4 -0
  23. package/declarations/bench/bench.did.js +4 -0
  24. package/dist/cache.js +13 -9
  25. package/dist/cli.d.ts +1 -0
  26. package/dist/cli.js +24 -27
  27. package/dist/commands/add.js +3 -0
  28. package/dist/commands/bench/bench-canister.mo +34 -8
  29. package/dist/commands/bench-replica.d.ts +2 -1
  30. package/dist/commands/bench-replica.js +10 -6
  31. package/dist/commands/bench.js +29 -5
  32. package/dist/commands/publish.js +1 -1
  33. package/dist/commands/replica.d.ts +59 -0
  34. package/dist/commands/replica.js +193 -0
  35. package/dist/commands/sources.d.ts +2 -2
  36. package/dist/commands/sources.js +2 -3
  37. package/dist/commands/test/mmf1.d.ts +2 -2
  38. package/dist/commands/test/mmf1.js +4 -4
  39. package/dist/commands/test/reporters/compact-reporter.d.ts +2 -1
  40. package/dist/commands/test/reporters/compact-reporter.js +1 -1
  41. package/dist/commands/test/reporters/files-reporter.d.ts +2 -1
  42. package/dist/commands/test/reporters/files-reporter.js +2 -2
  43. package/dist/commands/test/reporters/reporter.d.ts +2 -1
  44. package/dist/commands/test/reporters/silent-reporter.d.ts +2 -1
  45. package/dist/commands/test/reporters/silent-reporter.js +1 -1
  46. package/dist/commands/test/reporters/verbose-reporter.d.ts +3 -1
  47. package/dist/commands/test/reporters/verbose-reporter.js +12 -4
  48. package/dist/commands/test/test.d.ts +10 -8
  49. package/dist/commands/test/test.js +170 -71
  50. package/dist/commands/user.d.ts +6 -0
  51. package/dist/commands/user.js +59 -1
  52. package/dist/declarations/bench/bench.did +8 -4
  53. package/dist/declarations/bench/bench.did.d.ts +4 -0
  54. package/dist/declarations/bench/bench.did.js +4 -0
  55. package/dist/mops.d.ts +1 -1
  56. package/dist/mops.js +4 -28
  57. package/dist/package.json +4 -3
  58. package/dist/resolve-packages.d.ts +2 -2
  59. package/dist/resolve-packages.js +29 -7
  60. package/dist/types.d.ts +1 -0
  61. package/mops.ts +4 -31
  62. package/package.json +4 -3
  63. package/resolve-packages.ts +39 -8
  64. package/types.ts +3 -1
  65. package/commands/import-identity.ts +0 -62
  66. package/commands/whoami.ts +0 -12
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## unreleased
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
+
11
+ **Breaking changes**:
12
+ - Default replica in `mops bench` commands now is `pocket-ic` if `pocket-ic` is specified in `mops.toml` in `[toolchain]` section
13
+ - The only supported version of `pocket-ic` is `4.0.0`
14
+ - Removed the ability to install a specific package with `mops install <pkg>` command. Use `mops add <pkg>` instead.
15
+ - Default reporter in `mops test` command is now `verbose` if there is only one file to test and `files` otherwise.
16
+ - 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.
17
+ - Renamed `mops import-identity` command to `mops user import`
18
+ - Renamed `mops whoami` command to `mops user get-principal`
5
19
 
6
20
  ## 0.45.3
7
21
  - Fixed bug with missing `tar` package
package/README.md CHANGED
@@ -89,7 +89,7 @@ dfx identity new mops
89
89
  Import identity into `mops`
90
90
 
91
91
  ```
92
- mops import-identity -- "$(dfx identity export mops)"
92
+ mops user import -- "$(dfx identity export mops)"
93
93
  ```
94
94
 
95
95
  ### 2. Initialize
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 <string, Promise<HttpAgent>>();
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/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 globalCacheDir;
15
+ return getGlobalCacheDir();
11
16
  };
12
17
 
13
18
  export let getDepCacheDir = (cacheName : string) => {
14
- return path.join(globalCacheDir, 'packages', cacheName);
19
+ return path.join(getGlobalCacheDir(), 'packages', cacheName);
15
20
  };
16
21
 
17
22
  export let isDepCached = (cacheName : string) => {
@@ -34,7 +39,7 @@ export function getGithubDepCacheName(name : string, repo : string) {
34
39
  }
35
40
 
36
41
  export let addCache = (cacheName : string, source : string) => {
37
- let dest = path.join(globalCacheDir, 'packages', cacheName);
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(globalCacheDir, 'packages', cacheName);
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(globalCacheDir);
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 (!globalCacheDir.endsWith('mops/cache') && !globalCacheDir.endsWith('/mops')) {
77
- throw new Error('Invalid cache directory: ' + globalCacheDir);
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(globalCacheDir, {recursive: true, force: true});
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 [pkg]')
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 (pkg, options) => {
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
- if (pkg) {
108
- // @deprecated
109
- console.log(chalk.yellow('Consider using the \'mops add\' command to install a specific package.'));
110
- await add(pkg, options);
111
- }
112
- else {
113
- let ok = await installAll(options);
114
- await toolchain.installAll(options);
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-identity
155
+ // user import
159
156
  program
160
- .command('import-identity <data>')
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 whoami();
162
+ await getPrincipal();
166
163
  });
167
164
 
168
165
  // sources
@@ -170,7 +167,8 @@ program
170
167
  .command('sources')
171
168
  .description('for dfx packtool')
172
169
  .option('--no-install', 'Do not install dependencies before running sources')
173
- .option('--verbose')
170
+ .addOption(new Option('--conflicts <action>', 'What to do with dependency version conflicts').choices(['ignore', 'warning', 'error']).default('warning'))
171
+ .option('--verbose', 'Show more information') // for backcompat
174
172
  .action(async (options) => {
175
173
  if (!checkConfigFile()) {
176
174
  process.exit(1);
@@ -183,12 +181,12 @@ program
183
181
  console.log(sourcesArr.join('\n'));
184
182
  });
185
183
 
186
- // whoami
184
+ // get-principal
187
185
  program
188
- .command('whoami')
186
+ .command('get-principal')
189
187
  .description('Print your principal')
190
188
  .action(async () => {
191
- await whoami();
189
+ await getPrincipal();
192
190
  });
193
191
 
194
192
  // search
@@ -222,10 +220,12 @@ program
222
220
  program
223
221
  .command('test [filter]')
224
222
  .description('Run tests')
225
- .addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent']).default('verbose'))
226
- .addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi']).default('interpreter'))
223
+ .addOption(new Option('-r, --reporter <reporter>', 'Test reporter').choices(['verbose', 'compact', 'files', 'silent']))
224
+ .addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi', 'replica']).default('interpreter'))
225
+ .addOption(new Option('--replica <replica>', 'Which replica to use to run tests in replica mode').choices(['dfx', 'pocket-ic']))
227
226
  .option('-w, --watch', 'Enable watch mode')
228
227
  .action(async (filter, options) => {
228
+ checkConfigFile(true);
229
229
  await installAll({silent: true, lock: 'ignore'});
230
230
  await test(filter, options);
231
231
  });
@@ -234,13 +234,14 @@ program
234
234
  program
235
235
  .command('bench [filter]')
236
236
  .description('Run benchmarks')
237
- .addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic']).default('dfx'))
237
+ .addOption(new Option('--replica <replica>', 'Which replica to use to run benchmarks').choices(['dfx', 'pocket-ic']))
238
238
  .addOption(new Option('--gc <gc>', 'Garbage collector').choices(['copying', 'compacting', 'generational', 'incremental']).default('copying'))
239
239
  .addOption(new Option('--save', 'Save benchmark results to .bench/<filename>.json'))
240
240
  .addOption(new Option('--compare', 'Run benchmark and compare results with .bench/<filename>.json'))
241
241
  // .addOption(new Option('--force-gc', 'Force GC'))
242
242
  .addOption(new Option('--verbose', 'Show more information'))
243
243
  .action(async (filter, options) => {
244
+ checkConfigFile(true);
244
245
  await installAll({silent: true, lock: 'ignore'});
245
246
  await bench(filter, options);
246
247
  });
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() : Bench.BenchResult {
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 : Bench.BenchResult, after : Bench.BenchResult) : Bench.BenchResult {
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) : Bench.BenchResult {
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 Bench.BenchResult {
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 Bench.BenchResult {
98
+ public query func getStats() : async BenchResult {
73
99
  _getStats();
74
100
  };
75
101
 
76
- public query func runCellQuery(rowIndex : Nat, colIndex : Nat) : async Bench.BenchResult {
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 Bench.BenchResult {
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 Bench.BenchResult {
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'] !== '1.0.0') {
35
- console.error('Currently only pocket-ic 1.0.0 is supported');
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.pocketIc = await PocketIc.create(pocketIcBin);
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
 
@@ -96,7 +98,7 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
96
98
  files.sort();
97
99
 
98
100
  let benchDir = `${getRootDir()}/.mops/.bench/`;
99
- fs.rmSync(benchDir, {recursive: true, force: true});
101
+ // fs.rmSync(benchDir, {recursive: true, force: true});
100
102
  fs.mkdirSync(benchDir, {recursive: true});
101
103
 
102
104
  if (!options.silent) {
@@ -145,7 +147,7 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
145
147
  options.silent || console.log('Stopping replica...');
146
148
  await replica.stop();
147
149
 
148
- fs.rmSync(benchDir, {recursive: true, force: true});
150
+ // fs.rmSync(benchDir, {recursive: true, force: true});
149
151
 
150
152
  return benchResults;
151
153
  }
@@ -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
- curRow.push(formatNumber(res[prop]) + diff);
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
  }
@@ -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);