This is an automated email from the ASF dual-hosted git repository.

czy006 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git


The following commit(s) were added to refs/heads/master by this push:
     new 678b43c85 [AMORO-3183] Add Ams On K8S TestContainer Unit Base Test 
(#3183) (#3213)
678b43c85 is described below

commit 678b43c85347eb69d61e4f7ca016cb63d2ae56e4
Author: wyx <[email protected]>
AuthorDate: Tue Oct 22 14:48:23 2024 +0800

    [AMORO-3183] Add Ams On K8S TestContainer Unit Base Test (#3183) (#3213)
    
    * Add testcontainers test unit to AmoroAMS
    
    (cherry picked from commit 7b0bb6ec18ef4bd6e5cf54b13f289a783fb710f3)
    
    * Add testcontainers test unit to AmoroAMS
    
    * Added comparison between configmap and Deployment
    
    * Added comparison between configmap and Deployment
    
    * Added comparison between configmap and Deployment
---
 amoro-ams/pom.xml                                  |  37 ++++++
 .../java/org/apache/amoro/server/AmoroAMSTest.java |  56 ++++++++
 .../manager/TestKubernetesOptimizerContainer.java  | 144 +++++++++++++++++++++
 3 files changed, 237 insertions(+)

diff --git a/amoro-ams/pom.xml b/amoro-ams/pom.xml
index e731558fd..56eb1d5a3 100644
--- a/amoro-ams/pom.xml
+++ b/amoro-ams/pom.xml
@@ -407,6 +407,43 @@
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
+
+        <!-- testcontainers dependencies -->
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <version>1.17.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>1.17.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+            <version>15.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>k3s</artifactId>
+            <version>1.20.1</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>mysql</artifactId>
+            <version>1.19.6</version>
+            <scope>test</scope>
+        </dependency>
+
+
     </dependencies>
 
     <build>
diff --git a/amoro-ams/src/test/java/org/apache/amoro/server/AmoroAMSTest.java 
b/amoro-ams/src/test/java/org/apache/amoro/server/AmoroAMSTest.java
new file mode 100644
index 000000000..87d52c9c6
--- /dev/null
+++ b/amoro-ams/src/test/java/org/apache/amoro/server/AmoroAMSTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.server;
+
+import static org.apache.amoro.server.AmoroServiceContainer.LOG;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+public class AmoroAMSTest {
+  @ClassRule public static final Network NETWORK = Network.newNetwork();
+
+  private static final String AMS_IMAGE_VERSION = 
"apache/amoro:master-snapshot";
+
+  public GenericContainer AMSContainer =
+      new GenericContainer(DockerImageName.parse(AMS_IMAGE_VERSION))
+          .withExposedPorts(1630, 1630)
+          .withCommand("ams")
+          .withNetwork(NETWORK)
+          .waitingFor(Wait.forHttp("/"));
+
+  @Test
+  public void testAMS() throws Exception {
+
+    LOG.info("Starting AMS standalone containers...");
+
+    AMSContainer.start();
+    AMSContainer.waitingFor(Wait.forLogMessage(".*Ready to accept 
connections.*\\n", 1));
+
+    Assert.assertTrue(AMSContainer.isRunning());
+    Wait.forHealthcheck();
+
+    LOG.info("Containers are started.");
+  }
+}
diff --git 
a/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
 
b/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
index fa44530b4..417887052 100644
--- 
a/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
+++ 
b/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
@@ -18,10 +18,16 @@
 
 package org.apache.amoro.server.manager;
 
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
 import io.fabric8.kubernetes.api.model.LocalObjectReference;
 import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder;
 import io.fabric8.kubernetes.api.model.PodTemplate;
 import io.fabric8.kubernetes.api.model.apps.Deployment;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.ConfigBuilder;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClientBuilder;
 import org.apache.amoro.OptimizerProperties;
 import org.apache.amoro.resource.Resource;
 import org.apache.amoro.resource.ResourceType;
@@ -271,4 +277,142 @@ public class TestKubernetesOptimizerContainer {
             .get("memory")
             .toString());
   }
+
+  @Test
+  public void testAMSWithConfigMap() throws Exception {
+    ConfigMap configMap = buildConfigMap();
+
+    // Comparison with optimizer deployment
+    PodTemplate podTemplate =
+        kubernetesOptimizerContainer.initPodTemplateFromLocal(groupProperties);
+    ResourceType resourceType = ResourceType.OPTIMIZER;
+    Map<String, String> properties = Maps.newHashMap();
+    properties.put("memory", "1024");
+    Resource resource =
+        new Resource.Builder("KubernetesContainer", "k8s", resourceType)
+            .setMemoryMb(0)
+            .setThreadCount(1)
+            .setProperties(properties)
+            .build();
+    groupProperties.putAll(resource.getProperties());
+
+    // generate pod start args
+    long memoryPerThread;
+    long memory;
+
+    if (resource.getMemoryMb() > 0) {
+      memory = resource.getMemoryMb();
+    } else {
+      memoryPerThread = Long.parseLong(checkAndGetProperty(groupProperties, 
MEMORY_PROPERTY));
+      memory = memoryPerThread * resource.getThreadCount();
+    }
+    String startUpArgs =
+        String.format(
+            "/entrypoint.sh optimizer %s %s",
+            memory, 
kubernetesOptimizerContainer.buildOptimizerStartupArgsString(resource));
+    // read the image version from config and assert it , but not from 
podTemplate
+    String image = checkAndGetProperty(groupProperties, IMAGE);
+    String pullPolicy = checkAndGetProperty(groupProperties, PULL_POLICY);
+    String pullSecrets = groupProperties.getOrDefault(PULL_SECRETS, "");
+    String cpuLimitFactorString = 
groupProperties.getOrDefault(CPU_FACTOR_PROPERTY, "1.0");
+    double cpuLimitFactor = Double.parseDouble(cpuLimitFactorString);
+    int cpuLimit = (int) (Math.ceil(cpuLimitFactor * 
resource.getThreadCount()));
+
+    List<LocalObjectReference> imagePullSecretsList =
+        Arrays.stream(pullSecrets.split(";"))
+            .map(secret -> new 
LocalObjectReferenceBuilder().withName(secret).build())
+            .collect(Collectors.toList());
+
+    String resourceId = resource.getResourceId();
+    String groupName = resource.getGroupName();
+
+    Assert.assertEquals(1, 
podTemplate.getTemplate().getSpec().getContainers().size());
+    Assert.assertEquals(
+        "apache/amoro:0.6", 
podTemplate.getTemplate().getSpec().getContainers().get(0).getImage());
+
+    Deployment deployment =
+        kubernetesOptimizerContainer.initPodTemplateFromFrontEnd(
+            podTemplate,
+            image,
+            pullPolicy,
+            cpuLimit,
+            groupName,
+            resourceId,
+            startUpArgs,
+            memory,
+            imagePullSecretsList);
+
+    // Assert the Deployment
+    Assert.assertEquals("amoro-optimizer-" + resourceId, 
deployment.getMetadata().getName());
+    Assert.assertEquals(
+        "k8s",
+        
deployment.getSpec().getTemplate().getMetadata().getLabels().get("AmoroOptimizerGroup"));
+    Assert.assertEquals(1, deployment.getSpec().getReplicas().intValue());
+    Assert.assertEquals(
+        "IfNotPresent",
+        
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy());
+
+    Assert.assertEquals(1, 
deployment.getSpec().getTemplate().getSpec().getContainers().size());
+    Assert.assertEquals(
+        "apache/amoro:0.7-SNAPSHOT",
+        podTemplate.getTemplate().getSpec().getContainers().get(0).getImage());
+    // Assert the ConfigMap
+    Assert.assertEquals("amoro/amoro:0.8-SNAPSHOT", 
configMap.getData().get("image"));
+    Assert.assertEquals("IfNotPresent", configMap.getData().get("pullPolicy"));
+  }
+
+  private static ConfigMap buildConfigMap() {
+    Config config = new ConfigBuilder().build();
+    try (KubernetesClient client = new 
KubernetesClientBuilder().withConfig(config).build()) {
+
+      String namespace = null;
+      if (namespace == null) {
+        namespace = client.getNamespace();
+      }
+      if (namespace == null) {
+        namespace = "default";
+      }
+
+      String name = "kubernetes-config";
+
+      // The YAML formatted podTemplate
+      String podTemplate =
+          "apiVersion: apps/v1\n"
+              + "kind: PodTemplate\n"
+              + "template:\n"
+              + "  metadata:\n"
+              + "    labels:\n"
+              + "      app: <NAME_PREFIX><resourceId>\n"
+              + "      AmoroOptimizerGroup: <groupName>\n"
+              + "      AmoroResourceId: <resourceId>\n"
+              + "  spec:\n"
+              + "    containers:\n"
+              + "      - name: optimizer\n"
+              + "        image: amoro/amoro:0.8-SNAPSHOT\n"
+              + "        resources:\n"
+              + "          limits:\n"
+              + "            memory: 2048Mi\n"
+              + "            cpu: 2\n"
+              + "          requests:\n"
+              + "            memory: 2048Mi\n"
+              + "            cpu: 2";
+
+      // Build ConfigMap with desired structure
+      ConfigMap configMap =
+          new ConfigMapBuilder()
+              .withNewMetadata()
+              .withName(name)
+              .endMetadata()
+              .addToData("name", "kubernetes")
+              .addToData(
+                  "container-impl", 
"org.apache.amoro.server.manager.KubernetesOptimizerContainer")
+              .addToData("image", "amoro/amoro:0.8-SNAPSHOT")
+              .addToData("namespace", "default")
+              .addToData("podTemplate", podTemplate)
+              .addToData("pullPolicy", "IfNotPresent")
+              .build();
+
+      return configMap;
+    }
+  }
 }

Reply via email to