Skip to content

Commit

Permalink
thresholds reworked (#316)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Apr 5, 2023
1 parent 293de66 commit 6735fcc
Show file tree
Hide file tree
Showing 16 changed files with 328 additions and 215 deletions.
2 changes: 1 addition & 1 deletion src/app/item-detail/item-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

<div class="overview-info">

<div class="row" *ngIf="itemData.thresholds && !itemData.thresholds?.passed">
<div class="row" *ngIf="itemData.thresholds && itemData.thresholds?.passed === false">
<div class="col">
<app-regression-alert [itemData]="itemData"></app-regression-alert>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/app/item-detail/item-detail.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ReloadCustomChartComponent } from "./analyze-charts/reload-custom-chart
import { ExcelService } from "../_services/excel.service";
import { ChartIntervalComponent } from "./chart-interval/chart-interval.component";
import { ForbiddenComponent } from "../forbidden/forbidden.component";
import { ThresholdFailureComponent } from "./request-stats/threshold-failure/threshold-failure.component";


const routes: Routes = [ {
Expand All @@ -40,7 +41,7 @@ const routes: Routes = [ {
declarations: [ItemDetailComponent, RequestStatsCompareComponent, ThresholdsAlertComponent,
PerformanceAnalysisComponent, ZeroErrorToleranceWarningComponent, LabelChartComponent, AnalyzeChartsComponent,
LabelHealthComponent, LabelTrendComponent, StatsCompareComponent, AddMetricComponent, ShareComponent, DeleteShareLinkComponent,
CreateNewShareLinkComponent, MonitoringStatsComponent, ReloadCustomChartComponent, ChartIntervalComponent, ForbiddenComponent ],
CreateNewShareLinkComponent, MonitoringStatsComponent, ReloadCustomChartComponent, ChartIntervalComponent, ForbiddenComponent, ThresholdFailureComponent ],
imports: [
CommonModule, NgbModule, RouterModule.forRoot(routes), DataTableModule, SharedItemModule, SharedModule, HighchartsChartModule,
ReactiveFormsModule, FormsModule, RoleModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
}

.expand-button {
width: 30px;
width: 50px;
}

.performance-regression-icon {
display: inline;
padding-left: 5px;
}
254 changes: 140 additions & 114 deletions src/app/item-detail/request-stats/request-stats-compare.component.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { StatsCompareComponent } from "../stats-compare/stats-compare.component"
import { LabelHealthComponent } from "./label-health/label-health.component";

import { RequestStatsCompareComponent } from "./request-stats-compare.component";
import { Metrics } from "../metrics";

describe("RequestStatsCompareComponent", () => {
let component: RequestStatsCompareComponent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
comparedMetadata;
defaultUnit = true;
externalSearchTerm = "";
collapsableSettings = {}
collapsableSettings = {};

constructor(
private itemsService: ItemsApiService,
Expand All @@ -48,7 +48,23 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.labelsData = this.itemData.statistics;
if (this.itemData?.thresholds?.passed === false) {
this.labelsData = this.itemData.statistics.map(labelData => {
const thresholdResult = this.itemData.thresholds.results.find(thresholdResult =>
thresholdResult.label === labelData.label);
if (thresholdResult) {
return Object.assign(labelData, {
thresholdResult: {
passed: thresholdResult.passed,
result: thresholdResult.result
}
});
}
return labelData;
});
} else {
this.labelsData = this.itemData.statistics;
}
this.analyzeChartService.currentData.subscribe(data => {
if (data && data.label) {
this.search(data.label);
Expand All @@ -65,7 +81,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
this.comparedData = null;
this.labelsData = this.itemData.statistics;
this.defaultUnit = true;
this.comparisonChartService.resetPlot()
this.comparisonChartService.resetPlot();
}

search(query: string) {
Expand Down Expand Up @@ -123,8 +139,8 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {

itemToCompare(data) {
this.resetStatsData();
this.comparisonChartService.setComparisonPlot(data.plot, data.extraPlotData)
this.comparisonChartService.setHistogramPlot(data.histogramPlotData)
this.comparisonChartService.setComparisonPlot(data.plot, data.extraPlotData);
this.comparisonChartService.setHistogramPlot(data.histogramPlotData);
this.comparingData = data;
this.comparedMetadata = { id: data.id, maxVu: data.maxVu };
if (data.maxVu !== this.itemData.overview.maxVu) {
Expand Down Expand Up @@ -285,12 +301,14 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
}

downloadAsXLXS() {
const { requestStats = {
samples: true,
avg: true, min: true,
max: true, p90: true, p95: true,
p99: true, throughput: true, network: true,
errorRate: true, standardDeviation: true }
const {
requestStats = {
samples: true,
avg: true, min: true,
max: true, p90: true, p95: true,
p99: true, throughput: true, network: true,
errorRate: true, standardDeviation: true
}
} = this.itemData.userSettings;
const dataToBeSaved = this.labelsData.map((label) => {
return {
Expand Down Expand Up @@ -319,18 +337,18 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {

calculateApdex(satisfaction, toleration, samples) {
if (satisfaction === null || toleration === null) {
return
return;
}
const apdexValue = roundNumberTwoDecimals((satisfaction + (toleration * 0.5)) / samples)
return this.apdexScore(apdexValue)
const apdexValue = roundNumberTwoDecimals((satisfaction + (toleration * 0.5)) / samples);
return this.apdexScore(apdexValue);
}

public sortByApdex(item) {
return roundNumberTwoDecimals(((item.apdex.satisfaction + ( item.apdex.toleration * 0.5)) / item.samples))
return roundNumberTwoDecimals(((item.apdex.satisfaction + (item.apdex.toleration * 0.5)) / item.samples));
}

public sortByNetwork(item) {
return roundNumberTwoDecimals(item.bytesPerSecond + item.bytesSentPerSecond)
return roundNumberTwoDecimals(item.bytesPerSecond + item.bytesSentPerSecond);
}

private apdexScore(apdexValue: number): string {
Expand All @@ -340,20 +358,21 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
{ rangeFrom: 0.7, rangeTo: 0.83, name: "Fair", },
{ rangeFrom: 0.5, rangeTo: 0.69, name: "Poor", },
{ rangeFrom: 0, rangeTo: 0.49, name: "Unacceptable" }
]
return score.find(sc => apdexValue >= sc.rangeFrom && apdexValue <= sc.rangeTo)?.name
];
return score.find(sc => apdexValue >= sc.rangeFrom && apdexValue <= sc.rangeTo)?.name;
}

toggleSectionVisibility(event, index) {
// eslint-disable-next-line no-prototype-builtins
if (!this.collapsableSettings.hasOwnProperty(index)) {
this.collapsableSettings[index] = true
} else {
this.collapsableSettings[index] = !this.collapsableSettings[index];
if (!this.collapsableSettings.hasOwnProperty(index)) {
this.collapsableSettings[index] = true;
} else {
this.collapsableSettings[index] = !this.collapsableSettings[index];

}
}
}
identify(index, item){

identify(index, item) {
return item.label;
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div>
<p *ngIf="thresholdResult?.result?.percentile?.passed === false">
<i class="fas fa-exclamation-triangle text-danger"></i>
90% Percentile performance regressed about {{thresholdResult?.result?.percentile?.diffValue - 100 | number: '1.0-2'}}% in comparison with baseline report.
</p>
<p *ngIf="thresholdResult?.result?.throughput?.passed === false"><i class="fas fa-exclamation-triangle text-danger"></i>
Throughput performance regressed about {{Math.abs(thresholdResult?.result?.throughput?.diffValue - 100) | number: '1.0-2'}}% in comparison with baseline report.
</p>
<p *ngIf="thresholdResult?.result?.errorRate?.passed === false"><i class="fas fa-exclamation-triangle text-danger"></i>
Error Rate performance regressed about {{Math.abs(100 - thresholdResult?.result?.errorRate?.diffValue) | number: '1.0-2'}}% in comparison with baseline report.
</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";

import { ThresholdFailureComponent } from "./threshold-failure.component";

describe("ThresholdFailureComponent", () => {
let component: ThresholdFailureComponent;
let fixture: ComponentFixture<ThresholdFailureComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ThresholdFailureComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(ThresholdFailureComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it("should create", () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component, Input, OnInit } from "@angular/core";
import { ThresholdResult } from "../../../items.service.model";

@Component({
selector: "app-threshold-failure",
templateUrl: "./threshold-failure.component.html",
styleUrls: ["./threshold-failure.component.css"]
})
export class ThresholdFailureComponent implements OnInit {

@Input() thresholdResult: { passed: boolean, result: ThresholdResult };

ngOnInit(): void {
console.log(this.thresholdResult)
}

protected readonly Math = Math;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.card-body{
padding-top: 0px;
}

.perf-issue {
border-left: 4px solid #dc3545 !important;
padding-bottom: 10px;
}

Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
<ng-template #tipContent>
<p>90 percentile decrease toleration: {{itemData.thresholds.thresholds.percentile}} %
</p>
<p>
Througput decrease toleration: {{itemData.thresholds.thresholds.throughput}}%
</p>
<p>
Error rate increase toleration: {{itemData.thresholds.thresholds.errorRate}}%
</p>
</ng-template>
<div class="card perf-issue card-shadow">
<h6 class="card-header bg-transparent border-0 text-alizarin">Performance threshold failure <i
class="ttp text-secondary" placement="bottom" [ngbTooltip]="tipContent"><i
<h6 class="card-header bg-transparent border-0 text-alizarin"><i
class="fas fa-exclamation-triangle text-danger"></i> Performance Regression Detected <i
class="ttp text-secondary" placement="bottom" ngbTooltip="Performance regression was detected - please check label statistics table below."><i
class="far fa-question-circle icon"></i></i></h6>
<div class="card-body">
<div class="perf-issue-check" *ngIf="!itemData.thresholds.result.percentile.passed"> <i
class="fas fa-exclamation-triangle text-danger"></i> 90 percentile response time
<div class="perf-analaysis-desc text-secondary"><small>
90 percentile response time is about {{Math.round(itemData.thresholds.result.percentile.diffValue - 100) }}%
slower than in the previous reports.
</small></div>
</div>
<div class="perf-issue-check" *ngIf="!itemData.thresholds.result.errorRate.passed"><i
class="fas fa-exclamation-triangle text-danger"></i> Error rate
<div class="perf-analaysis-desc text-secondary">
Error rate is about {{
Math.round(100 - itemData.thresholds.result.errorRate.diffValue) }}% higher than the average.
</div>
</div>
<div class="perf-issue-check" *ngIf="!itemData.thresholds.result.throughput.passed"><i
class="fas fa-exclamation-triangle text-danger"></i> Throughput
<div class="perf-analaysis-desc text-secondary"><small> Throughput is about {{
Math.round(100 - itemData.thresholds.result.throughput.diffValue ) }}% lower than in the previous
reports.</small>
</div>
</div>
</div>
<div></div>
</div>
Loading

0 comments on commit 6735fcc

Please sign in to comment.