mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-02 18:11:04 +08:00
Add tests for ServerTiming.createFromHeaderValue
This patch imports the tests from chromium/src/third_party/blink/web_tests/http/tests/devtools/network/server-timing.js and adds a few additional ones. Bug: 1032561 Change-Id: I8a8c5c3079a926fa4c664fa790560b05b4643da7 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/1998772 Commit-Queue: Mathias Bynens <mathias@chromium.org> Reviewed-by: Paul Lewis <aerotwist@chromium.org> Auto-Submit: Mathias Bynens <mathias@chromium.org>
This commit is contained in:
committed by
Commit Bot
parent
326caf16c1
commit
786589f59e
@@ -133,18 +133,18 @@ export default class ServerTiming {
|
||||
if (parseParameter) {
|
||||
// paramName is valid
|
||||
if (entry.hasOwnProperty(paramName)) {
|
||||
this.showWarning(ls`Duplicate parameter \"${paramName}\" ignored.`);
|
||||
this.showWarning(ls`Duplicate parameter "${paramName}" ignored.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (paramValue === null) {
|
||||
this.showWarning(ls`No value found for parameter \"${paramName}\".`);
|
||||
this.showWarning(ls`No value found for parameter "${paramName}".`);
|
||||
}
|
||||
|
||||
parseParameter.call(this, entry, paramValue);
|
||||
} else {
|
||||
// paramName is not valid
|
||||
this.showWarning(ls`Unrecognized parameter \"${paramName}\".`);
|
||||
this.showWarning(ls`Unrecognized parameter "${paramName}".`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ export default class ServerTiming {
|
||||
if (paramValue !== null) {
|
||||
const duration = parseFloat(paramValue);
|
||||
if (isNaN(duration)) {
|
||||
this.showWarning(ls`Unable to parse \"${paramName}\" value \"${paramValue}\".`);
|
||||
this.showWarning(ls`Unable to parse "${paramName}" value "${paramValue}".`);
|
||||
return;
|
||||
}
|
||||
entry.dur = duration;
|
||||
|
||||
@@ -9,10 +9,281 @@ import {default as ServerTiming} from '/front_end/sdk/ServerTiming.js';
|
||||
describe('ServerTiming', () => {
|
||||
it('can be instantiated correctly', () => {
|
||||
const serverTiming = new ServerTiming('example metric', 1, 'example description');
|
||||
assert.equal(serverTiming.metric, 'example metric','metric was not set correctly');
|
||||
assert.equal(serverTiming.value, 1,'value was not set correctly');
|
||||
assert.equal(serverTiming.description, 'example description','description was not set correctly');
|
||||
assert.equal(serverTiming.metric, 'example metric', 'metric was not set correctly');
|
||||
assert.equal(serverTiming.value, 1, 'value was not set correctly');
|
||||
assert.equal(serverTiming.description, 'example description', 'description was not set correctly');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ServerTiming.createFromHeaderValue', () => {
|
||||
it('parses headers correctly', () => {
|
||||
// A real-world-like example with some edge cases.
|
||||
const actual = ServerTiming.createFromHeaderValue('lb; desc = "Load bala\\ncer" ; dur= 42,sql-1 ;desc="MySQL lookup server";dur=100,sql-2;dur ="900.1";desc="MySQL shard server #1",fs;\tdur=600;desc="FileSystem",\tcache;dur=300;desc="",other;dur=200;desc="Database write",other;dur=110;desc="Database read",cpu;dur=1230;desc="Total CPU"');
|
||||
const expected = [
|
||||
{
|
||||
name: 'lb',
|
||||
desc: 'Load balancer',
|
||||
dur: 42,
|
||||
},
|
||||
{
|
||||
name: 'sql-1',
|
||||
desc: 'MySQL lookup server',
|
||||
dur: 100,
|
||||
},
|
||||
{
|
||||
name: 'sql-2',
|
||||
dur: 900.1,
|
||||
desc: 'MySQL shard server #1',
|
||||
},
|
||||
{
|
||||
name: 'fs',
|
||||
dur: 600,
|
||||
desc: 'FileSystem',
|
||||
},
|
||||
{
|
||||
name: 'cache',
|
||||
dur: 300,
|
||||
desc: '',
|
||||
},
|
||||
{
|
||||
name: 'other',
|
||||
dur: 200,
|
||||
desc: 'Database write',
|
||||
},
|
||||
{
|
||||
name: 'other',
|
||||
dur: 110,
|
||||
desc: 'Database read',
|
||||
},
|
||||
{
|
||||
name: 'cpu',
|
||||
dur: 1230,
|
||||
desc: 'Total CPU',
|
||||
},
|
||||
];
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
// TODO continue writing tests here or use another describe block
|
||||
it('parses Server Timing metric names correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric'), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue("aB3!#$%&'*+-.^_`|~"), [{ name: "aB3!#$%&'*+-.^_`|~" }]);
|
||||
});
|
||||
|
||||
it('parses Server Timing metric durations correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur=123.4'), [{ name: 'metric', dur: 123.4 }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur="123.4"'), [{ name: 'metric', dur: 123.4 }]);
|
||||
});
|
||||
|
||||
it('parses Server Timing metric descriptions correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=description'), [
|
||||
{ name: 'metric', desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="description"'), [
|
||||
{ name: 'metric', desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur=123.4;desc=description'), [
|
||||
{ name: 'metric', dur: 123.4, desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=description;dur=123.4'), [
|
||||
{ name: 'metric', desc: 'description', dur: 123.4 }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles spaces in Server Timing headers correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric ; '), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric , '), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric ; dur = 123.4 ; desc = description'), [
|
||||
{ name: 'metric', dur: 123.4, desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric ; desc = description ; dur = 123.4'), [
|
||||
{ name: 'metric', desc: 'description', dur: 123.4 }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc = "description"'), [
|
||||
{ name: 'metric', desc: 'description' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles tabs in Server Timing headers correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric\t;\t'), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric\t,\t'), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric\t;\tdur\t=\t123.4\t;\tdesc\t=\tdescription'), [
|
||||
{ name: 'metric', dur: 123.4, desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric\t;\tdesc\t=\tdescription\t;\tdur\t=\t123.4'), [
|
||||
{ name: 'metric', desc: 'description', dur: 123.4 }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc\t=\t"description"'), [
|
||||
{ name: 'metric', desc: 'description' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles Server Timing headers with multiple entries correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric1;dur=12.3;desc=description1,metric2;dur=45.6;desc=description2,metric3;dur=78.9;desc=description3'),
|
||||
[
|
||||
{ name: 'metric1', dur: 12.3, desc: 'description1' },
|
||||
{ name: 'metric2', dur: 45.6, desc: 'description2' },
|
||||
{ name: 'metric3', dur: 78.9, desc: 'description3' },
|
||||
]
|
||||
);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric1,metric2 ,metric3, metric4 , metric5'), [
|
||||
{ name: 'metric1' },
|
||||
{ name: 'metric2' },
|
||||
{ name: 'metric3' },
|
||||
{ name: 'metric4' },
|
||||
{ name: 'metric5' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles RFC7230 quoted-string Server Timing values correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="description"'), [
|
||||
{ name: 'metric', desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\t description \t"'), [
|
||||
{ name: 'metric', desc: '\t description \t' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="descr\\"iption"'), [
|
||||
{ name: 'metric', desc: 'descr"iption' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=""'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\"\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\""'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=""\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="""'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\"\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\\\""'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\"\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\"\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\""\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=\\"""'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\\\"'), [{ name: 'metric', desc: '\\' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\"\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="\\""'), [{ name: 'metric', desc: '"' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=""\\\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=""\\"'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="""\\'), [{ name: 'metric', desc: '' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=""""'), [{ name: 'metric', desc: '' }]);
|
||||
});
|
||||
|
||||
it('handles case-sensitivity correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;DuR=123.4;DeSc=description'), [
|
||||
{ name: 'metric', dur: 123.4, desc: 'description' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles duplicate entry names correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur=12.3;desc=description1,metric;dur=45.6;desc=description2'),
|
||||
[
|
||||
{ name: 'metric', dur: 12.3, desc: 'description1' },
|
||||
{ name: 'metric', dur: 45.6, desc: 'description2' }
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it('handles non-numeric durations correctly', () => {
|
||||
// Non-numeric durations.
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur=foo'), [{ name: 'metric', dur: 0 }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur="foo"'), [{ name: 'metric', dur: 0 }]);
|
||||
});
|
||||
|
||||
it('handles incomplete parameters correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur;dur=123.4;desc=description'), [
|
||||
{ name: 'metric', dur: 0, desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur=;dur=123.4;desc=description'), [
|
||||
{ name: 'metric', dur: 0, desc: 'description' }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc;desc=description;dur=123.4'), [
|
||||
{ name: 'metric', desc: '', dur: 123.4 }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=;desc=description;dur=123.4'), [
|
||||
{ name: 'metric', desc: '', dur: 123.4 }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles extraneous characters after parameter values correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc=d1 d2;dur=123.4'), [
|
||||
{ name: 'metric', desc: 'd1', dur: 123.4 }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric1;desc=d1 d2,metric2'), [
|
||||
{ name: 'metric1', desc: 'd1' },
|
||||
{ name: 'metric2' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles extraneous characters after RFC7230 quoted-string parameter values correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;desc="d1" d2;dur=123.4'), [
|
||||
{ name: 'metric', desc: 'd1', dur: 123.4 }
|
||||
]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric1;desc="d1" d2,metric2'), [
|
||||
{ name: 'metric1', desc: 'd1' },
|
||||
{ name: 'metric2' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles extraneous characters after entry name token correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric== ""foo;dur=123.4'), [{ name: 'metric' }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric1== ""foo,metric2'), [{ name: 'metric1' }]);
|
||||
});
|
||||
|
||||
it('handles extraneous characters after parameter name token correctly', () => {
|
||||
// Note: also see the tests below that checks for warnings.
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;dur foo=12'), [{ name: 'metric', dur: 0 }]);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('metric;foo dur=12'), [{ name: 'metric' }]);
|
||||
});
|
||||
|
||||
it('handles bad input resulting in zero entries correctly', () => {
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(' '), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('='), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(';'), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(','), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('=;'), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(';='), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue('=,'), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(',='), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(';,'), []);
|
||||
assert.deepEqual(ServerTiming.createFromHeaderValue(',;'), []);
|
||||
});
|
||||
|
||||
it('triggers warnings when needed', () => {
|
||||
// TODO: These tests require mocking `Common.console.warn`.
|
||||
// For now, we override `ServerTiming.showWarning` to throw an
|
||||
// exception instead of logging it.
|
||||
ServerTiming.showWarning = (message) => {
|
||||
throw new Error(message);
|
||||
};
|
||||
|
||||
assert.throws(() => {
|
||||
ServerTiming.createFromHeaderValue('lb=42; "Load balancer"');
|
||||
}, /Deprecated syntax found/, 'legacy header syntax should trigger a warning');
|
||||
assert.throws(() => {
|
||||
ServerTiming.createFromHeaderValue('sql;desc="MySQL";dur=100;dur=200');
|
||||
}, /Duplicate parameter/, 'duplicate parameters should trigger a warning');
|
||||
assert.throws(() => {
|
||||
ServerTiming.createFromHeaderValue('sql;desc;dur=100');
|
||||
}, /No value found for parameter/, 'parameters without a value should trigger a warning');
|
||||
assert.throws(() => {
|
||||
ServerTiming.createFromHeaderValue('sql;desc="MySQL";dur=abc');
|
||||
}, /Unable to parse/, 'duration values that cannot be converted to floats should trigger a warning');
|
||||
assert.throws(() => {
|
||||
ServerTiming.createFromHeaderValue('sql;desc="MySQL";dur=100;invalid=lol');
|
||||
}, /Unrecognized parameter/, 'invalid parameters should trigger a warning');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user