mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ftr] log every method call in services with --verbose (#28637)
* [ftr] log every method call in services with --verbose * print args, wrap async wrappers
This commit is contained in:
parent
579a738e98
commit
a82def12e3
3 changed files with 110 additions and 13 deletions
|
@ -17,18 +17,23 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
const createdInstanceProxies = new WeakSet();
|
||||
const INITIALIZING = Symbol('async instance initializing');
|
||||
const asyncInitFns = new WeakSet();
|
||||
|
||||
export const isAsyncInstance = val =>(
|
||||
createdInstanceProxies.has(val)
|
||||
export const isAsyncInstance = val => (
|
||||
val && asyncInitFns.has(val.init)
|
||||
);
|
||||
|
||||
export const createAsyncInstance = (type, name, promiseForValue) => {
|
||||
let instance = INITIALIZING;
|
||||
|
||||
const initPromise = promiseForValue.then(v => instance = v);
|
||||
const initFn = () => initPromise;
|
||||
const loadingTarget = {
|
||||
init() {
|
||||
return initPromise;
|
||||
}
|
||||
};
|
||||
asyncInitFns.add(loadingTarget.init);
|
||||
|
||||
const assertReady = desc => {
|
||||
if (instance === INITIALIZING) {
|
||||
|
@ -46,7 +51,7 @@ export const createAsyncInstance = (type, name, promiseForValue) => {
|
|||
}
|
||||
};
|
||||
|
||||
const proxy = new Proxy({}, {
|
||||
return new Proxy(loadingTarget, {
|
||||
apply(target, context, args) {
|
||||
assertReady(`${name}()`);
|
||||
return Reflect.apply(instance, context, args);
|
||||
|
@ -68,13 +73,19 @@ export const createAsyncInstance = (type, name, promiseForValue) => {
|
|||
},
|
||||
|
||||
get(target, prop, receiver) {
|
||||
if (prop === 'init') return initFn;
|
||||
if (loadingTarget.hasOwnProperty(prop)) {
|
||||
return Reflect.get(loadingTarget, prop, receiver);
|
||||
}
|
||||
|
||||
assertReady(`${name}.${prop}`);
|
||||
return Reflect.get(instance, prop, receiver);
|
||||
},
|
||||
|
||||
getOwnPropertyDescriptor(target, prop) {
|
||||
if (loadingTarget.hasOwnProperty(prop)) {
|
||||
return Reflect.getOwnPropertyDescriptor(loadingTarget, prop);
|
||||
}
|
||||
|
||||
assertReady(`${name}.${prop}`);
|
||||
return Reflect.getOwnPropertyDescriptor(instance, prop);
|
||||
},
|
||||
|
@ -85,7 +96,9 @@ export const createAsyncInstance = (type, name, promiseForValue) => {
|
|||
},
|
||||
|
||||
has(target, prop) {
|
||||
if (prop === 'init') return true;
|
||||
if (!loadingTarget.hasOwnProperty(prop)) {
|
||||
return Reflect.has(loadingTarget, prop);
|
||||
}
|
||||
|
||||
assertReady(`${name}.${prop}`);
|
||||
return Reflect.has(instance, prop);
|
||||
|
@ -116,10 +129,4 @@ export const createAsyncInstance = (type, name, promiseForValue) => {
|
|||
return Reflect.setPrototypeOf(instance, prototype);
|
||||
}
|
||||
});
|
||||
|
||||
// add the created provider to the WeakMap so we can
|
||||
// check for it later in `isAsyncProvider()`
|
||||
createdInstanceProxies.add(proxy);
|
||||
|
||||
return proxy;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import { loadTracer } from '../load_tracer';
|
||||
import { createAsyncInstance, isAsyncInstance } from './async_instance';
|
||||
import { createVerboseInstance } from './verbose_instance';
|
||||
|
||||
export class ProviderCollection {
|
||||
constructor(log, providers) {
|
||||
|
@ -104,6 +105,14 @@ export class ProviderCollection {
|
|||
instance = createAsyncInstance(type, name, instance);
|
||||
}
|
||||
|
||||
if (name !== '__leadfoot__' && name !== 'log' && name !== 'config' && instance && typeof instance === 'object') {
|
||||
instance = createVerboseInstance(
|
||||
this._log,
|
||||
type === 'PageObject' ? `PageObjects.${name}` : name,
|
||||
instance
|
||||
);
|
||||
}
|
||||
|
||||
instances.set(provider, instance);
|
||||
}
|
||||
|
||||
|
|
81
src/functional_test_runner/lib/providers/verbose_instance.js
Normal file
81
src/functional_test_runner/lib/providers/verbose_instance.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { inspect } from 'util';
|
||||
|
||||
function printArgs(args) {
|
||||
return args.map((arg) => {
|
||||
if (typeof arg === 'string' || typeof arg === 'number' || arg instanceof Date) {
|
||||
return inspect(arg);
|
||||
}
|
||||
|
||||
if (Array.isArray(arg)) {
|
||||
return `[${printArgs(arg)}]`;
|
||||
}
|
||||
|
||||
return Object.prototype.toString.call(arg);
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
export function createVerboseInstance(log, name, instance) {
|
||||
if (!log.getWriters().some(l => l.level.flags.verbose)) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
return new Proxy(instance, {
|
||||
get(_, prop) {
|
||||
const value = instance[prop];
|
||||
|
||||
if (typeof value !== 'function' || prop === 'init') {
|
||||
return value;
|
||||
}
|
||||
|
||||
return function (...args) {
|
||||
log.verbose(`${name}.${prop}(${printArgs(args)})`);
|
||||
log.indent(2);
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = {
|
||||
returned: value.apply(this, args)
|
||||
};
|
||||
} catch (error) {
|
||||
result = {
|
||||
thrown: error
|
||||
};
|
||||
}
|
||||
|
||||
if (result.hasOwnProperty('thrown')) {
|
||||
log.indent(-2);
|
||||
throw result.thrown;
|
||||
}
|
||||
|
||||
const { returned } = result;
|
||||
if (returned && typeof returned.then === 'function') {
|
||||
return returned.finally(() => {
|
||||
log.indent(-2);
|
||||
});
|
||||
}
|
||||
|
||||
log.indent(-2);
|
||||
return returned;
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue