Coverage for utils/helpers.py: 100%
81 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 14:47 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 14:47 +0000
1from utils.config import *
2import subprocess
3import os
4from flask import jsonify
6def compile_simulation(debug=False):
7 """
8 Compiles the C++ simulation executable on startup.
10 Returns:
11 bool: True if compilation succeeds, False otherwise
12 """
13 global COMPILE_ERROR
15 # Clean existing executable
16 if os.path.exists(SIMULATION_EXECUTABLE):
17 logger.info(f"Removing existing executable: {SIMULATION_EXECUTABLE}")
18 os.remove(SIMULATION_EXECUTABLE)
20 # Verify source file exists
21 if not os.path.exists("./src/main.cpp"):
22 COMPILE_ERROR = {
23 "error": "main.cpp not found",
24 "details": "Ensure main.cpp is in the correct directory."
25 }
26 logger.error(f"Compilation failed: {COMPILE_ERROR['error']} - {COMPILE_ERROR['details']}")
27 return False
29 # Run compilation with optimization
30 logger.info("Compiling simulation...")
31 compile_result = subprocess.run(
32 ["g++", "-O3", "-o", SIMULATION_EXECUTABLE, "./src/main.cpp"],
33 capture_output=True,
34 text=True
35 )
36 if compile_result.returncode != 0:
37 COMPILE_ERROR = {
38 "error": "Compilation failed",
39 "details": compile_result.stderr
40 }
41 logger.error(f"Compilation failed: {COMPILE_ERROR['error']} - {COMPILE_ERROR['details']}")
42 return False
44 if debug: COMPILE_ERROR = None
45 logger.info("File compiled successfully")
46 return True
48def validate_simulation_prerequisites():
49 """
50 Validates compilation status and executable existence.
52 Returns:
53 tuple: (is_valid, response) where is_valid is a boolean and
54 response is an optional error response
55 """
56 # Check if compilation failed during startup
57 if COMPILE_ERROR:
58 return False, (jsonify({
59 "status": "error",
60 "message": COMPILE_ERROR["error"],
61 "error": COMPILE_ERROR["details"]
62 }), 500)
64 # Verify executable exists
65 if not os.path.exists(SIMULATION_EXECUTABLE):
66 return False, (jsonify({
67 "status": "error",
68 "message": "Simulation executable not found",
69 "error": "Contact administrator for assistance"
70 }), 500)
72 return True, None
74def parse_simulation_parameters(data):
75 """
76 Parses and validates simulation parameters from request data.
78 Args:
79 data (dict): Request JSON data
81 Returns:
82 tuple: Either (True, parameters) if valid, or (False, error_response) if invalid
83 """
84 # Extract parameters with default values
85 algorithm = data.get("algorithm", "FirstFit")
86 networkType = data.get("networkType", 1)
87 goalConnections = data.get("goalConnections", 100000)
88 confidence = data.get("confidence", 0.05)
89 lambdaParam = data.get("lambdaParam", 1)
90 mu = data.get("mu", 10)
91 network = data.get("network", "NSFNet")
92 bitrate = data.get("bitrate", "fixed-rate")
93 K = data.get("K", 3)
95 # Validate data types
96 if not isinstance(algorithm, str):
97 return False, (jsonify({
98 "status": "error",
99 "message": "Invalid parameters",
100 "error": "algorithm must be a string"
101 }), 400)
102 if not isinstance(networkType, int):
103 return False, (jsonify({
104 "status": "error",
105 "message": "Invalid parameters",
106 "error": "networkType must be an integer"
107 }), 400)
108 if not isinstance(goalConnections, int):
109 return False, (jsonify({
110 "status": "error",
111 "message": "Invalid parameters",
112 "error": "goalConnections must be an integer"
113 }), 400)
114 if not isinstance(confidence, (int, float)):
115 return False, (jsonify({
116 "status": "error",
117 "message": "Invalid parameters",
118 "error": "confidence must be a number"
119 }), 400)
120 if not isinstance(lambdaParam, (int, float)):
121 return False, (jsonify({
122 "status": "error",
123 "message": "Invalid parameters",
124 "error": "lambdaParam must be a number"
125 }), 400)
126 if not isinstance(mu, (int, float)):
127 return False, (jsonify({
128 "status": "error",
129 "message": "Invalid parameters",
130 "error": "mu must be a number"
131 }), 400)
132 if not isinstance(network, str):
133 return False, (jsonify({
134 "status": "error",
135 "message": "Invalid parameters",
136 "error": "network must be a string"
137 }), 400)
138 if not isinstance(bitrate, str):
139 return False, (jsonify({
140 "status": "error",
141 "message": "Invalid parameters",
142 "error": "bitrate must be a string"
143 }), 400)
144 if not isinstance(K, int):
145 return False, (jsonify({
146 "status": "error",
147 "message": "Invalid parameters",
148 "error": "K must be an integer"
149 }), 400)
151 # Validate networkType
152 if networkType != 1:
153 return False, (jsonify({
154 "status": "error",
155 "message": "Invalid parameters",
156 "error": "At the moment only networkType 1 is supported"
157 }), 400)
159 # Validate goalConnections
160 if goalConnections > 10000000:
161 return False, (jsonify({
162 "status": "error",
163 "message": "Invalid parameters",
164 "error": "goalConnections must be less than 10,000,000"
165 }), 400)
166 elif goalConnections < 1:
167 return False, (jsonify({
168 "status": "error",
169 "message": "Invalid parameters",
170 "error": "goalConnections must be greater than 0"
171 }), 400)
173 # Validate K
174 if K > 6:
175 return False, (jsonify({
176 "status": "error",
177 "message": "Invalid parameters",
178 "error": "Max K is 6"
179 }), 400)
180 elif K < 1:
181 return False, (jsonify({
182 "status": "error",
183 "message": "Invalid parameters",
184 "error": "Min K is 1"
185 }), 400)
187 # Validate confidence
188 if confidence >= 1 or confidence <= 0:
189 return False, (jsonify({
190 "status": "error",
191 "message": "Invalid parameters",
192 "error": "confidence must be between 0 and 1"
193 }), 400)
195 # Validate lambda
196 if lambdaParam <= 0:
197 return False, (jsonify({
198 "status": "error",
199 "message": "Invalid parameters",
200 "error": "lambdaParam must be greater than 0"
201 }), 400)
203 # Validate mu
204 if mu <= 0:
205 return False, (jsonify({
206 "status": "error",
207 "message": "Invalid parameters",
208 "error": "mu must be greater than 0"
209 }), 400)
211 # Validate algorithm
212 if algorithm not in ["FirstFit", "BestFit"]:
213 return False, (jsonify({
214 "status": "error",
215 "message": "Invalid parameters",
216 "error": "algorithm must be FirstFit or BestFit"
217 }), 400)
219 # Validate network
220 if network not in valid_networks:
221 return False, (jsonify({
222 "status": "error",
223 "message": "Invalid parameters",
224 "error": f"network must be one of: {', '.join(valid_networks)}"
225 }), 400)
227 # Validate bitrate
228 if bitrate not in valid_bitrates:
229 return False, (jsonify({
230 "status": "error",
231 "message": "Invalid parameters",
232 "error": f"bitrate must be one of: {', '.join(valid_bitrates)}"
233 }), 400)
235 # All parameters are valid, return the parameter tuple
236 return True, (algorithm, networkType, goalConnections, confidence,
237 lambdaParam, mu, network, bitrate, K)
239def build_simulation_command(params):
240 """
241 Builds command for simulation process.
243 Args:
244 params (tuple): Simulation parameters
246 Returns:
247 list: Command list for subprocess
248 """
249 algorithm, networkType, goalConnections, confidence, lambdaParam, mu, network, bitrate, K = params
251 return [
252 f"./{SIMULATION_EXECUTABLE}",
253 str(algorithm),
254 str(networkType),
255 str(goalConnections),
256 str(confidence),
257 str(lambdaParam),
258 str(mu),
259 str(network),
260 str(bitrate),
261 str(K)
262 ]