Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ jobs:
with:
python-version: '3.10'

- name: Install dependencies
run: pip install -r assembler_tools/hec-assembler-tools/requirements.txt

- name: Install pre-commit
run: pip install pre-commit

- name: Install pylint
run: pip install pylint

- name: Fetch main branch for diff
run: git fetch origin main

Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/hec-asm-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: HEC Assembler Tools Tests
on:
push:
branches: [main]
paths:
- 'assembler_tools/hec-assembler-tools/**'
pull_request:
branches: [main]
paths:
- 'assembler_tools/hec-assembler-tools/**'

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: assembler_tools/hec-assembler-tools
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest

- name: Check for changes in hec-assembler-tools
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
module:
- '**'

- name: Run unit tests
if: steps.changes.outputs.module == 'true'
run: pytest tests
2 changes: 1 addition & 1 deletion HEADER
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Copyright (C) 2024 Intel Corporation
Copyright (C) 2025 Intel Corporation
SPDX-License-Identifier: Apache-2.0
9 changes: 9 additions & 0 deletions assembler_tools/hec-assembler-tools/.coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[run]
branch = True
source = .
omit =
tests/*

[report]
show_missing = True
skip_covered = True
4 changes: 4 additions & 0 deletions assembler_tools/hec-assembler-tools/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
pythonpath = .
testpaths = tests
#addopts = --cov=.
1 change: 1 addition & 0 deletions assembler_tools/hec-assembler-tools/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ networkx==3.0
numpy==1.24.2
packaging==23.0
Pillow==10.3.0
pytest==8.4.0
python-dateutil==2.8.2
PyYAML==6.0
six==1.16.0
Expand Down
36 changes: 36 additions & 0 deletions assembler_tools/hec-assembler-tools/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

"""
Pytest configuration and fixtures for assembler_tools tests.
"""

import os
import pytest
from assembler.spec_config.isa_spec import ISASpecConfig
from assembler.spec_config.mem_spec import MemSpecConfig


@pytest.fixture(scope="session", autouse=True)
def initialize_specs():
"""
Fixture to initialize ISA and memory specifications for test session.

This fixture is automatically used for the entire test session and ensures that
the ISA and memory specifications are initialized before any tests are run.
It determines the module directory relative to the current file and calls the
initialization methods for both ISASpecConfig and MemSpecConfig.

Note:
This fixture is intended to be run from the assembler root directory.

Yields:
None

Raises:
Any exceptions raised by ISASpecConfig.initialize_isa_spec or
MemSpecConfig.initialize_mem_spec will propagate.
"""
module_dir = os.path.dirname(os.path.dirname(__file__))
ISASpecConfig.initialize_isa_spec(module_dir, "")
MemSpecConfig.initialize_mem_spec(module_dir, "")
146 changes: 146 additions & 0 deletions assembler_tools/hec-assembler-tools/tests/unit_tests/test_he_prep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

"""
Unit tests for he_prep module.
"""

from unittest import mock
import os
import sys
import pathlib
import pytest
import he_prep


def test_main_assigns_and_saves(monkeypatch, tmp_path):
"""
Test that the main function assigns register banks, processes instructions, and saves the output.

This test uses monkeypatching to mock dependencies and verifies that the output file
contains the expected instruction after processing a dummy input file.
"""
# Prepare dummy input file
input_file = tmp_path / "input.csv"
input_file.write_text("dummy")
output_file = tmp_path / "output.csv"

dummy_model = object()
dummy_insts = [mock.Mock(toPISAFormat=mock.Mock(return_value="inst1"))]

monkeypatch.setattr(he_prep, "MemoryModel", mock.Mock(return_value=dummy_model))
monkeypatch.setattr(
he_prep.preprocessor,
"preprocessPISAKernelListing",
mock.Mock(return_value=dummy_insts),
)
monkeypatch.setattr(he_prep.preprocessor, "assignRegisterBanksToVars", mock.Mock())

he_prep.main(str(output_file), str(input_file), b_verbose=False)
# Output file should contain the instruction
assert output_file.read_text().strip() == "inst1"


def test_main_no_input_file():
"""
Test that main raises an error when no input file is provided.
"""
with pytest.raises(FileNotFoundError):
he_prep.main(
"", "", b_verbose=False
) # Should raise an error due to missing input file


def test_main_no_output_file():
"""
Test that main raises an error when no output file is provided.
"""
with pytest.raises(FileNotFoundError):
he_prep.main(
"", "input.csv", b_verbose=False
) # Should raise an error due to missing output file


def test_main_no_instructions(monkeypatch):
"""
Test that main handles the case where no instructions are processed.

This test checks that the function can handle an empty instruction list without errors.
"""
input_file = "empty_input.csv"
output_file = "empty_output.csv"

with open(input_file, "w", encoding="utf-8") as f:
f.write("") # Create an empty input file

dummy_model = object()
monkeypatch.setattr(he_prep, "MemoryModel", mock.Mock(return_value=dummy_model))
monkeypatch.setattr(
he_prep.preprocessor, "preprocessPISAKernelListing", mock.Mock(return_value=[])
)
monkeypatch.setattr(he_prep.preprocessor, "assignRegisterBanksToVars", mock.Mock())

he_prep.main(output_file, input_file, b_verbose=False)

# Output file should be empty
output_file_path = pathlib.Path(output_file)
assert (
not output_file_path.exists()
or output_file_path.read_text(encoding="utf-8").strip() == ""
)


def test_main_invalid_input_file(tmp_path):
"""
Test that main raises an error when the input file does not exist.
"""
input_file = tmp_path / "non_existent.csv"
output_file = tmp_path / "output.csv"

with pytest.raises(FileNotFoundError):
he_prep.main(
str(output_file), str(input_file), b_verbose=False
) # Should raise an error due to missing input file


def test_main_invalid_output_file(tmp_path):
"""
Test that main raises an error when the output file cannot be created.
This test checks that the function handles file permission errors gracefully.
"""
input_file = tmp_path / "input.csv"
input_file.write_text("") # Write empty string to avoid SyntaxError
output_file = tmp_path / "output.csv"

# Make the output file read-only
output_file.touch()
os.chmod(output_file, 0o444) # Read-only permissions

with pytest.raises(PermissionError):
he_prep.main(
str(output_file), str(input_file), b_verbose=False
) # Should raise an error due to permission issues


def test_parse_args():
"""
Test that parse_args returns the expected arguments.
"""
test_args = [
"prog",
"input.csv",
"output.csv",
"--isa_spec",
"isa.json",
"--mem_spec",
"mem.json",
"--verbose",
]
with mock.patch.object(sys, "argv", test_args):
args = he_prep.parse_args()

assert args.output_file_name == "output.csv"
assert args.input_file_name == "input.csv"
assert args.isa_spec_file == "isa.json"
assert args.mem_spec_file == "mem.json"
assert args.verbose == 1
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[pytest]
pythonpath = p-isa_tools/kerngen
pythonpath = p-isa_tools/kerngen assembler_tools/hec-assembler-tools