Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/manual-test-matrix-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
with:
name: "${{ github.run_id}}-${{ strategy.job-index }}-artifacts"
path: |
packages/testsuite/results
results
packages/testsuite/cypress/videos
process_report:
name: "Collect results & deploy GH pages"
Expand All @@ -104,6 +104,8 @@ jobs:
node-version: "22"
- name: "Install necessary tools"
run: npm install -g copyfiles gh-pages@3.0.0 mochawesome-merge mochawesome-report-generator
- name: "List downloaded artifacts"
run: find . -name "*.json" -path "*/results/*" | head -50
- name: "Generate Mochawesome Report"
run: mochawesome-merge "./*-artifacts/results/packages/testsuite/cypress/e2e/*.json" > mochawesome.json
- name: "Copy video assets"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/scheduled-run-all-tests-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
with:
name: "${{ github.run_id}}-${{ strategy.job-index }}-artifacts"
path: |
packages/testsuite/results
results
packages/testsuite/cypress/videos
process_report:
name: "Collect results & deploy GH pages"
Expand All @@ -96,6 +96,8 @@ jobs:
node-version: "22"
- name: "Install necessary tools"
run: npm install -g copyfiles gh-pages@3.0.0 mochawesome-merge mochawesome-report-generator
- name: "List downloaded artifacts"
run: find . -name "*.json" -path "*/results/*" | head -50
- name: "Generate Mochawesome Report"
run: mochawesome-merge "./*-artifacts/results/packages/testsuite/cypress/e2e/*.json" > mochawesome.json
- name: "Copy video assets"
Expand Down
46 changes: 24 additions & 22 deletions config/tasks/wildfly-tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,29 @@ export function createExecuteInContainer(
return Promise.reject(new Error(`Container ${containerName} not found`));
}

return containerToExec
.exec([
"/bin/sh",
"-c",
`${JBOSS_CLI_PATH} --connect --controller=localhost:${managementPort} --commands=${command}`,
])
.then((value) => {
if (value.exitCode === 0) {
return value;
} else {
logger.debug(value);
throw new Error(`Command failed with exit code ${value.exitCode}: ${value.output || ""}`);
}
})
// Only container.exec() errors and plain Errors from the .then() block can reach here.
// AxiosErrorResponse is not possible — Axios is not used in this function.
.catch((err: unknown) => {
if (err instanceof Error) {
throw err;
}
throw new Error(String(err));
});
return (
containerToExec
.exec([
"/bin/sh",
"-c",
`${JBOSS_CLI_PATH} --connect --controller=localhost:${managementPort} --commands=${command}`,
])
.then((value) => {
if (value.exitCode === 0) {
return value;
} else {
logger.debug(value);
throw new Error(`Command failed with exit code ${value.exitCode}: ${value.output || ""}`);
}
})
// Only container.exec() errors and plain Errors from the .then() block can reach here.
// AxiosErrorResponse is not possible — Axios is not used in this function.
.catch((err: unknown) => {
if (err instanceof Error) {
throw err;
}
throw new Error(String(err));
})
);
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
describe("TESTS: Configuration => Subsystem => Micrometer => Registry => OTLP", () => {
const subsystemAddress = ["subsystem", "micrometer"];
const address = ["subsystem", "micrometer", "registry", "otlp"];

// HAL generates form IDs with triple-dash separators for child resources,
// but collapses them to single dashes in some sub-elements (editing div, save button).
const formIds = {
configuration: "model-browser-model-browser-root---registry---otlp-form",
configurationNoDash: "model-browser-model-browser-root-registry-otlp-form",
addWizard: "model-browser-root-registry-singleton-add",
childrenTable: "model-browser-children-table",
};

const treeNodes = {
registry: "#model-browser-root___registry",
otlp: "#model-browser-root___registry___otlp",
};

const endpointAttr = {
name: "endpoint",
customValue: "http://otel-collector:4318/v1/metrics",
expressionProperty: "micrometer.otlp.endpoint",
expressionPropertyValue: "http://expression-endpoint:4318/v1/metrics",
expressionValue: "${micrometer.otlp.endpoint}",
};

const stepAttr = {
name: "step",
customValue: 30,
expressionProperty: "micrometer.otlp.step",
expressionPropertyValue: "45",
expressionValue: "${micrometer.otlp.step}",
};

// Context value for prometheus registry (required field, avoids conflict with metrics subsystem)
const prometheusContext = "/prometheus";

let managementEndpoint: string;

function navigateToOtlpRegistry() {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(`${treeNodes.registry} > .jstree-ocl`).click();
cy.get(treeNodes.otlp).should("be.visible").click();
cy.get('#model-browser-resource-tab-container a[href="#model-browser-resource-data-tab"]').click();
}

// Workaround for JBEAP-28819 - child resource form IDs use triple-dash separators
// for the container but single-dash for the editing div.
function editForm() {
const editButton = "#" + formIds.configuration + ' a.clickable[data-operation="edit"]';
cy.get(`#${formIds.configurationNoDash}-editing`).should("not.be.visible");
cy.get(editButton).click();
for (let reClickTry = 0; reClickTry < 5; reClickTry++) {
cy.get(editButton).then(($button) => {
if ($button.is(":visible")) {
cy.get(editButton).click();
}
});
}
cy.get(`#${formIds.configurationNoDash}-editing`).should("be.visible");
}

before(function () {
cy.startWildflyContainer().then((result) => {
managementEndpoint = result as string;
cy.skipIf(cy.isEAP(managementEndpoint), this);
// The micrometer extension is not part of the base configuration, so it must be added explicitly
cy.addAddress(managementEndpoint, ["extension", "org.wildfly.extension.micrometer"], {});
// Register the micrometer subsystem as a parent for the registries
cy.addAddress(managementEndpoint, subsystemAddress, {});
// System properties used as expression resolution targets in the expression tests
cy.addAddress(managementEndpoint, ["system-property", endpointAttr.expressionProperty], {
value: endpointAttr.expressionPropertyValue,
});
cy.addAddress(managementEndpoint, ["system-property", stepAttr.expressionProperty], {
value: stepAttr.expressionPropertyValue,
});
});
});

after(() => {
cy.task("stop:containers");
});

it("Add otlp registry", () => {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(treeNodes.registry).should("be.visible").click();
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
cy.addInTable(formIds.childrenTable);
// First registry added: wizard shows radio button step, otlp has no required fields
cy.get("input[type='radio'][value='otlp']").should("exist").check({ force: true });
cy.get("input[type='radio'][value='otlp']").should("be.checked");
cy.confirmNextInWizard();
cy.confirmFinishInWizard();
cy.verifySuccess();
});

it("Add prometheus registry", () => {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(treeNodes.registry).should("be.visible").click();
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
cy.addInTable(formIds.childrenTable);
// Second registry added: wizard skips radio button step, prometheus requires context
cy.text(formIds.addWizard, "context", prometheusContext);
cy.confirmAddResourceWizard();
cy.verifySuccess();
});

it("Edit endpoint", () => {
navigateToOtlpRegistry();
editForm();
cy.text(formIds.configurationNoDash, endpointAttr.name, endpointAttr.customValue);
cy.saveForm(formIds.configurationNoDash);
cy.verifySuccess();
cy.verifyAttribute(managementEndpoint, address, endpointAttr.name, endpointAttr.customValue);
});

it("Edit step", () => {
navigateToOtlpRegistry();
editForm();
cy.text(formIds.configurationNoDash, stepAttr.name, stepAttr.customValue.toString());
cy.saveForm(formIds.configurationNoDash);
cy.verifySuccess();
cy.verifyAttribute(managementEndpoint, address, stepAttr.name, stepAttr.customValue);
});

it("Edit endpoint with expression", () => {
const selector = `input#${formIds.configurationNoDash}-${endpointAttr.name}-editing.form-control`;
navigateToOtlpRegistry();
editForm();
cy.textExpression(formIds.configurationNoDash, endpointAttr.name, endpointAttr.expressionValue, { selector });
cy.saveForm(formIds.configurationNoDash);
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
cy.verifyAttributeAsExpression(managementEndpoint, address, endpointAttr.name, endpointAttr.expressionValue);
});

it("Edit step with expression", () => {
const selector = `input#${formIds.configurationNoDash}-${stepAttr.name}-editing.form-control`;
navigateToOtlpRegistry();
editForm();
cy.textExpression(formIds.configurationNoDash, stepAttr.name, stepAttr.expressionValue, { selector });
cy.saveForm(formIds.configurationNoDash);
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
cy.verifyAttributeAsExpression(managementEndpoint, address, stepAttr.name, stepAttr.expressionValue);
});

it("Reset configuration", () => {
navigateToOtlpRegistry();
cy.resetForm(formIds.configuration, managementEndpoint, address);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
describe("TESTS: Configuration => Subsystem => Micrometer => Registry => Prometheus", () => {
const subsystemAddress = ["subsystem", "micrometer"];
const address = ["subsystem", "micrometer", "registry", "prometheus"];

// HAL generates form IDs with triple-dash separators for child resources,
// but collapses them to single dashes in some sub-elements (editing div, save button).
const formIds = {
configuration: "model-browser-model-browser-root---registry---prometheus-form",
configurationNoDash: "model-browser-model-browser-root-registry-prometheus-form",
addWizard: "model-browser-root-registry-singleton-add",
childrenTable: "model-browser-children-table",
};

const treeNodes = {
registry: "#model-browser-root___registry",
prometheus: "#model-browser-root___registry___prometheus",
};

const contextAttr = {
name: "context",
// Default context is set to "/prometheus" to avoid a capability conflict with the metrics subsystem.
// Both serve an HTTP management context, and "/metrics" is already taken by the metrics subsystem.
defaultValue: "/prometheus",
customValue: "/prom-custom",
expressionProperty: "micrometer.prometheus.context",
expressionPropertyValue: "/prom-expression",
expressionValue: "${micrometer.prometheus.context}",
};

const securityEnabled = "security-enabled";

let managementEndpoint: string;

function navigateToPrometheusRegistry() {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(`${treeNodes.registry} > .jstree-ocl`).click();
cy.get(treeNodes.prometheus).should("be.visible").click();
cy.get('#model-browser-resource-tab-container a[href="#model-browser-resource-data-tab"]').click();
}

// Workaround for JBEAP-28819 - child resource form IDs use triple-dash separators
// for the container but single-dash for the editing div.
function editForm() {
const editButton = "#" + formIds.configuration + ' a.clickable[data-operation="edit"]';
cy.get(`#${formIds.configurationNoDash}-editing`).should("not.be.visible");
cy.get(editButton).click();
for (let reClickTry = 0; reClickTry < 5; reClickTry++) {
cy.get(editButton).then(($button) => {
if ($button.is(":visible")) {
cy.get(editButton).click();
}
});
}
cy.get(`#${formIds.configurationNoDash}-editing`).should("be.visible");
}

before(function () {
cy.startWildflyContainer().then((result) => {
managementEndpoint = result as string;
cy.skipIf(cy.isEAP(managementEndpoint), this);
// The micrometer extension is not part of the base configuration, so it must be added explicitly
cy.addAddress(managementEndpoint, ["extension", "org.wildfly.extension.micrometer"], {});
// Register the micrometer subsystem as a parent for the registries
cy.addAddress(managementEndpoint, subsystemAddress, {});
// System property used as expression resolution target in the expression test
cy.addAddress(managementEndpoint, ["system-property", contextAttr.expressionProperty], {
value: contextAttr.expressionPropertyValue,
});
});
});

after(() => {
cy.task("stop:containers");
});

it("Add otlp registry", () => {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(treeNodes.registry).should("be.visible").click();
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
cy.addInTable(formIds.childrenTable);
// First registry added: wizard shows radio button step, otlp has no required fields
cy.get("input[type='radio'][value='otlp']").should("exist").check({ force: true });
cy.get("input[type='radio'][value='otlp']").should("be.checked");
cy.confirmNextInWizard();
cy.confirmFinishInWizard();
cy.verifySuccess();
});

it("Add prometheus registry", () => {
cy.navigateToGenericSubsystemPage(managementEndpoint, subsystemAddress);
cy.get(treeNodes.registry).should("be.visible").click();
cy.get(`#${formIds.childrenTable}_wrapper`).should("be.visible");
cy.addInTable(formIds.childrenTable);
// Second registry added: wizard skips radio button step, prometheus requires context
cy.text(formIds.addWizard, contextAttr.name, contextAttr.defaultValue);
cy.confirmAddResourceWizard();
cy.verifySuccess();
cy.verifyAttribute(managementEndpoint, address, contextAttr.name, contextAttr.defaultValue);
});

it("Edit context", () => {
navigateToPrometheusRegistry();
editForm();
cy.text(formIds.configurationNoDash, contextAttr.name, contextAttr.customValue);
cy.saveForm(formIds.configurationNoDash);
cy.verifySuccess();
cy.verifyAttribute(managementEndpoint, address, contextAttr.name, contextAttr.customValue);
});

it("Toggle security-enabled", () => {
cy.readAttributeAsBoolean(managementEndpoint, address, securityEnabled).then((defaultValue: boolean) => {
navigateToPrometheusRegistry();
editForm();
cy.flip(formIds.configurationNoDash, securityEnabled, defaultValue);
cy.saveForm(formIds.configurationNoDash);
cy.verifySuccess();
cy.verifyAttribute(managementEndpoint, address, securityEnabled, !defaultValue);
});
});

it("Edit context with expression", () => {
const selector = `input#${formIds.configurationNoDash}-${contextAttr.name}-editing.form-control`;
navigateToPrometheusRegistry();
editForm();
cy.textExpression(formIds.configurationNoDash, contextAttr.name, contextAttr.expressionValue, { selector });
cy.saveForm(formIds.configurationNoDash);
cy.get(".toast-notifications-list-pf .alert").should("be.visible");
cy.verifyAttributeAsExpression(managementEndpoint, address, contextAttr.name, contextAttr.expressionValue);
});

it("Reset configuration", () => {
navigateToPrometheusRegistry();
cy.resetForm(formIds.configuration, managementEndpoint, address);
});
});
Loading
Loading