Skip to content
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
3 changes: 0 additions & 3 deletions docs/DEVELOPMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,6 @@ pytest -x
# Run specific test file
pytest tests/test_params.py

# Run with physical device
pytest --fc -s

# Run specific test
pytest -k "test_param_set"

Expand Down
31 changes: 26 additions & 5 deletions radio/app/controllers/missionController.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ def _convertCoordinate(coordinate) -> Number:
)


def _wp_to_dict(
wp: mavutil.mavlink.MAVLink_mission_item_int_message,
altitude_decimal_places: int = 4,
) -> dict:
"""
Convert a MAVLink mission item to a dict, rounding the altitude (z) field
to a fixed number of decimal places to avoid floating-point noise.

Args:
wp: A MAVLink mission item object with a to_dict() method.
altitude_decimal_places (int): Number of decimal places to round z to.

Returns:
dict: The waypoint as a dictionary with z rounded.
"""
d = wp.to_dict()
if "z" in d and isinstance(d["z"], float):
d["z"] = round(d["z"], altitude_decimal_places)
return d
Comment thread
1Blademaster marked this conversation as resolved.


def _getMissionName(mission_type: int) -> str:
"""
Get the name of the mission type.
Expand Down Expand Up @@ -285,7 +306,7 @@ def importMissionFromFile(
return {
"success": True,
"message": f"Waypoint file loaded {loader.count()} points successfully",
"data": [wp.to_dict() for wp in loader.wpoints],
"data": [_wp_to_dict(wp) for wp in loader.wpoints],
}


Expand Down Expand Up @@ -419,7 +440,7 @@ def getCurrentMission(

return {
"success": True,
"data": [item.to_dict() for item in mission_items.get("data", [])],
"data": [_wp_to_dict(item) for item in mission_items.get("data", [])],
}
except serial.serialutil.SerialException:
return {
Expand Down Expand Up @@ -456,9 +477,9 @@ def getCurrentMissionAll(self) -> Response:
return {
"success": True,
"data": {
"mission_items": [item.to_dict() for item in mission_items],
"fence_items": [item.to_dict() for item in fence_items],
"rally_items": [item.to_dict() for item in rally_items],
"mission_items": [_wp_to_dict(item) for item in mission_items],
"fence_items": [_wp_to_dict(item) for item in fence_items],
"rally_items": [_wp_to_dict(item) for item in rally_items],
},
}

Expand Down
43 changes: 0 additions & 43 deletions radio/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
from typing import Callable, Optional

import app.droneStatus as droneStatus
import pytest
from app import create_app, socketio
from flask.testing import FlaskClient
from flask_socketio.test_client import SocketIOTestClient
Expand All @@ -27,42 +23,3 @@ def ignore_link_debug_stats(data):
socketio_client: SocketIOTestClient = socketio.test_client(
app, flask_test_client=flask_client
)


def falcon_test(pass_drone_status: bool = False, pass_flask: bool = False) -> Callable:
"""
A wrapper to connect to backend and pass necessary details to test function

Args:
pass_drone_status (bool): True if you want to accept the droneStatus file to the test func
pass_flask (bool): True if you want to accept the flask_test_client file to the test func
"""

def run_test(test_func: Optional[Callable] = None):
"""Inner wrapper to run test"""

if test_func is None:
raise ValueError(
"You forgot to write parenthesis around falcon_test() so test_func was set to None"
)

def inner(*args, **kwargs):
# Make sure the server did not rejected the connection
assert socketio_client.is_connected()

# Get variables to pass into test_func
passing_variables = {}
if pass_drone_status:
passing_variables["droneStatus"] = droneStatus
if pass_flask:
passing_variables["flask_client"] = flask_client

# Run test
if droneStatus.drone is None and pass_drone_status:
pytest.skip("Passing as no flight controller was found.")
else:
test_func(socketio_client, *args, **passing_variables, **kwargs)

return inner

return run_test
45 changes: 22 additions & 23 deletions radio/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import app.droneStatus as droneStatus # noqa: F401
import app.droneStatus as _droneStatus_module
import pytest
from app.drone import Drone
from app.utils import getComPort

from tests import socketio_client as _socketio_client


def pytest_configure(config):
Expand All @@ -19,57 +20,55 @@ def setupDrone(connectionString: str) -> bool:
Setup the drone globally, this is done before running pytest

Args:
connectionString (str): Either the port for a physical device or network connection string for a simulator
connectionString (str): Network connection string for a simulator
"""
global droneStatus

drone = Drone(connectionString)

if drone.master is None:
return False

droneStatus.drone = drone
_droneStatus_module.drone = drone
return True


def pytest_addoption(parser):
parser.addoption("--fc", action="store_true")


def pytest_sessionstart(session):
"""
Called after the Session object has been created and
before performing collection and entering the run test loop.
"""
global droneStatus

connection_string = "tcp:127.0.0.1:5760"

if session.config.getoption("--fc"):
print("\033[1;31;40mRUNNING TESTS WITH A PHYSICAL DEVICE \033[0m")
connection_string = getComPort()
print("\033[1;31;40mRUNNING TESTS WITH A SIMULATOR \033[0m")

else:
print("\033[1;31;40mRUNNING TESTS WITH A SIMULATOR \033[0m")

success = setupDrone(connection_string)
success = setupDrone("tcp:127.0.0.1:5760")

if not success:
print("\033[1;31;40mFAILED TO CONNECT TO DRONE, EXITING TESTS\033[0m")
pytest.exit(1)
Comment thread
1Blademaster marked this conversation as resolved.


@pytest.fixture
def droneStatus():
"""Fixture providing the droneStatus module"""
return _droneStatus_module


@pytest.fixture
def socketio_client():
"""Fixture providing the socketio test client"""
assert _socketio_client.is_connected(), "SocketIO test client is not connected"
return _socketio_client


@pytest.fixture(autouse=True)
def check_aircraft_type(request):
"""Fixture to skip tests based on aircraft type markers"""

markers = [marker.name for marker in request.node.iter_markers()]

if droneStatus.drone is None:
if _droneStatus_module.drone is None:
pytest.skip("No drone connected")
return

aircraft_type = droneStatus.drone.aircraft_type
aircraft_type = _droneStatus_module.drone.aircraft_type

# Skip if marked as plane_only but not a plane
if "plane_only" in markers and aircraft_type != 1:
Expand Down
106 changes: 0 additions & 106 deletions radio/tests/ftp_test_files/expected_locations.txt

This file was deleted.

2 changes: 1 addition & 1 deletion radio/tests/mission_test_files/exported_mission_check.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
QGC WPL 110
0 0 0 16 0.000000 0.000000 0.000000 0.000000 52.780569 -0.707924 0.100000 1
0 0 0 16 0.000000 0.000000 0.000000 0.000000 52.780569 -0.707923 0.190000 1
1 0 3 22 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 30.000000 1
2 0 3 16 0.000000 0.000000 0.000000 0.000000 52.780320 -0.709793 30.000000 1
3 0 3 16 0.000000 0.000000 0.000000 0.000000 52.781228 -0.709895 30.000000 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"seq": 0,
"target_component": 190,
"target_system": 255,
"x": 527805690,
"y": -7079236,
"z": 0.09999999403953552
"x": 527805691,
"y": -7079234,
"z": 0.19
},
{
"mavpackettype": "MISSION_ITEM_INT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"seq": 0,
"target_component": 190,
"target_system": 255,
"x": 527805690,
"y": -7079236,
"z": 0.09999999403953552
"x": 527805691,
"y": -7079234,
"z": 0.19
},
{
"mavpackettype": "MISSION_ITEM_INT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"seq": 0,
"target_component": 190,
"target_system": 255,
"x": 527805690,
"y": -7079236,
"z": 0.09999999403953552
"x": 527805691,
"y": -7079234,
"z": 0.19
},
{
"mavpackettype": "MISSION_ITEM_INT",
Expand Down
Loading
Loading