Skip to content

Commit 5f63a20

Browse files
committed
WIP - tests should pass.
Signed-off-by: Mike Stitt <mike@stitt.cc>
1 parent 4cce809 commit 5f63a20

File tree

2 files changed

+372
-151
lines changed

2 files changed

+372
-151
lines changed

subprojects/robotpy-wpilib/tests/conftest.py

Lines changed: 0 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,8 @@
22

33
import pytest
44
import ntcore
5-
import wpilib
65
from wpilib.simulation._simulation import _resetWpilibSimulationData
76

8-
from pathlib import Path
9-
10-
import gc
11-
12-
import weakref
13-
14-
import hal
15-
import hal.simulation
16-
import wpilib.shuffleboard
17-
from wpilib.simulation import DriverStationSim, pauseTiming, restartTiming
18-
import wpilib.simulation
19-
from pyfrc.test_support.controller import TestController
20-
from pyfrc.physics.core import PhysicsInterface
21-
227
try:
238
import commands2
249
except ImportError:
@@ -48,133 +33,3 @@ def nt(cfg_logging, wpilib_state):
4833
finally:
4934
instance.stopLocal()
5035
instance._reset()
51-
52-
53-
@pytest.fixture(scope="class", autouse=False)
54-
def physics_and_decorated_robot_class(
55-
myrobot_class, robots_sim_enable_physics
56-
) -> tuple:
57-
# attach physics
58-
59-
robotClass = myrobot_class
60-
physicsInterface = None
61-
if robots_sim_enable_physics:
62-
physicsInterface, robotClass = PhysicsInterface._create_and_attach(
63-
myrobot_class,
64-
Path(__file__).parent,
65-
)
66-
67-
if physicsInterface:
68-
physicsInterface.log_init_errors = False
69-
70-
# Tests need to know when robotInit is called, so override the robot
71-
# to do that
72-
class TestRobot(robotClass):
73-
def robotInit(self):
74-
try:
75-
super().robotInit()
76-
finally:
77-
self.__robotInitialized()
78-
79-
TestRobot.__name__ = robotClass.__name__
80-
TestRobot.__module__ = robotClass.__module__
81-
TestRobot.__qualname__ = robotClass.__qualname__
82-
83-
return (physicsInterface, TestRobot)
84-
85-
86-
@pytest.fixture(scope="function", autouse=False)
87-
def robot_with_sim_setup_teardown(physics_and_decorated_robot_class):
88-
"""
89-
Your robot instance
90-
91-
.. note:: RobotPy/WPILib testing infrastructure is really sensitive
92-
to ensuring that things get cleaned up properly. Make sure
93-
that you don't store references to your robot or other
94-
WPILib objects in a global or static context.
95-
"""
96-
97-
#
98-
# This function needs to do the same things that RobotBase.main does
99-
# plus some extra things needed for testing
100-
#
101-
# Previously this was separate from robot fixture, but we need to
102-
# ensure that the robot cleanup happens deterministically relative to
103-
# when handle cleanup/etc happens, otherwise unnecessary HAL errors will
104-
# bubble up to the user
105-
#
106-
107-
nt_inst = ntcore.NetworkTableInstance.getDefault()
108-
nt_inst.startLocal()
109-
110-
pauseTiming()
111-
restartTiming()
112-
113-
wpilib.DriverStation.silenceJoystickConnectionWarning(True)
114-
DriverStationSim.setAutonomous(False)
115-
DriverStationSim.setEnabled(False)
116-
DriverStationSim.notifyNewData()
117-
118-
robot = physics_and_decorated_robot_class[1]()
119-
120-
# Tests only get a proxy to ensure cleanup is more reliable
121-
yield weakref.proxy(robot)
122-
123-
# If running in separate processes, no need to do cleanup
124-
# if ISOLATED:
125-
# # .. and funny enough, in isolated mode we *don't* want the
126-
# # robot to be cleaned up, as that can deadlock
127-
# self._saved_robot = robot
128-
# return
129-
130-
# reset engine to ensure it gets cleaned up too
131-
# -> might be holding wpilib objects, or the robot
132-
if physics_and_decorated_robot_class[0]:
133-
physics_and_decorated_robot_class[0].engine = None
134-
135-
# HACK: avoid motor safety deadlock
136-
wpilib.simulation._simulation._resetMotorSafety()
137-
138-
del robot
139-
140-
if commands2 is not None:
141-
commands2.CommandScheduler.resetInstance()
142-
143-
# Double-check all objects are destroyed so that HAL handles are released
144-
gc.collect()
145-
146-
# shutdown networktables before other kinds of global cleanup
147-
# -> some reset functions will re-register listeners, so it's important
148-
# to do this before so that the listeners are active on the current
149-
# NetworkTables instance
150-
nt_inst.stopLocal()
151-
nt_inst._reset()
152-
153-
# Cleanup WPILib globals
154-
# -> preferences, SmartDashboard, Shuffleboard, LiveWindow, MotorSafety
155-
wpilib.simulation._simulation._resetWpilibSimulationData()
156-
wpilib._wpilib._clearSmartDashboardData()
157-
wpilib.shuffleboard._shuffleboard._clearShuffleboardData()
158-
159-
# Cancel all periodic callbacks
160-
hal.simulation.cancelAllSimPeriodicCallbacks()
161-
162-
# Reset the HAL handles
163-
hal.simulation.resetGlobalHandles()
164-
165-
# Reset the HAL data
166-
hal.simulation.resetAllSimData()
167-
168-
# Don't call HAL shutdown! This is only used to cleanup HAL extensions,
169-
# and functions will only be called the first time (unless re-registered)
170-
# hal.shutdown()
171-
172-
173-
@pytest.fixture(scope="function")
174-
def getTestController(
175-
reraise, robot_with_sim_setup_teardown: wpilib.RobotBase
176-
) -> TestController:
177-
"""
178-
A pytest fixture that provides control over your robot_with_sim_setup_teardown
179-
"""
180-
return TestController(reraise, robot_with_sim_setup_teardown)

0 commit comments

Comments
 (0)