Skip to content

Commit

Permalink
avoid day long gaps in sample data (elastic#20897) (elastic#21070)
Browse files Browse the repository at this point in the history
* avoid day long gaps in sample data

* avoid using toISOString to avoid an timezone problems

* unskip sample test now that problem is fixed

* use much better cj algorithm for translating time

* cjcenizal review updates

* update funtion name in install.js

* push source reference date back a week
  • Loading branch information
nreese authored Jul 23, 2018
1 parent 0a25360 commit 286843a
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/server/sample_data/data_sets/flights/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function flightsSpecProvider() {
}
},
timeFields: ['timestamp'],
currentTimeMarker: '2018-01-02T00:00:00',
currentTimeMarker: '2018-01-09T00:00:00',
preserveDayOfWeekTimeOfDay: true,
savedObjects: savedObjects,
};
Expand Down
13 changes: 9 additions & 4 deletions src/server/sample_data/routes/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import Joi from 'joi';

import { loadData } from './lib/load_data';
import { createIndexName } from './lib/create_index_name';
import { adjustTimestamp } from './lib/adjust_timestamp';
import {
dateToIso8601IgnoringTime,
translateTimeRelativeToDifference,
translateTimeRelativeToWeek
} from './lib/translate_timestamp';

export const createInstallRoute = () => ({
path: '/api/sample_data/{id}',
Expand Down Expand Up @@ -81,12 +85,13 @@ export const createInstallRoute = () => ({
return reply(errMsg).code(err.status);
}

const now = new Date();
const currentTimeMarker = new Date(Date.parse(sampleDataset.currentTimeMarker));
const nowReference = dateToIso8601IgnoringTime(new Date());
function updateTimestamps(doc) {
sampleDataset.timeFields.forEach(timeFieldName => {
if (doc[timeFieldName]) {
doc[timeFieldName] = adjustTimestamp(doc[timeFieldName], currentTimeMarker, now, sampleDataset.preserveDayOfWeekTimeOfDay);
doc[timeFieldName] = sampleDataset.preserveDayOfWeekTimeOfDay
? translateTimeRelativeToWeek(doc[timeFieldName], sampleDataset.currentTimeMarker, nowReference)
: translateTimeRelativeToDifference(doc[timeFieldName], sampleDataset.currentTimeMarker, nowReference);
}
});
return doc;
Expand Down
48 changes: 0 additions & 48 deletions src/server/sample_data/routes/lib/adjust_timestamp.js

This file was deleted.

73 changes: 0 additions & 73 deletions src/server/sample_data/routes/lib/adjust_timestamp.test.js

This file was deleted.

75 changes: 75 additions & 0 deletions src/server/sample_data/routes/lib/translate_timestamp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const MILLISECONDS_IN_DAY = 86400000;

function iso8601ToDateIgnoringTime(iso8601) {
const split = iso8601.split('-');
if (split.length < 3) {
throw new Error('Unexpected timestamp format, expecting YYYY-MM-DDTHH:mm:ss');
}
const year = parseInt(split[0]);
const month = parseInt(split[1]) - 1; // javascript months are zero-based indexed
const date = parseInt(split[2]);
return new Date(year, month, date);
}

export function dateToIso8601IgnoringTime(date) {
// not using "Date.toISOString" because only using Date methods that deal with local time
const year = date.getFullYear();
const month = date.getMonth() + 1;
const monthString = month < 10 ? `0${month}` : `${month}`;
const dateString = date.getDate() < 10 ? `0${date.getDate()}` : `${date.getDate()}`;
return `${year}-${monthString}-${dateString}`;
}

// Translate source timestamp by targetReference timestamp,
// perserving the distance between source and sourceReference
export function translateTimeRelativeToDifference(source, sourceReference, targetReference) {
const sourceDate = iso8601ToDateIgnoringTime(source);
const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference);
const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference);

const timeDelta = sourceDate.getTime() - sourceReferenceDate.getTime();
const translatedDate = (new Date(targetReferenceDate.getTime() + timeDelta));

return `${dateToIso8601IgnoringTime(translatedDate)}T${source.substring(11)}`;
}

// Translate source timestamp by targetReference timestamp,
// perserving the week distance between source and sourceReference and day of week of the source timestamp
export function translateTimeRelativeToWeek(source, sourceReference, targetReference) {
const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference);
const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference);

// If these dates were in the same week, how many days apart would they be?
const dayOfWeekDelta = sourceReferenceDate.getDay() - targetReferenceDate.getDay();

// If we pretend that the targetReference is actually the same day of the week as the
// sourceReference, then we can translate the source to the target while preserving their
// days of the week.
const normalizationDelta = dayOfWeekDelta * MILLISECONDS_IN_DAY;
const normalizedTargetReference =
dateToIso8601IgnoringTime(new Date(targetReferenceDate.getTime() + normalizationDelta));

return translateTimeRelativeToDifference(
source,
sourceReference,
normalizedTargetReference);
}
107 changes: 107 additions & 0 deletions src/server/sample_data/routes/lib/translate_timestamp.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/


import { translateTimeRelativeToWeek } from './translate_timestamp';

describe('translateTimeRelativeToWeek', () => {
const sourceReference = '2018-01-02T00:00:00'; //Tuesday
const targetReference = '2018-04-25T18:24:58.650'; // Wednesday

describe('2 weeks before', () => {
test('should properly adjust timestamp when day is before targetReference day of week', () => {
const source = '2017-12-18T23:50:00'; // Monday, -2 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-09T23:50:00'); // Monday 2 week before targetReference week
});

test('should properly adjust timestamp when day is same as targetReference day of week', () => {
const source = '2017-12-20T23:50:00'; // Wednesday, -2 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-11T23:50:00'); // Wednesday 2 week before targetReference week
});

test('should properly adjust timestamp when day is after targetReference day of week', () => {
const source = '2017-12-22T16:16:50'; // Friday, -2 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-13T16:16:50'); // Friday 2 week before targetReference week
});
});

describe('week before', () => {
test('should properly adjust timestamp when day is before targetReference day of week', () => {
const source = '2017-12-25T23:50:00'; // Monday, -1 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-16T23:50:00'); // Monday 1 week before targetReference week
});

test('should properly adjust timestamp when day is same as targetReference day of week', () => {
const source = '2017-12-27T23:50:00'; // Wednesday, -1 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-18T23:50:00'); // Wednesday 1 week before targetReference week
});

test('should properly adjust timestamp when day is after targetReference day of week', () => {
const source = '2017-12-29T16:16:50'; // Friday, -1 week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-20T16:16:50'); // Friday 1 week before targetReference week
});
});

describe('same week', () => {
test('should properly adjust timestamp when day is before targetReference day of week', () => {
const source = '2018-01-01T23:50:00'; // Monday, same week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday same week as targetReference
});

test('should properly adjust timestamp when day is same as targetReference day of week', () => {
const source = '2018-01-03T23:50:00'; // Wednesday, same week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-25T23:50:00'); // Wednesday same week as targetReference
});

test('should properly adjust timestamp when day is after targetReference day of week', () => {
const source = '2018-01-05T16:16:50'; // Friday, same week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-27T16:16:50'); // Friday same week as targetReference
});
});

describe('week after', () => {
test('should properly adjust timestamp when day is before targetReference day of week', () => {
const source = '2018-01-08T23:50:00'; // Monday, 1 week after relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-04-30T23:50:00'); // Monday 1 week after targetReference week
});

test('should properly adjust timestamp when day is same as targetReference day of week', () => {
const source = '2018-01-10T23:50:00'; // Wednesday, same week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-05-02T23:50:00'); // Wednesday 1 week after targetReference week
});

test('should properly adjust timestamp when day is after targetReference day of week', () => {
const source = '2018-01-12T16:16:50'; // Friday, same week relative to sourceReference
const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference);
expect(timestamp).toBe('2018-05-04T16:16:50'); // Friday 1 week after targetReference week
});
});
});

3 changes: 1 addition & 2 deletions test/functional/apps/home/_sample_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ export default function ({ getService, getPageObjects }) {
expect(isInstalled).to.be(true);
});

// Skipping issue # 20807
describe.skip('dashboard', () => {
describe('dashboard', () => {
after(async () => {
await PageObjects.common.navigateToUrl('home', 'tutorial_directory/sampleData');
await PageObjects.header.waitUntilLoadingHasFinished();
Expand Down

0 comments on commit 286843a

Please sign in to comment.