Skip to content

Commit bd2d882

Browse files
committed
EAP7-2053 add new test for micrometer subsystem
1 parent 7de4dfe commit bd2d882

8 files changed

Lines changed: 409 additions & 27 deletions

.github/workflows/manual-test-matrix-workflow.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
with:
8989
name: "${{ github.run_id}}-${{ strategy.job-index }}-artifacts"
9090
path: |
91-
packages/testsuite/results
91+
results
9292
packages/testsuite/cypress/videos
9393
process_report:
9494
name: "Collect results & deploy GH pages"

.github/workflows/scheduled-run-all-tests-workflow.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
with:
8181
name: "${{ github.run_id}}-${{ strategy.job-index }}-artifacts"
8282
path: |
83-
packages/testsuite/results
83+
results
8484
packages/testsuite/cypress/videos
8585
process_report:
8686
name: "Collect results & deploy GH pages"

config/tasks/wildfly-tasks.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,29 @@ export function createExecuteInContainer(
7676
return Promise.reject(new Error(`Container ${containerName} not found`));
7777
}
7878

79-
return containerToExec
80-
.exec([
81-
"/bin/sh",
82-
"-c",
83-
`${JBOSS_CLI_PATH} --connect --controller=localhost:${managementPort} --commands=${command}`,
84-
])
85-
.then((value) => {
86-
if (value.exitCode === 0) {
87-
return value;
88-
} else {
89-
logger.debug(value);
90-
throw new Error(`Command failed with exit code ${value.exitCode}: ${value.output || ""}`);
91-
}
92-
})
93-
// Only container.exec() errors and plain Errors from the .then() block can reach here.
94-
// AxiosErrorResponse is not possible — Axios is not used in this function.
95-
.catch((err: unknown) => {
96-
if (err instanceof Error) {
97-
throw err;
98-
}
99-
throw new Error(String(err));
100-
});
79+
return (
80+
containerToExec
81+
.exec([
82+
"/bin/sh",
83+
"-c",
84+
`${JBOSS_CLI_PATH} --connect --controller=localhost:${managementPort} --commands=${command}`,
85+
])
86+
.then((value) => {
87+
if (value.exitCode === 0) {
88+
return value;
89+
} else {
90+
logger.debug(value);
91+
throw new Error(`Command failed with exit code ${value.exitCode}: ${value.output || ""}`);
92+
}
93+
})
94+
// Only container.exec() errors and plain Errors from the .then() block can reach here.
95+
// AxiosErrorResponse is not possible — Axios is not used in this function.
96+
.catch((err: unknown) => {
97+
if (err instanceof Error) {
98+
throw err;
99+
}
100+
throw new Error(String(err));
101+
})
102+
);
101103
};
102104
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
describe("TESTS: Configuration => Subsystem => Micrometer => Registry => OTLP", () => {
2+
const subsystemAddress = ["subsystem", "micrometer"];
3+
const address = ["subsystem", "micrometer", "registry", "otlp"];
4+
5+
// HAL generates form IDs with triple-dash separators for child resources,
6+
// but collapses them to single dashes in some sub-elements (editing div, save button).
7+
const formIds = {
8+
configuration: "model-browser-model-browser-root---registry---otlp-form",
9+
configurationNoDash: "model-browser-model-browser-root-registry-otlp-form",
10+
addWizard: "model-browser-root-registry-singleton-add",
11+
childrenTable: "model-browser-children-table",
12+
};
13+
14+
const treeNodes = {
15+
registry: "#model-browser-root___registry",
16+
otlp: "#model-browser-root___registry___otlp",
17+
};
18+
19+
const endpointAttr = {
20+
name: "endpoint",
21+
customValue: "http://otel-collector:4318/v1/metrics",
22+
expressionProperty: "micrometer.otlp.endpoint",
23+
expressionPropertyValue: "http://expression-endpoint:4318/v1/metrics",
24+
expressionValue: "${micrometer.otlp.endpoint}",
25+
};
26+
27+
const stepAttr = {
28+
name: "step",
29+
customValue: 30,
30+
expressionProperty: "micrometer.otlp.step",
31+
expressionPropertyValue: "45",
32+
expressionValue: "${micrometer.otlp.step}",
33+
};
34+
35+
// Context value for prometheus registry (required field, avoids conflict with metrics subsystem)
36+
const prometheusContext = "/prometheus";
37+
38+
let managementEndpoint: string;
39+
40+
function navigateToOtlpRegistry() {
41+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
42+
cy.get(`${treeNodes.registry} > .jstree-ocl`).click();
43+
cy.get(treeNodes.otlp).should("be.visible").click();
44+
cy.get('#model-browser-resource-tab-container a[href="#model-browser-resource-data-tab"]').click();
45+
}
46+
47+
// Workaround for JBEAP-28819 - child resource form IDs use triple-dash separators
48+
// for the container but single-dash for the editing div.
49+
function editForm() {
50+
const editButton = "#" + formIds.configuration + ' a.clickable[data-operation="edit"]';
51+
cy.get(`#${formIds.configurationNoDash}-editing`).should("not.be.visible");
52+
cy.get(editButton).click();
53+
for (let reClickTry = 0; reClickTry < 5; reClickTry++) {
54+
cy.get(editButton).then(($button) => {
55+
if ($button.is(":visible")) {
56+
cy.get(editButton).click();
57+
}
58+
});
59+
}
60+
cy.get(`#${formIds.configurationNoDash}-editing`).should("be.visible");
61+
}
62+
63+
before(function () {
64+
cy.startWildflyContainer().then((result) => {
65+
managementEndpoint = result as string;
66+
cy.skipIf(cy.isEAP(managementEndpoint), this);
67+
// The micrometer extension is not part of the base configuration, so it must be added explicitly
68+
cy.addAddress(managementEndpoint, ["extension", "org.wildfly.extension.micrometer"], {});
69+
// Register the micrometer subsystem as a parent for the registries
70+
cy.addAddress(managementEndpoint, subsystemAddress, {});
71+
// System properties used as expression resolution targets in the expression tests
72+
cy.addAddress(managementEndpoint, ["system-property", endpointAttr.expressionProperty], {
73+
value: endpointAttr.expressionPropertyValue,
74+
});
75+
cy.addAddress(managementEndpoint, ["system-property", stepAttr.expressionProperty], {
76+
value: stepAttr.expressionPropertyValue,
77+
});
78+
});
79+
});
80+
81+
after(() => {
82+
cy.task("stop:containers");
83+
});
84+
85+
it("Add otlp registry", () => {
86+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
87+
cy.get(treeNodes.registry).should("be.visible").click();
88+
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
89+
cy.addInTable(formIds.childrenTable);
90+
// First registry added: wizard shows radio button step, otlp has no required fields
91+
cy.get("input[type='radio'][value='otlp']").should("exist").check({ force: true });
92+
cy.get("input[type='radio'][value='otlp']").should("be.checked");
93+
cy.confirmNextInWizard();
94+
cy.confirmFinishInWizard();
95+
cy.verifySuccess();
96+
});
97+
98+
it("Add prometheus registry", () => {
99+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
100+
cy.get(treeNodes.registry).should("be.visible").click();
101+
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
102+
cy.addInTable(formIds.childrenTable);
103+
// Second registry added: wizard skips radio button step, prometheus requires context
104+
cy.text(formIds.addWizard, "context", prometheusContext);
105+
cy.confirmAddResourceWizard();
106+
cy.verifySuccess();
107+
});
108+
109+
it("Edit endpoint", () => {
110+
navigateToOtlpRegistry();
111+
editForm();
112+
cy.text(formIds.configurationNoDash, endpointAttr.name, endpointAttr.customValue);
113+
cy.saveForm(formIds.configurationNoDash);
114+
cy.verifySuccess();
115+
cy.verifyAttribute(managementEndpoint, address, endpointAttr.name, endpointAttr.customValue);
116+
});
117+
118+
it("Edit step", () => {
119+
navigateToOtlpRegistry();
120+
editForm();
121+
cy.text(formIds.configurationNoDash, stepAttr.name, stepAttr.customValue.toString());
122+
cy.saveForm(formIds.configurationNoDash);
123+
cy.verifySuccess();
124+
cy.verifyAttribute(managementEndpoint, address, stepAttr.name, stepAttr.customValue);
125+
});
126+
127+
it("Edit endpoint with expression", () => {
128+
const selector = `input#${formIds.configurationNoDash}-${endpointAttr.name}-editing.form-control`;
129+
navigateToOtlpRegistry();
130+
editForm();
131+
cy.textExpression(formIds.configurationNoDash, endpointAttr.name, endpointAttr.expressionValue, { selector });
132+
cy.saveForm(formIds.configurationNoDash);
133+
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
134+
cy.verifyAttributeAsExpression(managementEndpoint, address, endpointAttr.name, endpointAttr.expressionValue);
135+
});
136+
137+
it("Edit step with expression", () => {
138+
const selector = `input#${formIds.configurationNoDash}-${stepAttr.name}-editing.form-control`;
139+
navigateToOtlpRegistry();
140+
editForm();
141+
cy.textExpression(formIds.configurationNoDash, stepAttr.name, stepAttr.expressionValue, { selector });
142+
cy.saveForm(formIds.configurationNoDash);
143+
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
144+
cy.verifyAttributeAsExpression(managementEndpoint, address, stepAttr.name, stepAttr.expressionValue);
145+
});
146+
147+
it("Reset configuration", () => {
148+
navigateToOtlpRegistry();
149+
cy.resetForm(formIds.configuration, managementEndpoint, address);
150+
});
151+
});
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
describe("TESTS: Configuration => Subsystem => Micrometer => Registry => Prometheus", () => {
2+
const subsystemAddress = ["subsystem", "micrometer"];
3+
const address = ["subsystem", "micrometer", "registry", "prometheus"];
4+
5+
// HAL generates form IDs with triple-dash separators for child resources,
6+
// but collapses them to single dashes in some sub-elements (editing div, save button).
7+
const formIds = {
8+
configuration: "model-browser-model-browser-root---registry---prometheus-form",
9+
configurationNoDash: "model-browser-model-browser-root-registry-prometheus-form",
10+
addWizard: "model-browser-root-registry-singleton-add",
11+
childrenTable: "model-browser-children-table",
12+
};
13+
14+
const treeNodes = {
15+
registry: "#model-browser-root___registry",
16+
prometheus: "#model-browser-root___registry___prometheus",
17+
};
18+
19+
const contextAttr = {
20+
name: "context",
21+
// Default context is set to "/prometheus" to avoid a capability conflict with the metrics subsystem.
22+
// Both serve an HTTP management context, and "/metrics" is already taken by the metrics subsystem.
23+
defaultValue: "/prometheus",
24+
customValue: "/prom-custom",
25+
expressionProperty: "micrometer.prometheus.context",
26+
expressionPropertyValue: "/prom-expression",
27+
expressionValue: "${micrometer.prometheus.context}",
28+
};
29+
30+
const securityEnabled = "security-enabled";
31+
32+
let managementEndpoint: string;
33+
34+
function navigateToPrometheusRegistry() {
35+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
36+
cy.get(`${treeNodes.registry} > .jstree-ocl`).click();
37+
cy.get(treeNodes.prometheus).should("be.visible").click();
38+
cy.get('#model-browser-resource-tab-container a[href="#model-browser-resource-data-tab"]').click();
39+
}
40+
41+
// Workaround for JBEAP-28819 - child resource form IDs use triple-dash separators
42+
// for the container but single-dash for the editing div.
43+
function editForm() {
44+
const editButton = "#" + formIds.configuration + ' a.clickable[data-operation="edit"]';
45+
cy.get(`#${formIds.configurationNoDash}-editing`).should("not.be.visible");
46+
cy.get(editButton).click();
47+
for (let reClickTry = 0; reClickTry < 5; reClickTry++) {
48+
cy.get(editButton).then(($button) => {
49+
if ($button.is(":visible")) {
50+
cy.get(editButton).click();
51+
}
52+
});
53+
}
54+
cy.get(`#${formIds.configurationNoDash}-editing`).should("be.visible");
55+
}
56+
57+
before(function () {
58+
cy.startWildflyContainer().then((result) => {
59+
managementEndpoint = result as string;
60+
cy.skipIf(cy.isEAP(managementEndpoint), this);
61+
// The micrometer extension is not part of the base configuration, so it must be added explicitly
62+
cy.addAddress(managementEndpoint, ["extension", "org.wildfly.extension.micrometer"], {});
63+
// Register the micrometer subsystem as a parent for the registries
64+
cy.addAddress(managementEndpoint, subsystemAddress, {});
65+
// System property used as expression resolution target in the expression test
66+
cy.addAddress(managementEndpoint, ["system-property", contextAttr.expressionProperty], {
67+
value: contextAttr.expressionPropertyValue,
68+
});
69+
});
70+
});
71+
72+
after(() => {
73+
cy.task("stop:containers");
74+
});
75+
76+
it("Add otlp registry", () => {
77+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
78+
cy.get(treeNodes.registry).should("be.visible").click();
79+
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
80+
cy.addInTable(formIds.childrenTable);
81+
// First registry added: wizard shows radio button step, otlp has no required fields
82+
cy.get("input[type='radio'][value='otlp']").should("exist").check({ force: true });
83+
cy.get("input[type='radio'][value='otlp']").should("be.checked");
84+
cy.confirmNextInWizard();
85+
cy.confirmFinishInWizard();
86+
cy.verifySuccess();
87+
});
88+
89+
it("Add prometheus registry", () => {
90+
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
91+
cy.get(treeNodes.registry).should("be.visible").click();
92+
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
93+
cy.addInTable(formIds.childrenTable);
94+
// Second registry added: wizard skips radio button step, prometheus requires context
95+
cy.text(formIds.addWizard, contextAttr.name, contextAttr.defaultValue);
96+
cy.confirmAddResourceWizard();
97+
cy.verifySuccess();
98+
cy.verifyAttribute(managementEndpoint, address, contextAttr.name, contextAttr.defaultValue);
99+
});
100+
101+
it("Edit context", () => {
102+
navigateToPrometheusRegistry();
103+
editForm();
104+
cy.text(formIds.configurationNoDash, contextAttr.name, contextAttr.customValue);
105+
cy.saveForm(formIds.configurationNoDash);
106+
cy.verifySuccess();
107+
cy.verifyAttribute(managementEndpoint, address, contextAttr.name, contextAttr.customValue);
108+
});
109+
110+
it("Toggle security-enabled", () => {
111+
cy.readAttributeAsBoolean(managementEndpoint, address, securityEnabled).then((defaultValue: boolean) => {
112+
navigateToPrometheusRegistry();
113+
editForm();
114+
cy.flip(formIds.configurationNoDash, securityEnabled, defaultValue);
115+
cy.saveForm(formIds.configurationNoDash);
116+
cy.verifySuccess();
117+
cy.verifyAttribute(managementEndpoint, address, securityEnabled, !defaultValue);
118+
});
119+
});
120+
121+
it("Edit context with expression", () => {
122+
const selector = `input#${formIds.configurationNoDash}-${contextAttr.name}-editing.form-control`;
123+
navigateToPrometheusRegistry();
124+
editForm();
125+
cy.textExpression(formIds.configurationNoDash, contextAttr.name, contextAttr.expressionValue, { selector });
126+
cy.saveForm(formIds.configurationNoDash);
127+
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
128+
cy.verifyAttributeAsExpression(managementEndpoint, address, contextAttr.name, contextAttr.expressionValue);
129+
});
130+
131+
it("Reset configuration", () => {
132+
navigateToPrometheusRegistry();
133+
cy.resetForm(formIds.configuration, managementEndpoint, address);
134+
});
135+
});

0 commit comments

Comments
 (0)