Commit 8ca5afdf authored by Filipa Lacerda's avatar Filipa Lacerda Committed by Jacob Schatz

FE: Resolve "Performance issues when processing large build traces with Ansi2html"

parent 9216f59a
This diff is collapsed.
...@@ -57,6 +57,37 @@ ...@@ -57,6 +57,37 @@
margin-right: 5px; margin-right: 5px;
} }
} }
.truncated-info {
text-align: center;
border-bottom: 1px solid;
background-color: $black-transparent;
height: 45px;
&.affix {
top: 0;
}
// with sidebar
&.affix.sidebar-expanded {
right: 312px;
left: 22px;
}
// without sidebar
&.affix.sidebar-collapsed {
right: 20px;
left: 20px;
}
&.affix-top {
position: absolute;
top: 0;
margin: 0 auto;
right: 5px;
left: 5px;
}
}
} }
.scroll-controls { .scroll-controls {
...@@ -186,6 +217,7 @@ ...@@ -186,6 +217,7 @@
white-space: pre; white-space: pre;
overflow-x: auto; overflow-x: auto;
font-size: 12px; font-size: 12px;
position: relative;
.fa-refresh { .fa-refresh {
font-size: 24px; font-size: 24px;
......
...@@ -71,6 +71,11 @@ ...@@ -71,6 +71,11 @@
= custom_icon('scroll_down_hover_active') = custom_icon('scroll_down_hover_active')
#up-build-trace #up-build-trace
%pre.build-trace#build-trace %pre.build-trace#build-trace
.js-truncated-info.truncated-info.hidden
%span<
Showing last
%span.js-truncated-info-size><
KiB of log
%code.bash.js-build-output %code.bash.js-build-output
.build-loader-animation.js-build-refresh .build-loader-animation.js-build-refresh
......
...@@ -64,58 +64,33 @@ describe('Build', () => { ...@@ -64,58 +64,33 @@ describe('Build', () => {
}); });
}); });
describe('initial build trace', () => {
beforeEach(() => {
new Build();
});
it('displays the initial build trace', () => {
expect($.ajax.calls.count()).toBe(1);
const [{ url, dataType, success, context }] = $.ajax.calls.argsFor(0);
expect(url).toBe(
`${BUILD_URL}/trace.json`,
);
expect(dataType).toBe('json');
expect(success).toEqual(jasmine.any(Function));
spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
success.call(context, { html: '<span>Example</span>', status: 'running' });
expect($('#build-trace .js-build-output').text()).toMatch(/Example/);
});
it('removes the spinner', () => {
const [{ success, context }] = $.ajax.calls.argsFor(0);
spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
success.call(context, { trace_html: '<span>Example</span>', status: 'success' });
expect($('.js-build-refresh').length).toBe(0);
});
});
describe('running build', () => { describe('running build', () => {
beforeEach(function () { beforeEach(function () {
$('.js-build-options').data('buildStatus', 'running');
this.build = new Build(); this.build = new Build();
spyOn(this.build, 'location').and.returnValue(BUILD_URL);
}); });
it('updates the build trace on an interval', function () { it('updates the build trace on an interval', function () {
spyOn(gl.utils, 'visitUrl');
jasmine.clock().tick(4001); jasmine.clock().tick(4001);
expect($.ajax.calls.count()).toBe(2); expect($.ajax.calls.count()).toBe(1);
let [{ url, dataType, success, context }] = $.ajax.calls.argsFor(1);
expect(url).toBe( // We have to do it this way to prevent Webpack to fail to compile
`${BUILD_URL}/trace.json?state=`, // when destructuring assignments and reusing
); // the same variables names inside the same scope
expect(dataType).toBe('json'); let args = $.ajax.calls.argsFor(0)[0];
expect(success).toEqual(jasmine.any(Function));
expect(args.url).toBe(`${BUILD_URL}/trace.json`);
success.call(context, { expect(args.dataType).toBe('json');
expect(args.success).toEqual(jasmine.any(Function));
args.success.call($, {
html: '<span>Update<span>', html: '<span>Update<span>',
status: 'running', status: 'running',
state: 'newstate', state: 'newstate',
append: true, append: true,
complete: false,
}); });
expect($('#build-trace .js-build-output').text()).toMatch(/Update/); expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
...@@ -123,17 +98,20 @@ describe('Build', () => { ...@@ -123,17 +98,20 @@ describe('Build', () => {
jasmine.clock().tick(4001); jasmine.clock().tick(4001);
expect($.ajax.calls.count()).toBe(3); expect($.ajax.calls.count()).toBe(2);
[{ url, dataType, success, context }] = $.ajax.calls.argsFor(2);
expect(url).toBe(`${BUILD_URL}/trace.json?state=newstate`); args = $.ajax.calls.argsFor(1)[0];
expect(dataType).toBe('json'); expect(args.url).toBe(`${BUILD_URL}/trace.json`);
expect(success).toEqual(jasmine.any(Function)); expect(args.dataType).toBe('json');
expect(args.data.state).toBe('newstate');
expect(args.success).toEqual(jasmine.any(Function));
success.call(context, { args.success.call($, {
html: '<span>More</span>', html: '<span>More</span>',
status: 'running', status: 'running',
state: 'finalstate', state: 'finalstate',
append: true, append: true,
complete: true,
}); });
expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/); expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
...@@ -141,19 +119,22 @@ describe('Build', () => { ...@@ -141,19 +119,22 @@ describe('Build', () => {
}); });
it('replaces the entire build trace', () => { it('replaces the entire build trace', () => {
spyOn(gl.utils, 'visitUrl');
jasmine.clock().tick(4001); jasmine.clock().tick(4001);
let [{ success, context }] = $.ajax.calls.argsFor(1); let args = $.ajax.calls.argsFor(0)[0];
success.call(context, { args.success.call($, {
html: '<span>Update</span>', html: '<span>Update</span>',
status: 'running', status: 'running',
append: true, append: false,
complete: false,
}); });
expect($('#build-trace .js-build-output').text()).toMatch(/Update/); expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
jasmine.clock().tick(4001); jasmine.clock().tick(4001);
[{ success, context }] = $.ajax.calls.argsFor(2); args = $.ajax.calls.argsFor(1)[0];
success.call(context, { args.success.call($, {
html: '<span>Different</span>', html: '<span>Different</span>',
status: 'running', status: 'running',
append: false, append: false,
...@@ -163,15 +144,34 @@ describe('Build', () => { ...@@ -163,15 +144,34 @@ describe('Build', () => {
expect($('#build-trace .js-build-output').text()).toMatch(/Different/); expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
}); });
it('shows information about truncated log', () => {
jasmine.clock().tick(4001);
const [{ success }] = $.ajax.calls.argsFor(0);
success.call($, {
html: '<span>Update</span>',
status: 'success',
append: false,
truncated: true,
size: '50',
});
expect(
$('#build-trace .js-truncated-info').text().trim(),
).toContain('Showing last 50 KiB of log');
expect($('#build-trace .js-truncated-info-size').text()).toMatch('50');
});
it('reloads the page when the build is done', () => { it('reloads the page when the build is done', () => {
spyOn(gl.utils, 'visitUrl'); spyOn(gl.utils, 'visitUrl');
jasmine.clock().tick(4001); jasmine.clock().tick(4001);
const [{ success, context }] = $.ajax.calls.argsFor(1); const [{ success }] = $.ajax.calls.argsFor(0);
success.call(context, { success.call($, {
html: '<span>Final</span>', html: '<span>Final</span>',
status: 'passed', status: 'passed',
append: true, append: true,
complete: true,
}); });
expect(gl.utils.visitUrl).toHaveBeenCalledWith(BUILD_URL); expect(gl.utils.visitUrl).toHaveBeenCalledWith(BUILD_URL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment