From b9519973ddbe0d221fa80408f11904403bfe674f Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 15 Oct 2024 22:09:28 +0200 Subject: [PATCH 01/19] Changed package, added information to CODEOWNERS --- tpu/pom.xml | 98 ++++++++++++++ tpu/src/main/java/tpu/CreateTpuVm.java | 67 +++++++++ tpu/src/main/java/tpu/DeleteTpuVm.java | 54 ++++++++ tpu/src/main/java/tpu/GetTpuVm.java | 53 ++++++++ tpu/src/main/java/tpu/ListTpuVms.java | 51 +++++++ tpu/src/main/java/tpu/StartTpuVm.java | 55 ++++++++ tpu/src/main/java/tpu/StopTpuVm.java | 55 ++++++++ tpu/src/test/java/tpu/TpuVmIT.java | 179 +++++++++++++++++++++++++ 8 files changed, 612 insertions(+) create mode 100644 tpu/pom.xml create mode 100644 tpu/src/main/java/tpu/CreateTpuVm.java create mode 100644 tpu/src/main/java/tpu/DeleteTpuVm.java create mode 100644 tpu/src/main/java/tpu/GetTpuVm.java create mode 100644 tpu/src/main/java/tpu/ListTpuVms.java create mode 100644 tpu/src/main/java/tpu/StartTpuVm.java create mode 100644 tpu/src/main/java/tpu/StopTpuVm.java create mode 100644 tpu/src/test/java/tpu/TpuVmIT.java diff --git a/tpu/pom.xml b/tpu/pom.xml new file mode 100644 index 00000000000..a70da7fd766 --- /dev/null +++ b/tpu/pom.xml @@ -0,0 +1,98 @@ + + + + 4.0.0 + com.example.tpu + gce-diregapic-samples + 1.0-SNAPSHOT + + + + shared-configuration + com.google.cloud.samples + 1.2.0 + + + + 11 + 11 + + + + + com.google.cloud + google-cloud-tpu + 2.52.0 + + + + com.google.api + gax + + + + + google-cloud-storage + com.google.cloud + test + + + + truth + com.google.truth + test + 1.4.0 + + + junit + junit + test + 4.13.2 + + + + + org.junit.jupiter + junit-jupiter-engine + 5.10.2 + test + + + + + + + libraries-bom + com.google.cloud + import + pom + 26.40.0 + + + + + diff --git a/tpu/src/main/java/tpu/CreateTpuVm.java b/tpu/src/main/java/tpu/CreateTpuVm.java new file mode 100644 index 00000000000..178ade37e4a --- /dev/null +++ b/tpu/src/main/java/tpu/CreateTpuVm.java @@ -0,0 +1,67 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_create] + +import com.google.cloud.tpu.v2.CreateNodeRequest; +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.TpuClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class CreateTpuVm { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + String tpuVmName = "YOUR_TPU_NAME"; + String acceleratorType = "v2-8"; + String version = "tpu-vm-tf-2.14.1"; + + createTpuVm(projectId, zone, tpuVmName, acceleratorType, version); + } + + // Creates a TPU VM with the specified name, zone, accelerator type, and version. + public static void createTpuVm( + String projectId, String zone, String tpuVmName, String acceleratorType, String version) + throws IOException, ExecutionException, InterruptedException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + + Node tpuVm = Node.newBuilder() + .setName(tpuVmName) + .setAcceleratorType(acceleratorType) + .setRuntimeVersion(version) + .build(); + + CreateNodeRequest request = CreateNodeRequest.newBuilder() + .setParent(parent) + .setNodeId(tpuVmName) + .setNode(tpuVm) + .build(); + + Node response = tpuClient.createNodeAsync(request).get(); + System.out.printf("TPU VM created: %s\n", response.getName()); + } + } +} +//[END tpu_vm_create] diff --git a/tpu/src/main/java/tpu/DeleteTpuVm.java b/tpu/src/main/java/tpu/DeleteTpuVm.java new file mode 100644 index 00000000000..70dda8eb0ce --- /dev/null +++ b/tpu/src/main/java/tpu/DeleteTpuVm.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_delete] + +import com.google.cloud.tpu.v2.DeleteNodeRequest; +import com.google.cloud.tpu.v2.NodeName; +import com.google.cloud.tpu.v2.TpuClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class DeleteTpuVm { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + String tpuVmName = "YOUR_TPU_NAME"; + + deleteTpuVm(projectId, zone, tpuVmName); + } + + // Deletes a TPU VM with the specified name in the given project and zone. + public static void deleteTpuVm(String projectId, String zone, String tpuVmName) + throws IOException, ExecutionException, InterruptedException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + + DeleteNodeRequest request = DeleteNodeRequest.newBuilder().setName(nodeName).build(); + tpuClient.deleteNodeAsync(request).get(); + + System.out.println("TPU VM deleted"); + } + } +} +//[END tpu_vm_delete] diff --git a/tpu/src/main/java/tpu/GetTpuVm.java b/tpu/src/main/java/tpu/GetTpuVm.java new file mode 100644 index 00000000000..0addfe1b323 --- /dev/null +++ b/tpu/src/main/java/tpu/GetTpuVm.java @@ -0,0 +1,53 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_get] + +import com.google.cloud.tpu.v2.GetNodeRequest; +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.NodeName; +import com.google.cloud.tpu.v2.TpuClient; +import java.io.IOException; + +public class GetTpuVm { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + String tpuVmName = "YOUR_TPU_NAME"; + + getTpuVm(projectId, zone, tpuVmName); + } + + // Describes a TPU VM with the specified name in the given project and zone. + public static Node getTpuVm(String projectId, String zone, String tpuVmName) + throws IOException { + Node node; + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + + GetNodeRequest request = GetNodeRequest.newBuilder().setName(nodeName).build(); + node = tpuClient.getNode(request); + } + return node; + } +} +//[END tpu_vm_get] diff --git a/tpu/src/main/java/tpu/ListTpuVms.java b/tpu/src/main/java/tpu/ListTpuVms.java new file mode 100644 index 00000000000..edcccd98802 --- /dev/null +++ b/tpu/src/main/java/tpu/ListTpuVms.java @@ -0,0 +1,51 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_list] + +import com.google.cloud.tpu.v2.ListNodesRequest; +import com.google.cloud.tpu.v2.TpuClient; +import com.google.cloud.tpu.v2.TpuClient.ListNodesPagedResponse; +import java.io.IOException; + +public class ListTpuVms { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + + listTpuVms(projectId, zone); + } + + // Lists TPU VMs in the specified zone. + public static ListNodesPagedResponse listTpuVms(String projectId, String zone) + throws IOException { + ListNodesPagedResponse response; + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + + ListNodesRequest request = ListNodesRequest.newBuilder().setParent(parent).build(); + response = tpuClient.listNodes(request); + } + return response; + } +} +//[END tpu_vm_list] diff --git a/tpu/src/main/java/tpu/StartTpuVm.java b/tpu/src/main/java/tpu/StartTpuVm.java new file mode 100644 index 00000000000..b8be446dde4 --- /dev/null +++ b/tpu/src/main/java/tpu/StartTpuVm.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_start] + +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.NodeName; +import com.google.cloud.tpu.v2.StartNodeRequest; +import com.google.cloud.tpu.v2.TpuClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class StartTpuVm { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + String tpuVmName = "YOUR_TPU_NAME"; + + startTpuVm(projectId, zone, tpuVmName); + } + + // Starts a TPU VM with the specified name in the given project and zone. + public static void startTpuVm(String projectId, String zone, String tpuVmName) + throws IOException, ExecutionException, InterruptedException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + + StartNodeRequest request = StartNodeRequest.newBuilder().setName(nodeName).build(); + Node response = tpuClient.startNodeAsync(request).get(); + + System.out.printf("TPU VM started: %s\n", response.getName()); + } + } +} +//[END tpu_vm_start] diff --git a/tpu/src/main/java/tpu/StopTpuVm.java b/tpu/src/main/java/tpu/StopTpuVm.java new file mode 100644 index 00000000000..6b7800045fc --- /dev/null +++ b/tpu/src/main/java/tpu/StopTpuVm.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_vm_stop] + +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.NodeName; +import com.google.cloud.tpu.v2.StopNodeRequest; +import com.google.cloud.tpu.v2.TpuClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class StopTpuVm { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "YOUR_PROJECT_ID"; + String zone = "europe-west4-a"; + String tpuVmName = "YOUR_TPU_NAME"; + + stopTpuVm(projectId, zone, tpuVmName); + } + + // Stops a TPU VM with the specified name in the given project and zone. + public static void stopTpuVm(String projectId, String zone, String tpuVmName) + throws IOException, ExecutionException, InterruptedException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + + StopNodeRequest request = StopNodeRequest.newBuilder().setName(nodeName).build(); + Node response = tpuClient.stopNodeAsync(request).get(); + + System.out.printf("TPU VM stopped: %s\n", response.getName()); + } + } +} +//[END tpu_vm_stop] diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java new file mode 100644 index 00000000000..a2e337b2a60 --- /dev/null +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -0,0 +1,179 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +import static com.google.cloud.tpu.v2.Node.State.READY; +import static com.google.cloud.tpu.v2.Node.State.STOPPED; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertNotNull; + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.TpuClient; +import com.google.protobuf.Timestamp; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import org.junit.Assert; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +@Timeout(value = 25, unit = TimeUnit.MINUTES) +@TestMethodOrder(MethodOrderer. OrderAnnotation. class) +public class TpuVmIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String ZONE = "europe-west4-b"; + static String javaVersion = System.getProperty("java.version").substring(0, 2); + private static final String TPU_VM_NAME = "test-tpu-" + javaVersion + "-" + + UUID.randomUUID().toString().substring(0, 8); + private static final String ACCELERATOR_TYPE = "v5litepod-1"; + private static final String VERSION = "tpu-vm-cos-stable"; + private static final String TPU_VM_PATH_NAME = + String.format("projects/%s/locations/%s/nodes/%s", PROJECT_ID, ZONE, TPU_VM_NAME); + + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)).isNotEmpty(); + } + + @BeforeAll + public static void setUp() + throws IOException, ExecutionException, InterruptedException { + requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + + // Cleanup existing stale resources. + cleanUpExistingTpu("test-tpu-" + javaVersion, PROJECT_ID, ZONE); + } + + @AfterAll + public static void cleanup() throws Exception { + DeleteTpuVm.deleteTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + TimeUnit.MINUTES.sleep(5); + + // Test that TPUs is deleted + Assertions.assertThrows( + NotFoundException.class, + () -> GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME)); + } + + @Test + @Order(1) + public void testCreateTpuVm() throws IOException, ExecutionException, InterruptedException { + final PrintStream out = System.out; + ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME, ACCELERATOR_TYPE, VERSION); + + assertThat(stdOut.toString()).contains("TPU VM created: " + TPU_VM_PATH_NAME); + stdOut.close(); + System.setOut(out); + } + + @Test + @Order(2) + public void testGetTpuVm() throws IOException { + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertNotNull(node); + assertThat(node.getName()).isEqualTo(TPU_VM_PATH_NAME); + } + + @Test + @Order(2) + public void testListTpuVm() throws IOException { + TpuClient.ListNodesPagedResponse nodesList = ListTpuVms.listTpuVms(PROJECT_ID, ZONE); + assertNotNull(nodesList); + for (Node node : nodesList.iterateAll()) { + Assert.assertTrue(node.getName().contains("test-tpu")); + } + } + + @Test + @Order(2) + public void testStopTpuVm() throws IOException, ExecutionException, InterruptedException { + StopTpuVm.stopTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertThat(node.getState()).isEqualTo(STOPPED); + } + + @Test + @Order(3) + public void testStartTpuVm() throws IOException, ExecutionException, InterruptedException { + StartTpuVm.startTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertThat(node.getState()).isEqualTo(READY); + } + + public static void cleanUpExistingTpu(String prefixToDelete, String projectId, String zone) + throws IOException, ExecutionException, InterruptedException { + try (TpuClient tpuClient = TpuClient.create()) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + for (Node node : tpuClient.listNodes(parent).iterateAll()) { + String creationTime = formatTimestamp(node.getCreateTime()); + String name = node.getName().substring(node.getName().lastIndexOf("/") + 1); + if (containPrefixToDeleteAndZone(node, prefixToDelete, zone) + && isCreatedBeforeThresholdTime(creationTime)) { + DeleteTpuVm.deleteTpuVm(projectId, zone, name); + } + } + } + } + + public static boolean containPrefixToDeleteAndZone( + Node node, String prefixToDelete, String zone) { + boolean containPrefixAndZone = false; + try { + containPrefixAndZone = node.getName().contains(prefixToDelete) + && node.getName().split("/")[3].contains(zone); + + } catch (NullPointerException e) { + System.out.println("Resource not found, skipping deletion:"); + } + return containPrefixAndZone; + } + + public static boolean isCreatedBeforeThresholdTime(String timestamp) { + return OffsetDateTime.parse(timestamp).toInstant() + .isBefore(Instant.now().minus(5, ChronoUnit.MINUTES)); + } + + private static String formatTimestamp(Timestamp timestamp) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant( + Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()), + ZoneOffset.UTC); + return formatter.format(offsetDateTime); + } +} \ No newline at end of file From 9ee20d7f1aed6ff67d34728aa8f72a3c67210d22 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 15 Oct 2024 22:13:04 +0200 Subject: [PATCH 02/19] Added information to CODEOWNERS --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ca79aba529f..f21afe0f659 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -44,6 +44,7 @@ /security-command-center @GoogleCloudPlatform/java-samples-reviewers @yoshi-approver @GoogleCloudPlatform/cloud-samples-reviewers @GoogleCloudPlatform/dee-infra @GoogleCloudPlatform/gcp-security-command-center /servicedirectory @GoogleCloudPlatform/java-samples-reviewers @yoshi-approver @GoogleCloudPlatform/cloud-samples-reviewers @GoogleCloudPlatform/dee-infra /webrisk @GoogleCloudPlatform/java-samples-reviewers @yoshi-approver @GoogleCloudPlatform/cloud-samples-reviewers @GoogleCloudPlatform/dee-infra +/tpu @GoogleCloudPlatform/java-samples-reviewers @yoshi-approver @GoogleCloudPlatform/cloud-samples-reviewers @GoogleCloudPlatform/dee-infra # DEE Platform Ops (DEEPO) /errorreporting @GoogleCloudPlatform/java-samples-reviewers @yoshi-approver @GoogleCloudPlatform/cloud-samples-reviewers From f0b8314afe22f38cb35860e172a4cccc79cff362 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 16 Oct 2024 14:51:39 +0200 Subject: [PATCH 03/19] Added timeout --- tpu/src/test/java/tpu/TpuVmIT.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index a2e337b2a60..0c2014feacd 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -96,6 +96,7 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(stdOut)); CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME, ACCELERATOR_TYPE, VERSION); + TimeUnit.MINUTES.sleep(3); assertThat(stdOut.toString()).contains("TPU VM created: " + TPU_VM_PATH_NAME); stdOut.close(); @@ -106,6 +107,7 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte @Order(2) public void testGetTpuVm() throws IOException { Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertNotNull(node); assertThat(node.getName()).isEqualTo(TPU_VM_PATH_NAME); } @@ -114,6 +116,7 @@ public void testGetTpuVm() throws IOException { @Order(2) public void testListTpuVm() throws IOException { TpuClient.ListNodesPagedResponse nodesList = ListTpuVms.listTpuVms(PROJECT_ID, ZONE); + assertNotNull(nodesList); for (Node node : nodesList.iterateAll()) { Assert.assertTrue(node.getName().contains("test-tpu")); @@ -125,6 +128,7 @@ public void testListTpuVm() throws IOException { public void testStopTpuVm() throws IOException, ExecutionException, InterruptedException { StopTpuVm.stopTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertThat(node.getState()).isEqualTo(STOPPED); } @@ -133,6 +137,7 @@ public void testStopTpuVm() throws IOException, ExecutionException, InterruptedE public void testStartTpuVm() throws IOException, ExecutionException, InterruptedException { StartTpuVm.startTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + assertThat(node.getState()).isEqualTo(READY); } From d3e1dee1513658b0e44108697b4bb65fec8aacfb Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 16 Oct 2024 17:15:08 +0200 Subject: [PATCH 04/19] Fixed parameters for test --- tpu/src/test/java/tpu/TpuVmIT.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index 0c2014feacd..0798d8dd56e 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -54,12 +54,12 @@ @TestMethodOrder(MethodOrderer. OrderAnnotation. class) public class TpuVmIT { private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); - private static final String ZONE = "europe-west4-b"; + private static final String ZONE = "europe-west4-a"; static String javaVersion = System.getProperty("java.version").substring(0, 2); private static final String TPU_VM_NAME = "test-tpu-" + javaVersion + "-" + UUID.randomUUID().toString().substring(0, 8); - private static final String ACCELERATOR_TYPE = "v5litepod-1"; - private static final String VERSION = "tpu-vm-cos-stable"; + private static final String ACCELERATOR_TYPE = "v2-8"; + private static final String VERSION = "tpu-vm-tf-2.14.1"; private static final String TPU_VM_PATH_NAME = String.format("projects/%s/locations/%s/nodes/%s", PROJECT_ID, ZONE, TPU_VM_NAME); @@ -171,7 +171,7 @@ public static boolean containPrefixToDeleteAndZone( public static boolean isCreatedBeforeThresholdTime(String timestamp) { return OffsetDateTime.parse(timestamp).toInstant() - .isBefore(Instant.now().minus(5, ChronoUnit.MINUTES)); + .isBefore(Instant.now().minus(30, ChronoUnit.MINUTES)); } private static String formatTimestamp(Timestamp timestamp) { From 2253b54da9fa17159c82f947f6c6e2a0419471d9 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Thu, 17 Oct 2024 20:50:06 +0200 Subject: [PATCH 05/19] Fixed DeleteTpuVm and naming --- tpu/src/main/java/tpu/CreateTpuVm.java | 28 ++++++++++++------ tpu/src/main/java/tpu/DeleteTpuVm.java | 41 +++++++++++++++++++++----- tpu/src/main/java/tpu/GetTpuVm.java | 15 ++++++---- tpu/src/main/java/tpu/ListTpuVms.java | 4 +++ tpu/src/main/java/tpu/StartTpuVm.java | 15 ++++++---- tpu/src/main/java/tpu/StopTpuVm.java | 15 ++++++---- 6 files changed, 86 insertions(+), 32 deletions(-) diff --git a/tpu/src/main/java/tpu/CreateTpuVm.java b/tpu/src/main/java/tpu/CreateTpuVm.java index 178ade37e4a..8ce44fa4dc5 100644 --- a/tpu/src/main/java/tpu/CreateTpuVm.java +++ b/tpu/src/main/java/tpu/CreateTpuVm.java @@ -29,18 +29,28 @@ public class CreateTpuVm { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; - String tpuVmName = "YOUR_TPU_NAME"; - String acceleratorType = "v2-8"; - String version = "tpu-vm-tf-2.14.1"; + // The name for your TPU. + String nodeName = "YOUR_TPY_NAME"; + // The accelerator type that specifies the version and size of the Cloud TPU you want to create. + // For more information about supported accelerator types for each TPU version, + // see https://cloud.google.com/tpu/docs/system-architecture-tpu-vm#versions. + String tpuType = "v2-8"; + // Software version that specifies the version of the TPU runtime to install. + // For more information see https://cloud.google.com/tpu/docs/runtimes + String tpuSoftwareVersion = "tpu-vm-tf-2.14.1"; - createTpuVm(projectId, zone, tpuVmName, acceleratorType, version); + createTpuVm(projectId, zone, nodeName, tpuType, tpuSoftwareVersion); } // Creates a TPU VM with the specified name, zone, accelerator type, and version. public static void createTpuVm( - String projectId, String zone, String tpuVmName, String acceleratorType, String version) + String projectId, String zone, String nodeName, String tpuType, String tpuSoftwareVersion) throws IOException, ExecutionException, InterruptedException { // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. @@ -48,14 +58,14 @@ public static void createTpuVm( String parent = String.format("projects/%s/locations/%s", projectId, zone); Node tpuVm = Node.newBuilder() - .setName(tpuVmName) - .setAcceleratorType(acceleratorType) - .setRuntimeVersion(version) + .setName(nodeName) + .setAcceleratorType(tpuType) + .setRuntimeVersion(tpuSoftwareVersion) .build(); CreateNodeRequest request = CreateNodeRequest.newBuilder() .setParent(parent) - .setNodeId(tpuVmName) + .setNodeId(nodeName) .setNode(tpuVm) .build(); diff --git a/tpu/src/main/java/tpu/DeleteTpuVm.java b/tpu/src/main/java/tpu/DeleteTpuVm.java index 70dda8eb0ce..3c5200e8e77 100644 --- a/tpu/src/main/java/tpu/DeleteTpuVm.java +++ b/tpu/src/main/java/tpu/DeleteTpuVm.java @@ -18,37 +18,62 @@ //[START tpu_vm_delete] +import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; +import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.tpu.v2.DeleteNodeRequest; import com.google.cloud.tpu.v2.NodeName; import com.google.cloud.tpu.v2.TpuClient; +import com.google.cloud.tpu.v2.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; +import org.threeten.bp.Duration; public class DeleteTpuVm { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; - String tpuVmName = "YOUR_TPU_NAME"; + // The name for your TPU. + String nodeName = "YOUR_TPY_NAME"; - deleteTpuVm(projectId, zone, tpuVmName); + deleteTpuVm(projectId, zone, nodeName); } // Deletes a TPU VM with the specified name in the given project and zone. - public static void deleteTpuVm(String projectId, String zone, String tpuVmName) + public static void deleteTpuVm(String projectId, String zone, String nodeName) throws IOException, ExecutionException, InterruptedException { + TpuSettings.Builder clientSettings = + TpuSettings.newBuilder(); + clientSettings + .deleteNodeOperationSettings() + .setPollingAlgorithm( + OperationTimedPollAlgorithm.create( + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(5000L)) + .setRetryDelayMultiplier(1.5) + .setMaxRetryDelay(Duration.ofMillis(45000L)) + .setInitialRpcTimeout(Duration.ZERO) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ZERO) + .setTotalTimeout(Duration.ofHours(24L)) + .build())); + // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create()) { - String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + String name = NodeName.of(projectId, zone, nodeName).toString(); - DeleteNodeRequest request = DeleteNodeRequest.newBuilder().setName(nodeName).build(); - tpuClient.deleteNodeAsync(request).get(); + DeleteNodeRequest request = DeleteNodeRequest.newBuilder().setName(name).build(); + tpuClient.deleteNodeAsync(request).get(); System.out.println("TPU VM deleted"); } } } -//[END tpu_vm_delete] +//[END tpu_vm_delete] \ No newline at end of file diff --git a/tpu/src/main/java/tpu/GetTpuVm.java b/tpu/src/main/java/tpu/GetTpuVm.java index 0addfe1b323..22f2b6d2c0f 100644 --- a/tpu/src/main/java/tpu/GetTpuVm.java +++ b/tpu/src/main/java/tpu/GetTpuVm.java @@ -28,23 +28,28 @@ public class GetTpuVm { public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; - String tpuVmName = "YOUR_TPU_NAME"; + // The name for your TPU. + String nodeName = "YOUR_TPY_NAME"; - getTpuVm(projectId, zone, tpuVmName); + getTpuVm(projectId, zone, nodeName); } // Describes a TPU VM with the specified name in the given project and zone. - public static Node getTpuVm(String projectId, String zone, String tpuVmName) + public static Node getTpuVm(String projectId, String zone, String nodeName) throws IOException { Node node; // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create()) { - String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + String name = NodeName.of(projectId, zone, nodeName).toString(); - GetNodeRequest request = GetNodeRequest.newBuilder().setName(nodeName).build(); + GetNodeRequest request = GetNodeRequest.newBuilder().setName(name).build(); node = tpuClient.getNode(request); } return node; diff --git a/tpu/src/main/java/tpu/ListTpuVms.java b/tpu/src/main/java/tpu/ListTpuVms.java index edcccd98802..7f2124d4a03 100644 --- a/tpu/src/main/java/tpu/ListTpuVms.java +++ b/tpu/src/main/java/tpu/ListTpuVms.java @@ -27,7 +27,11 @@ public class ListTpuVms { public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; listTpuVms(projectId, zone); diff --git a/tpu/src/main/java/tpu/StartTpuVm.java b/tpu/src/main/java/tpu/StartTpuVm.java index b8be446dde4..d3421a8cc31 100644 --- a/tpu/src/main/java/tpu/StartTpuVm.java +++ b/tpu/src/main/java/tpu/StartTpuVm.java @@ -30,22 +30,27 @@ public class StartTpuVm { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; - String tpuVmName = "YOUR_TPU_NAME"; + // The name for your TPU. + String nodeName = "YOUR_TPY_NAME"; - startTpuVm(projectId, zone, tpuVmName); + startTpuVm(projectId, zone, nodeName); } // Starts a TPU VM with the specified name in the given project and zone. - public static void startTpuVm(String projectId, String zone, String tpuVmName) + public static void startTpuVm(String projectId, String zone, String nodeName) throws IOException, ExecutionException, InterruptedException { // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create()) { - String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + String name = NodeName.of(projectId, zone, nodeName).toString(); - StartNodeRequest request = StartNodeRequest.newBuilder().setName(nodeName).build(); + StartNodeRequest request = StartNodeRequest.newBuilder().setName(name).build(); Node response = tpuClient.startNodeAsync(request).get(); System.out.printf("TPU VM started: %s\n", response.getName()); diff --git a/tpu/src/main/java/tpu/StopTpuVm.java b/tpu/src/main/java/tpu/StopTpuVm.java index 6b7800045fc..6e3e5bfb646 100644 --- a/tpu/src/main/java/tpu/StopTpuVm.java +++ b/tpu/src/main/java/tpu/StopTpuVm.java @@ -30,22 +30,27 @@ public class StopTpuVm { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones String zone = "europe-west4-a"; - String tpuVmName = "YOUR_TPU_NAME"; + // The name for your TPU. + String nodeName = "YOUR_TPY_NAME"; - stopTpuVm(projectId, zone, tpuVmName); + stopTpuVm(projectId, zone, nodeName); } // Stops a TPU VM with the specified name in the given project and zone. - public static void stopTpuVm(String projectId, String zone, String tpuVmName) + public static void stopTpuVm(String projectId, String zone, String nodeName) throws IOException, ExecutionException, InterruptedException { // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create()) { - String nodeName = NodeName.of(projectId, zone, tpuVmName).toString(); + String name = NodeName.of(projectId, zone, nodeName).toString(); - StopNodeRequest request = StopNodeRequest.newBuilder().setName(nodeName).build(); + StopNodeRequest request = StopNodeRequest.newBuilder().setName(name).build(); Node response = tpuClient.stopNodeAsync(request).get(); System.out.printf("TPU VM stopped: %s\n", response.getName()); From d29a6b5d85bd42531a3b8a28fd17fe99fc8f12bf Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Fri, 18 Oct 2024 13:16:26 +0200 Subject: [PATCH 06/19] Added comment, created Util class --- tpu/src/main/java/tpu/DeleteTpuVm.java | 2 + tpu/src/test/java/tpu/TpuVmIT.java | 51 +----------------- tpu/src/test/java/tpu/Util.java | 75 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 tpu/src/test/java/tpu/Util.java diff --git a/tpu/src/main/java/tpu/DeleteTpuVm.java b/tpu/src/main/java/tpu/DeleteTpuVm.java index 3c5200e8e77..bd77ced58cd 100644 --- a/tpu/src/main/java/tpu/DeleteTpuVm.java +++ b/tpu/src/main/java/tpu/DeleteTpuVm.java @@ -48,6 +48,8 @@ public static void main(String[] args) // Deletes a TPU VM with the specified name in the given project and zone. public static void deleteTpuVm(String projectId, String zone, String nodeName) throws IOException, ExecutionException, InterruptedException { + // With these settings the client library handles the Operation's polling mechanism + // and prevent CancellationException error TpuSettings.Builder clientSettings = TpuSettings.newBuilder(); clientSettings diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index 0798d8dd56e..8ecbbb8acba 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -25,15 +25,9 @@ import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.tpu.v2.Node; import com.google.cloud.tpu.v2.TpuClient; -import com.google.protobuf.Timestamp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -75,13 +69,12 @@ public static void setUp() requireEnvVar("GOOGLE_CLOUD_PROJECT"); // Cleanup existing stale resources. - cleanUpExistingTpu("test-tpu-" + javaVersion, PROJECT_ID, ZONE); + Util.cleanUpExistingTpu("test-tpu-" + javaVersion, PROJECT_ID, ZONE); } @AfterAll public static void cleanup() throws Exception { DeleteTpuVm.deleteTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); - TimeUnit.MINUTES.sleep(5); // Test that TPUs is deleted Assertions.assertThrows( @@ -96,7 +89,6 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(stdOut)); CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME, ACCELERATOR_TYPE, VERSION); - TimeUnit.MINUTES.sleep(3); assertThat(stdOut.toString()).contains("TPU VM created: " + TPU_VM_PATH_NAME); stdOut.close(); @@ -140,45 +132,4 @@ public void testStartTpuVm() throws IOException, ExecutionException, Interrupted assertThat(node.getState()).isEqualTo(READY); } - - public static void cleanUpExistingTpu(String prefixToDelete, String projectId, String zone) - throws IOException, ExecutionException, InterruptedException { - try (TpuClient tpuClient = TpuClient.create()) { - String parent = String.format("projects/%s/locations/%s", projectId, zone); - for (Node node : tpuClient.listNodes(parent).iterateAll()) { - String creationTime = formatTimestamp(node.getCreateTime()); - String name = node.getName().substring(node.getName().lastIndexOf("/") + 1); - if (containPrefixToDeleteAndZone(node, prefixToDelete, zone) - && isCreatedBeforeThresholdTime(creationTime)) { - DeleteTpuVm.deleteTpuVm(projectId, zone, name); - } - } - } - } - - public static boolean containPrefixToDeleteAndZone( - Node node, String prefixToDelete, String zone) { - boolean containPrefixAndZone = false; - try { - containPrefixAndZone = node.getName().contains(prefixToDelete) - && node.getName().split("/")[3].contains(zone); - - } catch (NullPointerException e) { - System.out.println("Resource not found, skipping deletion:"); - } - return containPrefixAndZone; - } - - public static boolean isCreatedBeforeThresholdTime(String timestamp) { - return OffsetDateTime.parse(timestamp).toInstant() - .isBefore(Instant.now().minus(30, ChronoUnit.MINUTES)); - } - - private static String formatTimestamp(Timestamp timestamp) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); - OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant( - Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()), - ZoneOffset.UTC); - return formatter.format(offsetDateTime); - } } \ No newline at end of file diff --git a/tpu/src/test/java/tpu/Util.java b/tpu/src/test/java/tpu/Util.java new file mode 100644 index 00000000000..178d7783a81 --- /dev/null +++ b/tpu/src/test/java/tpu/Util.java @@ -0,0 +1,75 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +import com.google.cloud.tpu.v2.Node; +import com.google.cloud.tpu.v2.TpuClient; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.ExecutionException; + +public class Util { + private static final int DELETION_THRESHOLD_TIME_MINUTES = 30; + + // Delete TPU VMs which starts with the given prefixToDelete and + // has creation timestamp >30 minutes. + public static void cleanUpExistingTpu(String prefixToDelete, String projectId, String zone) + throws IOException, ExecutionException, InterruptedException { + try (TpuClient tpuClient = TpuClient.create()) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + for (Node node : tpuClient.listNodes(parent).iterateAll()) { + String creationTime = formatTimestamp(node.getCreateTime()); + String name = node.getName().substring(node.getName().lastIndexOf("/") + 1); + if (containPrefixToDeleteAndZone(node, prefixToDelete, zone) + && isCreatedBeforeThresholdTime(creationTime)) { + DeleteTpuVm.deleteTpuVm(projectId, zone, name); + } + } + } + } + + public static boolean containPrefixToDeleteAndZone( + Node node, String prefixToDelete, String zone) { + boolean containPrefixAndZone = false; + try { + containPrefixAndZone = node.getName().contains(prefixToDelete) + && node.getName().split("/")[3].contains(zone); + + } catch (NullPointerException e) { + System.out.println("Resource not found, skipping deletion:"); + } + return containPrefixAndZone; + } + + public static boolean isCreatedBeforeThresholdTime(String timestamp) { + return OffsetDateTime.parse(timestamp).toInstant() + .isBefore(Instant.now().minus(DELETION_THRESHOLD_TIME_MINUTES, ChronoUnit.MINUTES)); + } + + private static String formatTimestamp(Timestamp timestamp) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant( + Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()), + ZoneOffset.UTC); + return formatter.format(offsetDateTime); + } +} From 69568520ec2d40a6c70bf34a0c5d3aabe586369b Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 23 Oct 2024 10:30:28 +0200 Subject: [PATCH 07/19] Fixed naming --- tpu/src/main/java/tpu/GetTpuVm.java | 5 ++--- tpu/src/main/java/tpu/ListTpuVms.java | 4 +--- tpu/src/test/java/tpu/TpuVmIT.java | 30 +++++++++++++-------------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/tpu/src/main/java/tpu/GetTpuVm.java b/tpu/src/main/java/tpu/GetTpuVm.java index 22f2b6d2c0f..cb1e335bf4a 100644 --- a/tpu/src/main/java/tpu/GetTpuVm.java +++ b/tpu/src/main/java/tpu/GetTpuVm.java @@ -43,16 +43,15 @@ public static void main(String[] args) throws IOException { // Describes a TPU VM with the specified name in the given project and zone. public static Node getTpuVm(String projectId, String zone, String nodeName) throws IOException { - Node node; // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create()) { String name = NodeName.of(projectId, zone, nodeName).toString(); GetNodeRequest request = GetNodeRequest.newBuilder().setName(name).build(); - node = tpuClient.getNode(request); + + return tpuClient.getNode(request); } - return node; } } //[END tpu_vm_get] diff --git a/tpu/src/main/java/tpu/ListTpuVms.java b/tpu/src/main/java/tpu/ListTpuVms.java index 7f2124d4a03..a0f5ad33b7e 100644 --- a/tpu/src/main/java/tpu/ListTpuVms.java +++ b/tpu/src/main/java/tpu/ListTpuVms.java @@ -40,16 +40,14 @@ public static void main(String[] args) throws IOException { // Lists TPU VMs in the specified zone. public static ListNodesPagedResponse listTpuVms(String projectId, String zone) throws IOException { - ListNodesPagedResponse response; // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create()) { String parent = String.format("projects/%s/locations/%s", projectId, zone); ListNodesRequest request = ListNodesRequest.newBuilder().setParent(parent).build(); - response = tpuClient.listNodes(request); + return tpuClient.listNodes(request); } - return response; } } //[END tpu_vm_list] diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index 8ecbbb8acba..b5767e8495c 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -50,12 +50,12 @@ public class TpuVmIT { private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); private static final String ZONE = "europe-west4-a"; static String javaVersion = System.getProperty("java.version").substring(0, 2); - private static final String TPU_VM_NAME = "test-tpu-" + javaVersion + "-" + private static final String NODE_NAME = "test-tpu-" + javaVersion + "-" + UUID.randomUUID().toString().substring(0, 8); - private static final String ACCELERATOR_TYPE = "v2-8"; - private static final String VERSION = "tpu-vm-tf-2.14.1"; - private static final String TPU_VM_PATH_NAME = - String.format("projects/%s/locations/%s/nodes/%s", PROJECT_ID, ZONE, TPU_VM_NAME); + private static final String TPU_TYPE = "v2-8"; + private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.14.1"; + private static final String NODE_PATH_NAME = + String.format("projects/%s/locations/%s/nodes/%s", PROJECT_ID, ZONE, NODE_NAME); public static void requireEnvVar(String envVarName) { assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) @@ -74,12 +74,12 @@ public static void setUp() @AfterAll public static void cleanup() throws Exception { - DeleteTpuVm.deleteTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + DeleteTpuVm.deleteTpuVm(PROJECT_ID, ZONE, NODE_NAME); // Test that TPUs is deleted Assertions.assertThrows( NotFoundException.class, - () -> GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME)); + () -> GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME)); } @Test @@ -88,9 +88,9 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte final PrintStream out = System.out; ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(stdOut)); - CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME, ACCELERATOR_TYPE, VERSION); + CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, NODE_NAME, TPU_TYPE , TPU_SOFTWARE_VERSION); - assertThat(stdOut.toString()).contains("TPU VM created: " + TPU_VM_PATH_NAME); + assertThat(stdOut.toString()).contains("TPU VM created: " + NODE_PATH_NAME); stdOut.close(); System.setOut(out); } @@ -98,10 +98,10 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte @Test @Order(2) public void testGetTpuVm() throws IOException { - Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); assertNotNull(node); - assertThat(node.getName()).isEqualTo(TPU_VM_PATH_NAME); + assertThat(node.getName()).isEqualTo(NODE_PATH_NAME); } @Test @@ -118,8 +118,8 @@ public void testListTpuVm() throws IOException { @Test @Order(2) public void testStopTpuVm() throws IOException, ExecutionException, InterruptedException { - StopTpuVm.stopTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); - Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + StopTpuVm.stopTpuVm(PROJECT_ID, ZONE, NODE_NAME); + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); assertThat(node.getState()).isEqualTo(STOPPED); } @@ -127,8 +127,8 @@ public void testStopTpuVm() throws IOException, ExecutionException, InterruptedE @Test @Order(3) public void testStartTpuVm() throws IOException, ExecutionException, InterruptedException { - StartTpuVm.startTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); - Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, TPU_VM_NAME); + StartTpuVm.startTpuVm(PROJECT_ID, ZONE, NODE_NAME); + Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); assertThat(node.getState()).isEqualTo(READY); } From 478beaa3fb09a4fb8ee6ffe94bbf298c728d0a5f Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 23 Oct 2024 11:05:56 +0200 Subject: [PATCH 08/19] Fixed whitespace --- tpu/src/test/java/tpu/TpuVmIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index b5767e8495c..d0a5aeece9b 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -88,7 +88,7 @@ public void testCreateTpuVm() throws IOException, ExecutionException, Interrupte final PrintStream out = System.out; ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(stdOut)); - CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, NODE_NAME, TPU_TYPE , TPU_SOFTWARE_VERSION); + CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, NODE_NAME, TPU_TYPE, TPU_SOFTWARE_VERSION); assertThat(stdOut.toString()).contains("TPU VM created: " + NODE_PATH_NAME); stdOut.close(); From ec13f4d34f3855f46c17090e5edb0879a5ee3e70 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 29 Oct 2024 11:13:49 +0100 Subject: [PATCH 09/19] Split PR into smaller, deleted redundant code --- tpu/src/main/java/tpu/CreateTpuVm.java | 28 ++++++++++-- tpu/src/main/java/tpu/DeleteTpuVm.java | 1 - tpu/src/main/java/tpu/GetTpuVm.java | 1 - tpu/src/main/java/tpu/ListTpuVms.java | 53 ----------------------- tpu/src/main/java/tpu/StartTpuVm.java | 60 -------------------------- tpu/src/main/java/tpu/StopTpuVm.java | 60 -------------------------- tpu/src/test/java/tpu/TpuVmIT.java | 54 ++++------------------- 7 files changed, 34 insertions(+), 223 deletions(-) delete mode 100644 tpu/src/main/java/tpu/ListTpuVms.java delete mode 100644 tpu/src/main/java/tpu/StartTpuVm.java delete mode 100644 tpu/src/main/java/tpu/StopTpuVm.java diff --git a/tpu/src/main/java/tpu/CreateTpuVm.java b/tpu/src/main/java/tpu/CreateTpuVm.java index 8ce44fa4dc5..5daefabb6d2 100644 --- a/tpu/src/main/java/tpu/CreateTpuVm.java +++ b/tpu/src/main/java/tpu/CreateTpuVm.java @@ -17,12 +17,15 @@ package tpu; //[START tpu_vm_create] - +import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; +import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.tpu.v2.CreateNodeRequest; import com.google.cloud.tpu.v2.Node; import com.google.cloud.tpu.v2.TpuClient; +import com.google.cloud.tpu.v2.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; +import org.threeten.bp.Duration; public class CreateTpuVm { @@ -49,12 +52,30 @@ public static void main(String[] args) } // Creates a TPU VM with the specified name, zone, accelerator type, and version. - public static void createTpuVm( + public static Node createTpuVm( String projectId, String zone, String nodeName, String tpuType, String tpuSoftwareVersion) throws IOException, ExecutionException, InterruptedException { + // With these settings the client library handles the Operation's polling mechanism + // and prevent CancellationException error + TpuSettings.Builder clientSettings = + TpuSettings.newBuilder(); + clientSettings + .createNodeOperationSettings() + .setPollingAlgorithm( + OperationTimedPollAlgorithm.create( + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(5000L)) + .setRetryDelayMultiplier(1.5) + .setMaxRetryDelay(Duration.ofMillis(45000L)) + .setInitialRpcTimeout(Duration.ZERO) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ZERO) + .setTotalTimeout(Duration.ofHours(24L)) + .build())); + // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create()) { + try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { String parent = String.format("projects/%s/locations/%s", projectId, zone); Node tpuVm = Node.newBuilder() @@ -71,6 +92,7 @@ public static void createTpuVm( Node response = tpuClient.createNodeAsync(request).get(); System.out.printf("TPU VM created: %s\n", response.getName()); + return response; } } } diff --git a/tpu/src/main/java/tpu/DeleteTpuVm.java b/tpu/src/main/java/tpu/DeleteTpuVm.java index bd77ced58cd..a63af99bf23 100644 --- a/tpu/src/main/java/tpu/DeleteTpuVm.java +++ b/tpu/src/main/java/tpu/DeleteTpuVm.java @@ -17,7 +17,6 @@ package tpu; //[START tpu_vm_delete] - import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.tpu.v2.DeleteNodeRequest; diff --git a/tpu/src/main/java/tpu/GetTpuVm.java b/tpu/src/main/java/tpu/GetTpuVm.java index cb1e335bf4a..4a4ec43db2c 100644 --- a/tpu/src/main/java/tpu/GetTpuVm.java +++ b/tpu/src/main/java/tpu/GetTpuVm.java @@ -17,7 +17,6 @@ package tpu; //[START tpu_vm_get] - import com.google.cloud.tpu.v2.GetNodeRequest; import com.google.cloud.tpu.v2.Node; import com.google.cloud.tpu.v2.NodeName; diff --git a/tpu/src/main/java/tpu/ListTpuVms.java b/tpu/src/main/java/tpu/ListTpuVms.java deleted file mode 100644 index a0f5ad33b7e..00000000000 --- a/tpu/src/main/java/tpu/ListTpuVms.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed 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. - */ - -package tpu; - -//[START tpu_vm_list] - -import com.google.cloud.tpu.v2.ListNodesRequest; -import com.google.cloud.tpu.v2.TpuClient; -import com.google.cloud.tpu.v2.TpuClient.ListNodesPagedResponse; -import java.io.IOException; - -public class ListTpuVms { - - public static void main(String[] args) throws IOException { - // TODO(developer): Replace these variables before running the sample. - // Project ID or project number of the Google Cloud project you want to create a node. - String projectId = "YOUR_PROJECT_ID"; - // The zone in which to create the TPU. - // For more information about supported TPU types for specific zones, - // see https://cloud.google.com/tpu/docs/regions-zones - String zone = "europe-west4-a"; - - listTpuVms(projectId, zone); - } - - // Lists TPU VMs in the specified zone. - public static ListNodesPagedResponse listTpuVms(String projectId, String zone) - throws IOException { - // Initialize client that will be used to send requests. This client only needs to be created - // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create()) { - String parent = String.format("projects/%s/locations/%s", projectId, zone); - - ListNodesRequest request = ListNodesRequest.newBuilder().setParent(parent).build(); - return tpuClient.listNodes(request); - } - } -} -//[END tpu_vm_list] diff --git a/tpu/src/main/java/tpu/StartTpuVm.java b/tpu/src/main/java/tpu/StartTpuVm.java deleted file mode 100644 index d3421a8cc31..00000000000 --- a/tpu/src/main/java/tpu/StartTpuVm.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed 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. - */ - -package tpu; - -//[START tpu_vm_start] - -import com.google.cloud.tpu.v2.Node; -import com.google.cloud.tpu.v2.NodeName; -import com.google.cloud.tpu.v2.StartNodeRequest; -import com.google.cloud.tpu.v2.TpuClient; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -public class StartTpuVm { - - public static void main(String[] args) - throws IOException, ExecutionException, InterruptedException { - // TODO(developer): Replace these variables before running the sample. - // Project ID or project number of the Google Cloud project you want to create a node. - String projectId = "YOUR_PROJECT_ID"; - // The zone in which to create the TPU. - // For more information about supported TPU types for specific zones, - // see https://cloud.google.com/tpu/docs/regions-zones - String zone = "europe-west4-a"; - // The name for your TPU. - String nodeName = "YOUR_TPY_NAME"; - - startTpuVm(projectId, zone, nodeName); - } - - // Starts a TPU VM with the specified name in the given project and zone. - public static void startTpuVm(String projectId, String zone, String nodeName) - throws IOException, ExecutionException, InterruptedException { - // Initialize client that will be used to send requests. This client only needs to be created - // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create()) { - String name = NodeName.of(projectId, zone, nodeName).toString(); - - StartNodeRequest request = StartNodeRequest.newBuilder().setName(name).build(); - Node response = tpuClient.startNodeAsync(request).get(); - - System.out.printf("TPU VM started: %s\n", response.getName()); - } - } -} -//[END tpu_vm_start] diff --git a/tpu/src/main/java/tpu/StopTpuVm.java b/tpu/src/main/java/tpu/StopTpuVm.java deleted file mode 100644 index 6e3e5bfb646..00000000000 --- a/tpu/src/main/java/tpu/StopTpuVm.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed 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. - */ - -package tpu; - -//[START tpu_vm_stop] - -import com.google.cloud.tpu.v2.Node; -import com.google.cloud.tpu.v2.NodeName; -import com.google.cloud.tpu.v2.StopNodeRequest; -import com.google.cloud.tpu.v2.TpuClient; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -public class StopTpuVm { - - public static void main(String[] args) - throws IOException, ExecutionException, InterruptedException { - // TODO(developer): Replace these variables before running the sample. - // Project ID or project number of the Google Cloud project you want to create a node. - String projectId = "YOUR_PROJECT_ID"; - // The zone in which to create the TPU. - // For more information about supported TPU types for specific zones, - // see https://cloud.google.com/tpu/docs/regions-zones - String zone = "europe-west4-a"; - // The name for your TPU. - String nodeName = "YOUR_TPY_NAME"; - - stopTpuVm(projectId, zone, nodeName); - } - - // Stops a TPU VM with the specified name in the given project and zone. - public static void stopTpuVm(String projectId, String zone, String nodeName) - throws IOException, ExecutionException, InterruptedException { - // Initialize client that will be used to send requests. This client only needs to be created - // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create()) { - String name = NodeName.of(projectId, zone, nodeName).toString(); - - StopNodeRequest request = StopNodeRequest.newBuilder().setName(name).build(); - Node response = tpuClient.stopNodeAsync(request).get(); - - System.out.printf("TPU VM stopped: %s\n", response.getName()); - } - } -} -//[END tpu_vm_stop] diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index d0a5aeece9b..e2b9f54fdbe 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -16,22 +16,16 @@ package tpu; -import static com.google.cloud.tpu.v2.Node.State.READY; -import static com.google.cloud.tpu.v2.Node.State.STOPPED; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertNotNull; import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.tpu.v2.Node; -import com.google.cloud.tpu.v2.TpuClient; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import org.junit.Assert; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -44,15 +38,15 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) -@Timeout(value = 25, unit = TimeUnit.MINUTES) +@Timeout(value = 15, unit = TimeUnit.MINUTES) @TestMethodOrder(MethodOrderer. OrderAnnotation. class) public class TpuVmIT { private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); - private static final String ZONE = "europe-west4-a"; + private static final String ZONE = "us-central1-a"; static String javaVersion = System.getProperty("java.version").substring(0, 2); private static final String NODE_NAME = "test-tpu-" + javaVersion + "-" + UUID.randomUUID().toString().substring(0, 8); - private static final String TPU_TYPE = "v2-8"; + private static final String TPU_TYPE = "v3-8"; private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.14.1"; private static final String NODE_PATH_NAME = String.format("projects/%s/locations/%s/nodes/%s", PROJECT_ID, ZONE, NODE_NAME); @@ -85,14 +79,13 @@ public static void cleanup() throws Exception { @Test @Order(1) public void testCreateTpuVm() throws IOException, ExecutionException, InterruptedException { - final PrintStream out = System.out; - ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); - System.setOut(new PrintStream(stdOut)); - CreateTpuVm.createTpuVm(PROJECT_ID, ZONE, NODE_NAME, TPU_TYPE, TPU_SOFTWARE_VERSION); - assertThat(stdOut.toString()).contains("TPU VM created: " + NODE_PATH_NAME); - stdOut.close(); - System.setOut(out); + Node node = CreateTpuVm.createTpuVm( + PROJECT_ID, ZONE, NODE_NAME, TPU_TYPE, TPU_SOFTWARE_VERSION); + + assertNotNull(node); + assertThat(node.getName().equals(NODE_NAME)); + assertThat(node.getAcceleratorType().equals(TPU_TYPE)); } @Test @@ -103,33 +96,4 @@ public void testGetTpuVm() throws IOException { assertNotNull(node); assertThat(node.getName()).isEqualTo(NODE_PATH_NAME); } - - @Test - @Order(2) - public void testListTpuVm() throws IOException { - TpuClient.ListNodesPagedResponse nodesList = ListTpuVms.listTpuVms(PROJECT_ID, ZONE); - - assertNotNull(nodesList); - for (Node node : nodesList.iterateAll()) { - Assert.assertTrue(node.getName().contains("test-tpu")); - } - } - - @Test - @Order(2) - public void testStopTpuVm() throws IOException, ExecutionException, InterruptedException { - StopTpuVm.stopTpuVm(PROJECT_ID, ZONE, NODE_NAME); - Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); - - assertThat(node.getState()).isEqualTo(STOPPED); - } - - @Test - @Order(3) - public void testStartTpuVm() throws IOException, ExecutionException, InterruptedException { - StartTpuVm.startTpuVm(PROJECT_ID, ZONE, NODE_NAME); - Node node = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); - - assertThat(node.getState()).isEqualTo(READY); - } } \ No newline at end of file From 66ae551811c6e61b3454bf8b4260f5ca8354ea88 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 29 Oct 2024 15:16:43 +0100 Subject: [PATCH 10/19] Implemented tpu_queued_resources_create, tpu_queued_resources_get, tpu_queued_resources_delete_force and tpu_queued_resources_delete samples, created tests --- .../main/java/tpu/CreateQueuedResource.java | 122 ++++++++++++++++++ .../java/tpu/DeleteForceQueuedResource.java | 77 +++++++++++ .../main/java/tpu/DeleteQueuedResource.java | 88 +++++++++++++ tpu/src/main/java/tpu/GetQueuedResource.java | 53 ++++++++ tpu/src/test/java/tpu/QueuedResourcesIT.java | 110 ++++++++++++++++ tpu/src/test/java/tpu/TpuVmIT.java | 2 +- tpu/src/test/java/tpu/Util.java | 38 +++++- 7 files changed, 484 insertions(+), 6 deletions(-) create mode 100644 tpu/src/main/java/tpu/CreateQueuedResource.java create mode 100644 tpu/src/main/java/tpu/DeleteForceQueuedResource.java create mode 100644 tpu/src/main/java/tpu/DeleteQueuedResource.java create mode 100644 tpu/src/main/java/tpu/GetQueuedResource.java create mode 100644 tpu/src/test/java/tpu/QueuedResourcesIT.java diff --git a/tpu/src/main/java/tpu/CreateQueuedResource.java b/tpu/src/main/java/tpu/CreateQueuedResource.java new file mode 100644 index 00000000000..24fc7802d52 --- /dev/null +++ b/tpu/src/main/java/tpu/CreateQueuedResource.java @@ -0,0 +1,122 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_queued_resources_create] +import com.google.api.gax.retrying.RetrySettings; +import com.google.cloud.tpu.v2alpha1.CreateQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.Node; +import com.google.cloud.tpu.v2alpha1.QueuedResource; +import com.google.cloud.tpu.v2alpha1.TpuClient; +import com.google.cloud.tpu.v2alpha1.TpuSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import org.threeten.bp.Duration; + +public class CreateQueuedResource { + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project you want to create a node. + String projectId = "YOUR_PROJECT_ID"; + // The zone in which to create the TPU. + // For more information about supported TPU types for specific zones, + // see https://cloud.google.com/tpu/docs/regions-zones + String zone = "europe-west4-a"; + // The name for your TPU. + String nodeName = "YOUR_NODE_ID"; + // The accelerator type that specifies the version and size of the Cloud TPU you want to create. + // For more information about supported accelerator types for each TPU version, + // see https://cloud.google.com/tpu/docs/system-architecture-tpu-vm#versions. + String tpuType = "v2-8"; + // Software version that specifies the version of the TPU runtime to install. + // For more information see https://cloud.google.com/tpu/docs/runtimes + String tpuSoftwareVersion = "tpu-vm-tf-2.14.1"; + // The name for your Queued Resource. + String queuedResourceId = "QUEUED_RESOURCE_ID"; + + createQueuedResource( + projectId, zone, queuedResourceId, nodeName, tpuType, tpuSoftwareVersion); + } + + // Creates a Queued Resource + public static QueuedResource createQueuedResource(String projectId, String zone, + String queuedResourceId, String nodeName, String tpuType, String tpuSoftwareVersion) + throws IOException, ExecutionException, InterruptedException { + // With these settings the client library handles the Operation's polling mechanism + // and prevent CancellationException error + TpuSettings.Builder clientSettings = + TpuSettings.newBuilder(); + clientSettings + .createQueuedResourceSettings() + .setRetrySettings( + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(5000L)) + .setRetryDelayMultiplier(2.0) + .setInitialRpcTimeout(Duration.ZERO) + .setRpcTimeoutMultiplier(1.0) + .setMaxRetryDelay(Duration.ofMillis(45000L)) + .setTotalTimeout(Duration.ofHours(24L)) + .build()); + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + Node node = + Node.newBuilder() + .setName(nodeName) + .setAcceleratorType(tpuType) + .setRuntimeVersion(tpuSoftwareVersion) + .setQueuedResource( + String.format( + "projects/%s/locations/%s/queuedResources/%s", + projectId, zone, queuedResourceId)) + .build(); + + QueuedResource queuedResource = + QueuedResource.newBuilder() + .setName(queuedResourceId) + .setTpu( + QueuedResource.Tpu.newBuilder() + .addNodeSpec( + QueuedResource.Tpu.NodeSpec.newBuilder() + .setParent(parent) + .setNode(node) + .setNodeId(nodeName) + .build()) + .build()) + // You can request a queued resource using a reservation by specifying it in code + //.setReservationName( + // "projects/YOUR_PROJECT_ID/locations/YOUR_ZONE/reservations/YOUR_RESERVATION_NAME") + .build(); + + CreateQueuedResourceRequest request = + CreateQueuedResourceRequest.newBuilder() + .setParent(parent) + .setQueuedResourceId(queuedResourceId) + .setQueuedResource(queuedResource) + .build(); + + QueuedResource response = tpuClient.createQueuedResourceAsync(request).get(); + // You can wait until TPU Node is READY, + // and check its status using getTpuVm() from "tpu_vm_get" sample. + System.out.printf("Queued Resource created: %s\n", response.getName()); + return response; + } + } +} +//[END tpu_queued_resources_create] \ No newline at end of file diff --git a/tpu/src/main/java/tpu/DeleteForceQueuedResource.java b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java new file mode 100644 index 00000000000..91e75612954 --- /dev/null +++ b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_queued_resources_delete_force] +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.UnknownException; +import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.TpuClient; +import com.google.cloud.tpu.v2alpha1.TpuSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import org.threeten.bp.Duration; + +public class DeleteForceQueuedResource { + public static void main(String[] args) { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project. + String projectId = "YOUR_PROJECT_ID"; + // The zone in which the TPU was created. + String zone = "europe-west4-a"; + // The name for your Queued Resource. + String queuedResourceId = "QUEUED_RESOURCE_ID"; + + deleteForceQueuedResource(projectId, zone, queuedResourceId); + } + + // Deletes a Queued Resource asynchronously with --force flag. + public static void deleteForceQueuedResource( + String projectId, String zone, String queuedResourceId) { + String name = String.format("projects/%s/locations/%s/queuedResources/%s", + projectId, zone, queuedResourceId); + // With these settings the client library handles the Operation's polling mechanism + // and prevent CancellationException error + TpuSettings.Builder clientSettings = + TpuSettings.newBuilder(); + clientSettings + .deleteQueuedResourceSettings() + .setRetrySettings( + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(5000L)) + .setRetryDelayMultiplier(2.0) + .setInitialRpcTimeout(Duration.ZERO) + .setRpcTimeoutMultiplier(1.0) + .setMaxRetryDelay(Duration.ofMillis(45000L)) + .setTotalTimeout(Duration.ofHours(24L)) + .build()); + + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + DeleteQueuedResourceRequest request = + DeleteQueuedResourceRequest.newBuilder().setName(name).setForce(true).build(); + + tpuClient.deleteQueuedResourceAsync(request).get(); + + } catch (UnknownException | InterruptedException | ExecutionException | IOException e) { + System.out.println(e.getMessage()); + } + System.out.printf("Deleted Queued Resource: %s\n", name); + } +} +//[END tpu_queued_resources_delete_force] \ No newline at end of file diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java new file mode 100644 index 00000000000..0f592ff165f --- /dev/null +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_queued_resources_delete] +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.UnknownException; +import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.QueuedResource; +import com.google.cloud.tpu.v2alpha1.TpuClient; +import com.google.cloud.tpu.v2alpha1.TpuSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import org.threeten.bp.Duration; + +public class DeleteQueuedResource { + public static void main(String[] args) { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project. + String projectId = "YOUR_PROJECT_ID"; + // The zone in which the TPU was created. + String zone = "europe-west4-a"; + // The name for your Queued Resource. + String queuedResourceId = "QUEUED_RESOURCE_ID"; + + deleteQueuedResource(projectId, zone, queuedResourceId); + } + + // Deletes a Queued Resource asynchronously. + public static void deleteQueuedResource(String projectId, String zone, String queuedResourceId) { + String name = String.format("projects/%s/locations/%s/queuedResources/%s", + projectId, zone, queuedResourceId); + // With these settings the client library handles the Operation's polling mechanism + // and prevent CancellationException error + TpuSettings.Builder clientSettings = + TpuSettings.newBuilder(); + clientSettings + .deleteQueuedResourceSettings() + .setRetrySettings( + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(5000L)) + .setRetryDelayMultiplier(2.0) + .setInitialRpcTimeout(Duration.ZERO) + .setRpcTimeoutMultiplier(1.0) + .setMaxRetryDelay(Duration.ofMillis(45000L)) + .setTotalTimeout(Duration.ofHours(24L)) + .build()); + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + // Retrive node name + GetQueuedResourceRequest getRequest = + GetQueuedResourceRequest.newBuilder().setName(name).build(); + QueuedResource queuedResource = tpuClient.getQueuedResource(getRequest); + String nodeName = queuedResource.getTpu().getNodeSpec(0).getNode().getName(); + // Before deleting the queued resource it is required to delete the TPU VM. + DeleteTpuVm.deleteTpuVm(projectId, zone, nodeName); + // Wait until TpuVm is deleted + TimeUnit.MINUTES.sleep(3); + + DeleteQueuedResourceRequest request = + DeleteQueuedResourceRequest.newBuilder().setName(name).build(); + + tpuClient.deleteQueuedResourceAsync(request).get(); + + } catch (UnknownException | InterruptedException | ExecutionException | IOException e) { + System.out.println(e.getMessage()); + } + System.out.printf("Deleted Queued Resource: %s\n", name); + } +} +//[END tpu_queued_resources_delete] diff --git a/tpu/src/main/java/tpu/GetQueuedResource.java b/tpu/src/main/java/tpu/GetQueuedResource.java new file mode 100644 index 00000000000..80c6762327c --- /dev/null +++ b/tpu/src/main/java/tpu/GetQueuedResource.java @@ -0,0 +1,53 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +//[START tpu_queued_resources_get] +import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.QueuedResource; +import com.google.cloud.tpu.v2alpha1.TpuClient; +import java.io.IOException; + +public class GetQueuedResource { + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Google Cloud project. + String projectId = "YOUR_PROJECT_ID"; + // The zone in which the TPU was created. + String zone = "europe-west4-a"; + // The name for your Queued Resource. + String queuedResourceId = "QUEUED_RESOURCE_ID"; + + getQueuedResource(projectId, zone, queuedResourceId); + } + + // Get a Queued Resource. + public static QueuedResource getQueuedResource( + String projectId, String zone, String queuedResourceId) throws IOException { + String name = String.format("projects/%s/locations/%s/queuedResources/%s", + projectId, zone, queuedResourceId); + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (TpuClient tpuClient = TpuClient.create()) { + GetQueuedResourceRequest request = + GetQueuedResourceRequest.newBuilder().setName(name).build(); + + return tpuClient.getQueuedResource(request); + } + } +} +//[END tpu_queued_resources_get] \ No newline at end of file diff --git a/tpu/src/test/java/tpu/QueuedResourcesIT.java b/tpu/src/test/java/tpu/QueuedResourcesIT.java new file mode 100644 index 00000000000..35382bbed09 --- /dev/null +++ b/tpu/src/test/java/tpu/QueuedResourcesIT.java @@ -0,0 +1,110 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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. + */ + +package tpu; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertNotNull; + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.tpu.v2alpha1.QueuedResource; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +@Timeout(value = 10, unit = TimeUnit.MINUTES) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class QueuedResourcesIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String ZONE = "us-central1-f"; + static String javaVersion = System.getProperty("java.version").substring(0, 2); + private static final String NODE_NAME = "test-tpu-queued-resource-" + javaVersion + "-" + + UUID.randomUUID().toString().substring(0, 8); + private static final String TPU_TYPE = "v2-8"; + private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.17.0-pjrt"; + private static final String QUEUED_RESOURCE_NAME = "queued-resource-" + javaVersion + "-" + + UUID.randomUUID().toString().substring(0, 8); + private static final String QUEUED_RESOURCE_PATH_NAME = + String.format("projects/%s/locations/%s/queuedResources/%s", + PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); + + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)).isNotEmpty(); + } + + @BeforeAll + public static void setUp() throws IOException { + requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + + // Cleanup existing stale resources. + Util.cleanUpExistingQueuedResources("queued-resource-", PROJECT_ID, ZONE); + } + + @AfterAll + public static void cleanup() throws IOException { + final PrintStream out = System.out; + ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + DeleteQueuedResource.deleteQueuedResource(PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); + + // Test that resources are deleted + assertThat(stdOut.toString()).contains("Deleted Queued Resource:"); + Assertions.assertThrows( + NotFoundException.class, + () -> GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME)); + + stdOut.close(); + System.setOut(out); + } + + @Test + @Order(1) + public void testCreateQueuedResource() + throws IOException, ExecutionException, InterruptedException { + QueuedResource queuedResource = CreateQueuedResource.createQueuedResource(PROJECT_ID, ZONE, + QUEUED_RESOURCE_NAME, NODE_NAME, TPU_TYPE, TPU_SOFTWARE_VERSION); + + assertThat(queuedResource.getName()).isEqualTo(QUEUED_RESOURCE_PATH_NAME); + assertThat(queuedResource.getTpu().getNodeSpec(0).getNode().getName()).isEqualTo(NODE_NAME); + } + + @Test + @Order(2) + public void testGetQueuedResource() throws IOException { + QueuedResource queuedResource = GetQueuedResource.getQueuedResource( + PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); + + assertNotNull(queuedResource); + assertThat(queuedResource.getName()).isEqualTo(QUEUED_RESOURCE_PATH_NAME); + } +} \ No newline at end of file diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index e2b9f54fdbe..dfc3c6f683c 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -39,7 +39,7 @@ @RunWith(JUnit4.class) @Timeout(value = 15, unit = TimeUnit.MINUTES) -@TestMethodOrder(MethodOrderer. OrderAnnotation. class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class TpuVmIT { private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); private static final String ZONE = "us-central1-a"; diff --git a/tpu/src/test/java/tpu/Util.java b/tpu/src/test/java/tpu/Util.java index 178d7783a81..dedd3628fd0 100644 --- a/tpu/src/test/java/tpu/Util.java +++ b/tpu/src/test/java/tpu/Util.java @@ -18,6 +18,7 @@ import com.google.cloud.tpu.v2.Node; import com.google.cloud.tpu.v2.TpuClient; +import com.google.cloud.tpu.v2alpha1.QueuedResource; import com.google.protobuf.Timestamp; import java.io.IOException; import java.time.Instant; @@ -47,13 +48,40 @@ && isCreatedBeforeThresholdTime(creationTime)) { } } + // Delete QueuedResources which starts with the given prefixToDelete and + // has creation timestamp >30 minutes. + public static void cleanUpExistingQueuedResources( + String prefixToDelete, String projectId, String zone) + throws IOException { + try (com.google.cloud.tpu.v2alpha1.TpuClient tpuClient = + com.google.cloud.tpu.v2alpha1.TpuClient.create()) { + String parent = String.format("projects/%s/locations/%s", projectId, zone); + + for (QueuedResource queuedResource : tpuClient.listQueuedResources(parent).iterateAll()) { + com.google.cloud.tpu.v2alpha1.Node node = queuedResource.getTpu().getNodeSpec(0).getNode(); + String creationTime = formatTimestamp(node.getCreateTime()); + String name = queuedResource.getName() + .substring(queuedResource.getName().lastIndexOf("/") + 1); + if (containPrefixToDeleteAndZone(queuedResource, prefixToDelete, zone) + && isCreatedBeforeThresholdTime(creationTime)) { + DeleteForceQueuedResource.deleteForceQueuedResource(projectId, zone, name); + } + } + } + } + public static boolean containPrefixToDeleteAndZone( - Node node, String prefixToDelete, String zone) { + Object resource, String prefixToDelete, String zone) { boolean containPrefixAndZone = false; try { - containPrefixAndZone = node.getName().contains(prefixToDelete) - && node.getName().split("/")[3].contains(zone); - + if (resource instanceof Node) { + containPrefixAndZone = ((Node) resource).getName().contains(prefixToDelete) + && ((Node) resource).getName().split("/")[3].contains(zone); + } + if (resource instanceof QueuedResource) { + containPrefixAndZone = ((QueuedResource) resource).getName().contains(prefixToDelete) + && ((QueuedResource) resource).getName().split("/")[3].contains(zone); + } } catch (NullPointerException e) { System.out.println("Resource not found, skipping deletion:"); } @@ -72,4 +100,4 @@ private static String formatTimestamp(Timestamp timestamp) { ZoneOffset.UTC); return formatter.format(offsetDateTime); } -} +} \ No newline at end of file From d0386c6eef3da2e264a4a605ff310b9915589511 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Mon, 18 Nov 2024 20:35:51 +0100 Subject: [PATCH 11/19] Fixed test --- tpu/src/test/java/tpu/CreateTpuIT.java | 70 ----------- tpu/src/test/java/tpu/DeleteIT.java | 40 +++++++ tpu/src/test/java/tpu/QueuedResourceIT.java | 67 ++++++++++- tpu/src/test/java/tpu/QueuedResourcesIT.java | 115 ------------------- tpu/src/test/java/tpu/TpuVmIT.java | 39 ++++++- 5 files changed, 137 insertions(+), 194 deletions(-) delete mode 100644 tpu/src/test/java/tpu/CreateTpuIT.java create mode 100644 tpu/src/test/java/tpu/DeleteIT.java delete mode 100644 tpu/src/test/java/tpu/QueuedResourcesIT.java diff --git a/tpu/src/test/java/tpu/CreateTpuIT.java b/tpu/src/test/java/tpu/CreateTpuIT.java deleted file mode 100644 index cdb11831364..00000000000 --- a/tpu/src/test/java/tpu/CreateTpuIT.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed 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. - */ - -package tpu; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.api.gax.longrunning.OperationFuture; -import com.google.cloud.tpu.v2.CreateNodeRequest; -import com.google.cloud.tpu.v2.Node; -import com.google.cloud.tpu.v2.TpuClient; -import com.google.cloud.tpu.v2.TpuSettings; -import org.junit.Test; -import org.junit.jupiter.api.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.MockedStatic; - -@RunWith(JUnit4.class) -@Timeout(value = 3) -public class CreateTpuIT { - private static final String PROJECT_ID = "project-id"; - private static final String ZONE = "asia-east1-c"; - private static final String NODE_NAME = "test-tpu"; - private static final String TPU_TYPE = "v2-8"; - private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.12.1"; - - @Test - public void testCreateTpuVm() throws Exception { - try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { - Node mockNode = mock(Node.class); - TpuClient mockTpuClient = mock(TpuClient.class); - OperationFuture mockFuture = mock(OperationFuture.class); - - mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) - .thenReturn(mockTpuClient); - when(mockTpuClient.createNodeAsync(any(CreateNodeRequest.class))) - .thenReturn(mockFuture); - when(mockFuture.get()).thenReturn(mockNode); - - Node returnedNode = CreateTpuVm.createTpuVm( - PROJECT_ID, ZONE, NODE_NAME, - TPU_TYPE, TPU_SOFTWARE_VERSION); - - verify(mockTpuClient, times(1)) - .createNodeAsync(any(CreateNodeRequest.class)); - verify(mockFuture, times(1)).get(); - assertEquals(returnedNode, mockNode); - } - } -} diff --git a/tpu/src/test/java/tpu/DeleteIT.java b/tpu/src/test/java/tpu/DeleteIT.java new file mode 100644 index 00000000000..5a3b0844951 --- /dev/null +++ b/tpu/src/test/java/tpu/DeleteIT.java @@ -0,0 +1,40 @@ +package tpu; + +import com.google.cloud.tpu.v2alpha1.QueuedResource; +import com.google.cloud.tpu.v2alpha1.TpuClient; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.MockedStatic; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; + +@RunWith(JUnit4.class) +@Timeout(value = 30) +public class DeleteIT { + private static final String PROJECT_ID = "project-id"; + private static final String ZONE = "europe-west4-a"; + private static final String NODE_NAME = "test-tpu"; + private ByteArrayOutputStream bout; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @Test + public void testCreateQueuedResource() { + try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { + QueuedResource mockQueuedResource = mock(QueuedResource.class); + TpuClient mockTpuClient = mock(TpuClient.class); + + } + } +} diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 906d0e270df..59d2c4656c8 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -26,15 +26,19 @@ import static org.mockito.Mockito.when; import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.tpu.v2.DeleteNodeRequest; import com.google.cloud.tpu.v2alpha1.CreateQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; +import com.google.cloud.tpu.v2alpha1.Node; import com.google.cloud.tpu.v2alpha1.QueuedResource; import com.google.cloud.tpu.v2alpha1.TpuClient; import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.util.concurrent.ExecutionException; + import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Timeout; @@ -43,7 +47,7 @@ import org.mockito.MockedStatic; @RunWith(JUnit4.class) -@Timeout(value = 3) +@Timeout(value = 30) public class QueuedResourceIT { private static final String PROJECT_ID = "project-id"; private static final String ZONE = "europe-west4-a"; @@ -60,6 +64,31 @@ public void setUp() { System.setOut(new PrintStream(bout)); } + @Test + public void testCreateQueuedResource() throws Exception { + try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { + QueuedResource mockQueuedResource = mock(QueuedResource.class); + TpuClient mockTpuClient = mock(TpuClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + + mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) + .thenReturn(mockTpuClient); + when(mockTpuClient.createQueuedResourceAsync(any(CreateQueuedResourceRequest.class))) + .thenReturn(mockFuture); + when(mockFuture.get()).thenReturn(mockQueuedResource); + + QueuedResource returnedQueuedResource = + CreateQueuedResource.createQueuedResource( + PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME, NODE_NAME, + TPU_TYPE, TPU_SOFTWARE_VERSION); + + verify(mockTpuClient, times(1)) + .createQueuedResourceAsync(any(CreateQueuedResourceRequest.class)); + verify(mockFuture, times(1)).get(); + assertEquals(returnedQueuedResource, mockQueuedResource); + } + } + @Test public void testCreateQueuedResourceWithSpecifiedNetwork() throws Exception { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { @@ -89,7 +118,6 @@ public void testCreateQueuedResourceWithSpecifiedNetwork() throws Exception { public void testGetQueuedResource() throws IOException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockClient = mock(TpuClient.class); - GetQueuedResource mockGetQueuedResource = mock(GetQueuedResource.class); QueuedResource mockQueuedResource = mock(QueuedResource.class); mockedTpuClient.when(TpuClient::create).thenReturn(mockClient); @@ -99,14 +127,42 @@ public void testGetQueuedResource() throws IOException { QueuedResource returnedQueuedResource = GetQueuedResource.getQueuedResource(PROJECT_ID, ZONE, NODE_NAME); - verify(mockGetQueuedResource, times(1)) - .getQueuedResource(PROJECT_ID, ZONE, NODE_NAME); + verify(mockClient, times(1)) + .getQueuedResource(any(GetQueuedResourceRequest.class)); assertEquals(returnedQueuedResource, mockQueuedResource); } } @Test - public void testDeleteTpuVm() { + public void testDeleteQueuedResource() throws ExecutionException, InterruptedException, IOException { + try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { + TpuClient mockTpuClient = mock(TpuClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + OperationFuture mockFutureForQueuedResource = mock(OperationFuture.class); + QueuedResource mockQueuedResource = mock(QueuedResource.class); + + mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) + .thenReturn(mockTpuClient); + when(mockTpuClient.getQueuedResource(any(GetQueuedResourceRequest.class))) + .thenReturn(mockQueuedResource); + when(mockQueuedResource.getTpu().getNodeSpec(0).getNode().getName()).thenReturn(any(String.class)); + + + when(mockTpuClient.deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class))) + .thenReturn(mockFutureForQueuedResource); + when(mockFutureForQueuedResource.get()).thenReturn(null); + + DeleteQueuedResource.deleteQueuedResource(PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); + String output = bout.toString(); + + assertThat(output).contains("Deleted Queued Resource:"); + verify(mockTpuClient, times(1)) + .deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class)); + } + } + + @Test + public void testDeleteForceQueuedResource() throws ExecutionException, InterruptedException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); @@ -115,6 +171,7 @@ public void testDeleteTpuVm() { .thenReturn(mockTpuClient); when(mockTpuClient.deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class))) .thenReturn(mockFuture); + when(mockFuture.get()).thenReturn(null); DeleteForceQueuedResource.deleteForceQueuedResource(PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); String output = bout.toString(); diff --git a/tpu/src/test/java/tpu/QueuedResourcesIT.java b/tpu/src/test/java/tpu/QueuedResourcesIT.java deleted file mode 100644 index 487b29523f4..00000000000 --- a/tpu/src/test/java/tpu/QueuedResourcesIT.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed 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. - */ - -package tpu; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static org.junit.Assert.assertNotNull; - -import com.google.api.gax.rpc.NotFoundException; -import com.google.cloud.tpu.v2alpha1.QueuedResource; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -@Timeout(value = 6, unit = TimeUnit.MINUTES) -public class QueuedResourcesIT { - private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); - private static final String ZONE = "us-central1-f"; - private static final String NODE_NAME = "test-tpu-queued-resource-" + UUID.randomUUID(); - private static final String NODE_WITH_NETWORK_NAME = - "test-tpu-queued-resource-network-" + UUID.randomUUID(); - private static final String TPU_TYPE = "v2-8"; - private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.17.0-pjrt"; - private static final String QUEUED_RESOURCE_NAME = "queued-resource-" + UUID.randomUUID(); - private static final String QUEUED_RESOURCE_PATH_NAME = - String.format("projects/%s/locations/%s/queuedResources/%s", - PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); - private static final String QUEUED_RESOURCE_WITH_NETWORK = - "queued-resource-network-" + UUID.randomUUID(); - private static final String NETWORK_NAME = "default"; - - public static void requireEnvVar(String envVarName) { - assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) - .that(System.getenv(envVarName)).isNotEmpty(); - } - - @BeforeAll - public static void setUp() throws IOException, ExecutionException, InterruptedException { - requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); - requireEnvVar("GOOGLE_CLOUD_PROJECT"); - - QueuedResource queuedResource = CreateQueuedResource.createQueuedResource(PROJECT_ID, ZONE, - QUEUED_RESOURCE_NAME, NODE_NAME, TPU_TYPE, TPU_SOFTWARE_VERSION); - - assertThat(queuedResource.getName()).isEqualTo(QUEUED_RESOURCE_PATH_NAME); - assertThat(queuedResource.getTpu().getNodeSpec(0).getNode().getName()).isEqualTo(NODE_NAME); - } - - @AfterAll - public static void cleanup() throws IOException { - final PrintStream out = System.out; - ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); - System.setOut(new PrintStream(stdOut)); - DeleteQueuedResource.deleteQueuedResource(PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); - DeleteForceQueuedResource.deleteForceQueuedResource( - PROJECT_ID, ZONE, QUEUED_RESOURCE_WITH_NETWORK); - - // Test that resources are deleted - assertThat(stdOut.toString()).contains("Deleted Queued Resource:"); - Assertions.assertThrows( - NotFoundException.class, - () -> GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME)); - - stdOut.close(); - System.setOut(out); - } - - @Test - public void testGetQueuedResource() throws IOException { - QueuedResource queuedResource = GetQueuedResource.getQueuedResource( - PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); - - assertNotNull(queuedResource); - assertThat(queuedResource.getName()).isEqualTo(QUEUED_RESOURCE_PATH_NAME); - } - - @Test - public void testCreateQueuedResourceWithSpecifiedNetwork() throws Exception { - QueuedResource queuedResource = CreateQueuedResourceWithNetwork.createQueuedResourceWithNetwork( - PROJECT_ID, ZONE, QUEUED_RESOURCE_WITH_NETWORK, NODE_WITH_NETWORK_NAME, - TPU_TYPE, TPU_SOFTWARE_VERSION, NETWORK_NAME); - - assertThat(queuedResource.getTpu().getNodeSpec(0).getNode().getName()) - .isEqualTo(NODE_WITH_NETWORK_NAME); - assertThat(queuedResource.getTpu().getNodeSpec(0).getNode().getNetworkConfig().getNetwork() - .contains(NETWORK_NAME)); - assertThat(queuedResource.getTpu().getNodeSpec(0).getNode().getNetworkConfig().getSubnetwork() - .contains(NETWORK_NAME)); - } -} \ No newline at end of file diff --git a/tpu/src/test/java/tpu/TpuVmIT.java b/tpu/src/test/java/tpu/TpuVmIT.java index 08dfeca8eb9..c0d219158dd 100644 --- a/tpu/src/test/java/tpu/TpuVmIT.java +++ b/tpu/src/test/java/tpu/TpuVmIT.java @@ -17,6 +17,7 @@ package tpu; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; @@ -25,14 +26,18 @@ import static org.mockito.Mockito.when; import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.tpu.v2.CreateNodeRequest; import com.google.cloud.tpu.v2.DeleteNodeRequest; import com.google.cloud.tpu.v2.GetNodeRequest; +import com.google.cloud.tpu.v2.ListNodesRequest; import com.google.cloud.tpu.v2.Node; import com.google.cloud.tpu.v2.TpuClient; import com.google.cloud.tpu.v2.TpuSettings; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -42,11 +47,13 @@ import org.mockito.MockedStatic; @RunWith(JUnit4.class) -@Timeout(value = 3) +@Timeout(value = 30) public class TpuVmIT { private static final String PROJECT_ID = "project-id"; private static final String ZONE = "asia-east1-c"; private static final String NODE_NAME = "test-tpu"; + private static final String TPU_TYPE = "v2-8"; + private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.12.1"; private static ByteArrayOutputStream bout; @BeforeAll @@ -55,21 +62,45 @@ public static void setUp() { System.setOut(new PrintStream(bout)); } + @Test + public void testCreateTpuVm() throws Exception { + try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { + Node mockNode = mock(Node.class); + TpuClient mockTpuClient = mock(TpuClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + + mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) + .thenReturn(mockTpuClient); + when(mockTpuClient.createNodeAsync(any(CreateNodeRequest.class))) + .thenReturn(mockFuture); + when(mockFuture.get()).thenReturn(mockNode); + + Node returnedNode = CreateTpuVm.createTpuVm( + PROJECT_ID, ZONE, NODE_NAME, + TPU_TYPE, TPU_SOFTWARE_VERSION); + + verify(mockTpuClient, times(1)) + .createNodeAsync(any(CreateNodeRequest.class)); + verify(mockFuture, times(1)).get(); + assertEquals(returnedNode, mockNode); + } + } + @Test public void testGetTpuVm() throws IOException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { Node mockNode = mock(Node.class); TpuClient mockClient = mock(TpuClient.class); - GetTpuVm mockGetTpuVm = mock(GetTpuVm.class); mockedTpuClient.when(TpuClient::create).thenReturn(mockClient); when(mockClient.getNode(any(GetNodeRequest.class))).thenReturn(mockNode); Node returnedNode = GetTpuVm.getTpuVm(PROJECT_ID, ZONE, NODE_NAME); - verify(mockGetTpuVm, times(1)) - .getTpuVm(PROJECT_ID, ZONE, NODE_NAME); + verify(mockClient, times(1)) + .getNode(any(GetNodeRequest.class)); assertThat(returnedNode).isEqualTo(mockNode); + verify(mockClient, times(1)).close(); } } From 2d3064dda79313f6060b6cb3507574ce12c8c13a Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 19 Nov 2024 11:25:36 +0100 Subject: [PATCH 12/19] Fixed tests --- .../main/java/tpu/DeleteQueuedResource.java | 23 ++++++----- tpu/src/test/java/tpu/DeleteIT.java | 40 ------------------- tpu/src/test/java/tpu/QueuedResourceIT.java | 16 ++------ 3 files changed, 16 insertions(+), 63 deletions(-) delete mode 100644 tpu/src/test/java/tpu/DeleteIT.java diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index 0f592ff165f..033861daf3d 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -20,14 +20,15 @@ import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.UnknownException; import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; -import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; -import com.google.cloud.tpu.v2alpha1.QueuedResource; import com.google.cloud.tpu.v2alpha1.TpuClient; import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import org.threeten.bp.Duration; +// Uncomment this imports for getting node name +//import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; +//import com.google.cloud.tpu.v2alpha1.QueuedResource; +//import java.util.concurrent.TimeUnit; public class DeleteQueuedResource { public static void main(String[] args) { @@ -64,15 +65,17 @@ public static void deleteQueuedResource(String projectId, String zone, String qu // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { - // Retrive node name - GetQueuedResourceRequest getRequest = - GetQueuedResourceRequest.newBuilder().setName(name).build(); - QueuedResource queuedResource = tpuClient.getQueuedResource(getRequest); - String nodeName = queuedResource.getTpu().getNodeSpec(0).getNode().getName(); // Before deleting the queued resource it is required to delete the TPU VM. - DeleteTpuVm.deleteTpuVm(projectId, zone, nodeName); + // Uncomment these lines to retrive node name + //GetQueuedResourceRequest getRequest = + // GetQueuedResourceRequest.newBuilder().setName(name).build(); + //QueuedResource queuedResource = tpuClient.getQueuedResource(getRequest); + //String nodeName = queuedResource.getTpu().getNodeSpec(0).getNode().getName(); + // For more information about deleting TPU + // see https://cloud.google.com/tpu/docs/managing-tpus-tpu-vm + //DeleteTpuVm.deleteTpuVm(projectId, zone, nodeName); // Wait until TpuVm is deleted - TimeUnit.MINUTES.sleep(3); + //TimeUnit.MINUTES.sleep(3); DeleteQueuedResourceRequest request = DeleteQueuedResourceRequest.newBuilder().setName(name).build(); diff --git a/tpu/src/test/java/tpu/DeleteIT.java b/tpu/src/test/java/tpu/DeleteIT.java deleted file mode 100644 index 5a3b0844951..00000000000 --- a/tpu/src/test/java/tpu/DeleteIT.java +++ /dev/null @@ -1,40 +0,0 @@ -package tpu; - -import com.google.cloud.tpu.v2alpha1.QueuedResource; -import com.google.cloud.tpu.v2alpha1.TpuClient; -import org.junit.Before; -import org.junit.Test; -import org.junit.jupiter.api.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.MockedStatic; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; - -@RunWith(JUnit4.class) -@Timeout(value = 30) -public class DeleteIT { - private static final String PROJECT_ID = "project-id"; - private static final String ZONE = "europe-west4-a"; - private static final String NODE_NAME = "test-tpu"; - private ByteArrayOutputStream bout; - - @Before - public void setUp() { - bout = new ByteArrayOutputStream(); - System.setOut(new PrintStream(bout)); - } - - @Test - public void testCreateQueuedResource() { - try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { - QueuedResource mockQueuedResource = mock(QueuedResource.class); - TpuClient mockTpuClient = mock(TpuClient.class); - - } - } -} diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 59d2c4656c8..204c24711fc 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -26,11 +26,9 @@ import static org.mockito.Mockito.when; import com.google.api.gax.longrunning.OperationFuture; -import com.google.cloud.tpu.v2.DeleteNodeRequest; import com.google.cloud.tpu.v2alpha1.CreateQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; -import com.google.cloud.tpu.v2alpha1.Node; import com.google.cloud.tpu.v2alpha1.QueuedResource; import com.google.cloud.tpu.v2alpha1.TpuClient; import com.google.cloud.tpu.v2alpha1.TpuSettings; @@ -38,7 +36,6 @@ import java.io.IOException; import java.io.PrintStream; import java.util.concurrent.ExecutionException; - import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Timeout; @@ -134,23 +131,16 @@ public void testGetQueuedResource() throws IOException { } @Test - public void testDeleteQueuedResource() throws ExecutionException, InterruptedException, IOException { + public void testDeleteQueuedResource() throws ExecutionException, InterruptedException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); - OperationFuture mockFutureForQueuedResource = mock(OperationFuture.class); - QueuedResource mockQueuedResource = mock(QueuedResource.class); mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) .thenReturn(mockTpuClient); - when(mockTpuClient.getQueuedResource(any(GetQueuedResourceRequest.class))) - .thenReturn(mockQueuedResource); - when(mockQueuedResource.getTpu().getNodeSpec(0).getNode().getName()).thenReturn(any(String.class)); - - when(mockTpuClient.deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class))) - .thenReturn(mockFutureForQueuedResource); - when(mockFutureForQueuedResource.get()).thenReturn(null); + .thenReturn(mockFuture); + when(mockFuture.get()).thenReturn(null); DeleteQueuedResource.deleteQueuedResource(PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME); String output = bout.toString(); From a62d98e26ab04b07b2a86f974feebd1cf0d61690 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 19 Nov 2024 11:36:23 +0100 Subject: [PATCH 13/19] Fixed error massage --- tpu/src/main/java/tpu/DeleteForceQueuedResource.java | 8 +++++--- tpu/src/main/java/tpu/DeleteQueuedResource.java | 8 +++++--- tpu/src/test/java/tpu/QueuedResourceIT.java | 6 ++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tpu/src/main/java/tpu/DeleteForceQueuedResource.java b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java index 91e75612954..da5e83e0986 100644 --- a/tpu/src/main/java/tpu/DeleteForceQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java @@ -27,7 +27,8 @@ import org.threeten.bp.Duration; public class DeleteForceQueuedResource { - public static void main(String[] args) { + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. // Project ID or project number of the Google Cloud project. String projectId = "YOUR_PROJECT_ID"; @@ -41,7 +42,8 @@ public static void main(String[] args) { // Deletes a Queued Resource asynchronously with --force flag. public static void deleteForceQueuedResource( - String projectId, String zone, String queuedResourceId) { + String projectId, String zone, String queuedResourceId) + throws IOException, ExecutionException, InterruptedException { String name = String.format("projects/%s/locations/%s/queuedResources/%s", projectId, zone, queuedResourceId); // With these settings the client library handles the Operation's polling mechanism @@ -68,7 +70,7 @@ public static void deleteForceQueuedResource( tpuClient.deleteQueuedResourceAsync(request).get(); - } catch (UnknownException | InterruptedException | ExecutionException | IOException e) { + } catch (UnknownException e) { System.out.println(e.getMessage()); } System.out.printf("Deleted Queued Resource: %s\n", name); diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index 033861daf3d..4d36c83d07d 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -31,7 +31,8 @@ //import java.util.concurrent.TimeUnit; public class DeleteQueuedResource { - public static void main(String[] args) { + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { // TODO(developer): Replace these variables before running the sample. // Project ID or project number of the Google Cloud project. String projectId = "YOUR_PROJECT_ID"; @@ -44,7 +45,8 @@ public static void main(String[] args) { } // Deletes a Queued Resource asynchronously. - public static void deleteQueuedResource(String projectId, String zone, String queuedResourceId) { + public static void deleteQueuedResource(String projectId, String zone, String queuedResourceId) + throws ExecutionException, InterruptedException, IOException { String name = String.format("projects/%s/locations/%s/queuedResources/%s", projectId, zone, queuedResourceId); // With these settings the client library handles the Operation's polling mechanism @@ -82,7 +84,7 @@ public static void deleteQueuedResource(String projectId, String zone, String qu tpuClient.deleteQueuedResourceAsync(request).get(); - } catch (UnknownException | InterruptedException | ExecutionException | IOException e) { + } catch (UnknownException e) { System.out.println(e.getMessage()); } System.out.printf("Deleted Queued Resource: %s\n", name); diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 204c24711fc..d384f7f91a9 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -131,7 +131,8 @@ public void testGetQueuedResource() throws IOException { } @Test - public void testDeleteQueuedResource() throws ExecutionException, InterruptedException { + public void testDeleteQueuedResource() + throws ExecutionException, InterruptedException, IOException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); @@ -152,7 +153,8 @@ public void testDeleteQueuedResource() throws ExecutionException, InterruptedExc } @Test - public void testDeleteForceQueuedResource() throws ExecutionException, InterruptedException { + public void testDeleteForceQueuedResource() + throws ExecutionException, InterruptedException, IOException { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); From 749b4310829773515088c3b4231715c826afbe0b Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Tue, 19 Nov 2024 12:43:15 +0100 Subject: [PATCH 14/19] Fixed typo --- tpu/src/main/java/tpu/DeleteQueuedResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index 4d36c83d07d..1c3f60269f6 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -68,7 +68,7 @@ public static void deleteQueuedResource(String projectId, String zone, String qu // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { // Before deleting the queued resource it is required to delete the TPU VM. - // Uncomment these lines to retrive node name + // Uncomment these lines to retrieve node name //GetQueuedResourceRequest getRequest = // GetQueuedResourceRequest.newBuilder().setName(name).build(); //QueuedResource queuedResource = tpuClient.getQueuedResource(getRequest); From ea4d87b07b3372c0d46c679e9593bf0574a4bae9 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 20 Nov 2024 21:37:44 +0100 Subject: [PATCH 15/19] Fixed zone --- tpu/src/main/java/tpu/CreateQueuedResource.java | 2 +- tpu/src/main/java/tpu/DeleteForceQueuedResource.java | 2 +- tpu/src/main/java/tpu/DeleteQueuedResource.java | 2 +- tpu/src/main/java/tpu/GetQueuedResource.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tpu/src/main/java/tpu/CreateQueuedResource.java b/tpu/src/main/java/tpu/CreateQueuedResource.java index 3503d12c6fa..fc5ecb7022a 100644 --- a/tpu/src/main/java/tpu/CreateQueuedResource.java +++ b/tpu/src/main/java/tpu/CreateQueuedResource.java @@ -36,7 +36,7 @@ public static void main(String[] args) // The zone in which to create the TPU. // For more information about supported TPU types for specific zones, // see https://cloud.google.com/tpu/docs/regions-zones - String zone = "europe-west4-a"; + String zone = "us-central1-f"; // The name for your TPU. String nodeName = "YOUR_NODE_ID"; // The accelerator type that specifies the version and size of the Cloud TPU you want to create. diff --git a/tpu/src/main/java/tpu/DeleteForceQueuedResource.java b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java index f569f5c34db..3a3a66e453a 100644 --- a/tpu/src/main/java/tpu/DeleteForceQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteForceQueuedResource.java @@ -32,7 +32,7 @@ public static void main(String[] args) // Project ID or project number of the Google Cloud project. String projectId = "YOUR_PROJECT_ID"; // The zone in which the TPU was created. - String zone = "europe-west4-a"; + String zone = "us-central1-f"; // The name for your Queued Resource. String queuedResourceId = "QUEUED_RESOURCE_ID"; diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index f355239df22..93b7626bd6d 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -35,7 +35,7 @@ public static void main(String[] args) // Project ID or project number of the Google Cloud project. String projectId = "YOUR_PROJECT_ID"; // The zone in which the TPU was created. - String zone = "europe-west4-a"; + String zone = "us-central1-f"; // The name for your Queued Resource. String queuedResourceId = "QUEUED_RESOURCE_ID"; diff --git a/tpu/src/main/java/tpu/GetQueuedResource.java b/tpu/src/main/java/tpu/GetQueuedResource.java index 80c6762327c..588987a25f0 100644 --- a/tpu/src/main/java/tpu/GetQueuedResource.java +++ b/tpu/src/main/java/tpu/GetQueuedResource.java @@ -28,7 +28,7 @@ public static void main(String[] args) throws IOException { // Project ID or project number of the Google Cloud project. String projectId = "YOUR_PROJECT_ID"; // The zone in which the TPU was created. - String zone = "europe-west4-a"; + String zone = "us-central1-f"; // The name for your Queued Resource. String queuedResourceId = "QUEUED_RESOURCE_ID"; From bc1f402ecad08b93f30dd42d631a3c15d3214f74 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Wed, 20 Nov 2024 21:47:43 +0100 Subject: [PATCH 16/19] Fixed test --- tpu/src/test/java/tpu/QueuedResourceIT.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 96cd03a2f18..6a6391b3e69 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -36,7 +36,6 @@ import java.io.IOException; import java.io.PrintStream; import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.runner.RunWith; @@ -53,13 +52,6 @@ public class QueuedResourceIT { private static final String TPU_SOFTWARE_VERSION = "tpu-vm-tf-2.14.1"; private static final String QUEUED_RESOURCE_NAME = "queued-resource"; private static final String NETWORK_NAME = "default"; - private static ByteArrayOutputStream bout; - - @BeforeAll - public static void setUp() { - bout = new ByteArrayOutputStream(); - System.setOut(new PrintStream(bout)); - } @Test public void testCreateQueuedResource() throws Exception { @@ -133,6 +125,8 @@ public void testGetQueuedResource() throws IOException { @Test public void testDeleteQueuedResource() throws IOException, ExecutionException, InterruptedException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); @@ -149,12 +143,16 @@ public void testDeleteQueuedResource() assertThat(output).contains("Deleted Queued Resource:"); verify(mockTpuClient, times(1)) .deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class)); + + bout.close(); } } @Test public void testDeleteForceQueuedResource() throws ExecutionException, InterruptedException, IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); @@ -171,6 +169,8 @@ public void testDeleteForceQueuedResource() assertThat(output).contains("Deleted Queued Resource:"); verify(mockTpuClient, times(1)) .deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class)); + + bout.close(); } } } \ No newline at end of file From eef678146fb262faca22782039a53b7ef424a542 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Thu, 12 Dec 2024 11:34:51 +0100 Subject: [PATCH 17/19] Fixed code --- .../main/java/tpu/CreateQueuedResource.java | 18 +++++------- .../main/java/tpu/DeleteQueuedResource.java | 5 ---- tpu/src/test/java/tpu/QueuedResourceIT.java | 29 ++++++++++++++++++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/tpu/src/main/java/tpu/CreateQueuedResource.java b/tpu/src/main/java/tpu/CreateQueuedResource.java index fc5ecb7022a..0470e734627 100644 --- a/tpu/src/main/java/tpu/CreateQueuedResource.java +++ b/tpu/src/main/java/tpu/CreateQueuedResource.java @@ -25,11 +25,13 @@ import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.threeten.bp.Duration; public class CreateQueuedResource { public static void main(String[] args) - throws IOException, ExecutionException, InterruptedException { + throws IOException, ExecutionException, InterruptedException, TimeoutException { // TODO(developer): Replace these variables before running the sample. // Project ID or project number of the Google Cloud project you want to create a node. String projectId = "YOUR_PROJECT_ID"; @@ -56,7 +58,7 @@ public static void main(String[] args) // Creates a Queued Resource public static QueuedResource createQueuedResource(String projectId, String zone, String queuedResourceId, String nodeName, String tpuType, String tpuSoftwareVersion) - throws IOException, ExecutionException, InterruptedException { + throws IOException, ExecutionException, InterruptedException, TimeoutException { // With these settings the client library handles the Operation's polling mechanism // and prevent CancellationException error TpuSettings.Builder clientSettings = @@ -72,6 +74,8 @@ public static QueuedResource createQueuedResource(String projectId, String zone, .setMaxRetryDelay(Duration.ofMillis(45000L)) .setTotalTimeout(Duration.ofHours(24L)) .build()); + String resource = String.format("projects/%s/locations/%s/queuedResources/%s", + projectId, zone, queuedResourceId); // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { @@ -81,10 +85,7 @@ public static QueuedResource createQueuedResource(String projectId, String zone, .setName(nodeName) .setAcceleratorType(tpuType) .setRuntimeVersion(tpuSoftwareVersion) - .setQueuedResource( - String.format( - "projects/%s/locations/%s/queuedResources/%s", - projectId, zone, queuedResourceId)) + .setQueuedResource(resource) .build(); QueuedResource queuedResource = @@ -111,10 +112,7 @@ public static QueuedResource createQueuedResource(String projectId, String zone, .setQueuedResource(queuedResource) .build(); - // You can wait until TPU Node is READY, - // and check its status using getTpuVm() from "tpu_vm_get" sample. - - return tpuClient.createQueuedResourceAsync(request).get(); + return tpuClient.createQueuedResourceAsync(request).get(1, TimeUnit.MINUTES); } } } diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index 93b7626bd6d..34aaec886ab 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -66,11 +66,6 @@ public static void deleteQueuedResource(String projectId, String zone, String qu // once, and can be reused for multiple requests. try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { // Before deleting the queued resource it is required to delete the TPU VM. - // Uncomment these lines to retrieve node name - //GetQueuedResourceRequest getRequest = - // GetQueuedResourceRequest.newBuilder().setName(name).build(); - //QueuedResource queuedResource = tpuClient.getQueuedResource(getRequest); - //String nodeName = queuedResource.getTpu().getNodeSpec(0).getNode().getName(); // For more information about deleting TPU // see https://cloud.google.com/tpu/docs/managing-tpus-tpu-vm diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 6185166d82f..512eff097a4 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -17,6 +17,7 @@ package tpu; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; @@ -33,6 +34,7 @@ import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.runner.RunWith; @@ -40,7 +42,7 @@ import org.mockito.MockedStatic; @RunWith(JUnit4.class) -@Timeout(value = 10) +@Timeout(value = 2, unit = TimeUnit.MINUTES) public class QueuedResourceIT { private static final String PROJECT_ID = "project-id"; private static final String ZONE = "europe-west4-a"; @@ -50,6 +52,31 @@ public class QueuedResourceIT { private static final String QUEUED_RESOURCE_NAME = "queued-resource"; private static final String NETWORK_NAME = "default"; + @Test + public void testCreateQueuedResource() throws Exception { + try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { + QueuedResource mockQueuedResource = mock(QueuedResource.class); + TpuClient mockTpuClient = mock(TpuClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + + mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) + .thenReturn(mockTpuClient); + when(mockTpuClient.createQueuedResourceAsync(any(CreateQueuedResourceRequest.class))) + .thenReturn(mockFuture); + when(mockFuture.get(anyLong(), any(TimeUnit.class))).thenReturn(mockQueuedResource); + + QueuedResource returnedQueuedResource = + CreateQueuedResource.createQueuedResource( + PROJECT_ID, ZONE, QUEUED_RESOURCE_NAME, NODE_NAME, + TPU_TYPE, TPU_SOFTWARE_VERSION); + + verify(mockTpuClient, times(1)) + .createQueuedResourceAsync(any(CreateQueuedResourceRequest.class)); + verify(mockFuture, times(1)).get(anyLong(), any(TimeUnit.class)); + assertEquals(returnedQueuedResource, mockQueuedResource); + } + } + @Test public void testCreateQueuedResourceWithSpecifiedNetwork() throws Exception { try (MockedStatic mockedTpuClient = mockStatic(TpuClient.class)) { From d2ca6dad2604762167f7764e5945025512f9e6b1 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Fri, 13 Dec 2024 09:11:23 +0100 Subject: [PATCH 18/19] Deleted commented imports --- tpu/src/main/java/tpu/DeleteQueuedResource.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index 34aaec886ab..dbd65efe6ad 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -24,9 +24,6 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; import org.threeten.bp.Duration; -// Uncomment this imports for getting node name -//import com.google.cloud.tpu.v2alpha1.GetQueuedResourceRequest; -//import com.google.cloud.tpu.v2alpha1.QueuedResource; public class DeleteQueuedResource { public static void main(String[] args) From 64c314c034b7a8fc520a63db6f8216746f2b25a1 Mon Sep 17 00:00:00 2001 From: Tetiana Yahodska Date: Thu, 19 Dec 2024 22:14:38 +0100 Subject: [PATCH 19/19] Fixed code as requested in comments --- .../main/java/tpu/CreateQueuedResource.java | 23 +----------------- .../main/java/tpu/DeleteQueuedResource.java | 24 +------------------ tpu/src/test/java/tpu/QueuedResourceIT.java | 6 ++--- 3 files changed, 4 insertions(+), 49 deletions(-) diff --git a/tpu/src/main/java/tpu/CreateQueuedResource.java b/tpu/src/main/java/tpu/CreateQueuedResource.java index 0470e734627..421acff2d04 100644 --- a/tpu/src/main/java/tpu/CreateQueuedResource.java +++ b/tpu/src/main/java/tpu/CreateQueuedResource.java @@ -17,17 +17,14 @@ package tpu; //[START tpu_queued_resources_create] -import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.tpu.v2alpha1.CreateQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.Node; import com.google.cloud.tpu.v2alpha1.QueuedResource; import com.google.cloud.tpu.v2alpha1.TpuClient; -import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.threeten.bp.Duration; public class CreateQueuedResource { public static void main(String[] args) @@ -59,26 +56,11 @@ public static void main(String[] args) public static QueuedResource createQueuedResource(String projectId, String zone, String queuedResourceId, String nodeName, String tpuType, String tpuSoftwareVersion) throws IOException, ExecutionException, InterruptedException, TimeoutException { - // With these settings the client library handles the Operation's polling mechanism - // and prevent CancellationException error - TpuSettings.Builder clientSettings = - TpuSettings.newBuilder(); - clientSettings - .createQueuedResourceSettings() - .setRetrySettings( - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(5000L)) - .setRetryDelayMultiplier(2.0) - .setInitialRpcTimeout(Duration.ZERO) - .setRpcTimeoutMultiplier(1.0) - .setMaxRetryDelay(Duration.ofMillis(45000L)) - .setTotalTimeout(Duration.ofHours(24L)) - .build()); String resource = String.format("projects/%s/locations/%s/queuedResources/%s", projectId, zone, queuedResourceId); // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + try (TpuClient tpuClient = TpuClient.create()) { String parent = String.format("projects/%s/locations/%s", projectId, zone); Node node = Node.newBuilder() @@ -100,9 +82,6 @@ public static QueuedResource createQueuedResource(String projectId, String zone, .setNodeId(nodeName) .build()) .build()) - // You can request a queued resource using a reservation by specifying it in code - //.setReservationName( - // "projects/YOUR_PROJECT_ID/locations/YOUR_ZONE/reservations/YOUR_RESERVATION_NAME") .build(); CreateQueuedResourceRequest request = diff --git a/tpu/src/main/java/tpu/DeleteQueuedResource.java b/tpu/src/main/java/tpu/DeleteQueuedResource.java index dbd65efe6ad..9f0e123a43e 100644 --- a/tpu/src/main/java/tpu/DeleteQueuedResource.java +++ b/tpu/src/main/java/tpu/DeleteQueuedResource.java @@ -17,13 +17,10 @@ package tpu; //[START tpu_queued_resources_delete] -import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.tpu.v2alpha1.DeleteQueuedResourceRequest; import com.google.cloud.tpu.v2alpha1.TpuClient; -import com.google.cloud.tpu.v2alpha1.TpuSettings; import java.io.IOException; import java.util.concurrent.ExecutionException; -import org.threeten.bp.Duration; public class DeleteQueuedResource { public static void main(String[] args) @@ -44,24 +41,9 @@ public static void deleteQueuedResource(String projectId, String zone, String qu throws ExecutionException, InterruptedException, IOException { String name = String.format("projects/%s/locations/%s/queuedResources/%s", projectId, zone, queuedResourceId); - // With these settings the client library handles the Operation's polling mechanism - // and prevent CancellationException error - TpuSettings.Builder clientSettings = - TpuSettings.newBuilder(); - clientSettings - .deleteQueuedResourceSettings() - .setRetrySettings( - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(5000L)) - .setRetryDelayMultiplier(2.0) - .setInitialRpcTimeout(Duration.ZERO) - .setRpcTimeoutMultiplier(1.0) - .setMaxRetryDelay(Duration.ofMillis(45000L)) - .setTotalTimeout(Duration.ofHours(24L)) - .build()); // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. - try (TpuClient tpuClient = TpuClient.create(clientSettings.build())) { + try (TpuClient tpuClient = TpuClient.create()) { // Before deleting the queued resource it is required to delete the TPU VM. // For more information about deleting TPU // see https://cloud.google.com/tpu/docs/managing-tpus-tpu-vm @@ -69,11 +51,7 @@ public static void deleteQueuedResource(String projectId, String zone, String qu DeleteQueuedResourceRequest request = DeleteQueuedResourceRequest.newBuilder().setName(name).build(); - // Waiting for updates in the library. Until then, the operation will complete successfully, - // but the user will receive an error message with UnknownException and IllegalStateException. tpuClient.deleteQueuedResourceAsync(request).get(); - - System.out.printf("Deleted Queued Resource: %s\n", name); } } } diff --git a/tpu/src/test/java/tpu/QueuedResourceIT.java b/tpu/src/test/java/tpu/QueuedResourceIT.java index 512eff097a4..92f96298829 100644 --- a/tpu/src/test/java/tpu/QueuedResourceIT.java +++ b/tpu/src/test/java/tpu/QueuedResourceIT.java @@ -59,8 +59,7 @@ public void testCreateQueuedResource() throws Exception { TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); - mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) - .thenReturn(mockTpuClient); + mockedTpuClient.when(TpuClient::create).thenReturn(mockTpuClient); when(mockTpuClient.createQueuedResourceAsync(any(CreateQueuedResourceRequest.class))) .thenReturn(mockFuture); when(mockFuture.get(anyLong(), any(TimeUnit.class))).thenReturn(mockQueuedResource); @@ -147,8 +146,7 @@ public void testDeleteQueuedResource() TpuClient mockTpuClient = mock(TpuClient.class); OperationFuture mockFuture = mock(OperationFuture.class); - mockedTpuClient.when(() -> TpuClient.create(any(TpuSettings.class))) - .thenReturn(mockTpuClient); + mockedTpuClient.when(TpuClient::create).thenReturn(mockTpuClient); when(mockTpuClient.deleteQueuedResourceAsync(any(DeleteQueuedResourceRequest.class))) .thenReturn(mockFuture); when(mockFuture.get()).thenReturn(null);