From daac7b334f52e1f5fbfd3a6461b74e50e5d31ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Tue, 8 Sep 2026 15:27:04 +0300 Subject: [PATCH] chore(api-tests): honour --base-url / VNEXT_BASE_URL in Python scripts and refresh runsettings wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Every script under api-tests/ that hard-coded http://localhost:4201 now takes --base-url, defaulting to the VNEXT_BASE_URL environment variable and then to localhost:4201, so the behaviour/load tests can target a second domain or offset (e.g. partner on :4211) like the integration tests already can. - publish.py (script-race-lab, script-perf-lab) gained main(argv=None, base_url=None): race-load.py and perf-load.py load it in-process and would otherwise have fed their own argv into its parser; they now pass argv=[] and their --base-url. - TEST-SCENARIOS.md, Tests/FanOut, Tests/RoleMatrixLab and api-tests/fan-out-documents READMEs no longer tell the reader to "uncomment" VNEXT_BASE_URL — it has been committed as set for a while; they now say to verify it and to use the git-ignored test.runsettings.local for a different port, with the SDK's precedence order. Companion of burgan-tech/vnext#974 (integration-test contract + runtime-integration-test skill). Co-Authored-By: Claude Fable 5.1 --- TEST-SCENARIOS.md | 11 +++++++++-- api-tests/chain-busy/chain-busy-accept-test.py | 8 +++++++- api-tests/chain-busy/chain-busy-behaviour-test.py | 8 +++++++- api-tests/data-integrity-lab/integrity-lab-test.py | 8 +++++++- api-tests/fan-out-documents/README.md | 3 ++- api-tests/l1-cache-lab/l1-cache-behaviour-test.py | 8 +++++++- api-tests/script-perf-lab/perf-load.py | 6 +++--- api-tests/script-perf-lab/publish.py | 14 ++++++++++++-- api-tests/script-race-lab/publish.py | 14 ++++++++++++-- api-tests/script-race-lab/race-load.py | 14 ++++++++++---- .../secret-cache-behaviour-test.py | 8 +++++++- .../updatedata-concurrency-test.py | 8 +++++++- tests/Core.IntegrationTests/Tests/FanOut/README.md | 5 +++-- .../Tests/RoleMatrixLab/README.md | 3 ++- 14 files changed, 95 insertions(+), 23 deletions(-) diff --git a/TEST-SCENARIOS.md b/TEST-SCENARIOS.md index fd83074..d22dc80 100644 --- a/TEST-SCENARIOS.md +++ b/TEST-SCENARIOS.md @@ -244,7 +244,12 @@ dotnet test tests/Core.IntegrationTests --filter "FullyQualifiedName~ChainBusy" **Lokalde derlenen runtime'a karşı (geliştirme sırasında doğru olan yol).** Henüz release edilmemiş bir geliştirme image üzerinden test edilemez — image eski kodu taşır. -`tests/Core.IntegrationTests/test.runsettings` içinde `VNEXT_BASE_URL`'i aç: +`tests/Core.IntegrationTests/test.runsettings` içinde `VNEXT_BASE_URL` **set olmalı** — repoda +halihazırda `http://localhost:4201` olarak commit'lidir, yorumdan çıkarılacak bir şey yoktur; sadece +doğrula. Farklı bir port/offset için commit'li dosyayı düzenleme: yanına git-ignore'lu +`test.runsettings.local` koy (csproj ve SDK onu tercih eder; öncelik: gerçek ortam değişkeni > +`test.runsettings.local` > `test.runsettings`). Set değilse SDK image'lı Testcontainers stack'ini kaldırır — +geliştirme testinde istenmeyen şey budur. ```xml http://localhost:4201 @@ -256,7 +261,9 @@ outbox — hepsi `--launch-profile http` ile), migration varsa db-migrator bir k ### Python davranış / yük testleri Senaryonun `api-tests//` klasöründe dururlar. Çalışan bir runtime'a ihtiyaç duyarlar; -`--publish` bayrağı bileşenleri publish eder. +`--publish` bayrağı bileşenleri publish eder. Hepsi `--base-url` alır (varsayılan: `VNEXT_BASE_URL` +ortam değişkeni, o da yoksa `http://localhost:4201`) — farklı bir domain/offset'e koşturmak için +`VNEXT_BASE_URL=http://localhost:4211 python3 ...` ya da `--base-url http://localhost:4211`. ```bash python3 api-tests/script-race-lab/race-load.py --publish --parallel 30 --timeout 240 diff --git a/api-tests/chain-busy/chain-busy-accept-test.py b/api-tests/chain-busy/chain-busy-accept-test.py index 28b9ebf..6b4645f 100644 --- a/api-tests/chain-busy/chain-busy-accept-test.py +++ b/api-tests/chain-busy/chain-busy-accept-test.py @@ -29,6 +29,7 @@ import argparse import json +import os import subprocess import sys import time @@ -37,7 +38,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" ROOT_WF = "chain-busy-root" MIDDLE_WF = "chain-busy-middle" @@ -198,10 +200,14 @@ def run_iteration(it): def main(): + global BASE ap = argparse.ArgumentParser() ap.add_argument("--iterations", type=int, default=5) ap.add_argument("--publish", action="store_true", help="calistirmadan once flow'lari publish et") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" print("=" * 72) print("Accept-time SubFlow chain reserve testi — chain-busy A -> B -> C") diff --git a/api-tests/chain-busy/chain-busy-behaviour-test.py b/api-tests/chain-busy/chain-busy-behaviour-test.py index c378423..ea9f07d 100644 --- a/api-tests/chain-busy/chain-busy-behaviour-test.py +++ b/api-tests/chain-busy/chain-busy-behaviour-test.py @@ -47,6 +47,7 @@ import argparse import json +import os import subprocess import sys import time @@ -55,7 +56,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" ROOT_WF = "chain-busy-root" MIDDLE_WF = "chain-busy-middle" @@ -534,6 +536,7 @@ def publish(): # ── main ──────────────────────────────────────────────────────────────────── def main(): + global BASE ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) ap.add_argument("--iterations", type=int, default=2) @@ -545,7 +548,10 @@ def main(): "uzerinden gider; onceki case'lerin olaylari drenaj halindeyken yeni bir " "kaskad gecikebilir. 0 = bekleme yok.") ap.add_argument("--list", action="store_true", help="case'leri listele ve cik") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" if args.list: for name in sorted(CASES): diff --git a/api-tests/data-integrity-lab/integrity-lab-test.py b/api-tests/data-integrity-lab/integrity-lab-test.py index 57454a9..23af702 100644 --- a/api-tests/data-integrity-lab/integrity-lab-test.py +++ b/api-tests/data-integrity-lab/integrity-lab-test.py @@ -39,6 +39,7 @@ import argparse import concurrent.futures as cf import json +import os import subprocess import sys import threading @@ -48,7 +49,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" WF = "data-integrity-lab" SCHEMA = "data_integrity_lab" @@ -361,12 +363,16 @@ def publish_definitions(): def main(): + global BASE ap = argparse.ArgumentParser() ap.add_argument("--iterations", type=int, default=6) ap.add_argument("--threshold", type=int, default=4) ap.add_argument("--burst", type=int, default=4) ap.add_argument("--publish", action="store_true", help="once task+flow tanimlarini publish et") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" if args.publish: print("== Definition publish ==") diff --git a/api-tests/fan-out-documents/README.md b/api-tests/fan-out-documents/README.md index b32940b..c003e79 100644 --- a/api-tests/fan-out-documents/README.md +++ b/api-tests/fan-out-documents/README.md @@ -173,7 +173,8 @@ MockLab seed'i `etc/docker/config/seed/fan-out-documents-collection.json` içerm > **Runtime sürümü.** FanOutTask henüz release edilmedi. Container image'ı **eski kodu taşır**; > senaryoyu lokalde derlenen runtime'a karşı koşun. Integration testler için -> `tests/Core.IntegrationTests/test.runsettings` içinde `VNEXT_BASE_URL`'i açın. +> `tests/Core.IntegrationTests/test.runsettings` içindeki `VNEXT_BASE_URL` (repoda commit'li) lokal +> orchestrator'ı göstermeli; farklı port için git-ignore'lu `test.runsettings.local` kullanın. > **`npm run validate` bu senaryoda BAŞARISIZ** — `@burgan-tech/vnext-schema@0.0.52` enum'u > `"20"`de bittiği için `attributes.type: "21"` reddediliyor. Bileşen doğru; şema paketi release diff --git a/api-tests/l1-cache-lab/l1-cache-behaviour-test.py b/api-tests/l1-cache-lab/l1-cache-behaviour-test.py index 3b4971f..55eb968 100644 --- a/api-tests/l1-cache-lab/l1-cache-behaviour-test.py +++ b/api-tests/l1-cache-lab/l1-cache-behaviour-test.py @@ -33,6 +33,7 @@ import argparse import json +import os import subprocess import sys import time @@ -41,7 +42,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" WF = "l1-cache-lab" USER = "11111111-1111-1111-1111-111111111111" @@ -191,11 +193,15 @@ def task_version_of(request_text, candidates): def main(): + global BASE ap = argparse.ArgumentParser() ap.add_argument("--minor", type=int, default=0, help="calisma surumleri 1.{2N}.0 / 1.{2N+1}.0 olur; ayni runtime'a " "tekrar kosum icin N'i artir (latest asserti ancak taze surumle anlamli)") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" v_old = f"1.{2 * args.minor}.0" v_new = f"1.{2 * args.minor + 1}.0" diff --git a/api-tests/script-perf-lab/perf-load.py b/api-tests/script-perf-lab/perf-load.py index 3551410..55de3b7 100644 --- a/api-tests/script-perf-lab/perf-load.py +++ b/api-tests/script-perf-lab/perf-load.py @@ -96,13 +96,13 @@ def http_text(url, timeout=30): return -1, str(error) -def publish(): +def publish(base_url): """Kardes publish.py'yi oldugu gibi calistirir; bilesen listesi orada tek yerde durur.""" path = Path(__file__).resolve().parent / "publish.py" spec = importlib.util.spec_from_file_location("script_perf_lab_publish", path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) - return module.main() == 0 + return module.main(argv=[], base_url=base_url) == 0 def start_one(args, label): @@ -337,7 +337,7 @@ def main(): if args.publish: print("Publish:") - if not publish(): + if not publish(args.base_url): return 1 if not args.skip_cold: diff --git a/api-tests/script-perf-lab/publish.py b/api-tests/script-perf-lab/publish.py index f8cbda8..373abe8 100644 --- a/api-tests/script-perf-lab/publish.py +++ b/api-tests/script-perf-lab/publish.py @@ -16,13 +16,16 @@ elle calistirma ve perf-load.py'nin --publish bayragi icindir. """ +import argparse import json +import os import sys import urllib.error import urllib.request from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir REPO = Path(__file__).resolve().parents[2] COMPONENTS = [ @@ -46,7 +49,14 @@ def http(method, url, body=None): return error.code, error.read().decode() -def main(): +def main(argv=None, base_url=None): + """Standalone: sys.argv parse eder. In-process cagiran (race-load/perf-load) argv=[] ve base_url verir.""" + global BASE + ap = argparse.ArgumentParser(description="bilesenleri publish et") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") + args = ap.parse_args(argv) + BASE = (base_url or args.base_url).rstrip("/") + "/api/v1" for path in COMPONENTS: document = json.loads(path.read_text()) status, response = http("POST", "%s/definitions/publish" % BASE, document) diff --git a/api-tests/script-race-lab/publish.py b/api-tests/script-race-lab/publish.py index c9385a1..94eee87 100644 --- a/api-tests/script-race-lab/publish.py +++ b/api-tests/script-race-lab/publish.py @@ -11,13 +11,16 @@ JMeter kosulari ve elle dogrulama icindir. """ +import argparse import json +import os import sys import urllib.error import urllib.request from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir REPO = Path(__file__).resolve().parents[2] COMPONENTS = [ @@ -38,7 +41,14 @@ def http(method, url, body=None): return error.code, error.read().decode() -def main(): +def main(argv=None, base_url=None): + """Standalone: sys.argv parse eder. In-process cagiran (race-load/perf-load) argv=[] ve base_url verir.""" + global BASE + ap = argparse.ArgumentParser(description="bilesenleri publish et") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") + args = ap.parse_args(argv) + BASE = (base_url or args.base_url).rstrip("/") + "/api/v1" for path in COMPONENTS: document = json.loads(path.read_text()) status, response = http("POST", "%s/definitions/publish" % BASE, document) diff --git a/api-tests/script-race-lab/race-load.py b/api-tests/script-race-lab/race-load.py index b1af5f2..fb07159 100644 --- a/api-tests/script-race-lab/race-load.py +++ b/api-tests/script-race-lab/race-load.py @@ -24,6 +24,7 @@ import argparse import importlib.util import json +import os import statistics import sys import time @@ -33,7 +34,8 @@ from concurrent.futures import ThreadPoolExecutor from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" PARENT_WF = "script-race-lab-parent" TERMINAL = {"C", "F", "P"} @@ -60,13 +62,13 @@ def http(method, url, body=None, timeout=60): return -1, {"error": str(error)} -def publish(): +def publish(base_url): """Kardes publish.py'yi oldugu gibi calistirir; bilesen listesi orada tek yerde durur.""" path = Path(__file__).resolve().parent / "publish.py" spec = importlib.util.spec_from_file_location("script_race_lab_publish", path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) - return module.main() == 0 + return module.main(argv=[], base_url=base_url) == 0 def start_one(index): @@ -115,15 +117,19 @@ def settle_one(record, timeout_s): def main(): + global BASE parser = argparse.ArgumentParser(description="script-race-lab paralel yuk surucusu") parser.add_argument("--parallel", type=int, default=30, help="baslatilacak instance sayisi") parser.add_argument("--publish", action="store_true", help="olcumden once publish adimini kos") parser.add_argument("--timeout", type=int, default=180, help="instance basina settle butcesi (s)") + parser.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = parser.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" if args.publish: print("Publish:") - if not publish(): + if not publish(args.base_url): return 1 print("\n%d instance baslatiliyor (max_workers=%d)..." % (args.parallel, args.parallel)) diff --git a/api-tests/secret-cache-lab/secret-cache-behaviour-test.py b/api-tests/secret-cache-lab/secret-cache-behaviour-test.py index 31a7a3e..613e100 100644 --- a/api-tests/secret-cache-lab/secret-cache-behaviour-test.py +++ b/api-tests/secret-cache-lab/secret-cache-behaviour-test.py @@ -43,6 +43,7 @@ import argparse import json +import os import subprocess import sys import time @@ -51,7 +52,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" WF = "secret-cache-lab" USER = "11111111-1111-1111-1111-111111111111" @@ -207,13 +209,17 @@ def summarize(tag, data, audit_delta): def main(): + global BASE ap = argparse.ArgumentParser() ap.add_argument("--ttl", type=int, default=30, help="Runtime'daki Scripting:SecretCache:TtlSeconds degeri (varsayilan 30)") ap.add_argument("--publish", action="store_true", help="Bilesenleri once publish et") ap.add_argument("--keep-secret", action="store_true", help="Test sonunda Vault'taki orijinal degeri geri yazma") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" print("== On kosullar") if not ensure_audit(): diff --git a/api-tests/subflow-orchestration/updatedata-concurrency-test.py b/api-tests/subflow-orchestration/updatedata-concurrency-test.py index c4ca611..871ecbd 100644 --- a/api-tests/subflow-orchestration/updatedata-concurrency-test.py +++ b/api-tests/subflow-orchestration/updatedata-concurrency-test.py @@ -30,6 +30,7 @@ import base64 import concurrent.futures as cf import json +import os import subprocess import sys import threading @@ -39,7 +40,8 @@ import uuid from pathlib import Path -BASE = "http://localhost:4201/api/v1" +DEFAULT_BASE_URL = os.environ.get("VNEXT_BASE_URL", "http://localhost:4201").rstrip("/") +BASE = DEFAULT_BASE_URL + "/api/v1" # main() icinde --base-url ile ezilir DOMAIN = "core" PARENT_WF = "subflow-orchestration-parent" CHILD_WF = "subflow-orchestration-child" @@ -298,12 +300,16 @@ def publish_flows(): def main(): + global BASE ap = argparse.ArgumentParser() ap.add_argument("--iterations", type=int, default=15) ap.add_argument("--threshold", type=int, default=5) ap.add_argument("--burst", type=int, default=4) ap.add_argument("--publish", action="store_true", help="once flow'lari publish et") + ap.add_argument("--base-url", default=DEFAULT_BASE_URL, + help="orchestrator base URL (varsayilan: VNEXT_BASE_URL ortam degiskeni ya da http://localhost:4201)") args = ap.parse_args() + BASE = args.base_url.rstrip("/") + "/api/v1" if args.publish: print("== Flow publish ==") diff --git a/tests/Core.IntegrationTests/Tests/FanOut/README.md b/tests/Core.IntegrationTests/Tests/FanOut/README.md index e3aadf5..34981a4 100644 --- a/tests/Core.IntegrationTests/Tests/FanOut/README.md +++ b/tests/Core.IntegrationTests/Tests/FanOut/README.md @@ -289,8 +289,9 @@ dotnet test tests/Core.IntegrationTests --filter "FullyQualifiedName~FanOutConfi ``` FanOutTask henüz release edilmedi; container image eski kodu taşır. Lokalde derlenen runtime'a karşı -koşmak için `tests/Core.IntegrationTests/test.runsettings` içinde `VNEXT_BASE_URL`'i -(`http://localhost:4201`) açın ve vNext çalışma alanında altyapı + **4 app'i** ayağa kaldırın +koşmak için `tests/Core.IntegrationTests/test.runsettings` içinde `VNEXT_BASE_URL`'in +(`http://localhost:4201`, repoda commit'li) set olduğunu doğrulayın ve vNext çalışma alanında altyapı + +**4 app'i** ayağa kaldırın (`--launch-profile http`). `VNEXT_BASE_URL` boşsa SDK kendi Testcontainers stack'ini **image'lardan** kaldırır — image eski runtime'ı taşıdığı için bu her sonucu sessizce geçersiz kılar. diff --git a/tests/Core.IntegrationTests/Tests/RoleMatrixLab/README.md b/tests/Core.IntegrationTests/Tests/RoleMatrixLab/README.md index 93cf336..91befd5 100644 --- a/tests/Core.IntegrationTests/Tests/RoleMatrixLab/README.md +++ b/tests/Core.IntegrationTests/Tests/RoleMatrixLab/README.md @@ -93,7 +93,8 @@ dotnet test tests/Core.IntegrationTests --filter "FullyQualifiedName~RoleMatrixL ``` Lokal runtime'a bağlamak için (geliştirme sırasında doğru yol — container image eski kodu taşır) -`tests/Core.IntegrationTests/test.runsettings` içindeki satırı yorumdan çıkar: +`tests/Core.IntegrationTests/test.runsettings` içindeki satırın set olduğunu doğrula (repoda commit'li; +farklı port için git-ignore'lu `test.runsettings.local`): ```xml http://localhost:4201