Newer
Older
openstack-caracal-dc-dc / tests / dc-edge-wan-import / fake_netbox.py
"""
In-memory stand-in for the NB client in netbox/dc-edge-wan-import.py.

No real NetBox / network access exists this session -- this fake implements just
the two methods the target script calls on its client (.one() and .create()) so the
REAL main()/preflight can be driven end-to-end without a live server. It is injected
at the get_nb() seam, exactly as tests/dc-dc-prefixes-import/ injects a fake pynetbox.

FIDELITY NOTE. The target's real .one() issues GET ...?<filter>&limit=1 and takes
results[0] -- so it is single-match by construction and CANNOT raise on a duplicate
prefix (unlike pynetbox.get(), which the sibling fake models raising on multi-match).
This fake matches THAT contract: .one() returns the first record whose fields equal
the filter, or None. For an idempotency SKIP that is the safe direction -- a
pre-existing prefix reads as "present" and is not duplicated. .create() records every
write so a test can assert a rejected/dry run wrote NOTHING.
"""
from __future__ import annotations


class FakeNB:
    def __init__(self, roles=(), prefixes=(), sites=()):
        # store: endpoint path -> list of record dicts (as the API would return them)
        self.store = {
            "ipam/roles": [dict(r) for r in roles],
            "ipam/prefixes": [dict(p) for p in prefixes],
            "dcim/sites": [dict(s) for s in sites],
        }
        self.creates = []   # (path, payload) for every .create() -- the write ledger
        self._next_id = 1000

    def one(self, path, **flt):
        for rec in self.store.get(path, []):
            if all(str(rec.get(k)) == str(v) for k, v in flt.items()):
                return rec
        return None

    def create(self, path, payload):
        self.creates.append((path, dict(payload)))
        rec = dict(payload)
        rec["id"] = self._next_id
        self._next_id += 1
        self.store.setdefault(path, []).append(rec)
        return rec