Skip to content

Commit

Permalink
Test error inputs handling, fix few bugs (#119)
Browse files Browse the repository at this point in the history
* Test error inputs handling

* Add mask tests

* Apply code review fix
  • Loading branch information
pavelkryukov authored May 17, 2022
1 parent 301686e commit f9272e8
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 15 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Unit tests

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install PyYAML
run: |
pip3 install -r requirements.txt
pip3 install coverage
- name: Test error outputs
run: coverage run -m unittest -b
- name: Generate coverage
run: coverage xml
- name: Upload coverage
uses: codecov/codecov-action@v2

33 changes: 18 additions & 15 deletions parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
pp = pprint.PrettyPrinter(indent=2)
logging.basicConfig(level=logging.INFO, format='%(levelname)s:: %(message)s')

def parse_constant(string):
return int(string, 0)

def process_enc_line(line, ext):
'''
This function processes each line of the encoding files (rv*). As part of
Expand Down Expand Up @@ -61,14 +64,23 @@ def process_enc_line(line, ext):
temp_instr = ['-'] * 32
entries = [
x[0] for x in re.findall(
r'((\d)+\.\.(\d)+\=((0b\d+)|(0x\d+)|(\d)+))*',
r'((\d)+\.\.(\d)+\=((0b\d+)|(0x[0-9a-fA-F]+)|(\d)+))*',
remaining) if x[0] != ''
]
for temp_entry in entries:
entry = temp_entry.split('=')[0]
f1, f2 = entry.split('..')
for ind in range(int(f1), int(f2)):
s2, s1 = entry.split('..')
msb = int(s2)
lsb = int(s1)

# check msb < lsb
if msb < lsb:
logging.error(
f'{line.split(" ")[0]:<10} has position {msb} less than position {lsb} in it\'s encoding'
)
raise SystemExit(1)

for ind in range(lsb, msb):
# overlapping bits
if temp_instr[ind] == 'X':
logging.error(
Expand All @@ -77,20 +89,11 @@ def process_enc_line(line, ext):
raise SystemExit(1)
temp_instr[ind] = 'X'

# check x < y
if int(f1) < int(f2):
logging.error(
f'{line.split(" ")[0]:<10} has position {f1} less than position {f2} in it\'s encoding'
)
raise SystemExit(1)

# illegal value assigned as per bit width
entry_value = temp_entry.split('=')[1]
temp_base = 16 if 'x' in entry_value else 2 if 'b' in entry_value else 10
if len(str(int(entry_value,
temp_base))[2:]) > (int(f1) - int(f2)):
entry_value = parse_constant(temp_entry.split('=')[1])
if entry_value >= (1 << (msb - lsb + 1)):
logging.error(
f'{line.split(" ")[0]:<10} has an illegal value {entry_value} assigned as per the bit width {f1 - f2}'
f'{line.split(" ")[0]:<10} has an illegal value {entry_value} assigned as per the bit width {msb - lsb}'
)
raise SystemExit(1)

Expand Down
44 changes: 44 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env python3

from parse import *
import logging
import unittest

class ConstantParseTest(unittest.TestCase):
def test_constant(self):
self.assertEqual(parse_constant('10'), 10)
self.assertEqual(parse_constant('0xa'), 10)
self.assertEqual(parse_constant('0xA'), 10)
self.assertEqual(parse_constant('0b1010'), 10)

class EncodingLineTest(unittest.TestCase):
def setUp(self):
logger = logging.getLogger()
logger.disabled = True

def assertError(self, string):
self.assertRaises(SystemExit, process_enc_line, string, 'rv_i')

def test_lui(self):
name, data = process_enc_line('lui rd imm20 6..2=0x0D 1..0=3', 'rv_i')
self.assertEqual(name, 'lui')
self.assertEqual(data['extension'], ['rv_i'])
self.assertEqual(data['match'], '0x37')
self.assertEqual(data['mask'], '0x7f')

def test_overlapping(self):
self.assertError('jol rd jimm20 6..2=0x00 3..0=7')

def test_invalid_order(self):
self.assertError('jol 2..6=0x1b')

def test_illegal_value(self):
self.assertError('jol rd jimm20 2..0=10')
self.assertError('jol rd jimm20 2..0=0xB')

@unittest.skip('not implemented')
def test_overlapping_field(self):
self.assertError('jol rd rs1 jimm20 6..2=0x1b 1..0=3')

def test_illegal_field(self):
self.assertError('jol rd jimm128 2..0=10')

0 comments on commit f9272e8

Please sign in to comment.