Commit 38931822 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '31162-update-parser' into 'master'

Updates job log parser

See merge request gitlab-org/gitlab!17586
parents 67cd4763 b2b102bf
...@@ -23,6 +23,46 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({ ...@@ -23,6 +23,46 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({
lines: [], lines: [],
}); });
/**
* Finds the matching header section
* for the section_duration object and adds it to it
*
* {
* isHeader: true,
* line: {
* content: [],
* lineNumber: 0,
* section_duration: "",
* },
* lines: []
* }
*
* @param Array data
* @param Object durationLine
*/
export function addDurationToHeader(data, durationLine) {
data.forEach(el => {
if (el.line && el.line.section === durationLine.section) {
el.line.section_duration = durationLine.section_duration;
}
});
}
/**
* Check is the current section belongs to a collapsible section
*
* @param Array acc
* @param Object last
* @param Object section
*
* @returns Boolean
*/
export const isCollapsibleSection = (acc = [], last = {}, section = {}) =>
acc.length > 0 &&
last.isHeader === true &&
!section.section_duration &&
section.section === last.line.section;
/** /**
* Parses the job log content into a structure usable by the template * Parses the job log content into a structure usable by the template
* *
...@@ -32,28 +72,35 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({ ...@@ -32,28 +72,35 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({
* - adds a isHeader property to handle template logic * - adds a isHeader property to handle template logic
* - adds the section_duration * - adds the section_duration
* For each line: * For each line:
* - adds the index as lineNumber * - adds the index as lineNumber
* *
* @param {Array} lines * @param Array lines
* @returns {Array} * @param Number lineNumberStart
* @param Array accumulator
* @returns Array parsed log lines
*/ */
export const logLinesParser = (lines = [], lineNumberStart) => export const logLinesParser = (lines = [], lineNumberStart, accumulator = []) =>
lines.reduce((acc, line, index) => { lines.reduce((acc, line, index) => {
const lineNumber = lineNumberStart ? lineNumberStart + index : index; const lineNumber = lineNumberStart ? lineNumberStart + index : index;
const last = acc[acc.length - 1]; const last = acc[acc.length - 1];
// If the object is an header, we parse it into another structure
if (line.section_header) { if (line.section_header) {
acc.push(parseHeaderLine(line, lineNumber)); acc.push(parseHeaderLine(line, lineNumber));
} else if (acc.length && last.isHeader && !line.section_duration && line.content.length) { } else if (isCollapsibleSection(acc, last, line)) {
// if the object belongs to a nested section, we append it to the new `lines` array of the
// previously formated header
last.lines.push(parseLine(line, lineNumber)); last.lines.push(parseLine(line, lineNumber));
} else if (acc.length && last.isHeader && line.section_duration) { } else if (line.section_duration) {
last.section_duration = line.section_duration; // if the line has section_duration, we look for the correct header to add it
} else if (line.content.length) { addDurationToHeader(acc, line);
} else {
// otherwise it's a regular line
acc.push(parseLine(line, lineNumber)); acc.push(parseLine(line, lineNumber));
} }
return acc; return acc;
}, []); }, accumulator);
/** /**
* Finds the repeated offset, removes the old one * Finds the repeated offset, removes the old one
......
...@@ -3,6 +3,8 @@ import { ...@@ -3,6 +3,8 @@ import {
updateIncrementalTrace, updateIncrementalTrace,
parseHeaderLine, parseHeaderLine,
parseLine, parseLine,
addDurationToHeader,
isCollapsibleSection,
findOffsetAndRemove, findOffsetAndRemove,
} from '~/jobs/store/utils'; } from '~/jobs/store/utils';
import { import {
...@@ -43,6 +45,127 @@ describe('Jobs Store Utils', () => { ...@@ -43,6 +45,127 @@ describe('Jobs Store Utils', () => {
}); });
}); });
describe('addDurationToHeader', () => {
const duration = {
offset: 106,
content: [],
section: 'prepare-script',
section_duration: '00:03',
};
it('adds the section duration to the correct header', () => {
const parsed = [
{
isClosed: true,
isHeader: true,
line: {
section: 'prepare-script',
content: [{ text: 'foo' }],
},
lines: [],
},
{
isClosed: true,
isHeader: true,
line: {
section: 'foo-bar',
content: [{ text: 'foo' }],
},
lines: [],
},
];
addDurationToHeader(parsed, duration);
expect(parsed[0].line.section_duration).toEqual(duration.section_duration);
expect(parsed[1].line.section_duration).toEqual(undefined);
});
it('does not add the section duration when the headers do not match', () => {
const parsed = [
{
isClosed: true,
isHeader: true,
line: {
section: 'bar-foo',
content: [{ text: 'foo' }],
},
lines: [],
},
{
isClosed: true,
isHeader: true,
line: {
section: 'foo-bar',
content: [{ text: 'foo' }],
},
lines: [],
},
];
addDurationToHeader(parsed, duration);
expect(parsed[0].line.section_duration).toEqual(undefined);
expect(parsed[1].line.section_duration).toEqual(undefined);
});
it('does not add when content has no headers', () => {
const parsed = [
{
section: 'bar-foo',
content: [{ text: 'foo' }],
lineNumber: 1,
},
{
section: 'foo-bar',
content: [{ text: 'foo' }],
lineNumber: 2,
},
];
addDurationToHeader(parsed, duration);
expect(parsed[0].line).toEqual(undefined);
expect(parsed[1].line).toEqual(undefined);
});
});
describe('isCollapsibleSection', () => {
const header = {
isHeader: true,
line: {
section: 'foo',
},
};
const line = {
lineNumber: 1,
section: 'foo',
content: [],
};
it('returns true when line belongs to the last section', () => {
expect(isCollapsibleSection([header], header, { section: 'foo', content: [] })).toEqual(true);
});
it('returns false when last line was not an header', () => {
expect(isCollapsibleSection([line], line, { section: 'bar' })).toEqual(false);
});
it('returns false when accumulator is empty', () => {
expect(isCollapsibleSection([], { isHeader: true }, { section: 'bar' })).toEqual(false);
});
it('returns false when section_duration is defined', () => {
expect(isCollapsibleSection([header], header, { section_duration: '10:00' })).toEqual(false);
});
it('returns false when `section` is not a match', () => {
expect(isCollapsibleSection([header], header, { section: 'bar' })).toEqual(false);
});
it('returns false when no parameters are provided', () => {
expect(isCollapsibleSection()).toEqual(false);
});
});
describe('logLinesParser', () => { describe('logLinesParser', () => {
let result; let result;
...@@ -75,7 +198,7 @@ describe('Jobs Store Utils', () => { ...@@ -75,7 +198,7 @@ describe('Jobs Store Utils', () => {
describe('section duration', () => { describe('section duration', () => {
it('adds the section information to the header section', () => { it('adds the section information to the header section', () => {
expect(result[1].section_duration).toEqual(utilsMockData[4].section_duration); expect(result[1].line.section_duration).toEqual(utilsMockData[4].section_duration);
}); });
it('does not add section duration as a line', () => { it('does not add section duration as a line', () => {
......
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