mirror of
https://github.com/davidalves04/Trabalho-Pratico-SD.git
synced 2025-12-08 12:33:31 +00:00
bullshit fixes
This commit is contained in:
@@ -22,7 +22,8 @@ import sd.protocol.SocketConnection;
|
||||
|
||||
/**
|
||||
* Main class for an Intersection Process in the distributed traffic simulation.
|
||||
* * Each IntersectionProcess runs as an independent Java application (JVM instance)
|
||||
* * Each IntersectionProcess runs as an independent Java application (JVM
|
||||
* instance)
|
||||
* representing one of the five intersections (Cr1-Cr5) in the network.
|
||||
*/
|
||||
public class IntersectionProcess {
|
||||
@@ -41,13 +42,14 @@ public class IntersectionProcess {
|
||||
|
||||
private final ExecutorService trafficLightPool;
|
||||
|
||||
private volatile boolean running; //Quando uma thread escreve um valor volatile, todas as outras
|
||||
//threads veem a mudança imediatamente.
|
||||
private volatile boolean running; // Quando uma thread escreve um valor volatile, todas as outras
|
||||
// threads veem a mudança imediatamente.
|
||||
|
||||
// Traffic Light Coordination
|
||||
/**
|
||||
* Lock to ensure mutual exclusion between traffic lights.
|
||||
* Only one traffic light can be green at any given time within this intersection.
|
||||
* Only one traffic light can be green at any given time within this
|
||||
* intersection.
|
||||
*/
|
||||
private final Lock trafficCoordinationLock;
|
||||
|
||||
@@ -91,7 +93,8 @@ public class IntersectionProcess {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates traffic lights for this intersection based on its physical connections.
|
||||
* Creates traffic lights for this intersection based on its physical
|
||||
* connections.
|
||||
* Each intersection has different number and directions of traffic lights
|
||||
* according to the network topology.
|
||||
*/
|
||||
@@ -101,19 +104,19 @@ public class IntersectionProcess {
|
||||
String[] directions = new String[0];
|
||||
switch (intersectionId) {
|
||||
case "Cr1":
|
||||
directions = new String[]{"East", "South"};
|
||||
directions = new String[] { "East", "South" };
|
||||
break;
|
||||
case "Cr2":
|
||||
directions = new String[]{"West", "East", "South"};
|
||||
directions = new String[] { "West", "East", "South" };
|
||||
break;
|
||||
case "Cr3":
|
||||
directions = new String[]{"West", "South"};
|
||||
directions = new String[] { "West", "South" };
|
||||
break;
|
||||
case "Cr4":
|
||||
directions = new String[]{"East"};
|
||||
directions = new String[] { "East" };
|
||||
break;
|
||||
case "Cr5":
|
||||
directions = new String[]{"East"};
|
||||
directions = new String[] { "East" };
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -125,8 +128,7 @@ public class IntersectionProcess {
|
||||
intersectionId + "-" + direction,
|
||||
direction,
|
||||
greenTime,
|
||||
redTime
|
||||
);
|
||||
redTime);
|
||||
|
||||
intersection.addTrafficLight(light);
|
||||
System.out.println(" Created traffic light: " + direction +
|
||||
@@ -314,8 +316,7 @@ public class IntersectionProcess {
|
||||
MessageProtocol message = new VehicleTransferMessage(
|
||||
intersectionId,
|
||||
nextDestination,
|
||||
vehicle
|
||||
);
|
||||
vehicle);
|
||||
|
||||
connection.sendMessage(message);
|
||||
|
||||
@@ -406,17 +407,29 @@ public class IntersectionProcess {
|
||||
try {
|
||||
Socket clientSocket = serverSocket.accept();
|
||||
|
||||
System.out.println("[" + intersectionId + "] New connection accepted from " +
|
||||
clientSocket.getInetAddress().getHostAddress());
|
||||
|
||||
// Check running flag again before handling - prevents accepting during shutdown
|
||||
if (!running) {
|
||||
clientSocket.close();
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle each connection in a separate thread
|
||||
connectionHandlerPool.submit(() -> handleIncomingConnection(clientSocket));
|
||||
|
||||
} catch (IOException e) {
|
||||
if (running) {
|
||||
// Expected when serverSocket.close() is called during shutdown
|
||||
if (!running) {
|
||||
break; // Normal shutdown
|
||||
}
|
||||
// Unexpected error during normal operation
|
||||
System.err.println("[" + intersectionId + "] Error accepting connection: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming connection from another process.
|
||||
@@ -427,6 +440,9 @@ public class IntersectionProcess {
|
||||
private void handleIncomingConnection(Socket clientSocket) {
|
||||
try (SocketConnection connection = new SocketConnection(clientSocket)) {
|
||||
|
||||
// Set socket timeout so receiveMessage() won't block forever
|
||||
clientSocket.setSoTimeout(1000); // 1 second timeout
|
||||
|
||||
System.out.println("[" + intersectionId + "] New connection accepted from " +
|
||||
clientSocket.getInetAddress().getHostAddress());
|
||||
|
||||
@@ -445,9 +461,16 @@ public class IntersectionProcess {
|
||||
intersection.receiveVehicle(vehicle);
|
||||
}
|
||||
|
||||
} catch (java.net.SocketTimeoutException e) {
|
||||
// Timeout is expected - just check running flag and continue
|
||||
if (!running) {
|
||||
break;
|
||||
}
|
||||
// Continue waiting for next message
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("[" + intersectionId + "] Unknown message type received: " +
|
||||
e.getMessage());
|
||||
break; // Invalid message, close connection
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +478,7 @@ public class IntersectionProcess {
|
||||
if (running) {
|
||||
System.err.println("[" + intersectionId + "] Connection error: " + e.getMessage());
|
||||
}
|
||||
// Expected during shutdown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,44 +490,43 @@ public class IntersectionProcess {
|
||||
System.out.println("\n[" + intersectionId + "] Shutting down...");
|
||||
running = false;
|
||||
|
||||
// Close server socket
|
||||
try {
|
||||
if (serverSocket != null && !serverSocket.isClosed()) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("[" + intersectionId + "] Error closing server socket: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
synchronized (outgoingConnections) {
|
||||
for (SocketConnection conn : outgoingConnections.values()) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
// Ignore errors during shutdown
|
||||
}
|
||||
}
|
||||
outgoingConnections.clear();
|
||||
}
|
||||
|
||||
// Shutdown thread pools
|
||||
trafficLightPool.shutdown();
|
||||
connectionHandlerPool.shutdown();
|
||||
connectionHandlerPool.shutdownNow(); // Use shutdownNow() to interrupt running tasks
|
||||
|
||||
try {
|
||||
if (!trafficLightPool.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||
if (!trafficLightPool.awaitTermination(2, TimeUnit.SECONDS)) {
|
||||
trafficLightPool.shutdownNow();
|
||||
}
|
||||
if (!connectionHandlerPool.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||
if (!connectionHandlerPool.awaitTermination(2, TimeUnit.SECONDS)) {
|
||||
connectionHandlerPool.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
trafficLightPool.shutdownNow();
|
||||
connectionHandlerPool.shutdownNow();
|
||||
}
|
||||
|
||||
// Close all outgoing connections
|
||||
for (Map.Entry<String, SocketConnection> entry : outgoingConnections.entrySet()) {
|
||||
try {
|
||||
entry.getValue().close();
|
||||
} catch (IOException e) {
|
||||
System.err.println("[" + intersectionId + "] Error closing connection to " +
|
||||
entry.getKey() + ": " + e.getMessage());
|
||||
}
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
System.out.println("[" + intersectionId + "] Shutdown complete.");
|
||||
System.out.println("=".repeat(60));
|
||||
System.out.println("=".repeat(60) + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,150 +9,100 @@ import sd.model.Vehicle;
|
||||
/**
|
||||
* Implements the control logic for a single TrafficLight
|
||||
* as a Runnable task that runs in its own Thread.
|
||||
*
|
||||
*/
|
||||
public class TrafficLightThread implements Runnable {
|
||||
|
||||
/**
|
||||
* The TrafficLight object (the *model*) that this thread controls.
|
||||
* Contains the queue and the state.
|
||||
*/
|
||||
private final TrafficLight light;
|
||||
|
||||
/**
|
||||
* The IntersectionProcess (the Process) that "owns" this thread.
|
||||
* Used to call methods on the process, such as sendVehicleToNextDestination().
|
||||
*/
|
||||
private final IntersectionProcess process;
|
||||
|
||||
/**
|
||||
* The simulation configuration, used to get timings (e.g., crossing time).
|
||||
*/
|
||||
private final SimulationConfig config;
|
||||
|
||||
/**
|
||||
* Volatile flag to control the graceful shutdown mechanism.
|
||||
* When set to 'false', the 'run()' loop terminates.
|
||||
*/
|
||||
private volatile boolean running;
|
||||
|
||||
/**
|
||||
* Constructor for the Traffic Light Thread.
|
||||
*
|
||||
* @param light The TrafficLight object (model) to be controlled.
|
||||
* @param process The parent IntersectionProcess (for callbacks).
|
||||
* @param config The simulation configuration (to get timings).
|
||||
*/
|
||||
// Store the thread reference for proper interruption
|
||||
private Thread currentThread;
|
||||
|
||||
public TrafficLightThread(TrafficLight light, IntersectionProcess process, SimulationConfig config) {
|
||||
this.light = light;
|
||||
this.process = process;
|
||||
this.config = config;
|
||||
this.running = false; // Starts as 'stopped'
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main entry point for the thread.
|
||||
* Implements the GREEN/RED cycle logic extracted from IntersectionProcess.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
// Capture the current thread reference
|
||||
this.currentThread = Thread.currentThread();
|
||||
this.running = true;
|
||||
System.out.println("[" + light.getId() + "] Traffic light thread started.");
|
||||
|
||||
try {
|
||||
// Main thread loop, continues while 'running' is true
|
||||
// This 'running' flag is controlled by the parent IntersectionProcess
|
||||
while (running) {
|
||||
while (running && !Thread.currentThread().isInterrupted()) {
|
||||
|
||||
// --- GREEN Phase ---
|
||||
light.changeState(TrafficLightState.GREEN); //
|
||||
light.changeState(TrafficLightState.GREEN);
|
||||
System.out.println("[" + light.getId() + "] State: GREEN");
|
||||
|
||||
// Process vehicles in the queue
|
||||
processGreenLightQueue();
|
||||
|
||||
// Wait for green duration
|
||||
Thread.sleep((long) (light.getGreenTime() * 1000)); //
|
||||
if (!running || Thread.currentThread().isInterrupted()) break;
|
||||
|
||||
if (!running) break; // Check flag after sleep
|
||||
// Wait for green duration
|
||||
Thread.sleep((long) (light.getGreenTime() * 1000));
|
||||
|
||||
if (!running || Thread.currentThread().isInterrupted()) break;
|
||||
|
||||
// --- RED Phase ---
|
||||
light.changeState(TrafficLightState.RED); //
|
||||
light.changeState(TrafficLightState.RED);
|
||||
System.out.println("[" + light.getId() + "] State: RED");
|
||||
|
||||
// Wait for red duration
|
||||
Thread.sleep((long) (light.getRedTime() * 1000)); //
|
||||
|
||||
Thread.sleep((long) (light.getRedTime() * 1000));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Apanha a InterruptedException (outra forma de parar a thread)
|
||||
System.out.println("[" + light.getId() + "] Traffic light thread interrupted.");
|
||||
this.running = false; // Garante que o loop termina
|
||||
}
|
||||
|
||||
// Restore interrupt status
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
this.running = false;
|
||||
System.out.println("[" + light.getId() + "] Traffic light thread stopped.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes vehicles in the queue while the traffic light is GREEN.
|
||||
* Logic extracted from IntersectionProcess.processGreenLight()
|
||||
*
|
||||
*/
|
||||
private void processGreenLightQueue() throws InterruptedException {
|
||||
//
|
||||
while (running && light.getState() == TrafficLightState.GREEN && light.getQueueSize() > 0) {
|
||||
while (running && !Thread.currentThread().isInterrupted()
|
||||
&& light.getState() == TrafficLightState.GREEN
|
||||
&& light.getQueueSize() > 0) {
|
||||
|
||||
Vehicle vehicle = light.removeVehicle(); //
|
||||
Vehicle vehicle = light.removeVehicle();
|
||||
|
||||
if (vehicle != null) {
|
||||
// 1. Get the crossing time (t_sem)
|
||||
double crossingTime = getCrossingTimeForVehicle(vehicle); //
|
||||
double crossingTime = getCrossingTimeForVehicle(vehicle);
|
||||
|
||||
// 2. Simulate the time the vehicle takes to cross
|
||||
Thread.sleep((long) (crossingTime * 1000)); //
|
||||
Thread.sleep((long) (crossingTime * 1000));
|
||||
|
||||
// 3. Update vehicle statistics
|
||||
vehicle.addCrossingTime(crossingTime); //
|
||||
|
||||
// 4. Update intersection statistics
|
||||
|
||||
process.getIntersection().incrementVehiclesSent(); //
|
||||
|
||||
// 5. Call the parent Process to send the vehicle
|
||||
|
||||
process.sendVehicleToNextDestination(vehicle); //
|
||||
vehicle.addCrossingTime(crossingTime);
|
||||
process.getIntersection().incrementVehiclesSent();
|
||||
process.sendVehicleToNextDestination(vehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the crossing time for a vehicle based on its type.
|
||||
* Logic extracted from IntersectionProcess.getCrossingTimeForVehicle()
|
||||
*
|
||||
*
|
||||
* @param vehicle The vehicle.
|
||||
* @return The crossing time in seconds.
|
||||
*/
|
||||
private double getCrossingTimeForVehicle(Vehicle vehicle) {
|
||||
switch (vehicle.getType()) { //
|
||||
case BIKE:
|
||||
return config.getBikeVehicleCrossingTime(); //
|
||||
case LIGHT:
|
||||
return config.getLightVehicleCrossingTime(); //
|
||||
case HEAVY:
|
||||
return config.getHeavyVehicleCrossingTime(); //
|
||||
default:
|
||||
return config.getLightVehicleCrossingTime(); //
|
||||
}
|
||||
return switch (vehicle.getType()) {
|
||||
case BIKE -> config.getBikeVehicleCrossingTime();
|
||||
case LIGHT -> config.getLightVehicleCrossingTime();
|
||||
case HEAVY -> config.getHeavyVehicleCrossingTime();
|
||||
default -> config.getLightVehicleCrossingTime();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the thread to stop gracefully (graceful shutdown).
|
||||
* Sets the 'running' flag to false. The thread will finish
|
||||
* its current sleep cycle and exit the 'run()' loop.
|
||||
* Requests the thread to stop gracefully.
|
||||
* Sets the running flag and interrupts the thread to unblock any sleep() calls.
|
||||
*/
|
||||
public void shutdown() {
|
||||
this.running = false;
|
||||
if (currentThread != null && currentThread.isAlive()) {
|
||||
currentThread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -19,6 +19,7 @@ import sd.IntersectionProcess;
|
||||
import sd.model.MessageType;
|
||||
import sd.model.Vehicle;
|
||||
import sd.model.VehicleType;
|
||||
import sd.protocol.SocketConnection;
|
||||
|
||||
/**
|
||||
* Tests for IntersectionProcess - covers initialization, traffic lights,
|
||||
@@ -187,7 +188,7 @@ public class IntersectionProcessTest {
|
||||
intersectionProcess = new IntersectionProcess("Cr1", configFile.toString());
|
||||
intersectionProcess.initialize();
|
||||
|
||||
// start server in seperate thread
|
||||
// start server in separate thread
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
intersectionProcess.start();
|
||||
@@ -197,13 +198,22 @@ public class IntersectionProcessTest {
|
||||
});
|
||||
serverThread.start();
|
||||
|
||||
Thread.sleep(500); // wait for server to start
|
||||
|
||||
// try connecting to check if its running
|
||||
try (Socket clientSocket = new Socket("localhost", 18001)) {
|
||||
assertTrue(clientSocket.isConnected());
|
||||
// Wait for server to actually start with retries
|
||||
boolean serverReady = false;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Thread.sleep(100);
|
||||
try (Socket testSocket = new Socket()) {
|
||||
testSocket.connect(new java.net.InetSocketAddress("localhost", 18001), 500);
|
||||
serverReady = true;
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
// Server not ready yet, continue waiting
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(serverReady, "Server should start and bind to port 18001");
|
||||
|
||||
// Shutdown immediately after confirming server is running
|
||||
intersectionProcess.shutdown();
|
||||
serverThread.join(2000);
|
||||
}
|
||||
@@ -219,11 +229,17 @@ public class IntersectionProcessTest {
|
||||
cr2.initialize();
|
||||
|
||||
Thread thread1 = new Thread(() -> {
|
||||
try { cr1.start(); } catch (IOException e) { }
|
||||
try {
|
||||
cr1.start();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
|
||||
Thread thread2 = new Thread(() -> {
|
||||
try { cr2.start(); } catch (IOException e) { }
|
||||
try {
|
||||
cr2.start();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
@@ -256,30 +272,32 @@ public class IntersectionProcessTest {
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
intersectionProcess.start();
|
||||
} catch (IOException e) { }
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
serverThread.start();
|
||||
|
||||
Thread.sleep(500);
|
||||
|
||||
// create test vehicle
|
||||
try {
|
||||
// create test vehicle - FIXED: use 4-parameter constructor
|
||||
java.util.List<String> route = Arrays.asList("Cr2", "Cr3", "S");
|
||||
Vehicle vehicle = new Vehicle("V001", VehicleType.LIGHT, 0.0, route);
|
||||
|
||||
// send vehicle from Cr1 to Cr2
|
||||
try (Socket socket = new Socket("localhost", 18002)) {
|
||||
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
|
||||
// send vehicle from Cr1 to Cr2 - FIXED: use SocketConnection
|
||||
try (Socket socket = new Socket("localhost", 18002);
|
||||
SocketConnection conn = new SocketConnection(socket)) {
|
||||
|
||||
TestVehicleMessage message = new TestVehicleMessage("Cr1", "Cr2", vehicle);
|
||||
out.writeObject(message);
|
||||
out.flush();
|
||||
conn.sendMessage(message);
|
||||
|
||||
Thread.sleep(1000); // wait for procesing
|
||||
Thread.sleep(1000); // wait for processing
|
||||
}
|
||||
|
||||
} finally {
|
||||
intersectionProcess.shutdown();
|
||||
serverThread.join(2000);
|
||||
}
|
||||
}
|
||||
|
||||
// routing config tests
|
||||
|
||||
@@ -312,7 +330,8 @@ public class IntersectionProcessTest {
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
intersectionProcess.start();
|
||||
} catch (IOException e) { }
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
serverThread.start();
|
||||
|
||||
@@ -330,30 +349,35 @@ public class IntersectionProcessTest {
|
||||
intersectionProcess = new IntersectionProcess("Cr1", configFile.toString());
|
||||
intersectionProcess.initialize();
|
||||
|
||||
// Start server in separate thread
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
intersectionProcess.start();
|
||||
} catch (IOException e) { }
|
||||
} catch (IOException e) {
|
||||
// Expected on shutdown
|
||||
}
|
||||
});
|
||||
serverThread.start();
|
||||
|
||||
// Wait for server to start
|
||||
Thread.sleep(500);
|
||||
|
||||
// verify server running
|
||||
try (Socket socket = new Socket("localhost", 18001)) {
|
||||
assertTrue(socket.isConnected());
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
intersectionProcess.shutdown();
|
||||
serverThread.join(2000);
|
||||
|
||||
// after shutdown conection should fail
|
||||
Thread.sleep(500);
|
||||
Exception exception = assertThrows(IOException.class, () -> {
|
||||
Socket socket = new Socket("localhost", 18001);
|
||||
socket.close();
|
||||
});
|
||||
assertNotNull(exception);
|
||||
// Give shutdown time to complete
|
||||
Thread.sleep(200);
|
||||
|
||||
// Verify we cannot connect (server socket is closed)
|
||||
boolean connectionFailed = false;
|
||||
try (Socket testSocket = new Socket()) {
|
||||
testSocket.connect(new InetSocketAddress("localhost", 18001), 500);
|
||||
} catch (IOException e) {
|
||||
connectionFailed = true; // Expected - server should be closed
|
||||
}
|
||||
|
||||
assertTrue(connectionFailed, "Server socket should be closed after shutdown");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -365,7 +389,8 @@ public class IntersectionProcessTest {
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
intersectionProcess.start();
|
||||
} catch (IOException e) { }
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
serverThread.start();
|
||||
|
||||
@@ -388,20 +413,34 @@ public class IntersectionProcessTest {
|
||||
@Test
|
||||
@Timeout(15)
|
||||
public void testIntegration_TwoIntersectionsVehicleTransfer() throws IOException, InterruptedException {
|
||||
IntersectionProcess cr1 = null;
|
||||
IntersectionProcess cr2 = null;
|
||||
Thread thread1 = null;
|
||||
Thread thread2 = null;
|
||||
|
||||
try {
|
||||
// setup 2 intersections
|
||||
IntersectionProcess cr1 = new IntersectionProcess("Cr1", configFile.toString());
|
||||
IntersectionProcess cr2 = new IntersectionProcess("Cr2", configFile.toString());
|
||||
cr1 = new IntersectionProcess("Cr1", configFile.toString());
|
||||
cr2 = new IntersectionProcess("Cr2", configFile.toString());
|
||||
|
||||
cr1.initialize();
|
||||
cr2.initialize();
|
||||
|
||||
// start both
|
||||
Thread thread1 = new Thread(() -> {
|
||||
try { cr1.start(); } catch (IOException e) { }
|
||||
final IntersectionProcess cr1Final = cr1;
|
||||
thread1 = new Thread(() -> {
|
||||
try {
|
||||
cr1Final.start();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
|
||||
Thread thread2 = new Thread(() -> {
|
||||
try { cr2.start(); } catch (IOException e) { }
|
||||
final IntersectionProcess cr2Final = cr2;
|
||||
thread2 = new Thread(() -> {
|
||||
try {
|
||||
cr2Final.start();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
@@ -409,25 +448,34 @@ public class IntersectionProcessTest {
|
||||
|
||||
Thread.sleep(1000); // wait for servers
|
||||
|
||||
// send vehicle to Cr1 that goes to Cr2
|
||||
// send vehicle to Cr1 that goes to Cr2 - FIXED: use 4-parameter constructor
|
||||
java.util.List<String> route = Arrays.asList("Cr1", "Cr2", "S");
|
||||
Vehicle vehicle = new Vehicle("V001", VehicleType.LIGHT, 0.0, route);
|
||||
|
||||
try (Socket socket = new Socket("localhost", 18001)) {
|
||||
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
|
||||
// FIXED: use SocketConnection
|
||||
try (Socket socket = new Socket("localhost", 18001);
|
||||
SocketConnection conn = new SocketConnection(socket)) {
|
||||
|
||||
TestVehicleMessage message = new TestVehicleMessage("Entry", "Cr1", vehicle);
|
||||
out.writeObject(message);
|
||||
out.flush();
|
||||
conn.sendMessage(message);
|
||||
|
||||
Thread.sleep(2000); // time for processing
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (cr1 != null) {
|
||||
cr1.shutdown();
|
||||
}
|
||||
if (cr2 != null) {
|
||||
cr2.shutdown();
|
||||
}
|
||||
if (thread1 != null) {
|
||||
thread1.join(2000);
|
||||
}
|
||||
if (thread2 != null) {
|
||||
thread2.join(2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMain_MissingArguments() {
|
||||
|
||||
Reference in New Issue
Block a user