Skip to content

Commit 9872329

Browse files
committed
Debugging
Signed-off-by: Mike Stitt <mike@stitt.cc>
1 parent 5f63a20 commit 9872329

File tree

1 file changed

+162
-47
lines changed

1 file changed

+162
-47
lines changed

subprojects/robotpy-wpilib/tests/test_poc_timedrobot.py

Lines changed: 162 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ class TestController:
5151
Use this object to control the robot's state during tests
5252
"""
5353

54-
def __init__(self, reraise, robot: wpilib.RobotBase):
54+
def __init__(self, reraise, robot: wpilib.RobotBase, expectFinished: bool):
5555
self._reraise = reraise
5656

5757
self._thread: typing.Optional[threading.Thread] = None
5858
self._robot = robot
59+
self._expectFinished = expectFinished
5960

6061
self._cond = threading.Condition()
6162
self._robot_started = False
@@ -79,9 +80,10 @@ def _robot_thread(self, robot):
7980

8081
try:
8182
robot.startCompetition()
82-
assert self._robot_finished
83+
assert self._expectFinished == self._robot_finished
8384
finally:
8485
# always call endCompetition or python hangs
86+
print("_robot_thread is calling endCompetition()")
8587
robot.endCompetition()
8688
del robot
8789

@@ -118,6 +120,7 @@ def run_robot(self):
118120
yield
119121
finally:
120122
self._robot_finished = True
123+
print("run_robot is calling endCompetition()")
121124
robot.endCompetition()
122125

123126
if isinstance(self._reraise.exception, RuntimeError):
@@ -162,8 +165,9 @@ def step_timing(
162165
self,
163166
*,
164167
seconds: float,
165-
autonomous: bool,
166-
enabled: bool,
168+
autonomous: bool = False,
169+
test: bool = False,
170+
enabled: bool = False,
167171
assert_alive: bool = True,
168172
) -> float:
169173
"""
@@ -178,22 +182,24 @@ def step_timing(
178182
:returns: Number of seconds time was incremented
179183
"""
180184

181-
assert self.robot_is_alive, "did you call control.run_robot()?"
185+
if self._expectFinished:
186+
assert self.robot_is_alive, "did you call control.run_robot()?"
182187

183188
assert seconds > 0
184189

185190
DriverStationSim.setDsAttached(True)
186191
DriverStationSim.setAutonomous(autonomous)
192+
DriverStationSim.setTest(test)
187193
DriverStationSim.setEnabled(enabled)
188194

189195
tm = 0.0
190196

191-
while tm < seconds + 0.01:
197+
while tm < seconds:
192198
DriverStationSim.notifyNewData()
193-
stepTiming(0.2)
194-
if assert_alive:
199+
stepTiming(0.001)
200+
if assert_alive and self._expectFinished:
195201
assert self.robot_is_alive
196-
tm += 0.2
202+
tm += 0.001
197203

198204
return tm
199205

@@ -304,12 +310,12 @@ def robot_with_sim_setup_teardown(decorated_robot_class):
304310

305311
@pytest.fixture(scope="function")
306312
def getTestController(
307-
reraise, robot_with_sim_setup_teardown: wpilib.RobotBase
313+
reraise, robot_with_sim_setup_teardown: wpilib.RobotBase, expectFinished
308314
) -> TestController:
309315
"""
310316
A pytest fixture that provides control over your robot_with_sim_setup_teardown
311317
"""
312-
return TestController(reraise, robot_with_sim_setup_teardown)
318+
return TestController(reraise, robot_with_sim_setup_teardown, expectFinished)
313319

314320

315321
def run_practice(control: "TestController"):
@@ -381,10 +387,15 @@ def testPeriodic(self):
381387
pass
382388

383389
@classmethod
384-
@pytest.fixture(scope="function", autouse=True)
390+
@pytest.fixture(scope="function", autouse=False)
385391
def myrobot_class(cls) -> type[MyRobot]:
386392
return cls.MyRobot
387393

394+
@classmethod
395+
@pytest.fixture(scope="function", autouse=False)
396+
def expectFinished(cls) -> bool:
397+
return True
398+
388399
def test_iterative(self, getTestController, robot_with_sim_setup_teardown):
389400
"""Ensure that all states of the iterative robot run"""
390401
assert robot_with_sim_setup_teardown.robotInitialized == False
@@ -403,76 +414,180 @@ def test_iterative_again(self, getTestController, robot_with_sim_setup_teardown)
403414
assert robot_with_sim_setup_teardown.robotInitialized == True
404415
assert robot_with_sim_setup_teardown.robotPeriodicCount > 0
405416

406-
class MyRobotRobotInitFails(TimedRobotPy):
417+
class TimedRobotPyExpectsException(TimedRobotPy):
418+
def startCompetition(self) -> None:
419+
hasAssertionError = False
420+
try:
421+
super().startCompetition()
422+
except AssertionError:
423+
hasAssertionError = True
424+
print(f"TimedRobotPyExpectsException hasAssertionError={hasAssertionError}")
425+
assert hasAssertionError
426+
427+
class TimedRobotPyDoNotExpectException(TimedRobotPy):
428+
def startCompetition(self) -> None:
429+
hasAssertionError = False
430+
try:
431+
super().startCompetition()
432+
except AssertionError:
433+
hasAssertionError = True
434+
print(f"TimedRobotPyExpectsException hasAssertionError={hasAssertionError}")
435+
assert not hasAssertionError
436+
437+
438+
from wpilib import RobotController
439+
440+
def printEntryAndExit(func):
441+
def wrapper(*args, **kwargs):
442+
#name = inspect.currentframe().f_code.co_name
443+
name = func.__name__
444+
print(f"Enter:{name} at {RobotController.getFPGATime()/1000_000.0:.3f}")
445+
result = func(*args, **kwargs)
446+
print(f"Exit_:{name} at {RobotController.getFPGATime()/1000_000.0:.3f}")
447+
return result
448+
return wrapper
449+
450+
class MyRobotRobotDefaultPass():
451+
452+
@printEntryAndExit
453+
def robotInit(self):
454+
pass
455+
456+
@printEntryAndExit
457+
def robotPeriodic(self):
458+
pass
459+
460+
@printEntryAndExit
461+
def autonomousInit(self):
462+
pass
463+
464+
@printEntryAndExit
465+
def autonomousPeriodic(self):
466+
pass
467+
468+
@printEntryAndExit
469+
def autonomousExit(self):
470+
pass
471+
472+
@printEntryAndExit
473+
def disabledInit(self):
474+
pass
475+
476+
@printEntryAndExit
477+
def disabledPeriodic(self):
478+
pass
479+
480+
@printEntryAndExit
481+
def disabledExit(self):
482+
pass
483+
484+
@printEntryAndExit
485+
def _simulationInit(self):
486+
pass
487+
488+
@printEntryAndExit
489+
def _simulationPeriodic(self):
490+
pass
491+
492+
493+
494+
class MyRobotRobotInitFails():
407495
def robotInit(self):
408496
assert False
409497

410-
class MyRobotRobotPeriodicFails(TimedRobotPy):
498+
class MyRobotRobotPeriodicFails():
411499
def robotPeriodic(self):
412500
assert False
413501

414-
class MyRobotAutonomousInitFails(TimedRobotPy):
502+
class MyRobotAutonomousInitFails():
415503
def autonomousInit(self):
416504
assert False
417505

418-
class MyRobotAutonomousPeriodicFails(TimedRobotPy):
506+
class MyRobotAutonomousPeriodicFails():
419507
def autonomousPeriodic(self):
420508
assert False
421509

422-
class MyRobotAutonomousExitFails(TimedRobotPy):
510+
class MyRobotAutonomousExitFails():
423511
def autonomousExit(self):
424512
assert False
425513

426-
class MyRobotTeleopInitFails(TimedRobotPy):
514+
class MyRobotTeleopInitFails():
427515
def teleopInit(self):
428516
assert False
429517

430-
class MyRobotTeleopPeriodicFails(TimedRobotPy):
518+
class MyRobotTeleopPeriodicFails():
431519
def teleopPeriodic(self):
432520
assert False
433521

434-
class MyRobotDisabledPeriodicFails(TimedRobotPy):
522+
class MyRobotDisabledPeriodicFails():
435523
def disabledPeriodic(self):
436524
assert False
437525

438-
class MyRobotDisabledInitFails(TimedRobotPy):
526+
class MyRobotDisabledInitFails():
439527
def disabledInit(self):
440528
assert False
441529

442-
class MyRobotTestInitFails(TimedRobotPy):
530+
class MyRobotTestInitFails():
443531
def testInit(self):
444532
assert False
445533

446-
class MyRobotTestPeriodicFails(TimedRobotPy):
534+
class MyRobotTestPeriodicFails():
447535
def testPeriodic(self):
448536
assert False
449537

450-
"""
451-
@pytest.mark.parametrize("myrobot_class", [
452-
MyRobotRobotInitFails,
453-
MyRobotAutonomousInitFails,
454-
MyRobotAutonomousPeriodicFails,
455-
MyRobotAutonomousExitFails,
456-
])
457-
class TestCanThrowFailures:
458538

459539

460-
def test_autonomous_fails(self, getTestController, robot_with_sim_setup_teardown):
540+
@pytest.mark.parametrize("myRobotAddMethods, timedRobotExpectation, _expectFinished, _autonomous, _test", [
541+
(MyRobotRobotDefaultPass, TimedRobotPyDoNotExpectException, True, True, False),
542+
(MyRobotRobotInitFails, TimedRobotPyExpectsException, False, True, False),
543+
(MyRobotAutonomousInitFails, TimedRobotPyExpectsException, False, True, False),
544+
(MyRobotAutonomousPeriodicFails, TimedRobotPyExpectsException, False, True, False),
545+
(MyRobotAutonomousExitFails, TimedRobotPyExpectsException, False, True, False)
546+
]
547+
)
548+
class TestCanThrowExceptions:
549+
@classmethod
550+
@pytest.fixture(scope="function", autouse=False)
551+
def myrobot_class(cls, myRobotAddMethods, timedRobotExpectation, _expectFinished, _autonomous, _test) -> type[TimedRobotPy]:
552+
class MyRobot(myRobotAddMethods, timedRobotExpectation):
553+
554+
@printEntryAndExit
555+
def startCompetition(self):
556+
super().startCompetition()
557+
558+
@printEntryAndExit
559+
def endCompetition(self):
560+
super().endCompetition()
561+
562+
return MyRobot
563+
564+
@classmethod
565+
@pytest.fixture(scope="function", autouse=False)
566+
def expectFinished(cls, myRobotAddMethods, timedRobotExpectation, _expectFinished, _autonomous, _test) -> bool:
567+
return _expectFinished
568+
569+
@classmethod
570+
@pytest.fixture(scope="function", autouse=False)
571+
def autonomous(cls, myRobotAddMethods, timedRobotExpectation, _expectFinished, _autonomous, _test) -> bool:
572+
return _autonomous
573+
574+
@classmethod
575+
@pytest.fixture(scope="function", autouse=False)
576+
def test(cls, myRobotAddMethods, timedRobotExpectation, _expectFinished, _autonomous, _test) -> bool:
577+
return _test
578+
579+
580+
def test_robot_mode_with_exceptions(self, getTestController, robot_with_sim_setup_teardown, autonomous, test):
461581
with getTestController.run_robot():
462-
hasAssertionError = False
463-
try:
464-
# Run disabled for a short period
465-
getTestController.step_timing(seconds=0.5, autonomous=True, enabled=False)
466-
467-
# Run autonomous + enabled for 15 seconds
468-
getTestController.step_timing(seconds=15, autonomous=True, enabled=True)
469-
470-
# Disabled for another short period
471-
getTestController.step_timing(seconds=0.5, autonomous=False, enabled=False)
472-
except AssertionError:
473-
hasAssertionError = True
474-
print("We had an assertion error")
475-
assert hasAssertionError
476-
"""
582+
periodS = robot_with_sim_setup_teardown.getPeriod()
583+
# Run disabled for a short period
584+
print(f"periodS={periodS} or {periodS*1.5}")
585+
getTestController.step_timing(seconds=periodS*1.5, autonomous=autonomous, test=test, enabled=False)
586+
587+
# Run in desired mode for 1 period
588+
getTestController.step_timing(seconds=periodS, autonomous=autonomous, test=test, enabled=True)
589+
590+
# Disabled for 1 period
591+
getTestController.step_timing(seconds=periodS, autonomous=autonomous, test=test, enabled=False)
477592

478593

0 commit comments

Comments
 (0)