feat: standardize transport contracts across Gin and nethttp
This commit is contained in:
66
scripts/verifyTransports.py
Normal file
66
scripts/verifyTransports.py
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run the public adapter contract from an independent consumer module."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
|
||||
from verifyScaffold import MODULE, run
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--go", default="go")
|
||||
parser.add_argument("--version", default="v0.3.0")
|
||||
parser.add_argument("--framework-dir", help="Use a local checkout before release")
|
||||
args = parser.parse_args()
|
||||
env = dict(os.environ, GOWORK="off")
|
||||
env["GOPRIVATE"] = ",".join(filter(None, [env.get("GOPRIVATE", ""), "git.yuntuo.hk"]))
|
||||
with tempfile.TemporaryDirectory(prefix="go omni transport ") as temporary:
|
||||
directory = Path(temporary).resolve()
|
||||
module = f"module example.com/adaptercheck\n\ngo 1.22\n\nrequire {MODULE} {args.version}\n"
|
||||
if args.framework_dir:
|
||||
module += f"\nreplace {MODULE} => {json.dumps(str(Path(args.framework_dir).resolve()), ensure_ascii=False)}\n"
|
||||
(directory / "go.mod").write_text(module)
|
||||
(directory / "adapter_test.go").write_text(f'''package adaptercheck_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"{MODULE}/httpx"
|
||||
ginrouter "{MODULE}/transport/gin"
|
||||
netrouter "{MODULE}/transport/nethttp"
|
||||
"{MODULE}/transport/transporttest"
|
||||
)
|
||||
|
||||
func TestContract(t *testing.T) {{
|
||||
t.Run("gin", func(t *testing.T) {{
|
||||
transporttest.Run(t, func() httpx.Router {{ return ginrouter.New("test") }})
|
||||
}})
|
||||
t.Run("nethttp", func(t *testing.T) {{
|
||||
transporttest.Run(t, func() httpx.Router {{ return netrouter.New() }})
|
||||
}})
|
||||
}}
|
||||
''')
|
||||
source = "local checkout" if args.framework_dir else f"remote {args.version}"
|
||||
print(f"Testing {source} in an independent consumer module", flush=True)
|
||||
run([args.go, "mod", "tidy"], directory, env)
|
||||
if not args.framework_dir and "replace " in (directory / "go.mod").read_text():
|
||||
raise AssertionError("remote verification must not contain replace")
|
||||
output = run([args.go, "test", "-race", "-count=1", "-json", "./..."], directory, env)
|
||||
events = [json.loads(line) for line in output.splitlines() if line.startswith("{")]
|
||||
if any(event.get("Action") == "skip" for event in events):
|
||||
raise AssertionError("contract suite unexpectedly skipped tests")
|
||||
for adapter in ("gin", "nethttp"):
|
||||
name = f"TestContract/{adapter}"
|
||||
if not any(event.get("Action") == "pass" and event.get("Test") == name for event in events):
|
||||
raise AssertionError(f"{adapter} contract did not pass")
|
||||
count = sum(event.get("Action") == "pass" and event.get("Test", "").startswith(name + "/")
|
||||
for event in events)
|
||||
print(f"PASS {adapter}: {count} contract checks, including business handlers, cancellation and concurrent requests", flush=True)
|
||||
print("PASS independent module: both adapters accepted by the same public contract suite", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user