|
| 1 | +# Test: subsystem-list returns real plugin data (not hardcoded ["bgp"]) |
| 2 | +# Exercises: dispatch-command -> ze-system:subsystem-list -> handleSystemSubsystemList |
| 3 | +# Verifies AC-9: returns JSON array with name, stage, running, command-count per plugin |
| 4 | + |
| 5 | +# ze-peer: accepts connection |
| 6 | +stdin=peer:terminator=EOF_PEER |
| 7 | +option=tcp_connections:value=1 |
| 8 | +option=timeout:value=15s |
| 9 | +option=asn:value=65001 |
| 10 | +expect=bgp:conn=1:seq=1:hex=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00170200000000 |
| 11 | +EOF_PEER |
| 12 | + |
| 13 | +tmpfs=subsystem-list-test.run:mode=755:terminator=EOF_RUN |
| 14 | +#!/usr/bin/env python3 |
| 15 | +import json |
| 16 | +import sys |
| 17 | +import time |
| 18 | +from ze_api import API |
| 19 | + |
| 20 | +def dispatch(api, command): |
| 21 | + resp = api._call_engine( |
| 22 | + 'ze-plugin-engine:dispatch-command', {'command': command}) |
| 23 | + if resp is None: |
| 24 | + return {'status': 'error', 'data': 'engine call returned None'} |
| 25 | + return resp.get('result', {}) |
| 26 | + |
| 27 | +def main(): |
| 28 | + api = API() |
| 29 | + api.declare_done() |
| 30 | + api.wait_for_config() |
| 31 | + api.capability_done() |
| 32 | + api.wait_for_registry() |
| 33 | + api.ready() |
| 34 | + time.sleep(1.0) |
| 35 | + |
| 36 | + try: |
| 37 | + # Call the wire method directly (system RPCs are not in the CLI tree) |
| 38 | + resp = api._call_engine('ze-system:subsystem-list', {}) |
| 39 | + if resp is None: |
| 40 | + print('FAIL: subsystem-list returned None', file=sys.stderr) |
| 41 | + sys.exit(1) |
| 42 | + result = resp.get('result', {}) |
| 43 | + status = result.get('status') |
| 44 | + if status != 'done': |
| 45 | + print(f'FAIL: status={status} data={result.get("data")}', file=sys.stderr) |
| 46 | + sys.exit(1) |
| 47 | + |
| 48 | + data = result.get('data', {}) |
| 49 | + if isinstance(data, str): |
| 50 | + data = json.loads(data) |
| 51 | + |
| 52 | + subsystems = data.get('subsystems', []) |
| 53 | + count = data.get('count', 0) |
| 54 | + |
| 55 | + if count < 1: |
| 56 | + print(f'FAIL: expected at least 1 subsystem, got {count}', file=sys.stderr) |
| 57 | + sys.exit(1) |
| 58 | + |
| 59 | + # Verify each entry has the expected fields |
| 60 | + for sub in subsystems: |
| 61 | + if not isinstance(sub, dict): |
| 62 | + print(f'FAIL: subsystem entry is not a dict: {sub}', file=sys.stderr) |
| 63 | + sys.exit(1) |
| 64 | + for field in ('name', 'stage', 'running', 'command-count'): |
| 65 | + if field not in sub: |
| 66 | + print(f'FAIL: missing field {field!r} in {sub}', file=sys.stderr) |
| 67 | + sys.exit(1) |
| 68 | + |
| 69 | + names = [s['name'] for s in subsystems] |
| 70 | + print(f'OK: subsystem-list returned {count} subsystem(s): {names}', file=sys.stderr) |
| 71 | + api._call_engine('ze-system:daemon-shutdown', {}) |
| 72 | + api.wait_for_shutdown() |
| 73 | + except SystemExit: |
| 74 | + raise |
| 75 | + except Exception as e: |
| 76 | + print(f'FAIL: unexpected error: {e}', file=sys.stderr) |
| 77 | + sys.exit(1) |
| 78 | + |
| 79 | +if __name__ == '__main__': |
| 80 | + main() |
| 81 | +EOF_RUN |
| 82 | + |
| 83 | +stdin=ze-bgp:terminator=EOF_CONF |
| 84 | +plugin { |
| 85 | + external subsystem-list-test { |
| 86 | + run ./subsystem-list-test.run |
| 87 | + encoder json |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +bgp { |
| 92 | + peer peer1 { |
| 93 | + connection { |
| 94 | + remote { |
| 95 | + ip 127.0.0.1 |
| 96 | + } |
| 97 | + local { |
| 98 | + ip 127.0.0.1 |
| 99 | + accept false |
| 100 | + } |
| 101 | + } |
| 102 | + session { |
| 103 | + asn { |
| 104 | + local 65000 |
| 105 | + remote 65001 |
| 106 | + } |
| 107 | + router-id 1.2.3.4 |
| 108 | + family { |
| 109 | + ipv4/unicast { |
| 110 | + prefix { |
| 111 | + maximum 10000 |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + capability { |
| 116 | + graceful-restart disable |
| 117 | + } |
| 118 | + } |
| 119 | + behavior { |
| 120 | + group-updates disable |
| 121 | + } |
| 122 | + |
| 123 | + process subsystem-list-test { |
| 124 | + } |
| 125 | + } |
| 126 | +} |
| 127 | +EOF_CONF |
| 128 | + |
| 129 | +cmd=background:seq=1:exec=ze-peer --port $PORT:stdin=peer |
| 130 | +cmd=foreground:seq=2:exec=ze -:stdin=ze-bgp:timeout=15s |
| 131 | +expect=exit:code=0 |
0 commit comments