From 7773780c6d7c337c124941a93571122d64fe1816 Mon Sep 17 00:00:00 2001 From: Olivier Desenfans Date: Mon, 8 Apr 2024 00:30:09 +0200 Subject: [PATCH] Fix: ignore missing null values when comparing PIEs Problem: the new implementation of `CairoPie` using the `CairoPieAdditionalData` struct makes it hard to reproduce the exact same behaviour as `cairo-lang` when handling builtins with no data. While `cairo-lang` will generate a null value and include it in the JSON file, we can only (easily) generate a null value for each builtin or for none of them. Solution: make the comparator script more flexible by filtering out null values from JSON contents. --- Cargo.lock | 1 + vm/src/tests/cairo_pie_comparator.py | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3cd2a2000..d51294e05e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -973,6 +973,7 @@ dependencies = [ "clap", "itertools 0.11.0", "mimalloc", + "num-traits 0.2.18", "rstest", "thiserror", ] diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py index ab604beaa4..32e29b0ffe 100755 --- a/vm/src/tests/cairo_pie_comparator.py +++ b/vm/src/tests/cairo_pie_comparator.py @@ -2,6 +2,7 @@ import sys import json +from typing import Any from zipfile import ZipFile import memory_comparator @@ -10,18 +11,36 @@ json_files = ["version.json", "metadata.json", "execution_resources.json", "additional_data.json"] + +def filter_null_values(content: Any) -> Any: + if isinstance(content, dict): + return {k: v for k, v in content.items() if v is not None} + + return content + + +def json_contents_are_equivalent(cl: Any, cv: Any) -> bool: + """ + Compares the two JSON contents. and returns whether they are equivalent. + Contents are considered equivalent if they are equal or if some keys have null values in one + content and are just missing from the other. + """ + + return filter_null_values(cl) == filter_null_values(cv) + + with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip: # Compare json files for file in json_files: with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file: cl_content = json.load(cairo_lang_file) cv_content = json.load(cairo_vm_file) - if cl_content != cv_content: + if not json_contents_are_equivalent(cl_content, cv_content): print(f"Comparison unsuccesful for {filename1}/{file} vs {filename2}/{file}") exit(1) # Compare binary files - with cairo_lang_pie_zip.open("memory.bin", 'r') as f1, cairo_vm_pie_zip.open("memory.bin", 'r') as f2: + with cairo_lang_pie_zip.open("memory.bin", 'r') as f1, cairo_vm_pie_zip.open("memory.bin", 'r') as f2: memory_comparator.compare_memory_file_contents(f1.read(), f2.read()) print(f"Comparison succesful for {filename1} vs {filename2}")