"""Controlled kill during the activation of a DDIC table (database table creation takes seconds).""" import json, os, signal, subprocess, sys, time sys.path.insert(0, "/Users/erhankeseli/projects/abap-llm/harness/scripts_probe") from lockprobe import * from killtest import VICTIM DDL = """@EndUserText.label : 'kill test' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #RESTRICTED define table {n} {{ key client : abap.clnt not null; key item_id : abap.char(10) not null; qty : abap.int4; name : abap.char({w}); }}""" def attempt(delay, n): name = "ZPROBE0KT_%03d" % n with McpClient() as m: print("create", m.call("sap_create_object", {"objectType": "TABL", "objectName": name, "packageName": "$TMP", "description": "kill table"})[1][:50]) # first write alone, to learn how long it takes args = {"objectType": "TABL", "objectName": name, "source": DDL.format(n=name.lower(), w=20 + n)} p = subprocess.Popen([sys.executable, "-c", VICTIM, json.dumps(args)], stdout=subprocess.PIPE, text=True) assert p.stdout.readline().strip() == "SENT" t0 = time.time(); time.sleep(delay) finished = p.poll() is not None try: os.kill(p.pid, signal.SIGKILL) except ProcessLookupError: finished = True p.wait() print("table write: victim %s after %.2f s" % ("had finished" if finished else "killed", time.time() - t0)) time.sleep(3) out = {"name": name, "delay": delay, "finished_before_kill": finished} with McpClient() as m: out["enqueue"] = read_locks(m) e, t = m.call("sap_push_source", {"objectType": "TABL", "objectName": name, "source": DDL.format(n=name.lower(), w=40 + n)}) out["second_write"] = t[:300] out["leak"] = "[LOCK]" in out["second_write"] or ("ZPROBE0KT" in out["enqueue"] and "enqueue entries matching the probe prefixes: 0" not in out["enqueue"]) out["delete"] = delete_uris(["/sap/bc/adt/ddic/tables/" + name.lower()]) return out if __name__ == "__main__": for i, d in enumerate(float(x) for x in sys.argv[1].split(",")): o = attempt(d, int(sys.argv[2]) + i) o["enqueue"] = o["enqueue"][:900] print(json.dumps(o, indent=1)) if o["leak"]: print("LEAK at delay", d, "object", o["name"]); break