test_parse.sh (3899B)
1 #!/bin/sh 2 # Parse the real config grammar through the real parser objects. 3 # 4 # This links the actual ifaces/ports/config objects out of the build tree 5 # rather than re-implementing the grammar, so it fails when the parser changes 6 # behaviour rather than when a test fixture drifts. 7 set -eu 8 HERE=$(cd "$(dirname "$0")" && pwd) 9 ROOT=$(cd "${HERE}/../.." && pwd) 10 . "${HERE}/../helpers.sh" 11 12 echo "==> test_parse: ports + interfaces, source, vlan, bridge, hooks, IPv6" 13 14 BUILD_DIR=$(ensure_built "${ROOT}") 15 16 TMPDIR=$(mktemp -d) 17 trap 'rm -rf "$TMPDIR"' EXIT 18 19 # Config lives under the temp dir, and the harness is told where via argv. 20 # The original version hardcoded a fixed /tmp path, which two 21 # concurrent runs would silently share. 22 CFGDIR="${TMPDIR}/etc/network" 23 mkdir -p "${CFGDIR}/interfaces.d" "${CFGDIR}/ports.d" 24 25 cat > "${CFGDIR}/interfaces" <<'EOF' 26 source interfaces.d/*.cnf 27 auto lo 28 iface lo 29 address 127.0.0.1/8 30 address ::1/128 31 32 auto br0 33 iface br0 34 address 10.20.0.1/24 35 bridge-ports eth0 36 bridge-stp off 37 pre-up echo pre-up-br0 38 post-up echo post-up-br0 39 40 auto eth0.100 41 iface eth0.100 42 address 10.100.0.1/24 43 address 2001:db8:100::1/64 44 vlan-raw-device eth0 45 EOF 46 47 cat > "${CFGDIR}/interfaces.d/dummy.cnf" <<'EOF' 48 iface dummy1 49 address 10.99.0.1/24 50 pre-up touch /tmp/pre 51 post-up touch /tmp/post 52 EOF 53 54 cat > "${TMPDIR}/test_parse.c" <<'C' 55 #include <stdio.h> 56 #include <stdlib.h> 57 #include <string.h> 58 #include "util/config.h" 59 #include "config/ports.h" 60 #include "config/ifaces.h" 61 62 /* argv[1] = interfaces file, argv[2] = its directory (for `source`) */ 63 int main(int argc, char **argv) { 64 if (argc < 3) { fprintf(stderr, "usage: test_parse <file> <dir>\n"); return 2; } 65 ports_register(); 66 ifaces_register(); 67 FILE *f = fopen(argv[1], "r"); 68 if (!f) { fprintf(stderr, "cannot open %s\n", argv[1]); return 2; } 69 int rc = cfg_parse(cfg_ns_get("interfaces"), argv[2], f, NULL); 70 fclose(f); 71 if (rc != 0) { fprintf(stderr, "cfg_parse rc=%d\n", rc); return 1; } 72 73 struct linkd_iface *lo = ifaces_find("lo"); 74 struct linkd_iface *br0 = ifaces_find("br0"); 75 struct linkd_iface *vlan = ifaces_find("eth0.100"); 76 struct linkd_iface *dum = ifaces_find("dummy1"); 77 78 if (!lo) { fprintf(stderr, "lo not found\n"); return 1; } 79 if (!lo->addrs) { fprintf(stderr, "lo addrs missing\n"); return 1; } 80 81 int addrc = 0; 82 for (struct iface_addr *a = lo->addrs; a; a = a->next) addrc++; 83 if (addrc < 2) { fprintf(stderr, "lo addrc %d expected 2 (IPv6 first-class)\n", addrc); return 1; } 84 85 if (!br0) { fprintf(stderr, "br0 not found\n"); return 1; } 86 if (!br0->bridge_ports) { fprintf(stderr, "br0 bridge-ports missing\n"); return 1; } 87 if (!br0->pre_up || !br0->post_up) { fprintf(stderr, "br0 hooks missing\n"); return 1; } 88 89 if (!vlan || vlan->vlan_id != 100) { fprintf(stderr, "vlan missing or id != 100\n"); return 1; } 90 91 /* proves `source interfaces.d/*.cnf` was followed */ 92 if (!dum) { fprintf(stderr, "dummy1 not found: source directive did not load interfaces.d\n"); return 1; } 93 94 printf("parse ok: lo addrs %d, br0 ports %s, vlan %d, sourced dummy1\n", 95 addrc, br0->bridge_ports, vlan->vlan_id); 96 return 0; 97 } 98 C 99 100 cc -I"${ROOT}/src" -I"${BUILD_DIR}/lib/.dep/include" -I"${BUILD_DIR}" \ 101 "${TMPDIR}/test_parse.c" \ 102 "${BUILD_DIR}/src/config/ifaces.o" \ 103 "${BUILD_DIR}/src/config/ports.o" \ 104 "${BUILD_DIR}/src/util/config.o" \ 105 "${BUILD_DIR}/lib/finwo/cnfparse/src/cnfparse.o" \ 106 "${BUILD_DIR}/lib/finwo/buf/src/buf.o" \ 107 "${BUILD_DIR}/lib/rxi/log/src/log.o" \ 108 -o "${TMPDIR}/test_parse" 2>&1 | head -20 109 110 [ -x "${TMPDIR}/test_parse" ] || { echo "FAIL: test_parse compile failed" >&2; exit 1; } 111 112 if "${TMPDIR}/test_parse" "${CFGDIR}/interfaces" "${CFGDIR}"; then 113 echo "PASS: config parsing, source, vlan, bridge, hooks, IPv6" 114 else 115 echo "FAIL: config parsing" >&2; exit 1 116 fi 117 118 echo "==> test_parse done"