async def test_armmodestatus(self): """Test getting of the arming status and mode from heartbeat""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh.isArmed is None assert self.veh.flightMode is None pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_AUTO_DISARMED, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is False assert self.veh.flightMode == "0" pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_MANUAL_ARMED, 1, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is True assert self.veh.flightMode == "1" pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_MANUAL_DISARMED, 15, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is False assert self.veh.flightMode == '15'
async def test_params_before(self): """Test getting of the parameters before downloaded""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh.getParams('RC8_MAX') is None assert self.veh.getParams() is None
async def test_set_param_no_params(self): """Test setting of params if params not downloaded yet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback assert await self.veh.setParam('RC8_MAX', 1800) is False
def setUp(self): """Set up some data that is reused in many tests""" self.manager = None # The PaGS settings dir (just in source dir) self.settingsdir = os.path.join(os.getcwd(), ".PaGS") if not os.path.exists(self.settingsdir): os.makedirs(self.settingsdir) self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink( self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.hasInitial = True self.VehB = Vehicle(self.loop, "VehB", 255, 0, 5, 0, self.dialect, self.version) self.VehB.hasInitial = True self.VehC = Vehicle(self.loop, "VehC", 255, 0, 10, 0, self.dialect, self.version) self.VehC.hasInitial = False self.txPackets = {}
def setUp(self): """Set up some data that is reused in many tests""" self.manager = None self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.VehA.hasInitial = True # The PaGS settings dir (just in source dir) self.settingsdir = os.path.join(os.getcwd(), ".PaGS") if not os.path.exists(self.settingsdir): os.makedirs(self.settingsdir) self.manager = moduleManager.moduleManager(self.loop, self.settingsdir, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("internalPrinterModule")
def setUp(self): """Set up some data that is reused in many tests""" self.manager = None self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.txPackets = {} self.txVehPackets = {} self.manager = moduleManager.moduleManager(self.loop, self.dialect, self.version, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("PaGS.modules.internalPrinterModule")
async def test_params_noresponse(self): """Test getting of the parameters, no response from vehicle""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) await self.veh.downloadParams(timeout=0.1) assert self.veh.getParams('RC8_MAX') is None assert self.veh.getParams() is None
async def test_get_params(self): """Test getting of the parameters, got all. Plus typo""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback await self.veh.downloadParams(timeout=0.25) assert self.veh.getParams('RC8_MAX') == 1900 assert self.veh.getParams('RC8_MAXXX') is None
async def test_get_params_retry(self): """Test getting of the parameters, need to retry some""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallbackpartial await self.veh.downloadParams(timeout=0.25) assert self.veh.getParams('RC8_MAX') == 1900 assert self.veh.getParams('RC8_TRIM') == 1500
async def test_set_param(self): """Test setting of param""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback await self.veh.downloadParams(timeout=0.25) assert await self.veh.setParam('RC8_MAX', 1730) is True assert self.veh.getParams('RC8_MAX') == 1730
async def test_norxheartbeat(self): """Test no rx hb task ever""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) await self.veh.setTimeout(0) await asyncio.sleep(0.01) assert self.veh.isConnected is False
async def test_noheartbeat(self): """Test no hb task ever""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setHearbeatRate(0) await asyncio.sleep(0.01) assert len(self.txpackets) == 0
async def test_vehtypename(self): """Test correct veh type and gf name from vehicle""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.fcName == "MAV_AUTOPILOT_ARDUPILOTMEGA" assert self.veh.vehType == "MAV_TYPE_QUADROTOR"
async def test_getPacket(self): """Test getting a packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) await asyncio.sleep(0.01) assert len(self.veh.latestPacketDict) == 1 assert self.veh.getPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT) == pkt assert self.veh.getPacket( self.mod.MAVLINK_MSG_ID_ESC_TELEMETRY_9_TO_12) is None
def test_sendPacket(self): """Assembling a packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback self.veh.sendPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.mod.MAV_TYPE_GCS, autopilot=self.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.mavversion)) assert len(self.txpackets) == 1
async def add_vehicle(self, name: str, source_system: int, source_component: int, target_system: int, target_component: int, dialect: str, mavversion: float, strconnection: str): """ Add a new vehicle""" if name in self.veh_list: raise ValueError('Already a vehicle with that name') else: self.veh_list[name] = Vehicle(self.loop, name, source_system, source_component, target_system, target_component, dialect, mavversion) # Connect packet RX from vehicle to moduleManager # self.veh_list[name].onPacketRxAttach(self.incoming_packet_callback) # Connect packet TX from vehicle to connectionManager self.veh_list[name].onPacketTxAttach(self.outgoingPacketBuffer) # tell the modulemanager if self.add_vehicle_callback: self.add_vehicle_callback(name) # matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkC) if self.add_link: # self.add_link(name, target_system, strconnection) asyncio.ensure_future( self.add_link(name, target_system, strconnection))
async def test_rxheartbeat(self): """Test correct rx of hb from vehicle - time of last packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setTimeout(0.05) pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) await asyncio.sleep(0.02) assert self.veh.isConnected is True await asyncio.sleep(0.10) assert self.veh.isConnected is False
async def test_heartbeat(self): """Test heatbeat rate and stopping hb task""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setHearbeatRate(0.001) await asyncio.sleep(0.15) # stop for a while - no extra hb emitted await self.veh.setHearbeatRate(0) await asyncio.sleep(0.01) # due to timer jitter, can only test for approx rate # Expecting between 4 and 120 hb packets assert len(self.txpackets) > 4 assert len(self.txpackets) < 120
def setUp(self): """Set up some data that is reused in many tests""" self.manager = None self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink( self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.txPackets = {}
def setUp(self): """Set up some data that is reused in many tests""" self.dialect = 'ardupilotmega' self.version = 2.0 self.ip = "127.0.0.1" # The links self.linkA = 'tcpclient:127.0.0.1:15001' self.linkB = 'tcpserver:127.0.0.1:15020' self.linkC = 'udpclient:127.0.0.1:15002' self.linkD = 'udpserver:127.0.0.1:15021' # The vehicles. Note the vehicles A and C have the same sysid # Source s/c then target s/c self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehB = Vehicle(self.loop, "VehB", 254, 0, 3, 0, self.dialect, self.version) self.VehC = Vehicle(self.loop, "VehC", 255, 0, 4, 0, self.dialect, self.version) # Dict of data rx'd by each link self.rxdata = {} # Dict of data rx'd by each vehicle self.vehpkts = {} self.mod = getpymavlinkpackage(self.dialect, self.version) # From the vehicle self.mavUAS = self.mod.MAVLink( self, srcSystem=4, srcComponent=0, use_native=False) self.mavoneUAS = self.mod.MAVLink( self, srcSystem=3, srcComponent=0, use_native=False) self.mavGCS = self.mod.MAVLink( self, srcSystem=255, srcComponent=0, use_native=False) self.mavoneGCS = self.mod.MAVLink( self, srcSystem=254, srcComponent=0, use_native=False)
class ModuleManagerTest(asynctest.TestCase): """ Class to test templateModule """ def setUp(self): """Set up some data that is reused in many tests""" self.manager = None self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.txPackets = {} self.txVehPackets = {} self.manager = moduleManager.moduleManager(self.loop, self.dialect, self.version, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("PaGS.modules.internalPrinterModule") async def tearDown(self): """Close down the test""" await self.VehA.stopheartbeat() await self.VehA.stoprxtimeout() def vehSendFunc(self, buf, name): """Event for when vehicle send buffer""" self.txVehPackets[name] = buf def txcallback(self, name, pkt, **kwargs): """Event callback to sending a packet on to vehiclemanager""" self.txPackets[name] = pkt def getVehListCallback(self): """Get list of vehicles""" return ["VehA"] def getVehicleCallback(self, vehname): """Get a particular vehicle""" if vehname == "VehA": return self.VehA else: raise ValueError('No vehicle with that name') def test_loadModule(self): """Test adding and removal of module""" self.manager.addModule("PaGS.modules.paramModule") # is the module loaded? # (noting that internalPrinter is already loaded) assert len(self.manager.multiModules) == 2 assert "param" in self.manager.commands assert len(self.manager.commands["param"]) == 6 self.manager.removeModule("PaGS.modules.paramModule") # is the module unloaded? assert len(self.manager.multiModules) == 1 assert "param" not in self.manager.commands async def test_cmd_download(self): """Test the "download" command""" self.manager.addModule("PaGS.modules.paramModule") # execute a command self.manager.onModuleCommandCallback("VehA", "param download") # assert await asyncio.sleep(0.001) assert self.txVehPackets['VehA'] is not None async def test_cmd_status(self): """Test the "status" command""" self.manager.addModule("PaGS.modules.paramModule") # execute a command self.manager.onModuleCommandCallback("VehA", "param status") # assert printed assert self.getOutText("VehA", 1) == "Params not downloaded" # now we have some params downloaded self.VehA.paramstatus = [15, 20, [1, 2, 4, 6, 13]] # execute a command self.manager.onModuleCommandCallback("VehA", "param status") # assert assert self.getOutText("VehA", 3) == "Downloaded 5 of 20 params" # now all params downloaded self.VehA.paramstatus = True # execute a command self.manager.onModuleCommandCallback("VehA", "param status") # assert assert self.getOutText("VehA", 5) == "Got all (0) params" async def test_cmd_show(self): """Test the "show" command""" self.manager.addModule("PaGS.modules.paramModule") # test with no params self.manager.onModuleCommandCallback("VehA", "param show *") # assert assert self.getOutText("VehA", 1) == "Params not downloaded" # now all params downloaded self.VehA.paramstatus = True self.VehA.params = {"RC1_MIN": 1000, "RC2_MAX": 2000} # get one param self.manager.onModuleCommandCallback("VehA", "param show RC1_MIN") assert self.getOutText("VehA", 3) == "RC1_MIN 1000" # get several params self.manager.onModuleCommandCallback("VehA", "param show RC*") allstr = self.getOutText("VehA", 5) + ", " + self.getOutText("VehA", 6) assert "RC1_MIN 1000" in allstr assert "RC2_MAX 2000" in allstr # get not existing param self.manager.onModuleCommandCallback("VehA", "param show RC5_MAX") assert self.getOutText("VehA", 8) == "No param RC5_MAX" # get no param self.manager.onModuleCommandCallback("VehA", "param show") assert "Traceback" in self.getOutText("VehA", 10) async def test_cmd_set(self): """Test the "set" command""" self.manager.addModule("PaGS.modules.paramModule") # test with no params self.manager.onModuleCommandCallback("VehA", "param set RC1_MIN 1102") # assert assert self.getOutText("VehA", 1) == "Params not downloaded" # now all params downloaded self.VehA.paramstatus = True self.VehA.params = {"RC1_MIN": 1000, "RC2_MAX": 2000} self.VehA.params_type = { "RC1_MIN": self.mod.MAV_PARAM_TYPE_UINT16, "RC2_MAX": self.mod.MAV_PARAM_TYPE_UINT16 } # test with single param self.manager.onModuleCommandCallback("VehA", "param set RC1_MIN 1102") # assert await asyncio.sleep(0.1) assert self.txVehPackets['VehA'] is not None # test with not existing param self.manager.onModuleCommandCallback("VehA", "param set RC1_MAX 1102") # assert assert self.getOutText("VehA", 4) == "No param with that name" # test with invalid val self.manager.onModuleCommandCallback("VehA", "param set RC1_MIN fgda") # assert assert self.getOutText("VehA", 6) == "Invalid param value" # test with no val self.manager.onModuleCommandCallback("VehA", "param set RC1_MIN") # assert assert "Traceback" in self.getOutText("VehA", 8) def test_cmd_save(self): """Test the save param command""" self.manager.addModule("PaGS.modules.paramModule") # test with no params self.manager.onModuleCommandCallback("VehA", "param save temp.parm") # assert assert self.getOutText("VehA", 1) == "Params not downloaded" # now all params downloaded self.VehA.paramstatus = True self.VehA.params = {"RC1_MIN": 1000, "RC2_MAX": 2000} self.VehA.params_type = { "RC1_MIN": self.mod.MAV_PARAM_TYPE_UINT16, "RC2_MAX": self.mod.MAV_PARAM_TYPE_UINT16 } # test with params self.manager.onModuleCommandCallback("VehA", "param save temp.parm") # assert assert self.getOutText("VehA", 3) == "2 params saved to temp.parm" assert os.path.isfile("temp.parm") with open('temp.parm', 'r') as myfile: data = myfile.read() assert "RC1_MIN 1000\n" in data assert "RC2_MAX 2000\n" in data # test with space in filename self.manager.onModuleCommandCallback("VehA", "param save \"temp 1.parm\"") # assert assert self.getOutText("VehA", 5) == "2 params saved to temp 1.parm" assert os.path.isfile("temp 1.parm") with open('temp 1.parm', 'r') as myfile: data = myfile.read() assert "RC1_MIN 1000\n" in data assert "RC2_MAX 2000\n" in data # and clean up files os.remove("temp.parm") os.remove("temp 1.parm") async def test_cmd_load(self): """Test the load param command""" self.manager.addModule("PaGS.modules.paramModule") # create the param files - good, param name bad, param value bad, # corrupt with open('tempload.parm', 'w') as myfile: myfile.write("RC1_MIN 1100\nRC2_MAX 2100\n") with open('temploadbad1.parm', 'w') as myfile: myfile.write("RC1_MID 1100\nRC2_MAX 2100\n") with open('temploadbad2.parm', 'w') as myfile: myfile.write("RC1_MIN 1100\nRC2_MAX dsf\n") with open('temploadbad3.parm', 'w') as myfile: myfile.write("w309836nb32n98n72\nw983n5c032 948") # test with no params self.manager.onModuleCommandCallback("VehA", "param load tempload.parm") # assert assert self.getOutText("VehA", 1) == "Params not downloaded" # now all params downloaded self.VehA.paramstatus = True self.VehA.params = {"RC1_MIN": 1000, "RC2_MAX": 2000} self.VehA.params_type = { "RC1_MIN": self.mod.MAV_PARAM_TYPE_UINT16, "RC2_MAX": self.mod.MAV_PARAM_TYPE_UINT16 } # test the normal good file self.manager.onModuleCommandCallback("VehA", "param load tempload.parm") # and assert assert self.getOutText("VehA", 3) == "2 params loaded from tempload.parm" await asyncio.sleep(0.01) assert self.txVehPackets['VehA'] is not None # bad file 1 - wrong param name self.manager.onModuleCommandCallback("VehA", "param load temploadbad1.parm") # and assert assert self.getOutText("VehA", 5) == "Invalid param: RC1_MID" assert self.getOutText("VehA", 6) == "1 params loaded from temploadbad1.parm" # bad file 2 - wrong param value self.manager.onModuleCommandCallback("VehA", "param load temploadbad2.parm") # and assert assert self.getOutText("VehA", 8) == "Invalid param value: dsf" assert self.getOutText("VehA", 9) == "1 params loaded from temploadbad2.parm" # bad file 3 - just plain corrupt self.manager.onModuleCommandCallback("VehA", "param load temploadbad3.parm") # and assert assert self.getOutText("VehA", 11) == "Param line not valid: w309836nb32n98n72" assert self.getOutText("VehA", 12) == "Invalid param: w983n5c032" assert self.getOutText("VehA", 13) == "0 params loaded from temploadbad3.parm" # and clean up files os.remove("tempload.parm") os.remove("temploadbad1.parm") os.remove("temploadbad2.parm") os.remove("temploadbad3.parm") def test_guiStart(self): """Simple test of the GUI startup""" # need to reset for handling gui self.manager = moduleManager.moduleManager(self.loop, self.dialect, self.version, True) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("PaGS.modules.internalPrinterModule") self.manager.addModule("PaGS.modules.paramModule") # TODO: some GUI tests? def getOutText(self, Veh: str, line: int): """Helper function for getting output text from internalPrinterModule""" return self.manager.multiModules[ 'PaGS.modules.internalPrinterModule'].printedout[Veh][line] def test_incoming(self): """Test incoming packets""" pass
class StatusModuleTest(asynctest.TestCase): """ Class to test statusModule """ def setUp(self): """Set up some data that is reused in many tests""" self.manager = None self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.VehA.hasInitial = True # The PaGS settings dir (just in source dir) self.settingsdir = os.path.join(os.getcwd(), ".PaGS") if not os.path.exists(self.settingsdir): os.makedirs(self.settingsdir) self.manager = moduleManager.moduleManager(self.loop, self.settingsdir, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("internalPrinterModule") async def tearDown(self): """Close down the test""" await self.VehA.stopheartbeat() await self.VehA.stoprxtimeout() if "PaGS.modules.statusModule" in self.manager.multiModules: await self.manager.removeModule("PaGS.modules.statusModule") if os.path.exists(self.settingsdir): shutil.rmtree(self.settingsdir) def vehSendFunc(self, buf, name): """Event for when vehicle send buffer""" pass def txcallback(self, name, pkt, **kwargs): """Event callback to sending a packet on to vehiclemanager""" pass def getVehListCallback(self): """Get list of vehicles""" return ["VehA"] def getVehicleCallback(self, vehname): """Get a particular vehicle""" if vehname == "VehA": return self.VehA else: raise ValueError('No vehicle with that name') async def test_loadModule(self): """Test adding and removal of module""" self.manager.addModule("PaGS.modules.statusModule") # is the module loaded? # (noting that internalPrinter is already loaded) assert len(self.manager.multiModules) == 2 assert "status" in self.manager.commands assert len(self.manager.commands["status"]) == 1 await self.manager.removeModule("PaGS.modules.statusModule") # is the module unloaded? assert len(self.manager.multiModules) == 1 assert "status" not in self.manager.commands async def test_cmd_status(self): """Test the "show" command""" self.manager.addModule("PaGS.modules.statusModule") # test with no params self.manager.onModuleCommandCallback("VehA", "status status") # assert assert self.getOutText("VehA", 1) == "No status packets recieved yet" # now there's a status packet at vehicle self.VehA.latestPacketDict[ "SYS_STATUS"] = self.mod.MAVLink_sys_status_message( 52485167, 35684399, 52461871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) # test with no params self.manager.onModuleCommandCallback("VehA", "status status") # assert assert self.getOutText("VehA", 3) == "3D_GYRO: Healthy" assert self.getOutText("VehA", 4) == "3D_ACCEL: Healthy" assert self.getOutText("VehA", 5) == "3D_MAG: Healthy" async def test_guiStart(self): """Simple test of the GUI startup""" # need to reset for handling gui self.manager = moduleManager.moduleManager(self.loop, self.settingsdir, True) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("internalPrinterModule") self.manager.addModule("PaGS.modules.statusModule") # Wait for param gui to load await asyncio.sleep(0.2) # Update the GUI with some status pkt = self.mod.MAVLink_sys_status_message(52485167, 35684399, 52461871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) self.manager.multiModules["PaGS.modules.statusModule"].incomingPacket( "VehA", pkt) # TODO: some GUI tests? def getOutText(self, Veh: str, line: int): """Helper function for getting output text from internalPrinterModule""" return self.manager.multiModules['internalPrinterModule'].printedout[ Veh][line]
class VehicleTest(asynctest.TestCase): """ Class to test Vehicle """ def setUp(self): """Set up some data that is reused in many tests""" self.dialect = 'ardupilotmega' self.mavversion = 2.0 self.source_system = 255 self.source_component = 0 self.target_system = 1 self.target_component = 0 # This is the "vehicle" to respond to messages self.mod = getpymavlinkpackage(self.dialect, self.mavversion) self.mavVehicle = self.mod.MAVLink(self, srcSystem=self.target_system, srcComponent=self.target_component, use_native=False) self.mavVehicle.robust_parsing = True self.veh = None self.txpackets = [] self.onNewPackets = [] def onNewEvent(self, vehName, pkt): """Callback for new packet""" self.onNewPackets.append(pkt) async def tearDown(self): """Close down the test""" if self.veh: await self.veh.stopheartbeat() await self.veh.stoprxtimeout() def newpacketcallback(self, buf: bytes, vehname: str): """Callback when a vehicle sends a packet""" self.txpackets.append(buf) def paramcallback(self, buf: bytes, vehname: str): """Callback when a vehicle sends a packet - for param testing""" # if param request, start sending some params pkt = self.mavVehicle.parse_char(buf) if isinstance(pkt, self.mod.MAVLink_param_request_list_message): # send all params (3 of them) pkt = self.mod.MAVLink_param_value_message( 'RC8_MIN', 1100, self.mod.MAV_PARAM_TYPE_REAL32, 3, 0) self.veh.newPacketCallback(pkt) pkt = self.mod.MAVLink_param_value_message( 'RC8_TRIM', 1500, self.mod.MAV_PARAM_TYPE_REAL32, 3, 1) self.veh.newPacketCallback(pkt) pkt = self.mod.MAVLink_param_value_message( 'RC8_MAX', 1900, self.mod.MAV_PARAM_TYPE_REAL32, 3, 2) self.veh.newPacketCallback(pkt) # callback for setting a param elif isinstance(pkt, self.mod.MAVLink_param_set_message): # send back confirmation pkt = self.mod.MAVLink_param_value_message( pkt.param_id, pkt.param_value, pkt.param_type, 1, 1) self.veh.newPacketCallback(pkt) def paramcallbackpartial(self, buf: bytes, vehname: str): """Callback when a vehicle sends a packet - for param testing""" # if param request, start sending some params pkt = self.mavVehicle.parse_char(buf) if isinstance(pkt, self.mod.MAVLink_param_request_list_message): # send all params (3 of them) pkt = self.mod.MAVLink_param_value_message( 'RC8_MIN', 1100, self.mod.MAV_PARAM_TYPE_REAL32, 3, 0) self.veh.newPacketCallback(pkt) pkt = self.mod.MAVLink_param_value_message( 'RC8_MAX', 1900, self.mod.MAV_PARAM_TYPE_REAL32, 3, 2) self.veh.newPacketCallback(pkt) if isinstance(pkt, self.mod.MAVLink_param_request_read_message): # get the missing param if pkt.param_index == 1: pkt = self.mod.MAVLink_param_value_message( 'RC8_TRIM', 1500, self.mod.MAV_PARAM_TYPE_REAL32, 3, 1) self.veh.newPacketCallback(pkt) async def test_vehicle(self): """Test vehicle initialises OK""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh is not None # async def test_onPacketCallback(self): # """Test the onPacketCallback works""" # self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, # self.target_system, self.target_component, self.dialect, self.mavversion) # self.veh.onPacketRxAttach(self.onNewEvent) # # pkt = self.mod.MAVLink_heartbeat_message( # self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) # self.veh.newPacketCallback(pkt) # # await asyncio.sleep(0.01) # # assert len(self.onNewPackets) == 1 # assert self.onNewPackets[0] == pkt async def test_getPacket(self): """Test getting a packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) await asyncio.sleep(0.01) assert len(self.veh.latestPacketDict) == 1 assert self.veh.getPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT) == pkt assert self.veh.getPacket( self.mod.MAVLINK_MSG_ID_ESC_TELEMETRY_9_TO_12) is None async def test_heartbeat(self): """Test heatbeat rate and stopping hb task""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setHearbeatRate(0.001) await asyncio.sleep(0.15) # stop for a while - no extra hb emitted await self.veh.setHearbeatRate(0) await asyncio.sleep(0.01) # due to timer jitter, can only test for approx rate # Expecting between 4 and 120 hb packets assert len(self.txpackets) > 4 assert len(self.txpackets) < 120 async def test_noheartbeat(self): """Test no hb task ever""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setHearbeatRate(0) await asyncio.sleep(0.01) assert len(self.txpackets) == 0 async def test_rxheartbeat(self): """Test correct rx of hb from vehicle - time of last packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback await self.veh.setTimeout(0.05) pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) await asyncio.sleep(0.02) assert self.veh.isConnected is True await asyncio.sleep(0.10) assert self.veh.isConnected is False async def test_norxheartbeat(self): """Test no rx hb task ever""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) await self.veh.setTimeout(0) await asyncio.sleep(0.01) assert self.veh.isConnected is False async def test_vehtypename(self): """Test correct veh type and gf name from vehicle""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.fcName == "MAV_AUTOPILOT_ARDUPILOTMEGA" assert self.veh.vehType == "MAV_TYPE_QUADROTOR" async def test_armmodestatus(self): """Test getting of the arming status and mode from heartbeat""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh.isArmed is None assert self.veh.flightMode is None pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_AUTO_DISARMED, 0, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is False assert self.veh.flightMode == "0" pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_MANUAL_ARMED, 1, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is True assert self.veh.flightMode == "1" pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, self.mod.MAV_MODE_MANUAL_DISARMED, 15, 0, int(self.mavversion)) self.veh.newPacketCallback(pkt) assert self.veh.isArmed is False assert self.veh.flightMode == '15' async def test_params_before(self): """Test getting of the parameters before downloaded""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh.getParams('RC8_MAX') is None assert self.veh.getParams() is None async def test_params_noresponse(self): """Test getting of the parameters, no response from vehicle""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) await self.veh.downloadParams(timeout=0.1) assert self.veh.getParams('RC8_MAX') is None assert self.veh.getParams() is None async def test_get_params(self): """Test getting of the parameters, got all. Plus typo""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback await self.veh.downloadParams(timeout=0.25) assert self.veh.getParams('RC8_MAX') == 1900 assert self.veh.getParams('RC8_MAXXX') is None async def test_get_params_retry(self): """Test getting of the parameters, need to retry some""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallbackpartial await self.veh.downloadParams(timeout=0.25) assert self.veh.getParams('RC8_MAX') == 1900 assert self.veh.getParams('RC8_TRIM') == 1500 async def test_set_param_no_params(self): """Test setting of params if params not downloaded yet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback assert await self.veh.setParam('RC8_MAX', 1800) is False async def test_set_param(self): """Test setting of param""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.paramcallback await self.veh.downloadParams(timeout=0.25) assert await self.veh.setParam('RC8_MAX', 1730) is True assert self.veh.getParams('RC8_MAX') == 1730 def test_sendPacket(self): """Assembling a packet""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) self.veh.txcallback = self.newpacketcallback self.veh.sendPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.mod.MAV_TYPE_GCS, autopilot=self.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.mavversion)) assert len(self.txpackets) == 1
class ModeModuleTest(asynctest.TestCase): """ Class to test Mode module """ def setUp(self): """Set up some data that is reused in many tests""" self.manager = None # The PaGS settings dir (just in source dir) self.settingsdir = os.path.join(os.getcwd(), ".PaGS") if not os.path.exists(self.settingsdir): os.makedirs(self.settingsdir) self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.VehA.vehType = 1 self.VehA.fcName = 3 self.VehA.hasInitial = True self.txPackets = {} self.txVehPackets = {} self.txPackets["VehA"] = [] self.manager = moduleManager.moduleManager(self.loop, self.settingsdir, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("internalPrinterModule") async def tearDown(self): """Close down the test""" await self.VehA.stopheartbeat() await self.VehA.stoprxtimeout() if os.path.exists(self.settingsdir): shutil.rmtree(self.settingsdir) def vehSendFunc(self, buf, name): """Event for when vehicle send buffer""" self.txVehPackets[name] = buf def txcallback(self, name, pkt, **kwargs): """Event callback to sending a packet on to vehiclemanager""" self.txPackets[name].append(pkt) def getVehListCallback(self): """Get list of vehicles""" return ["VehA"] def getVehicleCallback(self, vehname): """Get a particular vehicle""" if vehname == "VehA": return self.VehA else: raise ValueError('No vehicle with that name') def getOutText(self, Veh: str, line: int): """Helper function for getting output text from internalPrinterModule""" return self.manager.multiModules['internalPrinterModule'].printedout[ Veh][line] async def test_loadModule(self): """Test adding and removal of module""" self.manager.addModule("PaGS.modules.modeModule") # is the module loaded? assert len(self.manager.multiModules) == 2 assert "mode" in self.manager.commands assert len(self.manager.commands["mode"]) == 5 await self.manager.removeModule("PaGS.modules.modeModule") # is the module unloaded? assert len(self.manager.multiModules) == 1 assert "mode" not in self.manager.commands def test_cmd_listmodes(self): """Test the listModes() command""" self.manager.addModule("PaGS.modules.modeModule") # execute a command self.manager.onModuleCommandCallback("VehA", "mode list") # and assert assert self.getOutText("VehA", 1)[0:18] == "Valid modes are: [" assert self.getOutText("VehA", 1)[-1] == "]" def test_cmd_doMode(self): """Test the doMode command""" self.manager.addModule("PaGS.modules.modeModule") # execute a bad mode self.manager.onModuleCommandCallback("VehA", "mode do BADMODE") # assert assert len(self.txPackets["VehA"]) == 0 assert self.getOutText("VehA", 1) == "No mode: BADMODE" # execute a mode change self.manager.onModuleCommandCallback("VehA", "mode do AUTO") # assert assert len(self.txPackets["VehA"]) == 1 assert len(self.txPackets) == 1 async def test_cmd_armDisarm(self): """Test the arm and disarm commands""" self.manager.addModule("PaGS.modules.modeModule") # execute an arm self.manager.onModuleCommandCallback("VehA", "mode arm") # assert assert len(self.txPackets["VehA"]) == 1 # execute a disarm self.manager.onModuleCommandCallback("VehA", "mode disarm") # assert assert len(self.txPackets["VehA"]) == 2 assert len(self.txPackets) == 1 async def test_cmd_reboot(self): """Test the reboot command""" self.manager.addModule("PaGS.modules.modeModule") # execute an arm self.manager.onModuleCommandCallback("VehA", "mode reboot") # assert assert len(self.txPackets["VehA"]) == 1 def test_incoming(self): """Test incoming packets""" self.manager.addModule("PaGS.modules.modeModule") # change mode pkt = self.mod.MAVLink_heartbeat_message( self.mod.MAV_TYPE_QUADROTOR, self.mod.MAV_AUTOPILOT_ARDUPILOTMEGA, 0, 0, 4, int(self.version)) self.manager.incomingPacket("VehA", pkt, "Constr") # assert assert self.getOutText("VehA", 0) == "Mode changed to: STABILIZE" # Don't change mode self.manager.incomingPacket("VehA", pkt, "Constr") # assert no extra text assert len(self.manager.multiModules['internalPrinterModule']. printedout["VehA"]) == 1
class ConnectionMatrixTest(asynctest.TestCase): """ Class to test The connection matrix """ def setUp(self): """Set up some data that is reused in many tests""" self.dialect = 'ardupilotmega' self.version = 2.0 self.ip = "127.0.0.1" # The links self.linkA = 'tcpclient:127.0.0.1:15001' self.linkB = 'tcpserver:127.0.0.1:15020' self.linkC = 'udpclient:127.0.0.1:15002' self.linkD = 'udpserver:127.0.0.1:15021' # The vehicles. Note the vehicles A and C have the same sysid # Source s/c then target s/c self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehB = Vehicle(self.loop, "VehB", 254, 0, 3, 0, self.dialect, self.version) self.VehC = Vehicle(self.loop, "VehC", 255, 0, 4, 0, self.dialect, self.version) # Dict of data rx'd by each link self.rxdata = {} # Dict of data rx'd by each vehicle self.vehpkts = {} self.mod = getpymavlinkpackage(self.dialect, self.version) # From the vehicle self.mavUAS = self.mod.MAVLink( self, srcSystem=4, srcComponent=0, use_native=False) self.mavoneUAS = self.mod.MAVLink( self, srcSystem=3, srcComponent=0, use_native=False) self.mavGCS = self.mod.MAVLink( self, srcSystem=255, srcComponent=0, use_native=False) self.mavoneGCS = self.mod.MAVLink( self, srcSystem=254, srcComponent=0, use_native=False) async def tearDown(self): """Called at the end of each test""" await self.VehA.stopheartbeat() await self.VehB.stopheartbeat() await self.VehC.stopheartbeat() await self.VehA.stoprxtimeout() await self.VehB.stoprxtimeout() await self.VehC.stoprxtimeout() def newpacketcallbackVeh(self, vehname, pkt, strconnection): """Callback when a vehicle has a new packet""" try: self.vehpkts[vehname].append(pkt) except KeyError: self.vehpkts[vehname] = [pkt] def newpacketcallbackLnk(self, pkt, strconnection): """Callback when a test link has a new packet""" try: self.rxdata[strconnection].append(pkt) except KeyError: self.rxdata[strconnection] = [pkt] async def test_matrixstartup(self): """Test a simple startup of the matrix""" matrix = ConnectionManager(self.loop, self.dialect, self.version, 0, 0) await matrix.stoploop() assert matrix is not None async def test_matrixaddremove(self): """Test adding and removing vehicles from the matrix""" matrix = ConnectionManager(self.loop, self.dialect, self.version, 0, 0) matrix.onPacketAttach(self.newpacketcallbackVeh) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkB) await matrix.addVehicleLink(self.VehB.name, self.VehB.target_system, self.linkB) await matrix.addVehicleLink(self.VehC.name, self.VehC.target_system, self.linkD) # now wait for a bit - 0.02 sec await asyncio.sleep(0.02) assert len(matrix.getAllVeh()) == 3 assert len(matrix.linkdict) == 2 # remove a link - it will remove the associated veh C too await matrix.removeLink(self.linkD) # now wait for a bit - 0.02 sec await asyncio.sleep(0.02) assert len(matrix.getAllVeh()) == 2 assert len(matrix.linkdict) == 1 # remove a vehicle await matrix.removeVehicle(self.VehA.name) # now wait for a bit - 0.02 sec await asyncio.sleep(0.02) await matrix.stoploop() # assert. It should be VehA and linkB left assert len(matrix.getAllVeh()) == 1 assert len(matrix.linkdict) == 1 async def test_linkretry_tcp(self): """For each of the TCP link types, test that they keep re-trying to connect, by only adding in the other side of the link 0.5 sec after startup""" matrix = ConnectionManager( self.loop, self.dialect, self.version, 0, 0, 0.05) matrix.onPacketAttach(self.newpacketcallbackVeh) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkA) await matrix.addVehicleLink(self.VehB.name, self.VehB.target_system, self.linkB) # now wait for a bit await asyncio.sleep(0.10) # now connect the other sides tcpserver = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=True, name='tcpserver:127.0.0.1:15001') tcpclient = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=False, name='tcpclient:127.0.0.1:15020') await self.loop.create_server(lambda: tcpserver, self.ip, 15001) await self.loop.create_connection(lambda: tcpclient, self.ip, 15020) # send packets on each link and wait await asyncio.sleep(0.20) pkt = self.mod.MAVLink_heartbeat_message( 5, 4, 0, 0, 0, int(self.version)) pktbytes = pkt.pack(self.mavUAS, force_mavlink1=False) pktbytesone = pkt.pack(self.mavoneUAS, force_mavlink1=False) tcpserver.send_data(pktbytes) tcpclient.send_data(pktbytesone) await asyncio.sleep(0.20) await matrix.stoploop() tcpserver.close() tcpclient.close() # assert the links are all still there assert len(matrix.getAllVeh()) == 2 assert len(matrix.linkdict) == 2 # assert packets were recived on both links (vehicles) in the matrix assert self.vehpkts[self.VehA.name][0].get_msgbuf() == pktbytes assert self.vehpkts[self.VehB.name][0].get_msgbuf() == pktbytesone async def test_linkretry_udp(self): """For each of the UDP link types, test that they keep re-trying to connect, by only adding in the other side of the link 0.5 sec after startup""" matrix = ConnectionManager( self.loop, self.dialect, self.version, 0, 0, 0.05) matrix.onPacketAttach(self.newpacketcallbackVeh) self.VehA.onPacketTxAttach(matrix.outgoingPacket) self.VehB.onPacketTxAttach(matrix.outgoingPacket) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkC) await matrix.addVehicleLink(self.VehB.name, self.VehB.target_system, self.linkD) # now wait for a bit - 0.02 sec await asyncio.sleep(0.02) # now connect the other sides udpserver = UDPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=True, name='udpserver:127.0.0.1:15002') udpclient = UDPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=False, name='udpclient:127.0.0.1:15021') await self.loop.create_datagram_endpoint(lambda: udpserver, local_addr=(self.ip, 15002)) await self.loop.create_datagram_endpoint(lambda: udpclient, remote_addr=(self.ip, 15021)) # send packets on each link and wait 0.02 sec await asyncio.sleep(0.02) pkt = self.mod.MAVLink_heartbeat_message( 5, 4, 0, 0, 0, int(self.version)) pktbytes = pkt.pack(self.mavUAS, force_mavlink1=False) pktbytesone = pkt.pack(self.mavoneUAS, force_mavlink1=False) # need to send a packet from client to server to init the link self.VehA.sendPacket(self.VehA.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.VehA.mod.MAV_TYPE_GCS, autopilot=self.VehA.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.VehA.mavversion)) await asyncio.sleep(0.02) udpserver.send_data(pktbytes) udpclient.send_data(pktbytesone) await asyncio.sleep(0.02) await matrix.stoploop() udpserver.close() udpclient.close() # assert the links are all still there assert len(matrix.getAllVeh()) == 2 assert len(matrix.linkdict) == 2 # assert packets were recived on both links (vehicles) in the matrix assert len(self.vehpkts) == 2 assert self.vehpkts[self.VehA.name][0].get_msgbuf() == pktbytes assert self.vehpkts[self.VehB.name][0].get_msgbuf() == pktbytesone async def test_incomingdistribution(self): """Test incoming packets (from vehicle) are distributed correctly""" # -VehA: LinkA,LinkB, VehB: LinkB, VehC: LinkC matrix = ConnectionManager( self.loop, self.dialect, self.version, 0, 0, 0.05) matrix.onPacketAttach(self.newpacketcallbackVeh) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkA) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkB) await matrix.addVehicleLink(self.VehB.name, self.VehB.target_system, self.linkB) await matrix.addVehicleLink(self.VehC.name, self.VehC.target_system, self.linkD) # now wait for a bit await asyncio.sleep(0.10) # now connect the other sides tcpserver = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=True, name='tcpserver:127.0.0.1:15001') tcpclient = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=False, name='tcpclient:127.0.0.1:15020') udpclient = UDPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=False, name='udpclient:127.0.0.1:15021') await self.loop.create_server(lambda: tcpserver, self.ip, 15001) await self.loop.create_connection(lambda: tcpclient, self.ip, 15020) await self.loop.create_datagram_endpoint(lambda: udpclient, remote_addr=(self.ip, 15021)) # send packets on each link and wait await asyncio.sleep(0.10) pkt = self.mod.MAVLink_heartbeat_message( 5, 4, 0, 0, 0, int(self.version)) pktbytes = pkt.pack(self.mavUAS, force_mavlink1=False) pktbytesone = pkt.pack(self.mavoneUAS, force_mavlink1=False) # send packet to VehA on LinkA tcpserver.send_data(pktbytes) await asyncio.sleep(0.10) # send new (updated) packet to VehA on LinkB pktupdate = self.mod.MAVLink_heartbeat_message( 5, 3, 0, 0, 0, int(self.version)) pktbytesupdate = pktupdate.pack(self.mavUAS, force_mavlink1=False) tcpclient.send_data(pktbytesupdate) # need a small sleep here otherwise the linkB gets confused await asyncio.sleep(0.10) # send packet to VehB on linkB tcpclient.send_data(pktbytesone) await asyncio.sleep(0.10) # send packet to VehC on LinkC udpclient.send_data(pktbytes) # wait for packets to send await asyncio.sleep(0.10) # and close everything await matrix.stoploop() tcpserver.close() tcpclient.close() udpclient.close() # assert the links are all still there assert len(matrix.getAllVeh()) == 3 assert len(matrix.linkdict) == 3 # assert packets were recived assert self.vehpkts[self.VehA.name][0].get_msgbuf() == pktbytes assert self.vehpkts[self.VehA.name][1].get_msgbuf() == pktbytesupdate assert self.vehpkts[self.VehB.name][0].get_msgbuf() == pktbytesone assert self.vehpkts[self.VehC.name][0].get_msgbuf() == pktbytes async def test_outgoingdistribution(self): """Test outgoing packets (from gcs) are distributed correctly""" # -VehA: LinkA,LinkB, VehB: LinkB, VehC: LinkC await self.VehA.setHearbeatRate(0) await self.VehB.setHearbeatRate(0) await self.VehC.setHearbeatRate(0) matrix = ConnectionManager( self.loop, self.dialect, self.version, 0, 0, 0.05) matrix.onPacketAttach(self.newpacketcallbackVeh) self.VehA.onPacketTxAttach(matrix.outgoingPacket) self.VehB.onPacketTxAttach(matrix.outgoingPacket) self.VehC.onPacketTxAttach(matrix.outgoingPacket) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkA) await matrix.addVehicleLink(self.VehA.name, self.VehA.target_system, self.linkB) await matrix.addVehicleLink(self.VehB.name, self.VehB.target_system, self.linkB) await matrix.addVehicleLink(self.VehC.name, self.VehC.target_system, self.linkC) # now wait for a bit await asyncio.sleep(0.15) # now connect the other sides tcpserver = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=True, name='tcpserver:127.0.0.1:15001') tcpclient = TCPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=False, name='tcpclient:127.0.0.1:15020') udpserver = UDPConnection(rxcallback=self.newpacketcallbackLnk, dialect=self.dialect, mavversion=self.version, srcsystem=0, srccomp=0, server=True, name='udpserver:127.0.0.1:15002') await self.loop.create_server(lambda: tcpserver, self.ip, 15001) await self.loop.create_connection(lambda: tcpclient, self.ip, 15020) await self.loop.create_datagram_endpoint(lambda: udpserver, local_addr=(self.ip, 15002)) # send packets on each link and wait await asyncio.sleep(0.15) # send packet from the GCS of VehA, VehB and VehC pktbytesA = self.VehA.sendPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.mod.MAV_TYPE_GCS, autopilot=self.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.VehA.mavversion)) await asyncio.sleep(0.10) pktbytesB = self.VehB.sendPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.mod.MAV_TYPE_GCS, autopilot=self.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.VehB.mavversion)) await asyncio.sleep(0.10) pktbytesC = self.VehC.sendPacket(self.mod.MAVLINK_MSG_ID_HEARTBEAT, type=self.mod.MAV_TYPE_GCS, autopilot=self.mod.MAV_AUTOPILOT_INVALID, base_mode=0, custom_mode=0, system_status=0, mavlink_version=int(self.VehC.mavversion)) # wait for packets to send await asyncio.sleep(0.15) # and close everything await matrix.stoploop() tcpserver.close() tcpclient.close() udpserver.close() # assert the links are all still there assert len(matrix.getAllVeh()) == 3 assert len(matrix.linkdict) == 3 # assert packets were recived on the endpoints assert self.rxdata['tcpserver:127.0.0.1:15001'][0].get_msgbuf( ) == pktbytesA assert self.rxdata['tcpclient:127.0.0.1:15020'][0].get_msgbuf( ) == pktbytesC assert self.rxdata['tcpclient:127.0.0.1:15020'][1].get_msgbuf( ) == pktbytesB assert self.rxdata['udpserver:127.0.0.1:15002'][0].get_msgbuf( ) == pktbytesC
async def test_vehicle(self): """Test vehicle initialises OK""" self.veh = Vehicle(self.loop, "VehA", self.source_system, self.source_component, self.target_system, self.target_component, self.dialect, self.mavversion) assert self.veh is not None
class ModuleManagerTest(asynctest.TestCase): """ Class to test manager module commands """ def setUp(self): """Set up some data that is reused in many tests""" self.manager = None # The PaGS settings dir (just in source dir) self.settingsdir = os.path.join(os.getcwd(), ".PaGS") if not os.path.exists(self.settingsdir): os.makedirs(self.settingsdir) self.dialect = 'ardupilotmega' self.version = 2.0 self.mod = getpymavlinkpackage(self.dialect, self.version) self.mavUAS = self.mod.MAVLink(self, srcSystem=4, srcComponent=0, use_native=False) self.VehA = Vehicle(self.loop, "VehA", 255, 0, 4, 0, self.dialect, self.version) self.VehA.onPacketTxAttach(self.vehSendFunc) self.VehA.vehType = 1 self.VehA.fcName = 3 self.VehA.hasInitial = True self.txPackets = {} self.txVehPackets = {} self.txPackets["VehA"] = [] self.manager = moduleManager.moduleManager(self.loop, self.settingsdir, False) self.manager.onVehListAttach(self.getVehListCallback) self.manager.onVehGetAttach(self.getVehicleCallback) self.manager.onPktTxAttach(self.txcallback) self.manager.addModule("internalPrinterModule") async def tearDown(self): """Close down the test""" await self.VehA.stopheartbeat() await self.VehA.stoprxtimeout() if os.path.exists(self.settingsdir): shutil.rmtree(self.settingsdir) def vehSendFunc(self, buf, name): """Event for when vehicle send buffer""" self.txVehPackets[name] = buf def txcallback(self, name, pkt, **kwargs): """Event callback to sending a packet on to vehiclemanager""" self.txPackets[name].append(pkt) def getVehListCallback(self): """Get list of vehicles""" return ["VehA"] def getVehicleCallback(self, vehname): """Get a particular vehicle""" if vehname == "VehA": return self.VehA else: raise ValueError('No vehicle with that name') def getOutText(self, Veh: str, line: int): """Helper function for getting output text from internalPrinterModule""" return self.manager.multiModules['internalPrinterModule'].printedout[ Veh][line] def test_loadModule(self): """Test loading: good, bad and existing""" self.manager.onModuleCommandCallback("VehA", "module load modules.dontexist") assert self.getOutText("VehA", 1) == "Cannot find module" assert len(self.manager.multiModules) == 1 self.manager.onModuleCommandCallback("VehA", "module load modules.modeModule") assert self.getOutText("VehA", 3) == "Loaded module modules.modeModule" assert len(self.manager.multiModules) == 2 self.manager.onModuleCommandCallback("VehA", "module load modules.modeModule") assert self.getOutText("VehA", 5) == "Module already loaded" assert len(self.manager.multiModules) == 2 def test_listModule(self): """ Test listing of modules "module list" """ self.manager.onModuleCommandCallback("VehA", "module list") assert self.getOutText("VehA", 1) == "Loaded Modules: " assert self.getOutText("VehA", 2) == "internalPrinterModule" self.manager.onModuleCommandCallback("VehA", "module load modules.modeModule") self.manager.onModuleCommandCallback("VehA", "module list") # The loaded module listing order is not important assert self.getOutText("VehA", 6) == "Loaded Modules: " assert self.getOutText( "VehA", 7) == "internalPrinterModule" or "PaGS.modules.modeModule" assert self.getOutText( "VehA", 8) == "internalPrinterModule" or "PaGS.modules.modeModule" assert self.getOutText("VehA", 7) != self.getOutText("VehA", 8)