feat: initial commit for merica-pipeline delivery
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""
|
||||
Unit tests for SitomatCallbackOperator (F16 Pipeline Hub Integration).
|
||||
Menggunakan unittest.mock standar tanpa dependensi eksternal tambahan.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
# Ensure airflow/dags directory is on python path
|
||||
DAGS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "dags"))
|
||||
if DAGS_DIR not in sys.path:
|
||||
sys.path.insert(0, DAGS_DIR)
|
||||
|
||||
from helpers.sitomat_callback_operator import SitomatCallbackOperator, create_sitomat_session
|
||||
|
||||
|
||||
class TestSitomatCallbackOperator:
|
||||
|
||||
def test_invalid_layer_raises_value_error(self):
|
||||
with pytest.raises(ValueError, match="Layer 'platinum' tidak valid"):
|
||||
SitomatCallbackOperator(
|
||||
task_id="test_invalid_layer",
|
||||
run_id="run-123",
|
||||
layer="platinum",
|
||||
artifact_ref="table.name"
|
||||
)
|
||||
|
||||
def test_mock_mode_execution(self):
|
||||
operator = SitomatCallbackOperator(
|
||||
task_id="test_mock",
|
||||
run_id="run-001",
|
||||
layer="bronze",
|
||||
artifact_ref="iceberg.bronze.permits",
|
||||
checksum="sha256-mock",
|
||||
mock_mode=True
|
||||
)
|
||||
result = operator.execute()
|
||||
assert result["status"] == "mock_success"
|
||||
assert result["acknowledged"] is True
|
||||
assert result["layer"] == "bronze"
|
||||
assert result["runId"] == "run-001"
|
||||
|
||||
@patch("helpers.sitomat_callback_operator.create_sitomat_session")
|
||||
def test_successful_bronze_callback(self, mock_create_session):
|
||||
mock_session = MagicMock()
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 201
|
||||
mock_response.json.return_value = {"success": True, "versionId": "v1-uuid", "layer": "bronze"}
|
||||
mock_session.post.return_value = mock_response
|
||||
mock_create_session.return_value = mock_session
|
||||
|
||||
sitomat_url = "http://sitomat.bpkp.go.id:3000"
|
||||
run_id = "run-20261005-001"
|
||||
|
||||
operator = SitomatCallbackOperator(
|
||||
task_id="test_bronze_callback",
|
||||
run_id=run_id,
|
||||
layer="bronze",
|
||||
artifact_ref="lakehouse.bronze.permits_cdc",
|
||||
checksum="sha256-111",
|
||||
sitomat_base_url=sitomat_url,
|
||||
api_key="secret-pipeline-key",
|
||||
metadata_payload={"record_count": 8, "ge_status": "PASSED"},
|
||||
mock_mode=False
|
||||
)
|
||||
|
||||
result = operator.execute()
|
||||
assert result["status"] == "success"
|
||||
assert result["statusCode"] == 201
|
||||
assert result["response"]["versionId"] == "v1-uuid"
|
||||
mock_session.post.assert_called_once()
|
||||
|
||||
@patch("helpers.sitomat_callback_operator.create_sitomat_session")
|
||||
def test_idempotent_replay_conflict_409(self, mock_create_session):
|
||||
mock_session = MagicMock()
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 409
|
||||
mock_response.text = "conflict_artifact: run already registered"
|
||||
mock_session.post.return_value = mock_response
|
||||
mock_create_session.return_value = mock_session
|
||||
|
||||
sitomat_url = "http://sitomat.bpkp.go.id:3000"
|
||||
run_id = "run-20261005-002"
|
||||
|
||||
operator = SitomatCallbackOperator(
|
||||
task_id="test_conflict_silver",
|
||||
run_id=run_id,
|
||||
layer="silver",
|
||||
artifact_ref="lakehouse.silver.permits_clean",
|
||||
derived_from_version_id="v1-uuid",
|
||||
checksum="sha256-222",
|
||||
sitomat_base_url=sitomat_url,
|
||||
mock_mode=False
|
||||
)
|
||||
|
||||
result = operator.execute()
|
||||
assert result["status"] == "conflict_acknowledged"
|
||||
assert result["statusCode"] == 409
|
||||
assert "conflict_artifact" in result["response"]
|
||||
|
||||
@patch("helpers.sitomat_callback_operator.create_sitomat_session")
|
||||
def test_connection_error_graceful_handling(self, mock_create_session):
|
||||
import requests
|
||||
mock_session = MagicMock()
|
||||
mock_session.post.side_effect = requests.exceptions.ConnectionError("Connection refused to Sitomat")
|
||||
mock_create_session.return_value = mock_session
|
||||
|
||||
operator = SitomatCallbackOperator(
|
||||
task_id="test_conn_error",
|
||||
run_id="run-unreachable",
|
||||
layer="gold",
|
||||
artifact_ref="lakehouse.gold.mart",
|
||||
sitomat_base_url="http://192.0.2.1:9999",
|
||||
mock_mode=False
|
||||
)
|
||||
|
||||
result = operator.execute()
|
||||
assert result["status"] == "connection_warning"
|
||||
assert result["acknowledged"] is False
|
||||
assert "Connection refused" in result["error"]
|
||||
Reference in New Issue
Block a user