This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 874499fb16 test(frontend): add tests for
WorkflowComputingUnitManagingService (#6469)
874499fb16 is described below
commit 874499fb167ce518657b6a734a62253ce17b5bc8
Author: Matthew B. <[email protected]>
AuthorDate: Thu Jul 16 13:06:25 2026 -0700
test(frontend): add tests for WorkflowComputingUnitManagingService (#6469)
### What changes were proposed in this PR?
- Adds workflow-computing-unit-managing.service.spec.ts covering
WorkflowComputingUnitManagingService; no production code changed.
- Verifies the create, terminate, list and rename endpoints (methods,
bodies, URI encoding).
- Covers resource-JSON parsing: valid string, malformed fallback, and
already-parsed object.
### Any related issues, documentation, discussions?
Closes: #6457
### How was this PR tested?
- Run `cd frontend && npx nx test gui
--include="**/workflow-computing-unit-managing.service.spec.ts"`, expect
10 passed.
- Full frontend suite runs in CI via `yarn test:ci`, selected by the
auto-applied `frontend` label.
### Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF
---
...orkflow-computing-unit-managing.service.spec.ts | 164 +++++++++++++++++++++
1 file changed, 164 insertions(+)
diff --git
a/frontend/src/app/common/service/computing-unit/workflow-computing-unit/workflow-computing-unit-managing.service.spec.ts
b/frontend/src/app/common/service/computing-unit/workflow-computing-unit/workflow-computing-unit-managing.service.spec.ts
new file mode 100644
index 0000000000..53983e0e88
--- /dev/null
+++
b/frontend/src/app/common/service/computing-unit/workflow-computing-unit/workflow-computing-unit-managing.service.spec.ts
@@ -0,0 +1,164 @@
+/**
+ * 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 { HttpClientTestingModule, HttpTestingController } from
"@angular/common/http/testing";
+import { TestBed } from "@angular/core/testing";
+import { AppSettings } from "../../../app-setting";
+import {
+ WorkflowComputingUnitManagingService,
+ COMPUTING_UNIT_BASE_URL,
+ COMPUTING_UNIT_CREATE_URL,
+ COMPUTING_UNIT_LIST_URL,
+ COMPUTING_UNIT_TYPES_URL,
+} from "./workflow-computing-unit-managing.service";
+
+describe("WorkflowComputingUnitManagingService", () => {
+ let service: WorkflowComputingUnitManagingService;
+ let httpMock: HttpTestingController;
+
+ const api = AppSettings.getApiEndpoint();
+ const unitWithResource = (resource: any) => ({ computingUnit: { cuid: 1,
name: "u", resource } }) as any;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [WorkflowComputingUnitManagingService],
+ });
+ service = TestBed.inject(WorkflowComputingUnitManagingService);
+ httpMock = TestBed.inject(HttpTestingController);
+ });
+
+ afterEach(() => {
+ httpMock.verify();
+ });
+
+ it("should be created", () => {
+ expect(service).toBeTruthy();
+ });
+
+ describe("createKubernetesBasedComputingUnit", () => {
+ it("POSTs a kubernetes body with an empty uri and parses the resource JSON
string", () => {
+ let result: any;
+ service.createKubernetesBasedComputingUnit("k8s", "2", "4G", "1", "1G",
"64M").subscribe(r => (result = r));
+
+ const req = httpMock.expectOne(`${api}/${COMPUTING_UNIT_CREATE_URL}`);
+ expect(req.request.method).toEqual("POST");
+ expect(req.request.body).toEqual({
+ name: "k8s",
+ cpuLimit: "2",
+ memoryLimit: "4G",
+ gpuLimit: "1",
+ jvmMemorySize: "1G",
+ shmSize: "64M",
+ uri: "",
+ unitType: "kubernetes",
+ });
+
+ req.flush(unitWithResource('{"cpuLimit":"2","memoryLimit":"4G"}'));
+ expect(result.computingUnit.resource).toEqual({ cpuLimit: "2",
memoryLimit: "4G" });
+ });
+ });
+
+ describe("createLocalComputingUnit", () => {
+ it("POSTs a local body with NaN resource placeholders and the given uri",
() => {
+ service.createLocalComputingUnit("local",
"http://localhost:8080").subscribe();
+
+ const req = httpMock.expectOne(`${api}/${COMPUTING_UNIT_CREATE_URL}`);
+ expect(req.request.body).toEqual({
+ name: "local",
+ cpuLimit: "NaN",
+ memoryLimit: "NaN",
+ gpuLimit: "NaN",
+ jvmMemorySize: "NaN",
+ shmSize: "NaN",
+ uri: "http://localhost:8080",
+ unitType: "local",
+ });
+ req.flush(unitWithResource({ cpuLimit: "NaN" }));
+ });
+ });
+
+ describe("resource parsing", () => {
+ it("falls back to a NaN-filled resource object when the resource JSON is
malformed", () => {
+ let result: any;
+ service.getComputingUnit(5).subscribe(r => (result = r));
+
+
httpMock.expectOne(`${api}/${COMPUTING_UNIT_BASE_URL}/5`).flush(unitWithResource("not-json"));
+
+ expect(result.computingUnit.resource).toEqual({
+ cpuLimit: "NaN",
+ memoryLimit: "NaN",
+ gpuLimit: "NaN",
+ jvmMemorySize: "NaN",
+ shmSize: "NaN",
+ nodeAddresses: [],
+ });
+ });
+
+ it("leaves an already-parsed resource object untouched", () => {
+ let result: any;
+ service.getComputingUnit(6).subscribe(r => (result = r));
+
+ const resource = { cpuLimit: "1", nodeAddresses: ["a"] };
+
httpMock.expectOne(`${api}/${COMPUTING_UNIT_BASE_URL}/6`).flush(unitWithResource(resource));
+
+ expect(result.computingUnit.resource).toEqual(resource);
+ });
+ });
+
+ it("terminateComputingUnit() DELETEs the terminate endpoint", () => {
+ service.terminateComputingUnit(9).subscribe();
+ const req =
httpMock.expectOne(`${api}/${COMPUTING_UNIT_BASE_URL}/9/terminate`);
+ expect(req.request.method).toEqual("DELETE");
+ req.flush({});
+ });
+
+ it("getComputingUnitLimitOptions() GETs the limits endpoint", () => {
+ service.getComputingUnitLimitOptions().subscribe();
+ const req = httpMock.expectOne(`${api}/${COMPUTING_UNIT_BASE_URL}/limits`);
+ expect(req.request.method).toEqual("GET");
+ req.flush({ cpuLimitOptions: [], memoryLimitOptions: [], gpuLimitOptions:
[] });
+ });
+
+ it("getComputingUnitTypes() GETs the types endpoint", () => {
+ service.getComputingUnitTypes().subscribe();
+ const req = httpMock.expectOne(`${api}/${COMPUTING_UNIT_TYPES_URL}`);
+ expect(req.request.method).toEqual("GET");
+ req.flush({ typeOptions: [] });
+ });
+
+ it("listComputingUnits() GETs the list endpoint and parses every unit's
resource", () => {
+ let result: any[] = [];
+ service.listComputingUnits().subscribe(r => (result = r));
+
+ const req = httpMock.expectOne(`${api}/${COMPUTING_UNIT_LIST_URL}`);
+ expect(req.request.method).toEqual("GET");
+ req.flush([unitWithResource('{"cpuLimit":"1"}'),
unitWithResource('{"cpuLimit":"2"}')]);
+
+ expect(result.map(u => u.computingUnit.resource)).toEqual([{ cpuLimit: "1"
}, { cpuLimit: "2" }]);
+ });
+
+ it("renameComputingUnit() PUTs to a URI-encoded rename endpoint", () => {
+ service.renameComputingUnit(3, "my unit/name").subscribe();
+
+ const req =
httpMock.expectOne(`${api}/${COMPUTING_UNIT_BASE_URL}/3/rename/${encodeURIComponent("my
unit/name")}`);
+ expect(req.request.method).toEqual("PUT");
+ req.flush({});
+ });
+});