Coverage for tests / test_ordering.py: 100%
16 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-29 02:37 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-29 02:37 +0000
1import pytest
2from unittest.mock import MagicMock
3from stepclient_traefik.config import settings
4from stepclient_traefik.discovery import DockerDiscovery
6CASES = [
7 {
8 "id": "host-explicit",
9 "labels": {
10 "traefik.enable": "true",
11 "traefik.http.routers.example.rule": "Host(`main.example.com`,`sub1.example.com`,`sub2.example.com`,`sub3.example.com`)",
12 "traefik.http.routers.example.entrypoints": "websecure",
13 "traefik.http.routers.example.tls": "true"
14 },
15 "expected": {
16 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"],
17 "tls_domains": []
18 }
19 },
20 {
21 "id": "hostsni-explicit",
22 "labels": {
23 "traefik.enable": "true",
24 "traefik.http.routers.example.rule": "HostSNI(`main.example.com`,`sub1.example.com`,`sub2.example.com`,`sub3.example.com`)",
25 "traefik.http.routers.example.entrypoints": "websecure",
26 "traefik.http.routers.example.tls": "true"
27 },
28 "expected": {
29 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"],
30 "tls_domains": []
31 }
32 },
33 {
34 "id": "hostregexp-pipe-group",
35 "labels": {
36 "traefik.enable": "true",
37 "traefik.http.routers.example.rule": "HostRegexp(`{sub:(main|sub1|sub2|sub3)}.example.com`)",
38 "traefik.http.routers.example.entrypoints": "websecure",
39 "traefik.http.routers.example.tls": "true"
40 },
41 "expected": {
42 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"],
43 "tls_domains": []
44 }
45 },
46 {
47 "id": "tls-domains-main-and-sans",
48 "labels": {
49 "traefik.enable": "true",
50 "traefik.http.routers.example.rule": "Host(`main.example.com`)",
51 "traefik.http.routers.example.entrypoints": "websecure",
52 "traefik.http.routers.example.tls": "true",
53 "traefik.http.routers.example.tls.domains[0].main": "main.example.com",
54 "traefik.http.routers.example.tls.domains[0].sans": "sub1.example.com,sub2.example.com,sub3.example.com"
55 },
56 "expected": {
57 "rule_domains": ["main.example.com"],
58 "tls_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"]
59 }
60 },
61 {
62 "id": "tls-domains-multiple-certs",
63 "labels": {
64 "traefik.enable": "true",
65 "traefik.http.routers.example.rule": "Host(`main.example.com`,`sub1.example.com`,`sub2.example.com`,`sub3.example.com`)",
66 "traefik.http.routers.example.entrypoints": "websecure",
67 "traefik.http.routers.example.tls": "true",
68 "traefik.http.routers.example.tls.domains[0].main": "main.example.com",
69 "traefik.http.routers.example.tls.domains[1].main": "sub1.example.com",
70 "traefik.http.routers.example.tls.domains[2].main": "sub2.example.com",
71 "traefik.http.routers.example.tls.domains[3].main": "sub3.example.com"
72 },
73 "expected": {
74 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"],
75 "tls_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"]
76 }
77 },
78 {
79 "id": "hostregexp-plus-tls-domains",
80 "labels": {
81 "traefik.enable": "true",
82 "traefik.http.routers.example.rule": "HostRegexp(`{sub:(main|sub1|sub2|sub3)}.example.com`)",
83 "traefik.http.routers.example.entrypoints": "websecure",
84 "traefik.http.routers.example.tls": "true",
85 "traefik.http.routers.example.tls.domains[0].main": "main.example.com",
86 "traefik.http.routers.example.tls.domains[0].sans": "sub1.example.com,sub2.example.com,sub3.example.com"
87 },
88 "expected": {
89 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"],
90 "tls_domains": ["main.example.com", "sub1.example.com", "sub2.example.com", "sub3.example.com"]
91 }
92 },
93 {
94 "id": "host-or-chaining",
95 "labels": {
96 "traefik.enable": "true",
97 "traefik.http.routers.example.rule": "Host(`main.example.com`) || Host(`sub1.example.com`) || Host(`sub2.example.com`)",
98 "traefik.http.routers.example.entrypoints": "websecure",
99 "traefik.http.routers.example.tls": "true"
100 },
101 "expected": {
102 "rule_domains": ["main.example.com", "sub1.example.com", "sub2.example.com"],
103 "tls_domains": []
104 }
105 }
106]
109@pytest.mark.parametrize("case", CASES, ids=lambda c: c["id"])
110def test_discovery_ordering(case):
111 d = DockerDiscovery()
112 # Mock return from get_services so we don't need real docker socket
113 d.get_services = MagicMock(return_value=[
114 {"Spec": {"Labels": case["labels"]}}
115 ])
117 routers, warnings = d.extract_routers()
118 assert "example" in routers, f"Router 'example' not found in case {case['id']}"
120 meta = routers["example"]
122 # 1. Check Rule Extraction Ordering
123 rule_domains, _ = d.extract_from_rules(meta.get("rule", ""))
125 # Convert to list to check order if it isn't already (current implementation returns set)
126 # But we want to fail if it's unordered.
127 # We assertion verifies strict equality with list.
128 assert list(rule_domains) == case["expected"]["rule_domains"], f"Rule domains order mismatch for {case['id']}"
130 # 2. Check TLS Domains Extraction Ordering
131 # Note: Flatten logic for tls_domains matches how we expect them to be accumulated
132 # The 'expected' in test case implies the aggregate of all tls.domains definitions
133 extracted_tls = meta.get("tls_domains") or []
134 assert list(extracted_tls) == case["expected"]["tls_domains"], f"TLS domains order mismatch for {case['id']}"