|
| 1 | +// Integration test against a REAL consul agent. Gated on `MOON_CONSUL_TEST`, so it is |
| 2 | +// skipped in the normal suite and runs only in the CI job that stands up a consul |
| 3 | +// container. It drives the exact discovery wire — register a service with a TTL check, |
| 4 | +// pass the check, resolve the healthy set, deregister — over the real HTTP socket, |
| 5 | +// reusing the root's request-body builder and health parser, so a green run proves the |
| 6 | +// HTTP/1 codec and the discovery flow against a live consul. |
| 7 | + |
| 8 | +///| |
| 9 | +/// The consul host for the integration test: `MOON_CONSUL_HOST`, or localhost. |
| 10 | +fn consul_test_host() -> String { |
| 11 | + match @env.get_env_var("MOON_CONSUL_HOST") { |
| 12 | + Some(h) => h |
| 13 | + None => "127.0.0.1" |
| 14 | + } |
| 15 | +} |
| 16 | + |
| 17 | +///| |
| 18 | +/// Register `endpoint` for `service` and pass its TTL check so it is healthy at once. |
| 19 | +async fn consul_put_healthy( |
| 20 | + sock : ConsulSocket, |
| 21 | + service : String, |
| 22 | + id : String, |
| 23 | + host : String, |
| 24 | + port : Int, |
| 25 | +) -> Unit { |
| 26 | + let ok = sock.request( |
| 27 | + "PUT", |
| 28 | + "/v1/agent/service/register", |
| 29 | + @moonzero.consul_register_body(id, service, host, port, 30), |
| 30 | + ) |
| 31 | + assert_eq(ok.status(), 200) |
| 32 | + let passed = sock.request("PUT", "/v1/agent/check/pass/service:" + id, b"") |
| 33 | + assert_eq(passed.status(), 200) |
| 34 | +} |
| 35 | + |
| 36 | +///| |
| 37 | +async test "integration: consul discovery register/resolve/deregister over a real consul" { |
| 38 | + guard @env.get_env_var("MOON_CONSUL_TEST") is Some(_) else { return } |
| 39 | + let sock = ConsulSocket::new(consul_test_host()) |
| 40 | + let id1 = "greeter-10.0.0.1-9090" |
| 41 | + let id2 = "greeter-10.0.0.2-9090" |
| 42 | + // Clean any leftover from a prior run. |
| 43 | + let _ = sock.request("PUT", "/v1/agent/service/deregister/" + id1, b"") |
| 44 | + let _ = sock.request("PUT", "/v1/agent/service/deregister/" + id2, b"") |
| 45 | + // Register two healthy instances. |
| 46 | + consul_put_healthy(sock, "greeter", id1, "10.0.0.1", 9090) |
| 47 | + consul_put_healthy(sock, "greeter", id2, "10.0.0.2", 9090) |
| 48 | + // Resolve the healthy set. |
| 49 | + let resp = sock.request("GET", "/v1/health/service/greeter?passing=true", b"") |
| 50 | + assert_eq(resp.status(), 200) |
| 51 | + let eps = @moonzero.consul_parse_health(resp.body()) |
| 52 | + assert_eq(eps.length(), 2) |
| 53 | + let addrs = eps.map(e => e.address()) |
| 54 | + assert_eq(addrs.contains("10.0.0.1:9090"), true) |
| 55 | + assert_eq(addrs.contains("10.0.0.2:9090"), true) |
| 56 | + // Deregister both; the healthy set is then empty. |
| 57 | + let _ = sock.request("PUT", "/v1/agent/service/deregister/" + id1, b"") |
| 58 | + let _ = sock.request("PUT", "/v1/agent/service/deregister/" + id2, b"") |
| 59 | + let after = sock.request( |
| 60 | + "GET", "/v1/health/service/greeter?passing=true", b"", |
| 61 | + ) |
| 62 | + assert_eq(@moonzero.consul_parse_health(after.body()).length(), 0) |
| 63 | +} |
0 commit comments