/* * JaamSim Discrete Event Simulation * Copyright (C) 2013 Ausenco Engineering Canada Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jaamsim.basicsim; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import com.jaamsim.events.EventManager; import com.jaamsim.events.EventTraceListener; import com.jaamsim.events.ProcessTarget; import com.jaamsim.input.InputAgent; class EventTracer implements EventTraceListener { private BufferedReader eventVerifyReader; private EventTraceRecord reader; private long bufferTime; // Internal sim time buffer has been filled to private final ArrayList<EventTraceRecord> eventBuffer; public EventTracer(String evtName) { eventBuffer = new ArrayList<>(); bufferTime = 0; File evtFile = new File(evtName); try { eventVerifyReader = new BufferedReader(new FileReader(evtFile)); } catch (FileNotFoundException e) {} if (eventVerifyReader == null) InputAgent.logMessage("Unable to open an event verification file."); reader = new EventTraceRecord(); } private void fillBufferUntil(long internalTime) { while (bufferTime <= internalTime) { // Read a full trace record form the file, terminated at a blank line EventTraceRecord temp = new EventTraceRecord(); while (true) { String line = null; try { line = eventVerifyReader.readLine(); } catch (IOException e) {} if (line == null) break; temp.add(line); if (line.length() == 0) break; } if (temp.size() == 0) break; // Parse the key information from the record temp.parse(); if (temp.isDefaultEventManager() && temp.getInternalTime() > bufferTime) { bufferTime = temp.getInternalTime(); } eventBuffer.add(temp); } } private void findEventInBuffer(EventManager e, EventTraceRecord record) { // Ensure we have read enough from the log to find this record this.fillBufferUntil(record.getInternalTime()); // Try an optimistic approach first looking for exact matches for (EventTraceRecord each : eventBuffer) { if (!each.basicCompare(record)) { continue; } for (int i = 1; i < record.size(); i++) { if (!record.get(i).equals(each.get(i))) { System.out.println("Difference in event stream detected"); System.out.println("Received:"); for (String line : record) { System.out.println(line); } System.out.println("Expected:"); for (String line : each) { System.out.println(line); } System.out.println("Lines:"); System.out.println("R:" + record.get(i)); System.out.println("E:" + each.get(i)); e.pause(); new Throwable().printStackTrace(); break; } } // Found the event, it compared OK, remove from the buffer eventBuffer.remove(each); //System.out.println("Buffersize:" + eventBuffer.size()); return; } System.out.println("No matching event found for:"); for (String line : record) { System.out.println(line); } for (EventTraceRecord rec : eventBuffer) { System.out.println("Buffered Record:"); for (String line : rec) { System.out.println(line); } System.out.println(); } e.pause(); } private void finish(EventManager e) { if (reader.traceLevel != 1) return; reader.add(""); reader.parse(); findEventInBuffer(e, reader); reader.clear(); reader.traceLevel--; } @Override public void traceWait(EventManager e, long curTick, long tick, int priority, ProcessTarget t) { reader.traceWait(e, curTick, tick, priority, t); this.finish(e); } @Override public void traceEvent(EventManager e, long curTick, long tick, int priority, ProcessTarget t) { reader.traceEvent(e, curTick, tick, priority, t); this.finish(e); } @Override public void traceSchedProcess(EventManager e, long curTick, long tick, int priority, ProcessTarget t) { reader.traceSchedProcess(e, curTick, tick, priority, t); this.finish(e); } @Override public void traceProcessStart(EventManager e, ProcessTarget t, long tick) { reader.traceProcessStart(e, t, tick); this.finish(e); } @Override public void traceProcessEnd(EventManager e, long tick) { reader.traceProcessEnd(e, tick); this.finish(e); } @Override public void traceInterrupt(EventManager e, long curTick, long tick, int priority, ProcessTarget t) { reader.traceInterrupt(e, curTick, tick, priority, t); this.finish(e); } @Override public void traceKill(EventManager e, long curTick, long tick, int priority, ProcessTarget t) { reader.traceKill(e, curTick, tick, priority, t); this.finish(e); } @Override public void traceWaitUntil(EventManager e, long tick) { reader.traceWaitUntil(e, tick); this.finish(e); } @Override public void traceWaitUntilEnded(EventManager e, long curTick, ProcessTarget t) { reader.traceWaitUntilEnded(e, curTick, t); this.finish(e); } }