|
| 1 | +# Tests for utils/helpers.py |
| 2 | + |
| 3 | +import pytest |
| 4 | +import os |
| 5 | +from flask_testing import TestCase |
| 6 | +from backend import app |
| 7 | +from utils.helpers import * |
| 8 | +from tests.test_utils import temporarily_rename_file |
| 9 | + |
| 10 | +class TestHelpers(TestCase): |
| 11 | + """Tests for utils functions""" |
| 12 | + |
| 13 | + def create_app(self): |
| 14 | + app.config['TESTING'] = True |
| 15 | + return app |
| 16 | + |
| 17 | + def test_compile_simulation(self): |
| 18 | + # Test compilation failure |
| 19 | + with temporarily_rename_file("./src/main.cpp", "./src/main.cpp.temp"): |
| 20 | + self.assertFalse(compile_simulation(debug=True)) |
| 21 | + |
| 22 | + # Test compilation success |
| 23 | + self.assertTrue(compile_simulation(debug=True)) |
| 24 | + |
| 25 | + def test_validate_simulation_prerequisites(self): |
| 26 | + # Test when executable is not found |
| 27 | + with temporarily_rename_file("./src/simulation.out", "./src/simulation.out.temp_error"): |
| 28 | + is_valid, response = validate_simulation_prerequisites() |
| 29 | + self.assertFalse(is_valid) |
| 30 | + self.assertEqual(response[1], 500) |
| 31 | + |
| 32 | + # Test when executable is found |
| 33 | + self.assertTrue(compile_simulation(debug=True)) |
| 34 | + is_valid, response = validate_simulation_prerequisites() |
| 35 | + self.assertTrue(is_valid) |
| 36 | + |
| 37 | + def test_invalid_lambda_param(self): |
| 38 | + # Test lambda = 0 |
| 39 | + is_valid, response = parse_simulation_parameters({"lambdaParam": 0}) |
| 40 | + self._assert_invalid_param(is_valid, response, "lambdaParam must be greater than 0") |
| 41 | + |
| 42 | + # Test lambda as string |
| 43 | + is_valid, response = parse_simulation_parameters({"lambdaParam": "string"}) |
| 44 | + self._assert_invalid_param(is_valid, response, "lambdaParam must be a number") |
| 45 | + |
| 46 | + def test_invalid_mu_param(self): |
| 47 | + # Test mu = 0 |
| 48 | + is_valid, response = parse_simulation_parameters({"mu": 0}) |
| 49 | + self._assert_invalid_param(is_valid, response, "mu must be greater than 0") |
| 50 | + |
| 51 | + # Test mu as string |
| 52 | + is_valid, response = parse_simulation_parameters({"mu": "string"}) |
| 53 | + self._assert_invalid_param(is_valid, response, "mu must be a number") |
| 54 | + |
| 55 | + def test_invalid_goal_connections(self): |
| 56 | + # Test goalConnections = 0 |
| 57 | + is_valid, response = parse_simulation_parameters({"goalConnections": 0}) |
| 58 | + self._assert_invalid_param(is_valid, response, "goalConnections must be greater than 0") |
| 59 | + |
| 60 | + # Test goalConnections too high |
| 61 | + is_valid, response = parse_simulation_parameters({"goalConnections": 10000001}) |
| 62 | + self._assert_invalid_param(is_valid, response, "goalConnections must be less than 10,000,000") |
| 63 | + |
| 64 | + # Test goalConnections as string |
| 65 | + is_valid, response = parse_simulation_parameters({"goalConnections": "string"}) |
| 66 | + self._assert_invalid_param(is_valid, response, "goalConnections must be an integer") |
| 67 | + |
| 68 | + def test_invalid_network_type(self): |
| 69 | + # Test unsupported network type |
| 70 | + is_valid, response = parse_simulation_parameters({"networkType": 99}) |
| 71 | + self._assert_invalid_param(is_valid, response, "At the moment only networkType 1 is supported") |
| 72 | + |
| 73 | + # Test network type as string |
| 74 | + is_valid, response = parse_simulation_parameters({"networkType": "string"}) |
| 75 | + self._assert_invalid_param(is_valid, response, "networkType must be an integer") |
| 76 | + |
| 77 | + def test_invalid_confidence(self): |
| 78 | + # Test confidence too high |
| 79 | + is_valid, response = parse_simulation_parameters({"confidence": 1.1}) |
| 80 | + self._assert_invalid_param(is_valid, response, "confidence must be between 0 and 1") |
| 81 | + |
| 82 | + # Test confidence too low |
| 83 | + is_valid, response = parse_simulation_parameters({"confidence": -0.1}) |
| 84 | + self._assert_invalid_param(is_valid, response, "confidence must be between 0 and 1") |
| 85 | + |
| 86 | + # Test confidence as string |
| 87 | + is_valid, response = parse_simulation_parameters({"confidence": "string"}) |
| 88 | + self._assert_invalid_param(is_valid, response, "confidence must be a number") |
| 89 | + |
| 90 | + def test_invalid_algorithm(self): |
| 91 | + # Test invalid algorithm name |
| 92 | + is_valid, response = parse_simulation_parameters({"algorithm": "InvalidAlgorithm"}) |
| 93 | + self._assert_invalid_param(is_valid, response, "algorithm must be FirstFit or BestFit") |
| 94 | + |
| 95 | + # Test algorithm as number |
| 96 | + is_valid, response = parse_simulation_parameters({"algorithm": 123}) |
| 97 | + self._assert_invalid_param(is_valid, response, "algorithm must be a string") |
| 98 | + |
| 99 | + def test_invalid_k(self): |
| 100 | + # Test K too small |
| 101 | + is_valid, response = parse_simulation_parameters({"K": 0}) |
| 102 | + self._assert_invalid_param(is_valid, response, "Min K is 1") |
| 103 | + |
| 104 | + # Test K too large |
| 105 | + is_valid, response = parse_simulation_parameters({"K": 100}) |
| 106 | + self._assert_invalid_param(is_valid, response, "Max K is 6") |
| 107 | + |
| 108 | + # Test K as string |
| 109 | + is_valid, response = parse_simulation_parameters({"K": "string"}) |
| 110 | + self._assert_invalid_param(is_valid, response, "K must be an integer") |
| 111 | + |
| 112 | + def test_invalid_network(self): |
| 113 | + # Test invalid network name |
| 114 | + is_valid, response = parse_simulation_parameters({"network": "TestNetwork"}) |
| 115 | + self._assert_invalid_param(is_valid, response, "network must be one of") |
| 116 | + |
| 117 | + # Test network as number |
| 118 | + is_valid, response = parse_simulation_parameters({"network": 123}) |
| 119 | + self._assert_invalid_param(is_valid, response, "network must be a string") |
| 120 | + |
| 121 | + def test_invalid_bitrate(self): |
| 122 | + # Test invalid bitrate name |
| 123 | + is_valid, response = parse_simulation_parameters({"bitrate": "TestBitRate"}) |
| 124 | + self._assert_invalid_param(is_valid, response, "bitrate must be one of") |
| 125 | + |
| 126 | + # Test bitrate as number |
| 127 | + is_valid, response = parse_simulation_parameters({"bitrate": 123}) |
| 128 | + self._assert_invalid_param(is_valid, response, "bitrate must be a string") |
| 129 | + |
| 130 | + def _assert_invalid_param(self, is_valid, response, expected_error): |
| 131 | + """Helper method to validate common assertions for invalid parameters""" |
| 132 | + self.assertFalse(is_valid) |
| 133 | + response_json = response[0].json |
| 134 | + self.assertEqual(response_json["status"], "error") |
| 135 | + self.assertEqual(response_json["message"], "Invalid parameters") |
| 136 | + self.assertIn(expected_error, response_json["error"]) |
| 137 | + |
| 138 | + def test_parse_simulation_parameters_valid(self): |
| 139 | + data = { |
| 140 | + "algorithm": "FirstFit", |
| 141 | + "networkType": 1, |
| 142 | + "goalConnections": 10, |
| 143 | + "confidence": 0.05, |
| 144 | + "lambdaParam": 1, |
| 145 | + "mu": 10, |
| 146 | + "network": "NSFNet", |
| 147 | + "bitrate": "fixed-rate", |
| 148 | + "K": 3 |
| 149 | + } |
| 150 | + is_valid, params = parse_simulation_parameters(data) |
| 151 | + self.assertTrue(is_valid) |
| 152 | + self.assertEqual(params, ("FirstFit", 1, 10, 0.05, 1, 10, "NSFNet", "fixed-rate", 3)) |
| 153 | + |
| 154 | + def test_build_simulation_command(self): |
| 155 | + params = ("FirstFit", 1, 10, 0.05, 1, 10, "NSFNet", "fixed-rate", 3) |
| 156 | + command = build_simulation_command(params) |
| 157 | + expected_command = [ |
| 158 | + f"./{SIMULATION_EXECUTABLE}", |
| 159 | + "FirstFit", |
| 160 | + "1", |
| 161 | + "10", |
| 162 | + "0.05", |
| 163 | + "1", |
| 164 | + "10", |
| 165 | + "NSFNet", |
| 166 | + "fixed-rate", |
| 167 | + "3" |
| 168 | + ] |
| 169 | + self.assertEqual(command, expected_command) |
0 commit comments