Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jun 4, 2025

This PR adds a new --dump-smt-directory flag that allows users to specify a custom directory for dumping SMT files, addressing the limitation where SMT files were always saved to /tmp/ with no user control.

Changes

New CLI Flag

halmos --dump-smt-queries --dump-smt-directory ./my-smt-files

Key Features

  • Custom directory support: Users can now specify where SMT files should be dumped
  • Automatic directory creation: Creates the specified directory and any parent directories if they don't exist
  • Function-specific subdirectories: Organizes files by function/contract (e.g., ./my-smt-files/testFunction/, ./my-smt-files/MyContract-constructor/)
  • Full backward compatibility: When --dump-smt-directory is not specified, behavior remains unchanged (files go to temporary directories)
  • Path flexibility: Supports both absolute and relative paths

Implementation Details

  1. Config option: Added dump_smt_directory: Union[str, None] field to the Config class
  2. DumpDirectory wrapper: Created an abstraction layer that handles both temporary and custom directories consistently
  3. Enhanced FunctionContext: Modified directory creation logic to use custom directories when specified while maintaining existing behavior as fallback

Example Usage

# Before - files scattered in /tmp with unpredictable names
halmos --dump-smt-queries

# After - organized files in custom location
halmos --dump-smt-queries --dump-smt-directory ./smt-analysis
# Creates: ./smt-analysis/testFunction/123.smt2
#          ./smt-analysis/MyContract-constructor/456.refined.smt2

Benefits

  • No more hunting for SMT files in /tmp
  • Better organization for debugging and analysis workflows
  • Persistent storage for CI/CD integration
  • Easier collaboration and result sharing

Fixes #490.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • http://168.63.129.16:80/machine/
    • Triggering command: /usr/bin/python3 -u bin/WALinuxAgent-2.13.1.1-py3.9.egg -collect-logs (http block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Adding a flag to provide directory to dump smt files. Add --dump-smt-directory flag to specify custom SMT dump location Jun 4, 2025
Copilot AI requested a review from 0xkarmacoma June 4, 2025 18:46
group=debugging,
)

dump_smt_directory: Union[str, None] = arg(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use str | None and avoid importing Union

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use str | None and removed the Union import. Changes in bd91173.

Comment on lines 30 to 55
@dataclass
class DumpDirectory:
"""Wrapper for directory used for dumping SMT files.
Can wrap either a TemporaryDirectory or a regular directory path.
Provides a consistent .name property for both cases.
"""
_temp_dir: TemporaryDirectory | None = None
_path: str | None = None

@classmethod
def from_temp_dir(cls, temp_dir: TemporaryDirectory) -> "DumpDirectory":
return cls(_temp_dir=temp_dir)

@classmethod
def from_path(cls, path: str | Path) -> "DumpDirectory":
return cls(_path=str(path))

@property
def name(self) -> str:
if self._temp_dir is not None:
return self._temp_dir.name
elif self._path is not None:
return self._path
else:
raise ValueError("DumpDirectory not properly initialized")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to introduce a whole new dataclass for this, instead introduce a simple DumpDirectory type alias for TemporaryDirectory | Path

then we can just have a helper function dirname(dump_dir: DumpDirectory) that does a match on the actual type of dump_dir. Basically like a lightweight algebraic data type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified the implementation using a type alias DumpDirectory = TemporaryDirectory | Path and helper function dirname(dump_dir: DumpDirectory) with pattern matching as suggested. This is much cleaner than the dataclass approach. Changes in fa5ad32.

Comment on lines 10 to 70
def test_dump_directory_from_temp_dir():
"""Test DumpDirectory.from_temp_dir creates correct wrapper"""
with TemporaryDirectory() as temp_dir_path:
temp_dir = TemporaryDirectory()
temp_dir.name = temp_dir_path # set a known path for testing

dump_dir = DumpDirectory.from_temp_dir(temp_dir)

assert dump_dir.name == temp_dir_path
assert dump_dir._temp_dir == temp_dir
assert dump_dir._path is None


def test_dump_directory_from_path_string():
"""Test DumpDirectory.from_path with string path"""
with tempfile.TemporaryDirectory() as temp_dir:
dump_dir = DumpDirectory.from_path(temp_dir)

assert dump_dir.name == temp_dir
assert dump_dir._temp_dir is None
assert dump_dir._path == temp_dir


def test_dump_directory_from_path_pathlib():
"""Test DumpDirectory.from_path with Path object"""
with tempfile.TemporaryDirectory() as temp_dir:
path_obj = Path(temp_dir)
dump_dir = DumpDirectory.from_path(path_obj)

assert dump_dir.name == str(path_obj)
assert dump_dir._temp_dir is None
assert dump_dir._path == str(path_obj)


def test_dump_directory_uninitialized():
"""Test that uninitialized DumpDirectory raises error"""
dump_dir = DumpDirectory()

with pytest.raises(ValueError, match="DumpDirectory not properly initialized"):
_ = dump_dir.name


def test_config_has_dump_smt_directory_field():
"""Test that Config has the new dump_smt_directory field"""
config = Config(_parent=None, _source=ConfigSource.void)

# Check that the field exists and defaults to None
assert hasattr(config, 'dump_smt_directory')
assert config.dump_smt_directory is None


def test_config_dump_smt_directory_accepts_string():
"""Test that dump_smt_directory accepts string values"""
with tempfile.TemporaryDirectory() as temp_dir:
config = Config(
_parent=None,
_source=ConfigSource.void,
dump_smt_directory=temp_dir
)

assert config.dump_smt_directory == temp_dir No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are too complex, add at most a couple simple tests for dirname in the existing tests/test_utils.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified the tests by removing the complex test_dump_directory.py file and adding just 2 simple tests for the dirname function in test_utils.py. This reduces test complexity from 62 lines with 6 tests to 18 lines with 2 focused tests. Changes in 9ede713.

group=debugging,
)

dump_smt_directory: str = arg(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bring back the str | None annotation since the default is None. Or make the default "", your choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use str type annotation with global_default="" instead of None to maintain consistency and resolve argparse compatibility issues. Changes in 9e13542.



def test_dirname_with_temporary_directory():
"""Test dirname function with TemporaryDirectory"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove low-information comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the low-information docstring. Changes in a10b253.



def test_dirname_with_path():
"""Test dirname function with Path"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove low-information comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the low-information docstring. Changes in a10b253.

@0xkarmacoma 0xkarmacoma marked this pull request as ready for review June 9, 2025 16:23
@0xkarmacoma 0xkarmacoma merged commit 64a854f into main Jun 9, 2025
42 checks passed
@0xkarmacoma 0xkarmacoma deleted the copilot/fix-490 branch June 9, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adding a flag to provide directory to dump smt files.

2 participants