fuzz: Add option for more complete testing

Add a FUZZ_LEVEL environment variable that can be used to test the
language server features under the fuzzer in addition to the compiler.
It's not enabled by default, but can be useful to run locally.
This commit is contained in:
James Westman 2025-07-05 16:26:26 -05:00
parent fe8a629d4b
commit 61acfbda98
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6

View file

@ -7,25 +7,28 @@ from blueprintcompiler.outputs.xml import XmlOutput
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from blueprintcompiler import decompiler, gir, parser, tokenizer, utils
from blueprintcompiler import gir, parser, tokenizer
from blueprintcompiler.completions import complete
from blueprintcompiler.errors import (
CompileError,
CompilerBugError,
MultipleErrors,
PrintableError,
)
from blueprintcompiler.tokenizer import Token, TokenType, tokenize
from blueprintcompiler.lsp import LanguageServer
fuzz_level = int(os.getenv("FUZZ_LEVEL") or "0")
@PythonFuzz
def fuzz(buf):
def fuzz(buf: bytes):
try:
blueprint = buf.decode("ascii")
tokens = tokenizer.tokenize(blueprint)
ast, errors, warnings = parser.parse(tokens)
if fuzz_level >= 1:
assert_ast_doesnt_crash(blueprint, tokens, ast)
xml = XmlOutput()
if errors is None and ast is not None:
xml.emit(ast)
@ -37,6 +40,17 @@ def fuzz(buf):
pass
def assert_ast_doesnt_crash(text, tokens, ast):
lsp = LanguageServer()
for i in range(len(text) + 1):
ast.get_docs(i)
for i in range(len(text) + 1):
list(complete(lsp, ast, tokens, i))
for i in range(len(text) + 1):
ast.get_reference(i)
ast.get_document_symbols()
if __name__ == "__main__":
# Make sure Gtk 4.0 is accessible, otherwise every test will fail on that
# and nothing interesting will be tested