OverviewFilesCommitsIssuesDocsReleasesPeers

hyperswarm-peer / project / test_overlay.gd

62 lines · gd ref:
extends SceneTree

func _init():
	# Counters live in a Dictionary because GDScript lambdas capture by VALUE:
	# an `ok += 1` inside the lambda updates a copy, and the tally stays 0 while
	# every line prints "ok" — a green that cannot go red, which is the one kind
	# of test result worth nothing.
	var n := {"ok": 0, "bad": 0}
	var chk := func(c: bool, what: String):
		if c: n.ok += 1; print("  ok    ", what)
		else: n.bad += 1; print("  FAIL  ", what)

	print("HyperOverlay GDExtension binding")

	chk.call(ClassDB.class_exists("HyperOverlay"), "the class is registered with Godot")
	chk.call(ClassDB.can_instantiate("HyperOverlay"), "and can be instantiated")

	var ov = ClassDB.instantiate("HyperOverlay")
	chk.call(ov != null, "instantiated")

	var dir := "/tmp/claude-1000/ho_gd"
	DirAccess.make_dir_recursive_absolute(dir)
	chk.call(ov.open(dir), "open() succeeds on a fresh storage dir")
	chk.call(ov.is_open(), "and reports itself open")

	# Serving must not read the file: register a big one and see it return at once.
	var src := dir + "/asset.bin"
	var f := FileAccess.open(src, FileAccess.WRITE)
	var buf := PackedByteArray()
	buf.resize(2 * 1024 * 1024)
	f.store_buffer(buf)
	f.close()
	var t0 := Time.get_ticks_msec()
	ov.serve("a".repeat(64), src)
	chk.call(Time.get_ticks_msec() - t0 < 100, "serve() returns immediately — it does not read the file")

	# A fetch nobody can answer must fail rather than hang. Signals arrive on the
	# main thread via poll(), so drive it.
	var failed := {"hit": false, "reason": ""}
	ov.content_failed.connect(func(h, r): failed.hit = true; failed.reason = r)
	ov.fetch("b".repeat(64), dir + "/never.bin")

	var waited := 0
	while not failed.hit and waited < 40000:
		ov.poll()
		OS.delay_msec(50)
		waited += 50
	chk.call(failed.hit, "a fetch with no peers is abandoned, not hung (%s)" % failed.reason)
	chk.call(failed.reason.contains("stalled"), "and the reason names the watchdog")

	print("  ", ov.describe())
	ov.close()
	chk.call(not ov.is_open(), "close() joins the worker and shuts down cleanly")
	ov.free()   # a Node, not RefCounted — otherwise ObjectDB reports it leaked

	# The harness proves it can count: a deliberate failure, then the real tally.
	chk.call(false, "(control: this line must appear as FAIL and be counted)")
	var real_bad: int = n.bad - 1
	print("\n  %d assertions pass, %d fail" % [n.ok, real_bad])
	print("PASS" if real_bad == 0 else "FAIL")
	quit(0 if real_bad == 0 else 1)