Web console: prevent the time parse view from going into a bad state (#7846)

* prevent the time parse view from going into a bad state

* add test
This commit is contained in:
Vadim Ogievetsky 2019-06-07 08:32:10 -07:00 committed by Fangjin Yang
parent ca5afd29b8
commit df01335789
4 changed files with 81 additions and 3 deletions

View File

@ -43,6 +43,14 @@ exports[`table cell matches snapshot null 1`] = `
</span>
`;
exports[`table cell matches snapshot null timestamp 1`] = `
<span
class="table-cell unparseable"
>
unparseable timestamp
</span>
`;
exports[`table cell matches snapshot simple 1`] = `Hello World`;
exports[`table cell matches snapshot truncate 1`] = `

View File

@ -33,6 +33,17 @@ describe('table cell', () => {
expect(container.firstChild).toMatchSnapshot();
});
it('matches snapshot null timestamp', () => {
const tableCell = <TableCell
value={null}
unparseable={false}
timestamp
/>;
const { container } = render(tableCell);
expect(container.firstChild).toMatchSnapshot();
});
it('matches snapshot simple', () => {
const tableCell = <TableCell
value="Hello World"

View File

@ -89,7 +89,11 @@ export class TableCell extends React.PureComponent<NullTableCellProps, {}> {
return TableCell.possiblyTruncate(String(value));
}
} else {
return <span className="table-cell null">null</span>;
if (timestamp) {
return <span className="table-cell unparseable">unparseable timestamp</span>;
} else {
return <span className="table-cell null">null</span>;
}
}
}
}

View File

@ -24,7 +24,7 @@ import {
DimensionsSpec,
getEmptyTimestampSpec, getSpecType,
IngestionSpec,
IoConfig, MetricSpec,
IoConfig, isColumnTimestampSpec, MetricSpec,
Parser,
ParseSpec,
Transform, TransformSpec
@ -209,7 +209,42 @@ export async function sampleForTimestamp(spec: IngestionSpec, sampleStrategy: Sa
const ioConfig: IoConfig = makeSamplerIoConfig(deepGet(spec, 'ioConfig'), samplerType, sampleStrategy);
const parser: Parser = deepGet(spec, 'dataSchema.parser') || {};
const parseSpec: ParseSpec = deepGet(spec, 'dataSchema.parser.parseSpec') || {};
const timestampSpec: ParseSpec = deepGet(spec, 'dataSchema.parser.parseSpec.timestampSpec') || getEmptyTimestampSpec();
const columnTimestampSpec = isColumnTimestampSpec(timestampSpec);
// First do a query with a static timestamp spec
const sampleSpecColumns: SampleSpec = {
type: samplerType,
spec: {
type: samplerType,
ioConfig: deepSet(ioConfig, 'type', samplerType),
dataSchema: {
dataSource: 'sample',
parser: {
type: parser.type,
parseSpec: (
parser.parseSpec ?
Object.assign({}, parseSpec, {
dimensionsSpec: {},
timestampSpec: columnTimestampSpec ? getEmptyTimestampSpec() : timestampSpec
}) :
undefined
) as any
}
}
},
samplerConfig: Object.assign({}, BASE_SAMPLER_CONFIG, {
cacheKey
})
};
const sampleColumns = await postToSampler(sampleSpecColumns, 'timestamp-columns');
// If we are not parsing a column then there is nothing left to do
if (!columnTimestampSpec) return sampleColumns;
// If we are trying to parts a column then get a bit fancy:
// Query the same sample again (same cache key)
const sampleSpec: SampleSpec = {
type: samplerType,
spec: {
@ -230,7 +265,27 @@ export async function sampleForTimestamp(spec: IngestionSpec, sampleStrategy: Sa
})
};
return postToSampler(sampleSpec, 'timestamp');
const sampleTime = await postToSampler(sampleSpec, 'timestamp-time');
if (
sampleTime.cacheKey !== sampleColumns.cacheKey ||
sampleTime.data.length !== sampleColumns.data.length
) {
// If the two responses did not come from the same cache (or for some reason have different lengths) then
// just return the one with the parsed time column.
return sampleTime;
}
const sampleTimeData = sampleTime.data;
return Object.assign({}, sampleColumns, {
data: sampleColumns.data.map((d, i) => {
// Merge the column sample with the time column sample
if (!d.parsed) return d;
const timeDatumParsed = sampleTimeData[i].parsed;
d.parsed.__time = timeDatumParsed ? timeDatumParsed.__time : null;
return d;
})
});
}
export async function sampleForTransform(spec: IngestionSpec, sampleStrategy: SampleStrategy, cacheKey: string | undefined): Promise<SampleResponse> {