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

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


The following commit(s) were added to refs/heads/master by this push:
     new af005ef679c fix post commit yaml test (#39142)
af005ef679c is described below

commit af005ef679c4ebd50d95bd3b54b8f61fe7ec9bbe
Author: Derrick Williams <[email protected]>
AuthorDate: Mon Jun 29 10:02:21 2026 -0400

    fix post commit yaml test (#39142)
    
    * try to fix iceberg post commit test
    
    * trigger file
    
    * isort
    
    * oops more lint
    
    * lint
    
    * fix tmp dir
    
    * add timeouts per gemini comments
---
 .../beam_PostCommit_Yaml_Xlang_Direct.json         |  2 +-
 .../yaml/extended_tests/databases/iceberg.yaml     | 54 +++++++++-------
 sdks/python/apache_beam/yaml/integration_tests.py  | 74 ++++++++++++++++++++++
 3 files changed, 107 insertions(+), 23 deletions(-)

diff --git a/.github/trigger_files/beam_PostCommit_Yaml_Xlang_Direct.json 
b/.github/trigger_files/beam_PostCommit_Yaml_Xlang_Direct.json
index b5704c67ef1..86bf1193abd 100644
--- a/.github/trigger_files/beam_PostCommit_Yaml_Xlang_Direct.json
+++ b/.github/trigger_files/beam_PostCommit_Yaml_Xlang_Direct.json
@@ -1,4 +1,4 @@
 {
   "comment": "Modify this file in a trivial way to cause this test suite to 
run",
-  "revision": 6
+  "revision": 7
 }
diff --git a/sdks/python/apache_beam/yaml/extended_tests/databases/iceberg.yaml 
b/sdks/python/apache_beam/yaml/extended_tests/databases/iceberg.yaml
index d7449233aab..98462f2d027 100644
--- a/sdks/python/apache_beam/yaml/extended_tests/databases/iceberg.yaml
+++ b/sdks/python/apache_beam/yaml/extended_tests/databases/iceberg.yaml
@@ -16,8 +16,18 @@
 #
 
 fixtures:
-  - name: TEMP_DIR
-    type: "tempfile.TemporaryDirectory"
+  - name: ICEBERG_FIXTURE
+    type: "apache_beam.yaml.integration_tests.temp_iceberg_table_with_pk"
+    config:
+      table_data:
+        name: "labels"
+        schema:
+          type: "struct"
+          schema-id: 0
+          fields:
+            - { id: 1, name: "label", required: true, type: "string" }
+            - { id: 2, name: "rank", required: true, type: "long" }
+          identifier-field-ids: [1]
 
 pipelines:
   - name: write
@@ -32,14 +42,14 @@ pipelines:
               - {label: "389a", rank: 2}
         - type: WriteToIceberg
           config:
-            table: db.labels
-            catalog_name: hadoop_catalog
+            table: "{ICEBERG_FIXTURE[table]}"
+            catalog_name: rest_catalog
             catalog_properties:
-              type: hadoop
-              warehouse: "{TEMP_DIR}"
+              type: rest
+              uri: "{ICEBERG_FIXTURE[api_url]}"
     options:
       project: "apache-beam-testing"
-      temp_location: "{TEMP_DIR}"
+      temp_location: "{ICEBERG_FIXTURE[temp_dir]}"
 
   - name: read
     pipeline:
@@ -47,11 +57,11 @@ pipelines:
       transforms:
         - type: ReadFromIceberg
           config:
-            table: db.labels
-            catalog_name: hadoop_catalog
+            table: "{ICEBERG_FIXTURE[table]}"
+            catalog_name: rest_catalog
             catalog_properties:
-              type: hadoop
-              warehouse: "{TEMP_DIR}"
+              type: rest
+              uri: "{ICEBERG_FIXTURE[api_url]}"
         - type: AssertEqual
           config:
             elements:
@@ -60,7 +70,7 @@ pipelines:
               - {label: "389a", rank: 2}
     options:
       project: "apache-beam-testing"
-      temp_location: "{TEMP_DIR}"
+      temp_location: "{ICEBERG_FIXTURE[temp_dir]}"
 
   - name: read_cdc_batch
     pipeline:
@@ -68,11 +78,11 @@ pipelines:
       transforms:
         - type: ReadFromIcebergCDC
           config:
-            table: db.labels
-            catalog_name: hadoop_catalog
+            table: "{ICEBERG_FIXTURE[table]}"
+            catalog_name: rest_catalog
             catalog_properties:
-              type: hadoop
-              warehouse: "{TEMP_DIR}"
+              type: rest
+              uri: "{ICEBERG_FIXTURE[api_url]}"
             from_timestamp: 1762819200000
             to_timestamp:  2078352000000
             filter: '"label" = ''11a'' or "rank" = 1'
@@ -86,7 +96,7 @@ pipelines:
               - {label: "37a", rank: 1}
     options:
       project: "apache-beam-testing"
-      temp_location: "{TEMP_DIR}"
+      temp_location: "{ICEBERG_FIXTURE[temp_dir]}"
 
   - name: read_cdc_streaming
     pipeline:
@@ -94,11 +104,11 @@ pipelines:
       transforms:
         - type: ReadFromIcebergCDC
           config:
-            table: db.labels
-            catalog_name: hadoop_catalog
+            table: "{ICEBERG_FIXTURE[table]}"
+            catalog_name: rest_catalog
             catalog_properties:
-              type: hadoop
-              warehouse: "{TEMP_DIR}"
+              type: rest
+              uri: "{ICEBERG_FIXTURE[api_url]}"
             streaming: True
             to_timestamp: 2078352000000
             filter: '"label" = ''11a'' or "rank" = 1'
@@ -112,4 +122,4 @@ pipelines:
               - {label: "37a", rank: 1}
     options:
       project: "apache-beam-testing"
-      temp_location: "{TEMP_DIR}"
+      temp_location: "{ICEBERG_FIXTURE[temp_dir]}"
diff --git a/sdks/python/apache_beam/yaml/integration_tests.py 
b/sdks/python/apache_beam/yaml/integration_tests.py
index e319a3d3a9b..a7abd223b29 100644
--- a/sdks/python/apache_beam/yaml/integration_tests.py
+++ b/sdks/python/apache_beam/yaml/integration_tests.py
@@ -26,15 +26,20 @@ import logging
 import os
 import random
 import secrets
+import shutil
 import sqlite3
 import string
 import struct
+import tempfile
+import time
 import unittest
 import uuid
 from datetime import datetime
 from datetime import timezone
 
 import mock
+import requests
+from testcontainers.core.container import DockerContainer
 
 from apache_beam.coders import Coder
 from apache_beam.coders.coder_impl import CoderImpl
@@ -556,6 +561,75 @@ def temp_oracle_database():
     yield f"jdbc:oracle:thin:system/oracle@localhost:{port}/XEPDB1"
 
 
[email protected]
+def temp_iceberg_table_with_pk(table_data):
+
+  # Create a temp dir that will be shared between host and container.
+  # We use the exact same path on both to avoid path mapping issues.
+  # We create it in the current working directory (workspace) because
+  # Docker in GitHub Actions often cannot mount directories from /tmp.
+  temp_dir = tempfile.mkdtemp(dir=os.getcwd())
+  os.chmod(temp_dir, 0o777)
+
+  # Start the Iceberg REST catalog container
+  container = DockerContainer("tabulario/iceberg-rest:0.6.0")
+  container.with_exposed_ports(8181)
+  container.with_volume_mapping(temp_dir, temp_dir, mode='rw')
+  container.with_env("HADOOP_USER_NAME", "iceberg")
+  container.with_env("CATALOG_WAREHOUSE", temp_dir)
+  container.with_env(
+      "CATALOG_IO__IMPL", "org.apache.iceberg.hadoop.HadoopFileIO")
+
+  try:
+    container.start()
+
+    ip = container.get_container_host_ip()
+    port = container.get_exposed_port(8181)
+    api_url = f"http://{ip}:{port}";
+
+    # Poll the REST API until it is ready
+    for _ in range(30):
+      try:
+        response = requests.get(f"{api_url}/v1/config", timeout=5)
+        if response.status_code == 200:
+          break
+      except (requests.exceptions.ConnectionError, 
requests.exceptions.Timeout):
+        pass
+      time.sleep(1)
+    else:
+      raise RuntimeError("Iceberg REST catalog failed to start in time.")
+
+    # Create namespace 'db'
+    requests.post(
+        f"{api_url}/v1/namespaces",
+        json={"namespace": ["db"]},
+        headers={"Content-Type": "application/json"},
+        timeout=10)
+
+    # Create table with primary key
+    response = requests.post(
+        f"{api_url}/v1/namespaces/db/tables",
+        json=table_data,
+        headers={"Content-Type": "application/json"},
+        timeout=10)
+    if response.status_code != 200:
+      raise RuntimeError(f"Failed to create Iceberg table: {response.text}")
+
+    # Change permissions of the created directories inside the container
+    # so the host user can write to them.
+    container.get_wrapped_container().exec_run(f"chmod -R 777 {temp_dir}")
+
+    yield {
+        "api_url": api_url,
+        "temp_dir": temp_dir,
+        "table": f"db.{table_data['name']}"
+    }
+
+  finally:
+    container.stop()
+    shutil.rmtree(temp_dir, ignore_errors=True)
+
+
 @contextlib.contextmanager
 def temp_kafka_server():
   """Context manager to provide a temporary Kafka server for testing.

Reply via email to