Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

applet: extract test code to a separate file. #448

Merged
merged 4 commits into from
Oct 21, 2023
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
5 changes: 4 additions & 1 deletion software/glasgow/applet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ async def repl(self, device, args, iface):
await AsyncInteractiveConsole(locals={"device":device, "iface":iface, "args":args},
run_callback=device.demultiplexer.flush).interact()

@classmethod
def tests(cls):
return None


class GlasgowAppletTool:
def __init_subclass__(cls, applet, **kwargs):
Expand Down Expand Up @@ -205,7 +209,6 @@ class GlasgowAppletTestCase(unittest.TestCase):
def __init_subclass__(cls, applet, **kwargs):
super().__init_subclass__(**kwargs)

applet.test_cls = cls
cls.applet_cls = applet

def setUp(self):
Expand Down
10 changes: 4 additions & 6 deletions software/glasgow/applet/audio/dac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,7 @@ async def interact(self, device, args, pcm_iface):
await pcm_iface.write(data)
await pcm_iface.flush(wait=False)

# -------------------------------------------------------------------------------------------------

class AudioDACAppletTestCase(GlasgowAppletTestCase, applet=AudioDACApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["--unsigned"])
@classmethod
def tests(cls):
from . import test
return test.AudioDACAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/audio/dac/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import AudioDACApplet


class AudioDACAppletTestCase(GlasgowAppletTestCase, applet=AudioDACApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["--unsigned"])
18 changes: 4 additions & 14 deletions software/glasgow/applet/audio/yamaha_opx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1249,17 +1249,7 @@ async def set_voltage(voltage):
await fut
args.pcm_file.write(record_fut.result())

# -------------------------------------------------------------------------------------------------

class AudioYamahaOPxAppletTestCase(GlasgowAppletTestCase, applet=AudioYamahaOPxApplet):
@synthesis_test
def test_build_opl2(self):
self.assertBuilds(args=["--device", "OPL2"])

@synthesis_test
def test_build_opl3(self):
self.assertBuilds(args=["--device", "OPL3"])

@synthesis_test
def test_build_opm(self):
self.assertBuilds(args=["--device", "OPM"])
@classmethod
def tests(cls):
from . import test
return test.AudioYamahaOPxAppletTestCase
16 changes: 16 additions & 0 deletions software/glasgow/applet/audio/yamaha_opx/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from ... import *
from . import AudioYamahaOPxApplet


class AudioYamahaOPxAppletTestCase(GlasgowAppletTestCase, applet=AudioYamahaOPxApplet):
@synthesis_test
def test_build_opl2(self):
self.assertBuilds(args=["--device", "OPL2"])

@synthesis_test
def test_build_opl3(self):
self.assertBuilds(args=["--device", "OPL3"])

@synthesis_test
def test_build_opm(self):
self.assertBuilds(args=["--device", "OPM"])
10 changes: 4 additions & 6 deletions software/glasgow/applet/display/hd44780/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,7 @@ async def data(bytes):
await data(datetime.now().strftime("%y-%m-%d").encode("ascii"))
await iface.flush()

# -------------------------------------------------------------------------------------------------

class DisplayHD44780AppletTestCase(GlasgowAppletTestCase, applet=DisplayHD44780Applet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.DisplayHD44780AppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/display/hd44780/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import DisplayHD44780Applet


class DisplayHD44780AppletTestCase(GlasgowAppletTestCase, applet=DisplayHD44780Applet):
@synthesis_test
def test_build(self):
self.assertBuilds()
10 changes: 4 additions & 6 deletions software/glasgow/applet/display/pdi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,7 @@ async def interact(self, device, args, pdi_iface):
await pdi_iface.display_frame(mode="white", time_ms=stage_ms, image=image)
await pdi_iface.power_off()

# -------------------------------------------------------------------------------------------------

class DisplayPDIAppletTestCase(GlasgowAppletTestCase, applet=DisplayPDIApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.DisplayPDIAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/display/pdi/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import DisplayPDIApplet


class DisplayPDIAppletTestCase(GlasgowAppletTestCase, applet=DisplayPDIApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
10 changes: 4 additions & 6 deletions software/glasgow/applet/interface/analyzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ async def interact(self, device, args, iface):
finally:
vcd_writer.close(timestamp)

# -------------------------------------------------------------------------------------------------

class AnalyzerAppletTestCase(GlasgowAppletTestCase, applet=AnalyzerApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.AnalyzerAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/interface/analyzer/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import AnalyzerApplet


class AnalyzerAppletTestCase(GlasgowAppletTestCase, applet=AnalyzerApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
10 changes: 4 additions & 6 deletions software/glasgow/applet/interface/i2c_initiator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,7 @@ async def interact(self, device, args, i2c_iface):
self.logger.info("device %s ID: manufacturer %s, part %s, revision %s",
bin(addr), bin(manufacturer), bin(part_ident), bin(revision))

# -------------------------------------------------------------------------------------------------

class I2CInitiatorAppletTestCase(GlasgowAppletTestCase, applet=I2CInitiatorApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.I2CInitiatorAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/interface/i2c_initiator/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import I2CInitiatorApplet


class I2CInitiatorAppletTestCase(GlasgowAppletTestCase, applet=I2CInitiatorApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
10 changes: 4 additions & 6 deletions software/glasgow/applet/interface/i2c_target/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,7 @@ async def interact(self, device, args, iface):
while True:
await iface.read_event()

# -------------------------------------------------------------------------------------------------

class I2CTargetAppletTestCase(GlasgowAppletTestCase, applet=I2CTargetApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["-A", "0b1010000"])
@classmethod
def tests(cls):
from . import test
return test.I2CTargetAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/interface/i2c_target/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import I2CTargetApplet


class I2CTargetAppletTestCase(GlasgowAppletTestCase, applet=I2CTargetApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["-A", "0b1010000"])
10 changes: 4 additions & 6 deletions software/glasgow/applet/interface/jtag_openocd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ async def forward_in():
await asyncio.wait([forward_out_fut, forward_in_fut],
return_when=asyncio.FIRST_EXCEPTION)

# -------------------------------------------------------------------------------------------------

class JTAGOpenOCDAppletTestCase(GlasgowAppletTestCase, applet=JTAGOpenOCDApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.JTAGOpenOCDAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/interface/jtag_openocd/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import JTAGOpenOCDApplet


class JTAGOpenOCDAppletTestCase(GlasgowAppletTestCase, applet=JTAGOpenOCDApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
10 changes: 4 additions & 6 deletions software/glasgow/applet/interface/jtag_pinout/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,7 @@ def bits_to_str(pins):
self.logger.warning("more than one JTAG interface detected; this is likely a false "
"positive")

# -------------------------------------------------------------------------------------------------

class JTAGPinoutAppletTestCase(GlasgowAppletTestCase, applet=JTAGPinoutApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["--pins-jtag", "0:3"])
@classmethod
def tests(cls):
from . import test
return test.JTAGPinoutAppletTestCase
8 changes: 8 additions & 0 deletions software/glasgow/applet/interface/jtag_pinout/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ... import *
from . import JTAGPinoutApplet


class JTAGPinoutAppletTestCase(GlasgowAppletTestCase, applet=JTAGPinoutApplet):
@synthesis_test
def test_build(self):
self.assertBuilds(args=["--pins-jtag", "0:3"])
133 changes: 4 additions & 129 deletions software/glasgow/applet/interface/jtag_probe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,132 +1100,7 @@ async def repl(self, device, args, jtag_iface):
run_callback=jtag_iface.flush
).interact()

# -------------------------------------------------------------------------------------------------

import unittest


class JTAGInterrogationTestCase(unittest.TestCase):
def setUp(self):
self.iface = JTAGProbeInterface(interface=None, logger=JTAGProbeApplet.logger)

def test_dr_empty(self):
self.assertEqual(self.iface.interrogate_dr(bits("")), [])

def test_dr_bypass(self):
self.assertEqual(self.iface.interrogate_dr(bits("0")), [None])

def test_dr_idcode(self):
dr = bits("00111011101000000000010001110111")
self.assertEqual(self.iface.interrogate_dr(dr), [0x3ba00477])

def test_dr_truncated(self):
dr = bits("0011101110100000000001000111011")
with self.assertRaisesRegex(JTAGProbeError,
r"^TAP #0 has truncated DR IDCODE=<1101110001000000000010111011100>$"):
self.iface.interrogate_dr(dr)
self.assertEqual(self.iface.interrogate_dr(dr, check=False), None)

def test_dr_bypass_idcode(self):
dr = bits("001110111010000000000100011101110")
self.assertEqual(self.iface.interrogate_dr(dr), [None, 0x3ba00477])

def test_dr_idcode_bypass(self):
dr = bits("000111011101000000000010001110111")
self.assertEqual(self.iface.interrogate_dr(dr), [0x3ba00477, None])

def test_dr_invalid(self):
dr = bits("00000000000000000000000011111111")
with self.assertRaisesRegex(JTAGProbeError,
r"^TAP #0 has invalid DR IDCODE=000000ff$"):
self.iface.interrogate_dr(dr)
self.assertEqual(self.iface.interrogate_dr(dr, check=False), None)

def test_ir_1tap_0start(self):
ir = bits("0100")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture does not start with <10> transition$"):
self.iface.interrogate_ir(ir, 1)
self.assertEqual(self.iface.interrogate_ir(ir, 1, check=False),
None)

def test_ir_1tap_0start_1length(self):
ir = bits("0100")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture does not start with <10> transition$"):
self.iface.interrogate_ir(ir, 1, ir_lengths=[4])
self.assertEqual(self.iface.interrogate_ir(ir, 1, ir_lengths=[4], check=False),
None)

def test_ir_1tap_1start(self):
ir = bits("0001")
self.assertEqual(self.iface.interrogate_ir(ir, 1),
[4])

def test_ir_1tap_2start(self):
ir = bits("0101")
self.assertEqual(self.iface.interrogate_ir(ir, 1),
[4])

def test_ir_1tap_2start_1length(self):
ir = bits("0101")
self.assertEqual(self.iface.interrogate_ir(ir, 1, ir_lengths=[4]),
[4])

def test_ir_1tap_2start_1length_over(self):
ir = bits("0101")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture length differs from sum of IR lengths$"):
self.iface.interrogate_ir(ir, 1, ir_lengths=[5])
self.assertEqual(self.iface.interrogate_ir(ir, 1, ir_lengths=[5], check=False),
None)

def test_ir_2tap_1start(self):
ir = bits("0001")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture has fewer <10> transitions than TAPs$"):
self.iface.interrogate_ir(ir, 2)
self.assertEqual(self.iface.interrogate_ir(ir, 2, check=False),
None)

def test_ir_2tap_1start_2length(self):
ir = bits("0001")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture has fewer <10> transitions than TAPs$"):
self.iface.interrogate_ir(ir, 2, ir_lengths=[2, 2])
self.assertEqual(self.iface.interrogate_ir(ir, 2, ir_lengths=[2, 2], check=False),
None)

def test_ir_2tap_2start(self):
ir = bits("01001")
self.assertEqual(self.iface.interrogate_ir(ir, 2),
[3, 2])

def test_ir_2tap_3start(self):
ir = bits("01001001")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR capture insufficiently constrains IR lengths$"):
self.iface.interrogate_ir(ir, 2)
self.assertEqual(self.iface.interrogate_ir(ir, 2, check=False),
None)

def test_ir_2tap_3start_1length(self):
ir = bits("01001001")
with self.assertRaisesRegex(JTAGProbeError,
r"^IR length count differs from TAP count$"):
self.iface.interrogate_ir(ir, 3, ir_lengths=[1])
self.assertEqual(self.iface.interrogate_ir(ir, 3, ir_lengths=[1], check=False),
None)

def test_ir_2tap_3start_2length(self):
ir = bits("01001001")
self.assertEqual(self.iface.interrogate_ir(ir, 2, ir_lengths=[6, 2]),
[6, 2])
self.assertEqual(self.iface.interrogate_ir(ir, 2, ir_lengths=[3, 5]),
[3, 5])


class JTAGProbeAppletTestCase(GlasgowAppletTestCase, applet=JTAGProbeApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
@classmethod
def tests(cls):
from . import test
return test.JTAGProbeAppletTestCase
Loading
Loading