From 306fc89f6846ea66076cc6d3ed6affad8fd74353 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Fri, 14 Aug 2020 20:10:16 -0700 Subject: [PATCH] chore(swingset): add slogging framework This adds a set of logging hooks which record swingset deliveries (the kernel sending messages and resolution notifications into vats), syscalls (from the vat into the kernel), and console messages. All these events can be correlated by their crank number, vatID, delivery number, and syscall number. The output function is not yet implemented; my notional plan is to log to lines of JSON for now, and maybe move to a SQLite based store for later. I've not written any analysis tools yet either. I made a few refactorings to make things smoother: * vats get their console object from `managerOptions.vatConsole`, rather than having the manager build it themselves, which makes it easier to provide one that writes to both the regular console and the slog * as a result, all vats get the same basic `vatEndowments` (with the console added on later), rather than calling `makeVatEndowments(vatID)` * in kernel.js, `deliverToVat` and `processNotify` had their common code factored out into `deliverAndLogToVat()`, which now writes to the slog in addition to actually performing the `manager.deliver`. The names aren't great and want to be changed at some point. * `buildVatSyscallHandler` function was moved out of `addVatManager` to make things easier to read. The new function writes syscalls to the slog. * console messages written by vats in top-level code, or during the execution of `buildRootObject`, are slogged in the "startup" phase. All other calls to `console.log` and friends are recorded in a "delivery" phase. The slog is disabled during test-kernel.js and test-vpid-kernel.js, because these tests make syscalls outside the context of a delivery, which is normally illegal, and the slog complains bitterly when it happens. refs #1535 --- packages/SwingSet/src/controller.js | 24 ++- packages/SwingSet/src/kernel/dynamicVat.js | 9 + packages/SwingSet/src/kernel/kernel.js | 159 +++++++++++------- packages/SwingSet/src/kernel/kernelSyscall.js | 2 +- packages/SwingSet/src/kernel/slogger.js | 111 ++++++++++++ .../SwingSet/src/kernel/vatManager/factory.js | 5 +- .../src/kernel/vatManager/localVatManager.js | 16 +- packages/SwingSet/test/test-kernel.js | 39 +++-- packages/SwingSet/test/test-vpid-kernel.js | 15 +- 9 files changed, 281 insertions(+), 99 deletions(-) create mode 100644 packages/SwingSet/src/kernel/slogger.js diff --git a/packages/SwingSet/src/controller.js b/packages/SwingSet/src/controller.js index eff717ce9b04..5ac9cf7034b7 100644 --- a/packages/SwingSet/src/controller.js +++ b/packages/SwingSet/src/controller.js @@ -287,14 +287,12 @@ export async function buildVatController( // the same is true for the tildot transform const transformTildot = harden(makeTransform(babelParser, babelGenerate)); - function makeVatEndowments(consoleTag) { - return harden({ - console: makeConsole(`${debugPrefix}SwingSet:${consoleTag}`), - // re2 is a RegExp work-a-like that disables backtracking expressions for - // safer memory consumption - RegExp: re2, - }); - } + // all vats get these in their global scope, plus a vat-specific 'console' + const vatEndowments = harden({ + // re2 is a RegExp work-a-like that disables backtracking expressions for + // safer memory consumption + RegExp: re2, + }); const hostStorage = runtimeOptions.hostStorage || initSwingStore().storage; insistStorageAPI(hostStorage); @@ -320,15 +318,23 @@ export async function buildVatController( return new Worker(supercode); } + function writeSlogObject(_obj) { + // TODO sqlite + // console.log(`--slog ${JSON.stringify(obj)}`); + } + const kernelEndowments = { waitUntilQuiescent, hostStorage, - makeVatEndowments, + debugPrefix, + vatEndowments, + makeConsole, replaceGlobalMeter, transformMetering, transformTildot, makeNodeWorker, startSubprocessWorker, + writeSlogObject, }; const kernel = buildKernel(kernelEndowments); diff --git a/packages/SwingSet/src/kernel/dynamicVat.js b/packages/SwingSet/src/kernel/dynamicVat.js index a51359d88731..63ed5e800bcc 100644 --- a/packages/SwingSet/src/kernel/dynamicVat.js +++ b/packages/SwingSet/src/kernel/dynamicVat.js @@ -12,6 +12,8 @@ export function makeDynamicVatCreator(stuff) { allocateUnusedVatID, vatNameToID, vatManagerFactory, + kernelSlog, + makeVatConsole, addVatManager, addExport, queueToExport, @@ -64,6 +66,11 @@ export function makeDynamicVatCreator(stuff) { if (!vatSourceBundle) { throw Error(`Bundle ${source.bundleName} not found`); } + // TODO: maybe hash the bundle object somehow for the description + const description = source.bundle + ? '(source bundle)' + : `from: ${source.bundleName}`; + assertKnownOptions(dynamicOptions, ['metered', 'vatParameters']); const { metered = true, vatParameters = {} } = dynamicOptions; let terminated = false; @@ -102,12 +109,14 @@ export function makeDynamicVatCreator(stuff) { ); } + kernelSlog.addVat(vatID, true, description); const managerOptions = { bundle: vatSourceBundle, metered, enableSetup: false, enableInternalMetering: false, notifyTermination: metered ? notifyTermination : undefined, + vatConsole: makeVatConsole(vatID), vatParameters, }; const manager = await vatManagerFactory(vatID, managerOptions); diff --git a/packages/SwingSet/src/kernel/kernel.js b/packages/SwingSet/src/kernel/kernel.js index 35a6645c67f1..f69aebd27f67 100644 --- a/packages/SwingSet/src/kernel/kernel.js +++ b/packages/SwingSet/src/kernel/kernel.js @@ -18,6 +18,7 @@ import { insistDeviceID, insistVatID } from './id'; import { makeMessageResult } from './messageResult'; import { makeMeterManager } from './metering'; import { makeKernelSyscallHandler } from './kernelSyscall'; +import { makeSlogger, makeDummySlogger } from './slogger'; import { makeDynamicVatCreator } from './dynamicVat'; import { makeVatTranslators } from './vatTranslator'; @@ -38,19 +39,28 @@ function makeError(s) { return harden({ body: JSON.stringify(s), slots: [] }); } -export default function buildKernel(kernelEndowments) { +export default function buildKernel(kernelEndowments, kernelOptions = {}) { const { waitUntilQuiescent, hostStorage, - makeVatEndowments, + debugPrefix, + vatEndowments, + makeConsole, replaceGlobalMeter, transformMetering, transformTildot, makeNodeWorker, startSubprocessWorker, + writeSlogObject, } = kernelEndowments; + const { disableSlog = false } = kernelOptions; insistStorageAPI(hostStorage); const { enhancedCrankBuffer, commitCrank } = wrapStorage(hostStorage); + + const kernelSlog = disableSlog + ? makeDummySlogger(makeConsole) + : makeSlogger(writeSlogObject); + const kernelKeeper = makeKernelKeeper(enhancedCrankBuffer); const meterManager = makeMeterManager(replaceGlobalMeter); @@ -81,6 +91,11 @@ export default function buildKernel(kernelEndowments) { } harden(testLog); + function makeVatConsole(vatID) { + const origConsole = makeConsole(`${debugPrefix}SwingSet:${vatID}`); + return kernelSlog.vatConsole(vatID, origConsole); + } + // track results of externally-injected messages (queueToExport, bootstrap) const pendingMessageResults = new Map(); // kpid -> messageResult @@ -263,6 +278,29 @@ export default function buildKernel(kernelEndowments) { } } + async function deliverAndLogToVat(vatID, kernelDelivery, vatDelivery) { + const vat = ephemeral.vats.get(vatID); + const crankNum = kernelKeeper.getCrankNumber(); + const finish = kernelSlog.delivery( + vatID, + crankNum, + kernelDelivery, + vatDelivery, + ); + try { + const deliveryResult = await vat.manager.deliver(vatDelivery); + finish(deliveryResult); + // TODO: eventually + // if (deliveryResult === death) { + // vat.notifyTermination(deliveryResult.causeOfDeath); + // } + } catch (e) { + // log so we get a stack trace + console.error(`error in kernel.deliver:`, e); + throw e; + } + } + async function deliverToVat(vatID, target, msg) { insistMessage(msg); const vat = ephemeral.vats.get(vatID); @@ -274,19 +312,7 @@ export default function buildKernel(kernelEndowments) { } else { const kd = harden(['message', target, msg]); const vd = vat.translators.kernelDeliveryToVatDelivery(kd); - try { - await vat.manager.deliver(vd); - /* // TODO: eventually this will be as follows, once deliver can return a delivery status - const deliveryResult = await vat.manager.deliver(vd); - if (deliveryResult === death) { - vat.notifyTermination(deliveryResult.causeOfDeath); - } - */ - } catch (e) { - // log so we get a stack trace - console.error(`error in kernel.deliver:`, e); - throw e; - } + await deliverAndLogToVat(vatID, kd, vd); } } @@ -362,19 +388,7 @@ export default function buildKernel(kernelEndowments) { kernelKeeper.incStat(statNameForNotify(p.state)); const kd = harden(['notify', kpid, p]); const vd = vat.translators.kernelDeliveryToVatDelivery(kd); - try { - await vat.manager.deliver(vd); - /* // TODO: eventually this will be as follows, once deliver can return a delivery status - const deliveryResult = await vat.manager.deliver(vd); - if (deliveryResult === death) { - vat.notifyTermination(deliveryResult.causeOfDeath); - } - */ - } catch (e) { - // log so we get a stack trace - console.error(`error in kernel.processNotify:`, e); - throw e; - } + await deliverAndLogToVat(vatID, kd, vd); } } @@ -592,7 +606,7 @@ export default function buildKernel(kernelEndowments) { const vatManagerFactory = makeVatManagerFactory({ allVatPowers, kernelKeeper, - makeVatEndowments, + vatEndowments, meterManager, testLog, transformMetering, @@ -601,40 +615,7 @@ export default function buildKernel(kernelEndowments) { startSubprocessWorker, }); - /* - * Take an existing VatManager (which is already configured to talk to a - * VatWorker, loaded with some vat code) and connect it to the rest of the - * kernel. The vat must be ready to go: any initial buildRootObject - * construction should have happened by this point. However the kernel - * might tell the manager to replay the transcript later, if it notices - * we're reloading a saved state vector. - */ - function addVatManager(vatID, manager, managerOptions) { - // addVatManager takes a manager, not a promise for one - assert( - manager.deliver && manager.setVatSyscallHandler, - `manager lacks .deliver, isPromise=${manager instanceof Promise}`, - ); - - const { - enablePipelining = false, - notifyTermination = () => {}, - } = managerOptions; - // This should create the vatKeeper. Other users get it from the - // kernelKeeper, so we don't need a reference ourselves. - kernelKeeper.allocateVatKeeperIfNeeded(vatID); - const translators = makeVatTranslators(vatID, kernelKeeper); - - ephemeral.vats.set( - vatID, - harden({ - translators, - manager, - notifyTermination, - enablePipelining: Boolean(enablePipelining), - }), - ); - + function buildVatSyscallHandler(vatID, translators) { // This handler never throws. The VatSyscallResult it returns is one of: // * success, no response data: ['ok', null] // * success, capdata (callNow) ['ok', capdata] @@ -661,6 +642,7 @@ export default function buildKernel(kernelEndowments) { return harden(['error', 'clist violation: prepare to die']); } + const finish = kernelSlog.syscall(vatID, ksc, vatSyscallObject); let vres; try { // this can fail if kernel or device code is buggy @@ -674,6 +656,7 @@ export default function buildKernel(kernelEndowments) { // capdata. vres = translators.kernelSyscallResultToVatSyscallResult(kres); // here, vres is either ['ok', null] or ['ok', capdata] + finish(kres, vres); // TODO call meaningfully on failure too? } catch (err) { // kernel/device errors cause a kernel panic panic(`error during syscall/device.invoke: ${err}`, err); @@ -684,6 +667,43 @@ export default function buildKernel(kernelEndowments) { return vres; } + return vatSyscallHandler; + } + + /* + * Take an existing VatManager (which is already configured to talk to a + * VatWorker, loaded with some vat code) and connect it to the rest of the + * kernel. The vat must be ready to go: any initial buildRootObject + * construction should have happened by this point. However the kernel + * might tell the manager to replay the transcript later, if it notices + * we're reloading a saved state vector. + */ + function addVatManager(vatID, manager, managerOptions) { + // addVatManager takes a manager, not a promise for one + assert( + manager.deliver && manager.setVatSyscallHandler, + `manager lacks .deliver, isPromise=${manager instanceof Promise}`, + ); + const { + enablePipelining = false, + notifyTermination = () => {}, + } = managerOptions; + // This should create the vatKeeper. Other users get it from the + // kernelKeeper, so we don't need a reference ourselves. + kernelKeeper.allocateVatKeeperIfNeeded(vatID); + const translators = makeVatTranslators(vatID, kernelKeeper); + + ephemeral.vats.set( + vatID, + harden({ + translators, + manager, + notifyTermination, + enablePipelining: Boolean(enablePipelining), + }), + ); + + const vatSyscallHandler = buildVatSyscallHandler(vatID, translators); manager.setVatSyscallHandler(vatSyscallHandler); } @@ -715,6 +735,8 @@ export default function buildKernel(kernelEndowments) { allocateUnusedVatID: kernelKeeper.allocateUnusedVatID, vatNameToID, vatManagerFactory, + kernelSlog, + makeVatConsole, addVatManager, addExport, queueToExport, @@ -783,11 +805,17 @@ export default function buildKernel(kernelEndowments) { // instantiate all genesis vats for (const name of genesisVats.keys()) { - const managerOptions = genesisVats.get(name); const vatID = kernelKeeper.allocateVatIDForNameIfNeeded(name); console.debug(`Assigned VatID ${vatID} for genesis vat ${name}`); + kernelSlog.addVat(vatID, false, name); + const managerOptions = harden({ + ...genesisVats.get(name), + vatConsole: makeVatConsole(vatID), + }); + const finish = kernelSlog.startup(vatID); // eslint-disable-next-line no-await-in-loop const manager = await vatManagerFactory(vatID, managerOptions); + finish(); addVatManager(vatID, manager, managerOptions); } @@ -837,10 +865,11 @@ export default function buildKernel(kernelEndowments) { const deviceID = kernelKeeper.allocateDeviceIDForNameIfNeeded(name); console.debug(`Assigned DeviceID ${deviceID} for genesis device ${name}`); const { bundle, endowments: devEndowments } = genesisDevices.get(name); + const devConsole = makeConsole(`${debugPrefix}SwingSet:dev-${name}`); // eslint-disable-next-line no-await-in-loop const NS = await importBundle(bundle, { filePrefix: `dev-${name}`, - endowments: makeVatEndowments(`dev-${name}`), + endowments: harden({ ...vatEndowments, console: devConsole }), }); assert( typeof NS.buildRootDeviceNode === 'function', diff --git a/packages/SwingSet/src/kernel/kernelSyscall.js b/packages/SwingSet/src/kernel/kernelSyscall.js index 219398f68af1..0293790089fe 100644 --- a/packages/SwingSet/src/kernel/kernelSyscall.js +++ b/packages/SwingSet/src/kernel/kernelSyscall.js @@ -148,7 +148,7 @@ export function makeKernelSyscallHandler(tools) { } const kernelSyscallHandler = harden({ - send, + send, // TODO remove these individual ones invoke, subscribe, fulfillToPresence, diff --git a/packages/SwingSet/src/kernel/slogger.js b/packages/SwingSet/src/kernel/slogger.js new file mode 100644 index 000000000000..4ec3017aba3f --- /dev/null +++ b/packages/SwingSet/src/kernel/slogger.js @@ -0,0 +1,111 @@ +/* global harden */ +import { assert } from '@agoric/assert'; + +const IDLE = 'idle'; +const STARTUP = 'startup'; +const DELIVERY = 'delivery'; + +export function makeDummySlogger(makeConsole) { + return harden({ + addVat: () => 0, + vatConsole: () => makeConsole('disabled slogger'), + startup: () => () => 0, // returns nop finish() function + delivery: () => () => 0, + syscall: () => () => 0, + }); +} + +export function makeSlogger(writeObj) { + const write = writeObj ? e => writeObj(harden(e)) : () => 0; + + const vatSlogs = new Map(); // vatID -> vatSlog + + function makeVatSlog(vatID) { + let state = IDLE; // or STARTUP or DELIVERY + let crankNum; + let deliveryNum = 0; + let syscallNum; + + function assertOldState(exp, msg) { + assert(state === exp, `vat ${vatID} in ${state}, not ${exp}: ${msg}`); + } + + function vatConsole(origConsole) { + const vc = {}; + for (const level of ['debug', 'log', 'info', 'warn', 'error']) { + vc[level] = (...args) => { + origConsole[level](...args); + const when = { state, crankNum, vatID, deliveryNum }; + write({ type: 'console', ...when, level, args }); + }; + } + return harden(vc); + } + + function startup() { + // provide a context for console calls during startup + assertOldState(IDLE, 'did startup get called twice?'); + state = STARTUP; + function finish() { + assertOldState(STARTUP, 'startup-finish called twice?'); + state = IDLE; + } + return harden(finish); + } + + // kd: kernelDelivery, vd: vatDelivery + function delivery(newCrankNum, kd, vd) { + assertOldState(IDLE, 'reentrant delivery?'); + state = DELIVERY; + crankNum = newCrankNum; + const when = { crankNum, vatID, deliveryNum }; + write({ type: 'deliver', ...when, kd, vd }); + deliveryNum += 1; + syscallNum = 0; + + // dr: deliveryResult + function finish(dr) { + assertOldState(DELIVERY, 'delivery-finish called twice?'); + write({ type: 'deliver-result', ...when, dr }); + state = IDLE; + } + return harden(finish); + } + + // ksc: kernelSyscallObject, vsc: vatSyscallObject + function syscall(ksc, vsc) { + assertOldState(DELIVERY, 'syscall invoked outside of delivery'); + const when = { crankNum, vatID, deliveryNum, syscallNum }; + write({ type: 'syscall', ...when, ksc, vsc }); + syscallNum += 1; + + // ksr: kernelSyscallResult, vsr: vatSyscallResult + function finish(ksr, vsr) { + assertOldState(DELIVERY, 'syscall finished after delivery?'); + write({ type: 'syscall-result', ...when, ksr, vsr }); + } + return harden(finish); + } + return harden({ vatConsole, startup, delivery, syscall }); + } + + function addVat(vatID, dynamic, description) { + assert(!vatSlogs.has(vatID), `already have slog for ${vatID}`); + const vatSlog = makeVatSlog(vatID); + vatSlogs.set(vatID, vatSlog); + write({ type: 'create-vat', vatID, dynamic, description }); + return vatSlog; + } + + // function annotateVat(vatID, data) { + // write({ type: 'annotate-vat', vatID, data }); + // } + + return harden({ + addVat, + vatConsole: (vatID, ...args) => vatSlogs.get(vatID).vatConsole(...args), + startup: (vatID, ...args) => vatSlogs.get(vatID).startup(...args), + delivery: (vatID, ...args) => vatSlogs.get(vatID).delivery(...args), + syscall: (vatID, ...args) => vatSlogs.get(vatID).syscall(...args), + }); +} diff --git a/packages/SwingSet/src/kernel/vatManager/factory.js b/packages/SwingSet/src/kernel/vatManager/factory.js index c47d395f0853..f3f6706ed0da 100644 --- a/packages/SwingSet/src/kernel/vatManager/factory.js +++ b/packages/SwingSet/src/kernel/vatManager/factory.js @@ -8,7 +8,7 @@ import { makeNodeSubprocessFactory } from './worker-subprocess-node'; export function makeVatManagerFactory({ allVatPowers, kernelKeeper, - makeVatEndowments, + vatEndowments, meterManager, transformMetering, waitUntilQuiescent, @@ -18,7 +18,7 @@ export function makeVatManagerFactory({ const localFactory = makeLocalVatManagerFactory({ allVatPowers, kernelKeeper, - makeVatEndowments, + vatEndowments, meterManager, transformMetering, waitUntilQuiescent, @@ -45,6 +45,7 @@ export function makeVatManagerFactory({ 'enableInternalMetering', 'notifyTermination', 'vatParameters', + 'vatConsole', ]); const { setup, diff --git a/packages/SwingSet/src/kernel/vatManager/localVatManager.js b/packages/SwingSet/src/kernel/vatManager/localVatManager.js index d161171bf2f1..376dd6256b09 100644 --- a/packages/SwingSet/src/kernel/vatManager/localVatManager.js +++ b/packages/SwingSet/src/kernel/vatManager/localVatManager.js @@ -10,7 +10,7 @@ export function makeLocalVatManagerFactory(tools) { const { allVatPowers, kernelKeeper, - makeVatEndowments, + vatEndowments, meterManager, transformMetering, waitUntilQuiescent, @@ -86,17 +86,19 @@ export function makeLocalVatManagerFactory(tools) { const vatPowers = harden({ ...baseVP, vatParameters, testLog }); const dispatch = setup(syscall, state, helpers, vatPowers); const meterRecord = null; - return finish(dispatch, meterRecord); + const manager = finish(dispatch, meterRecord); + return manager; } async function createFromBundle(vatID, bundle, managerOptions) { const { metered = false, - notifyTermination, enableSetup = false, enableInternalMetering = false, vatParameters = {}, + vatConsole, } = managerOptions; + assert(vatConsole, 'vats need managerOptions.vatConsole'); let meterRecord = null; if (metered) { @@ -121,12 +123,12 @@ export function makeLocalVatManagerFactory(tools) { const vatNS = await importBundle(bundle, { filePrefix: vatID, - endowments: makeVatEndowments(vatID), + endowments: harden({ ...vatEndowments, console: vatConsole }), inescapableTransforms, inescapableGlobalLexicals, }); - const { syscall, finish } = prepare(vatID, { notifyTermination }); + const { syscall, finish } = prepare(vatID, managerOptions); const imVP = enableInternalMetering ? internalMeteringVP : {}; const vatPowers = harden({ ...baseVP, @@ -155,7 +157,9 @@ export function makeLocalVatManagerFactory(tools) { const helpers = harden({}); // DEPRECATED, todo remove from setup() dispatch = setup(syscall, state, helpers, vatPowers); } - return finish(dispatch, meterRecord); + + const manager = finish(dispatch, meterRecord); + return manager; } const localVatManagerFactory = harden({ diff --git a/packages/SwingSet/test/test-kernel.js b/packages/SwingSet/test/test-kernel.js index 5c0a362b6827..ad12c4c99dfb 100644 --- a/packages/SwingSet/test/test-kernel.js +++ b/packages/SwingSet/test/test-kernel.js @@ -2,6 +2,7 @@ import '@agoric/install-ses'; import { test } from 'tape-promise/tape'; +import anylogger from 'anylogger'; import { initSwingStore } from '@agoric/swing-store-simple'; import { waitUntilQuiescent } from '../src/waitUntilQuiescent'; @@ -34,16 +35,26 @@ function emptySetup(_syscall) { return { deliver }; } +function makeConsole(tag) { + const log = anylogger(tag); + const cons = {}; + for (const level of ['debug', 'log', 'info', 'warn', 'error']) { + cons[level] = log[level]; + } + return harden(cons); +} + function makeEndowments() { return { waitUntilQuiescent, hostStorage: initSwingStore().storage, runEndOfCrank: () => {}, + makeConsole, }; } test('build kernel', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); await kernel.start(); // empty queue const data = kernel.dump(); t.deepEqual(data.vatTables, []); @@ -52,7 +63,7 @@ test('build kernel', async t => { }); test('simple call', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; function setup1(syscall, state, _helpers, vatPowers) { function deliver(facetID, method, args) { @@ -98,7 +109,7 @@ test('simple call', async t => { }); test('map inbound', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; function setup1(_syscall) { function deliver(facetID, method, args) { @@ -148,7 +159,7 @@ test('map inbound', async t => { }); test('addImport', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); function setup(_syscall) { function deliver(_facetID, _method, _args) {} return { deliver }; @@ -169,7 +180,7 @@ test('addImport', async t => { }); test('outbound call', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let v1tovat25; const p7 = 'p+7'; @@ -368,7 +379,7 @@ test('outbound call', async t => { }); test('three-party', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let bobForA; let carolForA; @@ -499,7 +510,7 @@ test('three-party', async t => { }); test('transfer promise', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); let syscallA; const logA = []; function setupA(syscall) { @@ -603,7 +614,7 @@ test('transfer promise', async t => { }); test('subscribe to promise', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); let syscall; const log = []; function setup(s) { @@ -646,7 +657,7 @@ test('subscribe to promise', async t => { }); test('promise resolveToData', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let syscallA; @@ -723,7 +734,7 @@ test('promise resolveToData', async t => { }); test('promise resolveToPresence', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let syscallA; @@ -803,7 +814,7 @@ test('promise resolveToPresence', async t => { }); test('promise reject', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let syscallA; @@ -881,7 +892,7 @@ test('promise reject', async t => { test('transcript', async t => { const aliceForAlice = 'o+1'; - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); function setup(syscall, _state) { function deliver(facetID, _method, args) { if (facetID === aliceForAlice) { @@ -937,7 +948,7 @@ test('transcript', async t => { // have a decider. Make sure p3 gets queued in p2 rather than exploding. test('non-pipelined promise queueing', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let syscall; @@ -1054,7 +1065,7 @@ test('non-pipelined promise queueing', async t => { // get delivered to vat-with-x. test('pipelined promise queueing', async t => { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); const log = []; let syscall; diff --git a/packages/SwingSet/test/test-vpid-kernel.js b/packages/SwingSet/test/test-vpid-kernel.js index c3ef37f7a72a..5153d69f3026 100644 --- a/packages/SwingSet/test/test-vpid-kernel.js +++ b/packages/SwingSet/test/test-vpid-kernel.js @@ -3,6 +3,7 @@ import '@agoric/install-ses'; import { test } from 'tape-promise/tape'; +import anylogger from 'anylogger'; import { initSwingStore } from '@agoric/swing-store-simple'; import { waitUntilQuiescent } from '../src/waitUntilQuiescent'; @@ -20,11 +21,21 @@ function capargs(args, slots = []) { return capdata(JSON.stringify(args), slots); } +function makeConsole(tag) { + const log = anylogger(tag); + const cons = {}; + for (const level of ['debug', 'log', 'info', 'warn', 'error']) { + cons[level] = log[level]; + } + return harden(cons); +} + function makeEndowments() { return { waitUntilQuiescent, hostStorage: initSwingStore().storage, runEndOfCrank: () => {}, + makeConsole, }; } @@ -189,7 +200,7 @@ function inCList(kernel, vatID, kpid, vpid) { } async function doTest123(t, which, mode) { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); // vatA is our primary actor const { log: logA, getSyscall: getSyscallA } = buildRawVat('vatA', kernel); // we use vatB when necessary to send messages to vatA @@ -358,7 +369,7 @@ for (const caseNum of [1, 2, 3]) { } async function doTest4567(t, which, mode) { - const kernel = buildKernel(makeEndowments()); + const kernel = buildKernel(makeEndowments(), { disableSlog: true }); // vatA is our primary actor let onDispatchCallback; function odc(d) {