blob: a7a85b9c8bc0b156d95c8a588a5cd0fe4ee77f3c [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 {describe, test, expect} from "@jest/globals";
import {exportedForTest, generateTimesamples, clearTimeseriesValues,
mapTimeseriesCounters, aggregateProfileTimeseries} from
"scripts/query_timeline/chart_commons.js";
describe("webui.js_tests.chart_commons.mapTimeseriesCounters", () => {
// Test whether the method correctly searches and maps indexes of counters based
// on counter_name
test("basic_test.serial_order", () => {
const parent_profile =
{
"profile_name" : "Per Node Profiles",
"num_children" : 3,
"child_profiles" : [
{
"profile_name" : "host-1 :27000",
"time_series_counters" : [{
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
}
]
};
const counters = [
["HostCpuIoWaitPercentage", "avg io wait", 0],
["HostCpuSysPercentage", "avg sys", 0],
["HostCpuUserPercentage", "avg user", 0]
];
expect(mapTimeseriesCounters(parent_profile.child_profiles[0].time_series_counters,
counters)).toBe(undefined);
for (let i = 0; i < counters.length; i++) {
expect(counters[i][2]).toBe(i);
}
});
test("basic_test.reverse_order", () => {
const parent_profile =
{
"profile_name" : "Per Node Profiles",
"num_children" : 3,
"child_profiles" : [
{
"profile_name" : "host-1 :27000",
"time_series_counters" : [{
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
}
]
};
const counters = [
["HostCpuIoWaitPercentage", "avg io wait", 0],
["HostCpuSysPercentage", "avg sys", 0],
["HostCpuUserPercentage", "avg user", 0]
];
expect(mapTimeseriesCounters(parent_profile.child_profiles[0].time_series_counters,
counters)).toBe(undefined);
for (let i = 0; i < counters.length; i++) {
expect(counters[i][2]).toBe(counters.length - i - 1);
}
});
test("edge_case.counter_name_undefined", () => {
const parent_profile =
{
"profile_name" : "Per Node Profiles",
"num_children" : 3,
"child_profiles" : [
{
"profile_name" : "host-1 :27000",
"time_series_counters" : [{
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
}
]
};
const counters = [
["HostPercentage", "avg io wait", 0],
["HostSysPercenage", "avg sys", 0],
["HostUserPercntage", "avg user", 0]
];
try {
mapTimeseriesCounters(parent_profile.child_profiles[0].time_series_counters,
counters);
} catch(e) {
expect(e.message).toBe(`"${counters[0][0]}" not found within profile`);
}
});
});
describe("webui.js_tests.chart_commons.accumulateTimeseriesValues", () => {
// Test whether the method correctly accumlates values after parsing values from 'data'
// in 'time_series_counters' and correctly updates 'max_samples' even in corner cases
const {accumulateTimeseriesValues} = exportedForTest;
const DATA_TYPE = "value type";
test("basic_case.samples_greater_than_collected", () => {
const max_samples = {
allocated : 7,
period : 0,
available : 0,
collected : 0
};
const values_array = [DATA_TYPE, 0, 60, 100, 40, 38, 49, 61, 27];
const time_series_counter = {
period : 100,
num : 2000,
data : "30, 100, 40"
};
expect(accumulateTimeseriesValues(values_array, time_series_counter, max_samples))
.toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, 90, 200, 80, 38, 49, 61, 27]);
expect(max_samples).toEqual({
allocated : 7,
period : 100,
available : 3,
collected : 2000
});
});
test("basic_case.sample_period_greater_than_current_period", () => {
const max_samples = {
allocated : 7,
period : 100,
available : 1000,
collected : 1000
};
const values_array = [DATA_TYPE, 0, 60, 100, 40, 38, 49, 61, 27];
const time_series_counter = {
period : 200,
num : 300,
data : "30, 100, 40"
};
expect(accumulateTimeseriesValues(values_array, time_series_counter, max_samples))
.toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, 90, 200, 80, 38, 49, 61, 27]);
expect(max_samples).toEqual({
allocated : 7,
period : 200,
available : 3,
collected : 300
});
});
test("basic_case.period_and_samples_num_within_limits", () => {
const max_samples = {
allocated : 7,
period : 100,
available : 1000,
collected : 1000
};
const values_array = [DATA_TYPE, 0, 60, 100, 40, 38, 49, 61, 27];
const time_series_counter = {
period : 100,
num : 300,
data : "30, 100, 40"
};
expect(accumulateTimeseriesValues(values_array, time_series_counter, max_samples))
.toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, 90, 200, 80, 38, 49, 61, 27]);
expect(max_samples).toEqual({
allocated : 7,
period : 100,
available : 1000,
collected : 1000
});
});
test("edge_case.allocated_values_array_smaller_than_collected_samples", () => {
const max_samples = {
allocated : 2,
period : 100,
available : 2,
collected : 1000
};
const values_array = [DATA_TYPE, 0, 60, 100];
const time_series_counter = {
period : 100,
num : 300,
data : "30, 100, 40"
};
expect(accumulateTimeseriesValues(values_array, time_series_counter, max_samples))
.toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, 90, 200]);
expect(max_samples).toEqual({
allocated : 2,
period : 100,
available : 2,
collected : 1000
});
});
});
describe("webui.js_tests.chart_commons.generateTimesamples", () => {
// Test whether time sample values generated based on 'max_samples' are correct,
// even in corner cases, with different 'max_samples' scenarios
const DATA_TYPE = "timesample type";
test("basic_case.available_samples_within_allocated_size", () => {
const max_samples = {
allocated : 10,
period : 1000,
available : 4,
collected : 10
};
const timesamples_array = new Array(max_samples.allocated + 2).fill(null);
timesamples_array[0] = DATA_TYPE;
expect(generateTimesamples(timesamples_array, max_samples)).toBe(undefined);
expect(timesamples_array).toEqual([DATA_TYPE, 0, 2.5, 5, 7.5, 10, null, null,
null, null, null, null]);
});
test("edge_case.available_samples_exceed_allocated_size", () => {
const max_samples = {
allocated : 10,
period : 1000,
available : 20,
collected : 10
};
const timesamples_array = new Array(max_samples.allocated + 2);
timesamples_array[0] = DATA_TYPE;
expect(generateTimesamples(timesamples_array, max_samples)).toBe(undefined);
expect(timesamples_array).toEqual([DATA_TYPE, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4,
4.5, 5]);
});
test("edge_case.same_num_available_samples_and_allocated", () => {
const max_samples = {
allocated : 10,
period : 1000,
available : 10,
collected : 10
};
const timesamples_array = new Array(max_samples.allocated + 2);
timesamples_array[0] = DATA_TYPE;
expect(generateTimesamples(timesamples_array, max_samples)).toBe(undefined);
expect(timesamples_array).toEqual([DATA_TYPE, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
});
});
describe("webui.js_tests.chart_commons.clearTimeseriesValues", () => {
// Test whether Timeseries arrays are being properly truncated in the correct range
const DATA_TYPE = "value type";
test("basic_case.available_samples_within_allocated_size", () => {
const max_samples = {
allocated : 7,
period : 1000,
available : 3,
collected : 10
};
const values_array = [DATA_TYPE, 0, 4, 3, 20, 10, 100, 10];
expect(clearTimeseriesValues(values_array, max_samples)).toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, null, null, null, 10, 100, 10]);
});
test("edge_case.available_samples_exceed_allocated_size", () => {
const max_samples = {
allocated : 7,
period : 1000,
available : 30,
collected : 10
};
const values_array = [DATA_TYPE, 0, 3, 4, 3, 20, 10, 100, 10];
expect(clearTimeseriesValues(values_array, max_samples)).toBe(undefined);
expect(values_array).toEqual([DATA_TYPE, 0, null, null, null, null, null, null,
null]);
});
});
describe("webui.js_tests.chart_commons.aggregateProfileTimeseries", () => {
// Test correctness of values being aggregated from parsing the profile
test("basic_case", () => {
const parent_profile =
{
"profile_name" : "Per Node Profiles",
"num_children" : 3,
"child_profiles" : [
{
"profile_name" : "host-1 :27000",
"time_series_counters" : [{
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
},
{
"profile_name" : "host-1 :27001",
"time_series_counters" : [{
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
},
{
"profile_name" : "host-1 :27001",
"time_series_counters" : [{
"counter_name" : "HostCpuIoWaitPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "0,0,0,70,0,0,0,0,0,10"
}, {
"counter_name" : "HostCpuSysPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}, {
"counter_name" : "HostCpuUserPercentage",
"unit" : "BASIS_POINTS",
"num" : 59,
"period" : 100,
"data" : "312,679,445,440,301,301,312,125,125,437"
}]
}
]
};
const max_samples = {
allocated : 10,
period : 0,
available : 0,
collected : 0
};
const counters = [
["HostCpuIoWaitPercentage", "avg io wait", 0],
["HostCpuSysPercentage", "avg sys", 0],
["HostCpuUserPercentage", "avg user", 0]
];
const aggregate_array = new Array(counters.length);
for (let i = 0; i < counters.length; ++i) {
aggregate_array[i] = new Array(max_samples.allocated + 2).fill(0);
aggregate_array[i][0] = counters[i][1];
}
mapTimeseriesCounters(parent_profile.child_profiles[0].time_series_counters,
counters);
expect(aggregateProfileTimeseries(parent_profile, aggregate_array, counters,
max_samples)).toBe(undefined);
expect(aggregate_array).toEqual([
["avg io wait", 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 30],
["avg sys", 0, 936, 2037, 1335,1320, 903, 903, 936, 375, 375, 1311],
["avg user", 0, 936, 2037, 1335, 1320, 903, 903, 936, 375, 375, 1311]
]);
expect(max_samples).toEqual({
allocated : 10,
period : 100,
available : 10,
collected : 59
});
});
});