[Inspector] Add tests for Runtime domain

New tests added for:
  * Runtime.getProperties while debugger is paused
  * Runtime.exceptionThrown
  * Runtime.releaseObject/releaseObjectGroup

Change-Id: I72b3455e9fb3269c097bf9a383187c119158a722
Reviewed-on: https://chromium-review.googlesource.com/c/1490172
Commit-Queue: Jeff Fisher <jeffish@microsoft.com>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59984}
This commit is contained in:
Jeff Fisher 2019-03-01 11:26:26 -08:00 committed by Commit Bot
parent cc5808cd9f
commit 368f55bb63
6 changed files with 505 additions and 0 deletions

View File

@ -0,0 +1,89 @@
Checks Runtime.getProperties method while debugger is paused.
Running test: testObject5
__proto__ own object undefined
foo own string cat
Internal properties
[[PrimitiveValue]] number 5
Running test: testNotOwn
__defineGetter__ inherited function undefined
__defineSetter__ inherited function undefined
__lookupGetter__ inherited function undefined
__lookupSetter__ inherited function undefined
__proto__ inherited no value, getter, setter
a own number 2
b own no value, getter, setter
c inherited number 4
constructor inherited function undefined
d inherited no value, getter
hasOwnProperty inherited function undefined
isPrototypeOf inherited function undefined
propertyIsEnumerable inherited function undefined
toLocaleString inherited function undefined
toString inherited function undefined
valueOf inherited function undefined
Running test: testAccessorsOnly
b own no value, getter, setter
d own no value, setter
Running test: testArray
0 own string red
1 own string green
2 own string blue
__proto__ own object undefined
length own number 3
Running test: testBound
__proto__ own function undefined
length own number 0
name own string bound Number
Internal properties
[[BoundArgs]] object undefined
[[BoundThis]] object undefined
[[TargetFunction]] function undefined
Running test: testObjectThrowsLength
__proto__ own object undefined
length own no value, getter
Running test: testTypedArrayWithoutLength
__proto__ own object undefined
Running test: testArrayBuffer
[[Int8Array]]
0 own number 1
1 own number 1
2 own number 1
3 own number 1
4 own number 1
5 own number 1
6 own number 1
7 own number 1
__proto__ own object undefined
[[Uint8Array]]
0 own number 1
1 own number 1
2 own number 1
3 own number 1
4 own number 1
5 own number 1
6 own number 1
7 own number 1
__proto__ own object undefined
[[Int16Array]]
0 own number 257
1 own number 257
2 own number 257
3 own number 257
__proto__ own object undefined
[[Int32Array]]
0 own number 16843009
1 own number 16843009
__proto__ own object undefined
Running test: testArrayBufferWithBrokenUintCtor
[[Int8Array]] own object undefined
[[Uint8Array]] own object undefined
__proto__ own object undefined

View File

@ -0,0 +1,109 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let { Protocol } = InspectorTest.start('Checks Runtime.getProperties method while debugger is paused.');
(async function test() {
await Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: 'debugger;' });
const callFrameId = (await Protocol.Debugger.oncePaused()).params.callFrames[0].callFrameId;
InspectorTest.runAsyncTestSuite([
function testObject5() {
return logExpressionProperties(`(function(){var r = Object(5); r.foo = 'cat';return r;})()`);
},
function testNotOwn() {
return logExpressionProperties(`({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3, c: 4, get d() {return 6;} }})`, { ownProperties: false });
},
function testAccessorsOnly() {
return logExpressionProperties(`({ a: 2, set b(_) {}, get b() {return 5;}, c: 'c', set d(_){} })`, { ownProperties: true, accessorPropertiesOnly: true });
},
function testArray() {
return logExpressionProperties(`['red', 'green', 'blue']`);
},
function testBound() {
return logExpressionProperties('Number.bind({}, 5)');
},
function testObjectThrowsLength() {
return logExpressionProperties(`({get length() { throw 'Length called'; }})`);
},
function testTypedArrayWithoutLength() {
return logExpressionProperties('({__proto__: Uint8Array.prototype})');
},
async function testArrayBuffer() {
let objectId = await evaluateToObjectId('new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1]).buffer');
let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
for (let prop of props.result.result) {
if (prop.name === '__proto__')
continue;
InspectorTest.log(prop.name);
await logGetPropertiesResult(prop.value.objectId);
}
},
async function testArrayBufferWithBrokenUintCtor() {
await evaluateToObjectId(`(function() {
this.uint8array_old = this.Uint8Array;
this.Uint8Array = 42;
})()`);
await logExpressionProperties('new Int8Array([1, 1, 1, 1, 1, 1, 1]).buffer');
await evaluateToObjectId(`(function() {
this.Uint8Array = this.uint8array_old;
delete this.uint8array_old;
})()`);
}
]);
async function logExpressionProperties(expression, flags) {
const objectId = await evaluateToObjectId(expression);
return await logGetPropertiesResult(objectId, flags);
}
async function evaluateToObjectId(expression) {
return (await Protocol.Debugger.evaluateOnCallFrame({ expression, callFrameId })).result.result.objectId;
}
async function logGetPropertiesResult(objectId, flags = { ownProperties: true }) {
function hasGetterSetter(property, fieldName) {
var v = property[fieldName];
if (!v) return false;
return v.type !== "undefined"
}
flags.objectId = objectId;
let props = await Protocol.Runtime.getProperties(flags);
var propertyArray = props.result.result;
propertyArray.sort(NamedThingComparator);
for (var i = 0; i < propertyArray.length; i++) {
var p = propertyArray[i];
var v = p.value;
var own = p.isOwn ? "own" : "inherited";
if (v)
InspectorTest.log(` ${p.name} ${own} ${v.type} ${v.value}`);
else
InspectorTest.log(` ${p.name} ${own} no value${(hasGetterSetter(p, "get") ? ", getter" : "")}${(hasGetterSetter(p, "set") ? ", setter" : "")}`);
}
var internalPropertyArray = props.result.internalProperties;
if (internalPropertyArray) {
InspectorTest.log('Internal properties');
internalPropertyArray.sort(NamedThingComparator);
for (var i = 0; i < internalPropertyArray.length; i++) {
var p = internalPropertyArray[i];
var v = p.value;
InspectorTest.log(` ${p.name} ${v.type} ${v.value}`);
}
}
function NamedThingComparator(o1, o2) {
return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1);
}
}
})();

View File

@ -0,0 +1,46 @@
Tests that Runtime throws exceptions after enabling domain on scripts with errors.
Enabling Runtime Domain.
{
method : Runtime.exceptionThrown
params : {
exceptionDetails : {
columnNumber : 12
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token ;
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
executionContextId : <executionContextId>
lineNumber : 1
scriptId : <scriptId>
text : Uncaught SyntaxError: Unexpected token ;
url : syntaxError.js
}
timestamp : <timestamp>
}
}
{
method : Runtime.exceptionThrown
params : {
exceptionDetails : {
columnNumber : 12
exception : {
className : ReferenceError
description : ReferenceError: y is not defined at referenceError.js:2:13
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
executionContextId : <executionContextId>
lineNumber : 1
scriptId : <scriptId>
text : Uncaught ReferenceError: y is not defined
url : referenceError.js
}
timestamp : <timestamp>
}
}

View File

@ -0,0 +1,25 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {Protocol, contextGroup} = InspectorTest.start(
`Tests that Runtime throws exceptions after enabling domain on scripts with errors.`);
(async function test(){
// Log all exceptions thrown
Protocol.Runtime.onExceptionThrown(exception => {
InspectorTest.logMessage(exception);
});
// Add scripts with syntax and reference errors
contextGroup.addScript(
`
var x = ;
//# sourceURL=syntaxError.js`);
contextGroup.addScript(
`
var x = y;
//# sourceURL=referenceError.js`);
InspectorTest.log('Enabling Runtime Domain.');
await Protocol.Runtime.enable();
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,157 @@
Tests that Runtime can properly release objects and object groups.
Running test: testReleaseObject
Evaluating 'var a = {x:3};'
Evaluating 'var b = {x:4};'
Evaluate 'this' for object a
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Evaluate 'this' for object b
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Release "a"
Evaluate 'this' for object a
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Evaluate 'this' for object b
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Release "b"
Evaluate 'this' for object a
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Evaluate 'this' for object b
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Running test: testReleaseObjectInvalid
ReleaseObject with invalid params.
{
error : {
code : -32602
data : objectId: string value expected
message : Invalid parameters
}
id : <messageId>
}
Running test: testObjectGroups
Evaluating 'var a = {x:3};'
Evaluating 'var b = {x:4};'
Evaluate "a" in objectGroup "x"
Evaluate "b" in objectGroup "y"
Evaluate 'this' for object a
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Evaluate 'this' for object b
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Release objectGroup "x"
Evaluate 'this' for object a
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Evaluate 'this' for object b
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Release objectGroup "y"
Evaluate 'this' for object a
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Evaluate 'this' for object b
{
error : {
code : -32000
message : Could not find object with given id
}
id : <messageId>
}
Running test: testReleaseObjectGroupInvalid
ReleaseObjectGroup with invalid params
{
error : {
code : -32602
data : objectGroup: string value expected
message : Invalid parameters
}
id : <messageId>
}

View File

@ -0,0 +1,79 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {Protocol} = InspectorTest.start(
`Tests that Runtime can properly release objects and object groups.`);
(async function test(){
await Protocol.Runtime.enable();
InspectorTest.runAsyncTestSuite([
async function testReleaseObject() {
await logAndEvaluate('var a = {x:3};');
await logAndEvaluate('var b = {x:4};');
const ids = [];
let result = await Protocol.Runtime.evaluate({ expression: 'a' });
const id1 = result.result.result.objectId;
ids.push({id: id1, name: 'a'});
result = await Protocol.Runtime.evaluate({ expression: 'b' });
const id2 = result.result.result.objectId;
ids.push({id: id2, name: 'b'});
// Call Function on both objects and log:
await objectGroupHelper(ids);
InspectorTest.log('Release "a"');
Protocol.Runtime.releaseObject({ objectId: id1 });
await objectGroupHelper(ids);
InspectorTest.log('Release "b"');
Protocol.Runtime.releaseObject({ objectId: id2 });
await objectGroupHelper(ids);
},
async function testReleaseObjectInvalid() {
const releaseObjectResult = await Protocol.Runtime.releaseObject({});
InspectorTest.log('ReleaseObject with invalid params.');
InspectorTest.logMessage(releaseObjectResult);
},
async function testObjectGroups() {
await logAndEvaluate('var a = {x:3};');
await logAndEvaluate('var b = {x:4};');
const ids = [];
InspectorTest.log('Evaluate "a" in objectGroup "x"');
let result = await Protocol.Runtime.evaluate({ expression: 'a', objectGroup: 'x' });
const id1 = result.result.result.objectId;
ids.push({id: id1, name: 'a'});
InspectorTest.log('Evaluate "b" in objectGroup "y"');
result = await Protocol.Runtime.evaluate({ expression: 'b', objectGroup: 'y' });
const id2 = result.result.result.objectId;
ids.push({id: id2, name: 'b'});
// Call Function on both objects and log:
await objectGroupHelper(ids);
InspectorTest.log('Release objectGroup "x"');
Protocol.Runtime.releaseObjectGroup({ objectGroup: 'x' });
await objectGroupHelper(ids);
InspectorTest.log('Release objectGroup "y"');
Protocol.Runtime.releaseObjectGroup({ objectGroup: 'y' });
await objectGroupHelper(ids);
},
async function testReleaseObjectGroupInvalid() {
const releaseObjectGroupResult = await Protocol.Runtime.releaseObjectGroup({});
InspectorTest.log('ReleaseObjectGroup with invalid params');
InspectorTest.logMessage(releaseObjectGroupResult);
}
]);
// Helper to log and evaluate an expression
async function logAndEvaluate(expression) {
InspectorTest.logMessage(`Evaluating '${expression}'`);
await Protocol.Runtime.evaluate({ expression });
}
// Helper function that calls a function on all objects with ids in objectIds, then returns
async function objectGroupHelper(objectIds) {
for (const {id , name } of objectIds) {
InspectorTest.log(`Evaluate 'this' for object ${name}`);
const result = await Protocol.Runtime.callFunctionOn({ objectId: id, functionDeclaration: 'function(){ return this;}' });
InspectorTest.logMessage(result);
}
}
})();