diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html
index 6303bf1b..40cfd30a 100644
--- a/src/app/dashboard/dashboard.component.html
+++ b/src/app/dashboard/dashboard.component.html
@@ -104,13 +104,10 @@
+
diff --git a/src/app/item-detail/item-detail.component.ts b/src/app/item-detail/item-detail.component.ts
index e8cc4c5b..65df30fc 100644
--- a/src/app/item-detail/item-detail.component.ts
+++ b/src/app/item-detail/item-detail.component.ts
@@ -15,7 +15,7 @@ import { bytesToMbps } from "./calculations";
import { ItemStatusValue } from "./item-detail.model";
import { Metrics } from "./metrics";
import { AnalyzeChartService } from "../analyze-chart.service";
-import { showZeroErrorWarning } from "../utils/showZeroErrorTolerance";
+import { getValidationResults } from "../utils/showZeroErrorTolerance";
import { ItemChartService } from "../_services/item-chart.service";
exporting(Highcharts);
@@ -59,6 +59,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
userSettings: null,
errorSummary: null,
status: null,
+ minTestDuration: null,
};
overallChartOptions;
scatterChartOptions;
@@ -76,10 +77,13 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
chartLines;
activeId = 1;
performanceAnalysisLines = null;
- externalSearchTerm = null;
totalRequests = null;
- plotRangeMin = null
- plotRangeMax = null
+ plotRangeMin = null;
+ plotRangeMax = null;
+ validations = {
+ zeroErrorValidation: null,
+ minTestDurationValidation: null,
+ };
constructor(
@@ -129,6 +133,11 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
this.selectedPlotSubscription();
this.plotRangeSubscription();
this.calculateTotalRequests();
+ const validations = this.showValidationWarning(this.itemData);
+ this.validations = {
+ zeroErrorValidation: validations.zeroErrorToleranceValidation,
+ minTestDurationValidation: validations.minTestDurationValidation
+ };
this.spinner.hide();
});
this.analyzeChartService.currentData.subscribe(data => {
@@ -140,6 +149,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
this.overallChartOptions = {
...overallChartSettings("ms")
};
+
}
ngOnDestroy() {
@@ -189,14 +199,14 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
*/
private plotRangeSubscription() {
this.itemChartService.plotRange$.subscribe((value) => {
- this.updateMinMaxOfCharts(value?.start?.getTime(), value?.end?.getTime())
+ this.updateMinMaxOfCharts(value?.start?.getTime(), value?.end?.getTime());
});
}
private updateMinMaxOfCharts(min, max) {
if (min && max) {
- this.plotRangeMin = min
- this.plotRangeMax = max
+ this.plotRangeMin = min;
+ this.plotRangeMax = max;
for (const chartOptions of [this.overallChartOptions, this.scatterChartOptions, this.statusChartOptions]) {
chartOptions.xAxis.min = min;
chartOptions.xAxis.max = max;
@@ -279,21 +289,22 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
return bytesToMbps(bytes);
}
- showZeroErrorToleranceWarning(): boolean | string {
- if (this.itemData.zeroErrorToleranceEnabled) {
- return showZeroErrorWarning(this.itemData.overview.errorRate,
- this.itemData.overview.errorCount);
+ showValidationWarning(itemData: ItemDetail): { zeroErrorToleranceValidation: boolean, minTestDurationValidation: boolean } {
+ if (itemData.zeroErrorToleranceEnabled || itemData.minTestDuration > 0) {
+ return getValidationResults(
+ itemData.zeroErrorToleranceEnabled,
+ itemData.overview.errorRate,
+ itemData.overview.errorCount,
+ itemData.overview.duration,
+ itemData.minTestDuration
+ );
}
- return false;
- }
-
- focusOnLabel($event: { label: string, metrics: Metrics[] }) {
- this.activeId = 2;
- this.performanceAnalysisLines = $event;
- this.externalSearchTerm = $event.label;
+ return {
+ zeroErrorToleranceValidation: false,
+ minTestDurationValidation: false,
+ };
}
-
chartCallback: Highcharts.ChartCallbackFunction = function (chart): void {
setTimeout(() => {
chart.reflow();
@@ -314,13 +325,13 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
} else {
const originalSeries = Array.from(this.chartLines?.overall?.values());
this.overallChartOptions = overallChartSettings("");
- this.overallChartOptions.series = originalSeries
+ this.overallChartOptions.series = originalSeries;
}
// we need always to set the correct zoom range
- this.overallChartOptions.xAxis.min = this.plotRangeMin
- this.overallChartOptions.xAxis.max = this.plotRangeMax
+ this.overallChartOptions.xAxis.min = this.plotRangeMin;
+ this.overallChartOptions.xAxis.max = this.plotRangeMax;
- this.updateOverallChartFlag = true;
+ this.updateOverallChartFlag = true;
}
}
diff --git a/src/app/item-detail/item-detail.module.ts b/src/app/item-detail/item-detail.module.ts
index a1edc3c3..2a17beba 100644
--- a/src/app/item-detail/item-detail.module.ts
+++ b/src/app/item-detail/item-detail.module.ts
@@ -9,7 +9,6 @@ import { AuthGuard } from "../auth.guard";
import { RouterModule, Routes } from "@angular/router";
import { SharedItemModule } from "../shared/shared-item/shared-item.module";
import { SharedModule } from "../shared/shared.module";
-import { ZeroErrorToleranceWarningComponent } from "./zero-error-tolerance-warning/zero-error-tolerance-warning.component";
import { HighchartsChartModule } from "highcharts-angular";
import { LabelChartComponent } from "./label-chart/label-chart.component";
import { AnalyzeChartsComponent } from "./analyze-charts/analyze-charts.component";
@@ -31,6 +30,7 @@ import { ForbiddenComponent } from "../forbidden/forbidden.component";
import { ThresholdFailureComponent } from "./request-stats/threshold-failure/threshold-failure.component";
import { ZoomChartsComponent } from "./zoom-charts/zoom-charts.component";
import { ErrorSummaryComponent } from "./error-summary/error-summary.component";
+import { ValidationsModule } from "./validations/validations.module";
const routes: Routes = [{
@@ -41,11 +41,11 @@ const routes: Routes = [{
@NgModule({
declarations: [ItemDetailComponent, RequestStatsCompareComponent, ThresholdsAlertComponent,
- PerformanceAnalysisComponent, ZeroErrorToleranceWarningComponent, LabelChartComponent, AnalyzeChartsComponent,
+ PerformanceAnalysisComponent, LabelChartComponent, AnalyzeChartsComponent,
LabelHealthComponent, LabelTrendComponent, StatsCompareComponent, AddMetricComponent, ShareComponent, DeleteShareLinkComponent,
CreateNewShareLinkComponent, MonitoringStatsComponent, ReloadCustomChartComponent, ChartIntervalComponent, ForbiddenComponent, ThresholdFailureComponent, ZoomChartsComponent, ErrorSummaryComponent],
imports: [
- CommonModule, NgbModule, RouterModule.forRoot(routes), DataTableModule, SharedItemModule, SharedModule, HighchartsChartModule,
+ CommonModule, NgbModule, RouterModule.forRoot(routes), DataTableModule, SharedItemModule, SharedModule, HighchartsChartModule, ValidationsModule,
ReactiveFormsModule, FormsModule, RoleModule,
],
exports: [],
diff --git a/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.css b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.html b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.html
new file mode 100644
index 00000000..872b8098
--- /dev/null
+++ b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.html
@@ -0,0 +1,8 @@
+
+
+
+ The test duration was too short
+
+ The scenario is set with minimum test duration.
+
+
diff --git a/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.spec.ts b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.spec.ts
new file mode 100644
index 00000000..65f08f74
--- /dev/null
+++ b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { MinTestDurationWarningComponent } from "./min-test-duration-warning.component";
+
+describe("MinTestDurationWarningComponent", () => {
+ let component: MinTestDurationWarningComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ MinTestDurationWarningComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MinTestDurationWarningComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.ts b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.ts
new file mode 100644
index 00000000..337c56e0
--- /dev/null
+++ b/src/app/item-detail/validations/min-test-duration-warning/min-test-duration-warning.component.ts
@@ -0,0 +1,10 @@
+import { Component, OnInit } from "@angular/core";
+
+@Component({
+ selector: "app-min-test-duration-warning",
+ templateUrl: "./min-test-duration-warning.component.html",
+ styleUrls: ["./min-test-duration-warning.component.css"]
+})
+export class MinTestDurationWarningComponent {
+
+}
diff --git a/src/app/item-detail/validations/validations.module.ts b/src/app/item-detail/validations/validations.module.ts
new file mode 100644
index 00000000..efb5d357
--- /dev/null
+++ b/src/app/item-detail/validations/validations.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { MinTestDurationWarningComponent } from "./min-test-duration-warning/min-test-duration-warning.component";
+import { ZeroErrorToleranceWarningComponent } from "./zero-error-tolerance-warning/zero-error-tolerance-warning.component";
+
+
+@NgModule({
+ declarations: [MinTestDurationWarningComponent, ZeroErrorToleranceWarningComponent],
+ exports: [
+ ZeroErrorToleranceWarningComponent,
+ MinTestDurationWarningComponent
+ ],
+ imports: [
+ CommonModule
+ ]
+})
+export class ValidationsModule {
+}
diff --git a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.css b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.css
similarity index 100%
rename from src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.css
rename to src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.css
diff --git a/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html
new file mode 100644
index 00000000..33d89aa3
--- /dev/null
+++ b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html
@@ -0,0 +1,8 @@
+
+
+ Error(s) detected
+
+ The scenario has zero error tolerance check enabled.
+
+
diff --git a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.spec.ts b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.spec.ts
similarity index 100%
rename from src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.spec.ts
rename to src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.spec.ts
diff --git a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts
similarity index 89%
rename from src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts
rename to src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts
index 43599072..e6bcbed8 100644
--- a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts
+++ b/src/app/item-detail/validations/zero-error-tolerance-warning/zero-error-tolerance-warning.component.ts
@@ -3,7 +3,7 @@ import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-zero-error-tolerance-warning",
templateUrl: "./zero-error-tolerance-warning.component.html",
- styleUrls: ["./zero-error-tolerance-warning.component.css", "../item-detail.component.scss"]
+ styleUrls: ["./zero-error-tolerance-warning.component.css", "../../item-detail.component.scss"]
})
export class ZeroErrorToleranceWarningComponent {
diff --git a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html b/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html
deleted file mode 100644
index 7b0368a4..00000000
--- a/src/app/item-detail/zero-error-tolerance-warning/zero-error-tolerance-warning.component.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
Test failure
-
-
- Error(s) detected
-
- The scenario has zero error tolerance check enabled.
-
-
-
-
diff --git a/src/app/items.service.model.ts b/src/app/items.service.model.ts
index 3e7c669f..460776e5 100644
--- a/src/app/items.service.model.ts
+++ b/src/app/items.service.model.ts
@@ -7,6 +7,7 @@ export interface ItemsListing {
environment: string;
status: string;
zeroErrorToleranceEnabled: boolean;
+ minTestDuration: number,
thresholdPassed?: boolean;
overview: ItemOverview;
@@ -63,6 +64,7 @@ export interface ItemDetail {
};
errorSummary: ErrorSummary
status: string
+ minTestDuration: number
}
interface TopMetricsSettings {
diff --git a/src/app/scenario.service.model.ts b/src/app/scenario.service.model.ts
index c9643cc3..c3087947 100644
--- a/src/app/scenario.service.model.ts
+++ b/src/app/scenario.service.model.ts
@@ -1,6 +1,7 @@
export interface Scenario {
analysisEnabled: boolean;
zeroErrorToleranceEnabled: boolean;
+ minTestDuration: boolean;
name: string;
keepTestRunsPeriod: number;
thresholds: {
diff --git a/src/app/scenario/scenario-settings/scenario-settings.component.html b/src/app/scenario/scenario-settings/scenario-settings.component.html
index 414d77bd..571f08db 100644
--- a/src/app/scenario/scenario-settings/scenario-settings.component.html
+++ b/src/app/scenario/scenario-settings/scenario-settings.component.html
@@ -74,6 +74,28 @@ Zero error tolerance
+
+
+
+
Delete sample data after processing
diff --git a/src/app/scenario/scenario-settings/scenario-settings.component.ts b/src/app/scenario/scenario-settings/scenario-settings.component.ts
index 09558706..16353196 100644
--- a/src/app/scenario/scenario-settings/scenario-settings.component.ts
+++ b/src/app/scenario/scenario-settings/scenario-settings.component.ts
@@ -33,6 +33,7 @@ export class SettingsScenarioComponent implements OnInit {
throughput: null,
enabled: null,
zeroErrorToleranceEnabled: null,
+ minTestDuration: null,
deleteSamples: null,
keepTestRunsPeriod: null,
generateShareToken: null,
@@ -52,7 +53,6 @@ export class SettingsScenarioComponent implements OnInit {
errorRate: null,
failures: null,
};
- labelFilterControls = {};
requestStatsCormControls = {
samples: null,
avg: null,
@@ -74,10 +74,7 @@ export class SettingsScenarioComponent implements OnInit {
satisfyingThreshold: null,
toleratingThreshold: null
};
-
-
params;
-
keepTestRunPeriods = [
{
period: 0,
@@ -110,7 +107,7 @@ export class SettingsScenarioComponent implements OnInit {
labelFilterOperators = ["includes", "match"];
labelFilters: FormArray;
- hasBaselineReport = false
+ hasBaselineReport = false;
constructor(
@@ -124,7 +121,7 @@ export class SettingsScenarioComponent implements OnInit {
ngOnInit(): void {
this.route.params.subscribe(_ => this.params = _);
this.scenarioApiService.getScenario(this.params.projectName, this.params.scenarioName).subscribe(_ => {
- this.hasBaselineReport = !!_.baselineReport
+ this.hasBaselineReport = !!_.baselineReport;
if (_.name) {
this.createFormControls(_);
this.createForm();
@@ -133,8 +130,6 @@ export class SettingsScenarioComponent implements OnInit {
}
-
-
this.apdexSettingsForm.valueChanges.subscribe(value => {
const { satisfyingThreshold, toleratingThreshold } = value;
if (satisfyingThreshold && toleratingThreshold) {
@@ -185,8 +180,16 @@ export class SettingsScenarioComponent implements OnInit {
Validators.required
]);
this.formControls.zeroErrorToleranceEnabled = new FormControl(settings.zeroErrorToleranceEnabled, [
+ Validators.min(0),
+ Validators.max(1000),
Validators.required
]);
+ this.formControls.minTestDuration = new FormControl(settings.minTestDuration, [
+ Validators.required,
+ Validators.min(0),
+ Validators.max(1000),
+ ]);
+
this.formControls.deleteSamples = new FormControl(settings.deleteSamples, [
Validators.required
]);
@@ -245,6 +248,7 @@ export class SettingsScenarioComponent implements OnInit {
thresholdThroughput: this.formControls.throughput,
thresholdErrorRate: this.formControls.errorRate,
zeroErrorToleranceEnabled: this.formControls.zeroErrorToleranceEnabled,
+ minTestDuration: this.formControls.minTestDuration,
deleteSamples: this.formControls.deleteSamples,
keepTestRunsPeriod: this.formControls.keepTestRunsPeriod,
generateShareToken: this.formControls.generateShareToken,
@@ -305,16 +309,18 @@ export class SettingsScenarioComponent implements OnInit {
thresholdThroughput,
deleteSamples,
zeroErrorToleranceEnabled,
+ minTestDuration,
keepTestRunsPeriod,
generateShareToken,
extraAggregations
} = this.scenarioSettingsForm.value;
- const { apdexEnabled, satisfyingThreshold, toleratingThreshold } = this.apdexSettingsForm.value
+ const { apdexEnabled, satisfyingThreshold, toleratingThreshold } = this.apdexSettingsForm.value;
const { projectName, scenarioName: currentScenarioName } = this.params;
const body = {
scenarioName,
analysisEnabled,
zeroErrorToleranceEnabled,
+ minTestDuration,
keepTestRunsPeriod,
deleteSamples,
generateShareToken,
@@ -365,5 +371,6 @@ export class SettingsScenarioComponent implements OnInit {
return name === this.params.scenarioName;
}
+ protected readonly JSON = JSON;
}
diff --git a/src/app/scenario/scenario.component.html b/src/app/scenario/scenario.component.html
index eedc4534..5b0cddf8 100644
--- a/src/app/scenario/scenario.component.html
+++ b/src/app/scenario/scenario.component.html
@@ -119,13 +119,10 @@