Java tutorial
/* ###################################################################################### ## ## ## (c) 2006-2012 Cable Television Laboratories, Inc. All rights reserved. Any use ## ## of this documentation/package is subject to the terms and conditions of the ## ## CableLabs License provided to you on download of the documentation/package. ## ## ## ###################################################################################### */ package com.cablelabs.sim; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.ConcurrentModificationException; import java.util.Date; import java.util.Enumeration; import java.util.LinkedList; import java.util.ListIterator; import java.util.Properties; import org.apache.commons.net.tftp.TFTP; import org.apache.commons.net.tftp.TFTPClient; import org.xml.sax.SAXParseException; import com.cablelabs.common.Conversion; import com.cablelabs.common.Transport; import com.cablelabs.fsm.Extension; import com.cablelabs.fsm.FSM; import com.cablelabs.fsm.InternalMsg; import com.cablelabs.fsm.MsgQueue; import com.cablelabs.fsm.MsgRef; import com.cablelabs.fsm.NetworkElements; import com.cablelabs.fsm.PC2Exception; import com.cablelabs.fsm.PresenceModel; import com.cablelabs.fsm.ProvDatabase; import com.cablelabs.fsm.ProvListener; import com.cablelabs.fsm.ProvisioningData; import com.cablelabs.fsm.RecordProvFileListener; import com.cablelabs.fsm.SettingConstants; import com.cablelabs.fsm.SystemSettings; import com.cablelabs.gui.PC2PlatformControls; import com.cablelabs.gui.PC2Result; import com.cablelabs.gui.PC2UI; import com.cablelabs.log.LogAPIConfig; import com.cablelabs.log.PC2LogCategory; import com.cablelabs.log.LogAPI; import com.cablelabs.models.GlobalRegistrar; import com.cablelabs.models.PC2Models; import com.cablelabs.models.PresenceServer; import com.cablelabs.models.Register; import com.cablelabs.models.Registrar; import com.cablelabs.models.Session; import com.cablelabs.models.Stun; import com.cablelabs.parser.PC2XMLException; import com.cablelabs.parser.TSDocument; import com.cablelabs.parser.TSParser; import com.cablelabs.provgen.ProvGen; /** * This is the initial entry class for the PC 2.0 * Test Script Platform. It reads in a test script * document, parses the information. Reads the * platform and DUT configuration files and executes * the test. * * It is in charge of terminating all of the * threads and protocol stacks when a fatal error has * been detected. * * @author ghassler * */ public class PCSim2 implements PC2PlatformControls { /** * The container class for all of the configuration * parameters to be used during the test */ protected static SystemSettings ss = null; /** * Logger */ protected static final LogAPI logger; static { if (LogAPI.isConfigured()) { logger = LogAPI.getInstance(); } else { LogAPIConfig config = new LogAPIConfig().setCategoryClass(PC2LogCategory.class).setLogPrefix("PCSim2_"); logger = LogAPI.getInstance(config); } } /** * The current Test Script document to execute. */ protected static TSDocument doc = null; /** * Global test result for this test case. */ protected static Boolean testPassed = null; /** * A handle to the SIP Stack to notify it when * to shutdown */ protected SIPDistributor dist = null; /** A handle to the Stun Stack to notify it when * to shutdown. */ protected StunDistributor stun = null; /** * The protocol stacks container class */ protected static Stacks stacks = null; /** * A flag indicating a specific test pair is * complete. * */ private static boolean complete = false; /** * A flag indicating that the system should shutdown */ private static boolean shutdown = false; /** * The global message queue used for comparison and * analysis by the FSMs. */ private static MsgQueue q = MsgQueue.getInstance(); /** * Name of the platform settings file to use while executing the * batch of DUT configuration file(s) and Test Script file(s). * */ private static String platformSettingsFile = null; /** * The pending platform settings file to use */ private String pendingPSFile = null; /** * The time the platformSettingsFile was last modified */ private long psLastModified = 0; /** * List of DUT configuration files to use execute this batch of * tests. */ private LinkedList<String> dutConfigFiles = new LinkedList<String>(); /** * List of Test Script files to use execute this batch of * tests. */ private LinkedList<String> testScriptFiles = new LinkedList<String>(); /** * This flag specifies whether the dut configuration files * are the primary looping mechanism for conducting the tests * or the test scripts. */ private boolean dutPrimary = true; /** * The active DUT Configuration file being used to execute * the active test script file. */ private static String activeDUTFile = null; /** * The active test script currently being executed by the * platform */ private static String activeTestScriptFile = null; /** * A flag indicating whether global registrar is enabled during * the tests or not. */ private boolean globalRegEnabled = false; /** * The XML document to use for the global registrar when enabled. */ private String globalRegFile = null; /** * A flag indicating whether presence server is enabled during * the tests or not. */ private boolean presenceServerEnabled = false; /** * The XML document to use for the presence server when enabled. */ private String presenceServerFile = null; /** * This is the graphical user interface for the PCSim2 platform. * */ private static PC2UI ui = null; /** * This container has all of the policy and provisioning scripts * that the platform should use when conducting a test. */ private static ProvDatabase provDB = null; /** * This flag indicates that the device was auto provisioned and * doesn't need to be rebooted during the script execution. * */ private static boolean autoProvisioned = false; /** * A list of the currently active Models that are performing * the test. Global Registrar models are not currently in * this list. */ private LinkedList<PC2Models> activeModels = new LinkedList<PC2Models>(); /** * A list of DUT configuration files to add to the global registrar for * processing. The UI adds files to the list and the main thread reads * entries from the list, loads the configuration into the SystemSettings * class. */ private LinkedList<File> dutConfigsToRead = new LinkedList<File>(); /** * A list of DUT configuration files to remove from the global registrar. The * UI adds files to the list and the main thread reads the entries in the * list and removes them from SystemSettings and terminates any FSMs that * may have started as a result. * */ private LinkedList<File> dutConfigsToRemove = new LinkedList<File>(); /** * This is a flag indicating that the close button for the batch file * has been pressed by the user. */ private boolean closeBatchFile = false; /** * The subcategory to use when logging */ private static String subCat = ""; /** * The sub-directory under the logs directory to store provisioning file information. */ private static String PROV_FILE_DIRECTORY = "prov_files"; /** * Store the main thread created once the class starts so that we can send any interrupts * when a test completes. * */ private static Thread mainThread = null; /** * Constructor. * */ public PCSim2() { } @Override public boolean addDUTConfig(File f) { if (f.exists() && f.canRead() && f.isFile()) { synchronized (dutConfigsToRead) { dutConfigsToRead.add(f); } logger.debug(PC2LogCategory.Parser, subCat, "Adding client defined by " + f.getName() + " to list of accepted clients for global registrar"); return true; } else { String reason = validateFile(f.getAbsolutePath()); logger.warn(PC2LogCategory.Parser, subCat, "Couldn't process DUT configuration for global registrar because " + reason); } return false; } /** * This method locates any UEs that may need to be updated and added to the * registrar settings. * */ private void addRegistrarClients() { if (globalRegEnabled) { Enumeration<String> keys = SystemSettings.getPlatformLabels(); if (keys != null) { while (keys.hasMoreElements()) { String key = keys.nextElement(); if (key.startsWith("UE") && !key.contains("@")) { Properties ue = SystemSettings.getSettings(key); String sim = ue.getProperty(SettingConstants.SIMULATED); if (sim != null && (sim.equalsIgnoreCase("false") || sim.equalsIgnoreCase("no") || sim.equalsIgnoreCase("disable"))) { Properties p = SystemSettings.getSettings(key); LinkedList<String> puis = createRegistrarLabels(p); Stacks.addSIPRegistrarClient(key, puis); } } } } } } /** * This method determines if the provisioning file used to conduct a test needs to * be generated from one of the templates prior to starting the test. * @return - the MAC address used for the name of the file */ private String autoGenerate(ProvisioningData pd) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); Properties dut = SystemSettings.getSettings(SettingConstants.DUT); if (pd != null && platform != null && dut != null) { String pcscfLabel = dut.getProperty(SettingConstants.PCSCF); String macAddr = dut.getProperty(SettingConstants.MAC_ADDRESS); String tftpIP = platform.getProperty(SettingConstants.TFTP_SERVER_IP); String tftpPort = platform.getProperty(SettingConstants.TFTP_SERVER_PORT); String phone1 = dut.getProperty(SettingConstants.PHONE_NUMBER_1); String phone2 = dut.getProperty(SettingConstants.PHONE_NUMBER_2); String cw = platform.getProperty(SettingConstants.CW_NUMBER); if (macAddr != null && pcscfLabel != null && tftpIP != null && tftpPort != null && cw != null) { // First see if we have already issued a generated file. if (!provDB.issued(macAddr, pd)) { // Next verify the port is not set to zero try { int port = Integer.parseInt(tftpPort); if (port > 0 && port <= 65535) { // Next make sure the TFTP Server IP is not set to 0.0.0.0 if (tftpIP.equals("0.0.0.0")) { logger.warn(PC2LogCategory.PCSim2, subCat, "The TFTP Server IP setting in the platform file is not valid. Ending auto generate operation."); return null; } File input = new File(SettingConstants.AUTO_PROV_FILE_DIRECTORY + File.separator + SettingConstants.CW + cw + File.separator + pd.getProvFileName()); if (input != null) { ProvGen pg = new ProvGen(input); if (phone1 != null) pg.changePhoneNum(SettingConstants.AUTO_GENERATE_PHONE_NUMBER_1, phone1); if (phone2 != null) pg.changePhoneNum(SettingConstants.AUTO_GENERATE_PHONE_NUMBER_2, phone2); Properties pcscf = SystemSettings.getSettings(pcscfLabel); if (pcscf != null) { String pcscfIP = pcscf.getProperty(SettingConstants.IP); if (pcscfIP != null) pg.changePCSCF(pcscfIP); } String newFileName = macAddr + ".bin"; if (pg.output(SettingConstants.AUTO_PROV_FILE_DIRECTORY + File.separator + SettingConstants.CW + cw + File.separator + newFileName)) { // Test system //File output = new File(SettingConstants.AUTO_PROV_FILE_DIRECTORY + newFileName); //File pact = new File(SettingConstants.AUTO_PROV_FILE_DIRECTORY + "chinmaya_base_ph1_pcscf.bin"); //pg.compare(pact, output); // Create a data entry of the issued event //ProvisioningData issuePD = new ProvisioningData(macAddr, pd.getPolicyFileName(), newFileName); logger.info(PC2LogCategory.PCSim2, subCat, "Beginning to TFTP the new provisioning file."); provDB.setIssuedData(macAddr, pd); // Next we need to TFTP the file to the server TFTPClient client = new TFTPClient(); File binFile = new File( SettingConstants.AUTO_PROV_FILE_DIRECTORY + File.separator + SettingConstants.CW + cw + File.separator + newFileName); if (binFile.isFile() && binFile.canRead()) { FileInputStream istrm = new FileInputStream(binFile); //InetAddress ia = InetAddress.getByName("10.4.1.37"); client.open(); // client.open(20003, ia); client.sendFile(newFileName, TFTP.BINARY_MODE, istrm, tftpIP, port); client.close(); logger.info(PC2LogCategory.PCSim2, subCat, "TFTP of the new provisioning file is complete."); return macAddr; } else { logger.warn(PC2LogCategory.PCSim2, subCat, "The " + macAddr + ".bin doesn't appear in the " + SettingConstants.AUTO_PROV_FILE_DIRECTORY + File.separator + SettingConstants.CW + cw + " Ending auto generate operation."); } } else { logger.error(PC2LogCategory.PCSim2, subCat, "PCSim2 could not locate provisioning template file[" + input.getAbsolutePath() + "]."); } } // else { // logger.info(PC2LogCategory.PCSim2, subCat, "Auto provisioning is terminating because the input directory is null."); // } } else { logger.info(PC2LogCategory.PCSim2, subCat, "Auto provisioning is terminating because the port(" + port + ") is less than 0 or greater than 65535."); } } catch (NumberFormatException nfe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "TFTP Server Port setting doesn't appear to be a number."); } catch (UnknownHostException uhe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "system encountered an error when attempting to send the file to the TFTP Server.\n" + uhe.getMessage() + "\n" + uhe.getStackTrace()); } catch (IOException ioe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "system encountered an error when attempting to send the file to the TFTP Server.\n" + ioe.getMessage() + "\n" + ioe.getStackTrace()); } } else { logger.info(PC2LogCategory.PCSim2, subCat, "Auto provisioning detected the same same provisioning template is already in use, skipping operation."); } } else { logger.info(PC2LogCategory.PCSim2, subCat, "Auto provisioning is stopping because one of the values is null.\n" + "macAddr=" + macAddr + " pcscfLabel=" + pcscfLabel + " tftpIP=" + tftpIP + " tftpPort=" + tftpPort); } } else { if (pd != null) logger.info(PC2LogCategory.PCSim2, subCat, "The provisioning data is null, terminating processing."); if (platform != null) logger.info(PC2LogCategory.PCSim2, subCat, "The Platform settings is null, terminating processing."); if (dut != null) logger.info(PC2LogCategory.PCSim2, subCat, "The DUT settings is null, terminating processing."); } return null; } /** * This method determines if any provisioning needs to take place for the * test prior to the beginning of the execution. * @return */ private ProvisioningData autoProvision(String testCase) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); Properties dut = SystemSettings.getSettings(SettingConstants.DUT); if (platform != null && dut != null) { String deviceType = dut.getProperty(SettingConstants.DEVICE_TYPE); boolean autoProv = SystemSettings .resolveBooleanSetting(platform.getProperty(SettingConstants.AUTO_PROVISION)); if (autoProv && deviceType.equals(SettingConstants.UE)) { // Now that we know we are testing a UE and auto provisioning is // active, see if we have the policy and provisioning files for the // DUT ProvisioningData pd = provDB.getData(testCase); if (pd != null) { logger.info(PC2LogCategory.PCSim2, subCat, "Using the policy and provisioning file for the DUT to " + pd.getPolicyFileName() + " and " + pd.getProvFileName() + " respectively."); return pd; } } } return null; } public static boolean autoProvisionedDevice() { //Only allow the value to be obtained once boolean result = autoProvisioned; logger.debug(PC2LogCategory.PCSim2, subCat, "Returning " + autoProvisioned + " for auto provisioned reboot flag."); autoProvisioned = false; return result; } /** * This method creates a list of the various alias labels that are used for * the registrar processing by the application for the various DUTs that * may attempt to register. * * @param p - the properties class for the network element * @return */ private static LinkedList<String> createRegistrarLabels(Properties p) { String pui = p.getProperty(SettingConstants.PUI); String pui2 = p.getProperty(SettingConstants.PUI2); LinkedList<String> puis = new LinkedList<String>(); if (pui != null) puis.add(pui); if (pui2 != null) puis.add(pui2); return puis; } /** * This method is invoked when the user closes a batch file. * It causes the platform to remove all of the test scripts * and configuration files from the system. It also causes all * of the registrar settings to be cleared. */ @Override public void closeBatch() { closeBatchFile = true; } /** * This method determines whether the global registration needs to be started * */ private boolean configGlobalRegistrar() { globalRegEnabled = SystemSettings.getBooleanSetting("Global Registrar"); if (globalRegEnabled) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); String grName = platform.getProperty(SettingConstants.GLOBAL_REGISTRAR_FSM); if (globalRegFile == null) { globalRegFile = grName; } else if (globalRegFile.equals(grName)) { return true; } else { if (stacks != null) stacks.shutdownGlobalRegistrars(); globalRegFile = grName; } if (globalRegFile != null) { File gr = new File(globalRegFile); if (gr != null && gr.exists() && gr.canRead() && gr.isFile()) { TSParser tsp = new TSParser(false); try { logger.info(PC2LogCategory.Parser, subCat, "Parsing document " + globalRegFile + " for GlobalRegistrar processing."); TSDocument grDoc = tsp.parse(globalRegFile); LinkedList<FSM> fsms = grDoc.getFsms(); if (fsms.size() == 1) { // Initialize the settings that can be overwritten from // within the document setExtensions(fsms); FSM grFsm = fsms.getFirst(); String transport = grFsm.getModel().getProperty(SettingConstants.TRANSPORT_PROTOCOL); Transport t = Transport.UDP; if (transport != null) { if (transport.equals(Transport.UDP.toString())) t = Transport.UDP; else if (transport.equals(Transport.TCP.toString())) t = Transport.TCP; else if (transport.equals(Transport.TLS.toString())) t = Transport.TLS; } else { if (platform != null) { transport = platform.getProperty(SettingConstants.SIP_DEF_TRANPORT_PROTOCOL); if (transport != null) { if (transport.equals(Transport.UDP.toString())) t = Transport.UDP; else if (transport.equals(Transport.TCP.toString())) t = Transport.TCP; else if (transport.equals(Transport.TLS.toString())) t = Transport.TLS; } } } GlobalRegistrar.setMasterFSM(grFsm, t); return true; } } catch (PC2XMLException pe) { String err = "\n** Parsing error in file \n " + pe.getFileName() + " at line " + pe.getLineNumber(); if (pe.getSystemId() != null) { err += ", uri " + pe.getSystemId(); } if (pe.getPublicId() != null) { err += ", public " + pe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, pe); } catch (SAXParseException spe) { String err = "\n** Parsing error in file \n " + globalRegFile + " at line " + spe.getLineNumber(); if (spe.getSystemId() != null) { err += ", uri " + spe.getSystemId(); } if (spe.getPublicId() != null) { err += ", public " + spe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, spe); } catch (Exception e) { e.printStackTrace(); } } else { // if (gr == null) { // logger.fatal(PC2LogCategory.Parser, subCat, // "The platform configuration file doesn't appear to have a " // + "value for the \"Global Registrar FSM\" setting."); // } if (!gr.exists()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Global Registrar FSM\" setting=[" + gr + "] doesn't appear to define a valid path or file name."); } if (!gr.canRead()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Global Registrar FSM\" setting=[" + gr + "] can not be read by the system."); } if (!gr.isFile()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Global Registrar FSM\" setting=[" + gr + "] doesn't appear to define a file."); } } } } return false; } /** * This method determines whether the global presence server needs to be started * */ private boolean configPresenceServer() { presenceServerEnabled = SystemSettings.getBooleanSetting("Presence Server"); if (presenceServerEnabled) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); String psName = platform.getProperty(SettingConstants.PRESENCE_SERVER_FSM); if (presenceServerFile == null) { presenceServerFile = psName; } else if (presenceServerFile.equals(psName)) { return true; } else { if (stacks != null) stacks.shutdownPresenceServer(); presenceServerFile = psName; } if (presenceServerFile != null) { File ps = new File(presenceServerFile); if (ps != null && ps.exists() && ps.canRead() && ps.isFile()) { TSParser tsp = new TSParser(false); try { logger.info(PC2LogCategory.Parser, subCat, "Parsing document " + presenceServerFile + " for PresenceServer processing."); TSDocument psDoc = tsp.parse(presenceServerFile); LinkedList<FSM> fsms = psDoc.getFsms(); if (fsms.size() == 1) { FSM f = fsms.getFirst(); if (f.getModel() instanceof PresenceModel) { PresenceModel model = (PresenceModel) f.getModel(); // Initialize the settings that can be overwritten from // within the document setExtensions(fsms); PresenceServer server = PresenceServer.getInstance(f, model.getElements()); if (server != null) { Stacks.setPresenceServer(server); server.init(); return true; } } } } catch (PC2XMLException pe) { String err = "\n** Parsing error in file \n " + pe.getFileName() + " at line " + pe.getLineNumber(); if (pe.getSystemId() != null) { err += ", uri " + pe.getSystemId(); } if (pe.getPublicId() != null) { err += ", public " + pe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, pe); } catch (SAXParseException spe) { String err = "\n** Parsing error in file \n " + presenceServerFile + " at line " + spe.getLineNumber(); if (spe.getSystemId() != null) { err += ", uri " + spe.getSystemId(); } if (spe.getPublicId() != null) { err += ", public " + spe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, spe); } catch (Exception e) { e.printStackTrace(); } } else { // if (ps == null) { // logger.fatal(PC2LogCategory.Parser, subCat, // "The platform configuration file doesn't appear to have a " // + "value for the \"Presence Server FSM\" setting."); // } if (!ps.exists()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Presence Server FSM\" setting=[" + ps + "] doesn't appear to define a valid path or file name."); } if (!ps.canRead()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Presence Server FSM\" setting=[" + ps + "] can not be read by the system."); } if (!ps.isFile()) { logger.fatal(PC2LogCategory.Parser, subCat, "The \"Presence Server FSM\" setting=[" + ps + "] doesn't appear to define a file."); } } } } return false; } /** * Displays the current results state for a test pair */ public static void displayResults() { if (isGUIActive() && activeDUTFile != null && activeTestScriptFile != null) { PC2Result r = PC2Result.TESTING; if (complete) { if (testPassed == null || testPassed) r = PC2Result.PASSED; else r = PC2Result.FAILED; } ui.setTestResults(r, ss.getCurrentRunNumber(), activeTestScriptFile, activeDUTFile); } } /** * This method performs the actual task of starting the test * and waiting for it to complete. * */ private void executeTest() { // First of all make sure that the we reset the // complete flag before starting the test complete = false; testPassed = null; File dut = new File(activeDUTFile); String[] settingChanges = ss.setDUTProperties(dut.getAbsolutePath()); if (settingChanges == null) { logger.fatal(PC2LogCategory.Parser, subCat, "DUTConfiguration property information could not be found and loaded."); setTestPassed(false); setTestComplete(); } else { stacks.updateRegistrarDisplay(settingChanges); boolean parsed = parseAndStart(); // Before starting test log if the Global Registrar is running or not. if (globalRegEnabled) { logger.info(PC2LogCategory.PCSim2, subCat, "The global registrar is enabled."); } else logger.info(PC2LogCategory.PCSim2, subCat, "The global registrar is disabled."); if (activeModels.size() > 0 && parsed) { ui.startingTest(ss.getCurrentRunNumber(), activeTestScriptFile, activeDUTFile); logger.info(PC2LogCategory.LOG_MSG, "", "Commencing test \"" + activeTestScriptFile + "\" for DUT \"" + activeDUTFile + "\"."); while (!complete) { try { Thread.sleep(250); } catch (InterruptedException ie) { } catch (Exception e) { String err = "Simulator failed to sleep. Terminating test."; logger.fatal(PC2LogCategory.Parser, subCat, err, e); setTestPassed(false); setTestComplete(); } } // Determine if we are using the new validation or not boolean useValidate = doc.useValidate(); if (useValidate) { if (testPassed == null) testPassed = doc.validateTest(); else testPassed &= doc.validateTest(); } else if (testPassed == null) testPassed = true; // Document the test results // Use the logMsg category to insure that the information // is displayed if (testPassed) { logger.info(PC2LogCategory.LOG_MSG, subCat, "Test \"" + doc.getName() + "\" Passed.\n" + ((useValidate) ? doc.getTestStats() : "") + logger.dumpLogStats()); } else logger.info(PC2LogCategory.LOG_MSG, subCat, "Test \"" + doc.getName() + "\" Failed.\n" + ((useValidate) ? doc.getTestStats() : "") + logger.dumpLogStats()); displayResults(); generateResults(doc); } else { setTestPassed(false); String err = "PCSim2 failed to parse the script or there were no models to conduct the test." + "Terminating test. Declaring test case failure."; logger.fatal(PC2LogCategory.Model, subCat, err); setTestComplete(); displayResults(); if (doc != null) generateResults(doc); } } // Now clean up for the next test ss.reset(); Stacks.reset(); doc = null; autoProvisioned = false; logger.debug(PC2LogCategory.PCSim2, subCat, "Resetting the auto provisioned reboot flag to " + autoProvisioned + "."); // We need to clear the message queue of any // models that only exist for the length of the // test. Information in a global model should // remain for operations that could occur between // tests, eg. registrar ListIterator<PC2Models> iter = activeModels.listIterator(); LinkedList<Integer> fsmUIDs = new LinkedList<Integer>(); while (iter.hasNext()) { PC2Models model = iter.next(); fsmUIDs.add(model.getFsmUID()); } if (!fsmUIDs.isEmpty()) q.reset(fsmUIDs); if (activeModels != null) { activeModels.clear(); } logger.clear(); } /** * Initializes and executes the test defined by the * file in the arguments. * * @param args - the fully-qualified name of the test * script document. */ public void init(String[] args) { PCSim2.ui = new PC2UI(this); if (logger == null) { System.out.println("LogAPI failed to create application log file. GLH PC2UI.vendor"); setTestComplete(); return; } else { // This is a hack to get the console's background color to be white // from the minute the window is launched System.out.println("\t" + PC2UI.vendor + " PCSim2 v." + PC2UI.version + " " + PC2UI.build + " " + " " + " " + " \n\t"); } if (ui != null) { ss = SystemSettings.getInstance(); PC2UI.init(); } // GLH - This operation is deprecated since we are not going to support headless system. // else if (processArgs(args)) { // // ss = SystemSettings.getInstance(); // if (!ss.loadPlatformSettings(platformSettingsFile)) { // logger.fatal(PC2LogCategory.Parser, subCat, // "PCSim2 encountered error while trying to read the Platform Settings information."); // setTestPassed(false); // setTestComplete(); // //shutdown(); // return; // } // else { // startServers(); // } // // String neLabel = ss.loadDUTSettings(dutConfigFiles.getFirst(), false, false); // if (neLabel == null) { // logger.fatal(PC2LogCategory.Parser, subCat, // "PCSim2 encountered error while trying to read the DUT Configuration information."); // setTestPassed(false); // setTestComplete(); // //shutdown(); // } // // //dist = new SIPDistributor(); // //dist.init(); // } // dist.test(); // if (parse()) { // run(); // //dist.test(); // } // else // shutdown(); // } // else // shutdown(); run(); } @Override public void injectUserEvent(String fsm, String event) { if (fsm != null && event != null) { ListIterator<PC2Models> iter = activeModels.listIterator(); boolean found = false; if (iter.hasNext()) { while (iter.hasNext() && !found) { PC2Models m = iter.next(); if (m.getFSMName().equals(fsm)) { found = true; InternalMsg msg = new InternalMsg(m.getFsmUID(), System.currentTimeMillis(), LogAPI.getSequencer(), event); boolean success = m.processEvent(msg); if (success) { logger.info(PC2LogCategory.PCSim2, subCat, "Delivered user event(" + event + ") to FSM(" + fsm + ").\n"); } else { logger.warn(PC2LogCategory.PCSim2, subCat, "Failed delivering user event(" + event + ") to FSM(" + fsm + ") because FSM is null.\n"); } } } } else { logger.warn(PC2LogCategory.PCSim2, subCat, "Failed delivering user event(" + event + ") to FSM(" + fsm + ") because there are no active FSM(s) running.\n"); } } else { if (fsm == null) logger.warn(PC2LogCategory.PCSim2, subCat, "Could not deliver user event(" + event + ") to FSM(" + fsm + ") because FSM is null.\n"); if (event == null) logger.warn(PC2LogCategory.PCSim2, subCat, "Could not deliver user event(" + event + ") to FSM(" + fsm + ") because event is null.\n"); } } /** * This method creates the T.I.M results file for the a specific * test case. */ private void generateResults(TSDocument doc) { String fileName = doc.getLogFileName(); int index = fileName.lastIndexOf("_ss.log"); String timFileName = fileName.substring(0, index) + "_ss.res"; File tim = new File(timFileName); if (!tim.exists()) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); Properties dut = SystemSettings.getSettings("DUT"); try { FileOutputStream output = null; if (tim.createNewFile()) { output = new FileOutputStream(tim); } else { output = new FileOutputStream((timFileName + "_" + System.currentTimeMillis())); } String testerName = platform.getProperty(SettingConstants.TESTER_NAME); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Date stop = new Date(); String cw = platform.getProperty(SettingConstants.CW_NUMBER); if (!cw.startsWith("CW")) cw = "CW" + cw; String result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<res-document xmlns=\"http://cablelabs.com/TEPResultDocument\" version=\"1.0\">\n\t" + "<execution method=\"automatic\" start=\"" + sdf.format(doc.getStart()) + "\" stop=\"" + sdf.format(stop) + "\" />\n\t" + "<tester username=\"" + testerName + "\" />\n\t" + "<certwave name=\"" + cw + "\" />\n\t" + "<test-result type=\"" + platform.getProperty(SettingConstants.DUT_SUBGROUP) + "\" name=\"" + doc.getNumber() + "\"\n\tproduct=\"" + dut.getProperty(SettingConstants.DUT_VENDOR) + "\" result=\"" + ((testPassed == null || testPassed) ? "PASS" : "FAIL") + "\"\n\tunit=\"" + dut.getProperty(SettingConstants.PRODUCT_UNIT) + "\"/>\n" + "</res-document>"; if (output != null) { output.write(result.getBytes()); output.close(); } // else // logger.fatal(PC2LogCategory.Parser, subCat, // "Couldn't write TIM file! Writing to log file for preservation!\n" + result); } catch (IOException ioe) { logger.error(PC2LogCategory.Parser, subCat, "Could not create new TIM file[" + timFileName + "]."); } String tftpIP = platform.getProperty(SettingConstants.TFTP_SERVER_IP); String tftpPort = platform.getProperty(SettingConstants.TFTP_SERVER_PORT); if (tftpIP != null && tftpPort != null) { boolean recProv = SystemSettings .resolveBooleanSetting(platform.getProperty(SettingConstants.RECORD_PROVISIONING_FILE)); if (recProv && dut != null) try { RecordProvFileListener rpfl = new RecordProvFileListener(); boolean success = rpfl.run(); String provFile = rpfl.getValue(); if (success) { int port = Integer.parseInt(tftpPort); if (port > 0 && port <= 65535) { // Next make sure the TFTP Server IP is not set to 0.0.0.0 if (tftpIP.equals("0.0.0.0")) { logger.warn(PC2LogCategory.PCSim2, subCat, "The TFTP Server IP setting in the platform file is not valid. Ending auto generate operation."); } else { // Next we need to TFTP the file from the server TFTPClient client = new TFTPClient(); int dirIndex = fileName.lastIndexOf("/", index); File dir = new File(fileName.substring(0, dirIndex) + PROV_FILE_DIRECTORY); if (dir.exists() && !dir.isDirectory()) { logger.error(PC2LogCategory.PCSim2, subCat, "The path " + dir.getPath() + " is not a directory. Terminating the recording of the provisioning file."); } File binFile = new File(fileName.substring(0, dirIndex + 1) + PROV_FILE_DIRECTORY + File.separator + fileName.substring(dirIndex + 1, index) + "_prov.bin"); boolean exists = false; if (!binFile.exists()) exists = binFile.createNewFile(); if (exists && binFile.canWrite()) { FileOutputStream ostrm = new FileOutputStream(binFile); //InetAddress ia = InetAddress.getByName("10.4.1.37"); client.open(); // client.open(20003, ia); client.receiveFile(provFile, TFTP.BINARY_MODE, ostrm, tftpIP, port); client.close(); logger.info(PC2LogCategory.PCSim2, subCat, "TFTP of the record provisioning file is complete."); } else { logger.warn(PC2LogCategory.PCSim2, subCat, "The system could not TFTP the provisioning file because TFTP address is " + tftpIP + "."); } } } else { logger.warn(PC2LogCategory.PCSim2, subCat, "Recording of the provisioning file is terminating because the port(" + port + ") is less than 0 or greater than 65535."); } } else { logger.warn(PC2LogCategory.PCSim2, subCat, "Recording of the provisioning file is terminating because PACT returned an error string of \"" + provFile + "\"."); } } catch (NumberFormatException nfe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "TFTP Server Port setting doesn't appear to be a number."); } catch (UnknownHostException uhe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "system encountered an error when attempting to send the file to the TFTP Server.\n" + uhe.getMessage() + "\n" + uhe.getStackTrace()); } catch (IOException ioe) { logger.warn(PC2LogCategory.PCSim2, subCat, "PCSim2 is not auto generating a provisioning file because the " + "system encountered an error when attempting to send the file to the TFTP Server.\n" + ioe.getMessage() + "\n" + ioe.getStackTrace()); } } } } /** * Gets the global message queue for the test. * */ public static MsgQueue getMsgQueue() { return q; } /** * Gets the current name of the Platform Configuration * file being used to conduct tests. * @return */ public static String getPlatformSettingsFileName() { return platformSettingsFile; } /** * Gets the name attribute within the currently active * test script if the document is not null. * @return */ public static String getTestName() { if (doc != null) return doc.getName(); return null; } public static PC2UI getUI() { return ui; } /** * This method displays the command-line arguments for the * platform. This method may soon be depricated. * * */ // private void help() { // String msg = "java -jar PC_Sim2-1.0-beta_1.jar [options]\n\n" // + "\toptions:\n" // + "\t-p <platform settings file> to use to conduct test(s).\n" // + "\t-t <test script file(s)>\n\t\t" // + "where <test script file(s)> is space separated list of file(s).\n" // + "\t-d <DUT configuration file(s)>\n\t\t" // + "where <DUT configuration file(s)> is space separated list of file(s).\n" // + "\t-h help\n\n" // + "NOTE: All files need to be include the absolute or relative-path\n" // + " as part of the file name."; // logger.info(PC2LogCategory.Parser, subCat, msg); // } // private boolean isArgOption(String arg) { // if (arg.equals("-t") || // arg.equals("-p") || // arg.equals("-d")) { // return true; // } // return false; // } /** * This method specifies whether the GUI has been started or * if the application is command-line only. */ public static boolean isGUIActive() { if (ui != null) return true; return false; } private static void logNE(String ne, Properties p) { // Only log the ip|port data for non-simulated elements. if (SystemSettings.resolveBooleanSetting(p.getProperty(SettingConstants.SIMULATED))) { return; } String ip1 = p.getProperty(SettingConstants.IP); if (Conversion.isIPv6Address(ip1)) { ip1 = Conversion.makeAddrURL(ip1, p.getProperty(SettingConstants.IPv6_ZONE)); } String ip2 = p.getProperty(SettingConstants.IP2); String[] ips; if (!ip1.equalsIgnoreCase(ip2)) { if (Conversion.isIPv6Address(ip2)) { ip2 = Conversion.makeAddrURL(ip2, p.getProperty(SettingConstants.IPv6_ZONE)); } ips = new String[] { ip1, ip2 }; } else { ips = new String[] { ip1 }; } String udp = p.getProperty(SettingConstants.UDP_PORT); String tcp = p.getProperty(SettingConstants.TCP_PORT); String tls = p.getProperty(SettingConstants.TLS_PORT); String sdp1 = p.getProperty(SettingConstants.SDP_PORT); String sdp2 = p.getProperty(SettingConstants.SDP_PORT2); StringBuilder ipPorts = new StringBuilder(); boolean addComma = false; for (String ip : ips) { if (udp != null && udp.trim().length() > 0 && !udp.equals("0")) { if (addComma) ipPorts.append(", "); ipPorts.append("UDP " + ip + "|" + udp); addComma = true; } if (tcp != null && tcp.trim().length() > 0 && !tcp.equals("0")) { if (addComma) ipPorts.append(", "); ipPorts.append("TCP " + ip + "|" + tcp); addComma = true; } if (tls != null && tls.trim().length() > 0 && !tls.equals("0")) { if (addComma) ipPorts.append(", "); ipPorts.append("TLS " + ip + "|" + tls); addComma = true; } if (sdp1 != null && sdp1.trim().length() > 0 && !sdp1.equals("0")) { if (addComma) ipPorts.append(", "); ipPorts.append("SDP " + ip + "|" + sdp1); addComma = true; } if (sdp2 != null && sdp2.trim().length() > 0 && !sdp2.equals("0")) { if (addComma) ipPorts.append(", "); ipPorts.append("SDP2 " + ip + "|" + sdp2); addComma = true; } } logger.info(PC2LogCategory.LOG_MSG, subCat, "IP|Ports of " + ne + " : " + ipPorts.toString()); } private static void logPackage() { Package p = Package.getPackage("com.cablelabs.sim"); if (p == null) { logger.info(PC2LogCategory.Parser, subCat, "com.cablelabs.sim not loaded"); return; } logger.info(PC2LogCategory.Parser, subCat, "com.cablelabs.sim version " + p.getSpecificationVersion() + " build-" + p.getImplementationVersion()); // if (logFile.exists()) // logDebugInfo(logFile); logger.logConfigSettings(); } /** * Parses the XML Document passed into the application. * * @param args - the fully-qualified name of the test * script document. * @return - true if the document parsed successfully, * false otherwise. */ protected boolean parseAndStart() { //String ts = testScriptFiles.getFirst(); File f = new File(activeTestScriptFile); if (f != null) { logger.info(PC2LogCategory.Parser, subCat, "Using input document " + activeTestScriptFile); TSParser tsp = new TSParser(true); try { doc = tsp.parse(activeTestScriptFile); logPackage(); logger.info(PC2LogCategory.Parser, subCat, "Using input document " + activeTestScriptFile + " v." + doc.getVersion()); Stacks.logStackSocketInformation(); ss.setDynamicPlatformSettings(doc.getProperties()); ss.logSettings(); // Now see if we are running a test for an UE and if so // See if we should auto provision the device? ProvisioningData pd = autoProvision(doc.getName()); if (pd != null) { String macAddr = autoGenerate(pd); if (macAddr != null) { // doc.setAutoProv(pd); logger.info(PC2LogCategory.PCSim2, subCat, "Updating the global registrar's that the DUT is rebooting"); ProvListener pl = new ProvListener(pd); if (pl != null) { logger.debug(PC2LogCategory.PCSim2, subCat, "Starting the provisioning listener operation."); autoProvisioned = pl.run(); if (!autoProvisioned) { logger.error(PC2LogCategory.PCSim2, subCat, "Auto provisioning did not occur as expected, test is terminating."); provDB.clearIssuedData(macAddr); return false; } else { Properties dut = SystemSettings.getSettings(SettingConstants.DUT); String pui = dut.getProperty(SettingConstants.PUI); if (pui != null) Stacks.generateAutoRebootEvent(pui); String pui2 = dut.getProperty(SettingConstants.PUI2); if (pui2 != null) Stacks.generateAutoRebootEvent(pui2); logger.info(PC2LogCategory.PCSim2, subCat, "Test execution pausing while resetting the DUT."); Thread.sleep(5000); logger.info(PC2LogCategory.PCSim2, subCat, "Pause complete."); } } } else { logger.info(PC2LogCategory.PCSim2, subCat, "Auto generate didn't return an updated data file for provisioning."); } } else { logger.info(PC2LogCategory.PCSim2, subCat, "Auto provisioning did not return a data file for the device."); } LinkedList<FSM> fsms = doc.getFsms(); // Initialize the settings that can be overwritten from // within the document setExtensions(fsms); if (doc.getInspector()) ss.enableInspector(); for (int i = 0; i < fsms.size(); i++) { FSM fsm = fsms.get(i); PC2Models testModel = null; String modelName = fsm.getModel().getName(); if (modelName.equalsIgnoreCase("session")) { testModel = new Session(fsm); if (testModel != null) testModel.init(); try { fsm.getNetworkElements().certify(); } catch (PC2Exception e) { } } else if (modelName.equalsIgnoreCase(MsgRef.STUN_MSG_TYPE)) { testModel = new Stun(fsm); if (testModel != null) testModel.init(); //if (!fsm.getNetworkElements().certify()) // return false; } else if (modelName.equalsIgnoreCase("registrar")) { Properties dut = SystemSettings.getSettings("DUT"); String pui = dut.getProperty(SettingConstants.PUI); Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); String destIP = platform.getProperty(SettingConstants.IP); if (pui != null) { testModel = new Registrar(fsm, pui, destIP); if (testModel != null) testModel.init(); try { fsm.getNetworkElements().certify(); } catch (PC2Exception e) { } } else return false; } if (modelName.equalsIgnoreCase("register")) { testModel = new Register(fsm); if (testModel != null) testModel.init(); try { fsm.getNetworkElements().certify(); } catch (PC2Exception e) { } } if (testModel != null) { testModel.start(); activeModels.add(testModel); } } return true; } catch (PC2XMLException pe) { String err = "\n** Parsing error in file \n " + pe.getFileName() + " at line " + pe.getLineNumber(); if (pe.getSystemId() != null) { err += ", uri " + pe.getSystemId(); } if (pe.getPublicId() != null) { err += ", public " + pe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, pe); } catch (SAXParseException spe) { String err = "\n** Parsing error in file \n " + activeTestScriptFile + " at line " + spe.getLineNumber(); if (spe.getSystemId() != null) { err += ", uri " + spe.getSystemId(); } if (spe.getPublicId() != null) { err += ", public " + spe.getPublicId(); } err += "\n"; logger.fatal(PC2LogCategory.Parser, subCat, err, spe); } catch (Exception e) { e.printStackTrace(); } } return false; } // private boolean processArgs(String [] args) { // boolean valid = true; // // // Process the arguments // if (ui != null) { // // No valid arguments are necessary if the UI exists // // integrate passed in arguments to the UI // } // else if (args.length >= 1) { // logger.trace(PC2LogCategory.Parser, subCat, // "Beginning to process application arguments."); // LinkedList<String> invalidArgs = new LinkedList<String>(); // int count = args.length; // for (int i=0; i < count; i++) { // logger.trace(PC2LogCategory.Parser, subCat, // "Argument["+i+"]="+args[i]); // if (args[i].equals("-p")) { // String fileName = args[++i]; // logger.trace(PC2LogCategory.Parser, subCat, // "Argument["+i+"]="+fileName); // String reason = validateFile(fileName); // if (reason == null) // platformSettingsFile = fileName; // else // invalidArgs.add("-p " + fileName + reason); // } // else if (args[i].equals("-t")) { // do { // String fileName = args[++i]; // logger.trace(PC2LogCategory.Parser, subCat, // "Argument["+i+"]="+fileName); // String reason = validateFile(fileName); // if (reason == null) // testScriptFiles.add(fileName); // else { // invalidArgs.add("-t " + fileName + reason); // } // } while ((i+1) < count && !isArgOption(args[i+1])); // } // else if (args[i].equals("-d")) { // do { // String fileName = args[++i]; // logger.trace(PC2LogCategory.Parser, subCat, // "Argument["+i+"]="+fileName); // String reason = validateFile(fileName); // if (reason == null) // dutConfigFiles.add(fileName); // else // invalidArgs.add("-d " + fileName + reason); // } while ((i+1) < count && !isArgOption(args[i+1])); // } // else if (args[i].equals("-h")) { // help(); // valid = false; // } // else // invalidArgs.add(args[i]); // } // if (invalidArgs.size() > 0) { // valid = false; // logger.fatal(PC2LogCategory.Parser, subCat, // "The following arguments are invalid:"); // for (int i = 0; i < invalidArgs.size(); i++) // logger.fatal(PC2LogCategory.Parser, subCat, // "\t" + invalidArgs.get(i)); // help(); // // } // else // logger.trace(PC2LogCategory.Parser, subCat, // "Processing of application arguments completed successfully."); // } // else // valid = false; // // return valid; // } /** * */ @Override public void removeDUTConfig(File f) { if (f.exists() && f.canRead() && f.isFile()) { synchronized (dutConfigsToRemove) { dutConfigsToRemove.add(f); } logger.debug(PC2LogCategory.Parser, subCat, "Removing client defined by " + f.getName() + " from list of accepted clients for global registrar."); } else { String reason = validateFile(f.getAbsolutePath()); logger.warn(PC2LogCategory.Parser, subCat, "Couldn't process DUT configuration for global registrar because " + reason); } } /** * Main thread simply looks for notification that the * test is complete, informs the various protocol stacks * to shutdown and then terminates the test. * */ public void run() { mainThread = Thread.currentThread(); // GAREY test code int count = 0; while (!shutdown) { // First determine if there are any tests to conduct boolean configsToProcess = false; synchronized (dutConfigsToRead) { synchronized (dutConfigsToRemove) { if (dutConfigsToRead.size() > 0 || dutConfigsToRemove.size() > 0) { configsToProcess = true; } } } if (!configsToProcess && closeBatchFile) { if (ss != null) { ss.closeBatch(); } if (stacks != null) { stacks.shutdown(); } closeBatchFile = false; platformSettingsFile = null; if (globalRegEnabled) { globalRegFile = null; GlobalRegistrar.setMasterFSM(null, Transport.UDP); globalRegEnabled = false; } if (presenceServerEnabled) { presenceServerFile = null; presenceServerEnabled = false; } } // Next see if we are ready to run some test pairs // This can only be done if there are no dutConfigs to // process in add or remove lists else if (dutConfigFiles.size() > 0 && testScriptFiles.size() > 0 && !configsToProcess && platformSettingsFile != null) { try { if (dutPrimary) { ListIterator<String> duts = dutConfigFiles.listIterator(); while (duts.hasNext() && !shutdown) { activeDUTFile = duts.next(); ListIterator<String> testScripts = testScriptFiles.listIterator(); while (testScripts.hasNext() && !shutdown) { activeTestScriptFile = testScripts.next(); executeTest(); } } } else { ListIterator<String> testScripts = testScriptFiles.listIterator(); while (testScripts.hasNext() && !shutdown) { activeTestScriptFile = testScripts.next(); ListIterator<String> duts = dutConfigFiles.listIterator(); while (duts.hasNext() && !shutdown) { activeDUTFile = duts.next(); executeTest(); } } } testsComplete(); } // This most likely will happen if the user stop's the tests. When the // user terminates the test, the lists are emptied so that no record is made for // unattempted test pairs. catch (ConcurrentModificationException cme) { logger.debug(PC2LogCategory.PCSim2, subCat, "Either DUT or Test Script list have changed during test pair execution."); } } else if (pendingPSFile != null) { boolean restart = false; // Determine if we need to restart the existing stacks and // configuration parameters of the platform. if (platformSettingsFile == null) restart = true; else if (platformSettingsFile != null) { // First we need to remove any UEs that are not being simulated from the // table of allowable registering devices. Enumeration<String> keys = SystemSettings.getPlatformLabels(); if (keys != null) { while (keys.hasMoreElements()) { String key = keys.nextElement(); if (key.startsWith("UE")) { Properties p = SystemSettings.getSettings(key); LinkedList<String> puis = createRegistrarLabels(p); Stacks.removeSIPRegistrarClient(key, puis); } } } if (!pendingPSFile.equals(platformSettingsFile)) restart = true; else if (psLastModified < (new File(platformSettingsFile)).lastModified()) restart = true; } if (restart && stacks != null) stacks.restart(); platformSettingsFile = pendingPSFile; pendingPSFile = null; File ps = new File(platformSettingsFile); psLastModified = ps.lastModified(); if (!ss.loadPlatformSettings(platformSettingsFile)) { logger.fatal(PC2LogCategory.Parser, subCat, "PCSim2 encountered error while trying to read the Platform Settings information."); // Clear the file information platformSettingsFile = null; } else { Enumeration<String> labels = SystemSettings.getPlatformLabels(); if (labels != null) { while (labels.hasMoreElements()) { String ne = labels.nextElement(); if (!ne.startsWith(SettingConstants.UE) && !ne.startsWith(SettingConstants.PCSCF) && !ne.startsWith(SettingConstants.SCSCF)) continue; Properties p = SystemSettings.getSettings(ne); logNE(ne, p); } } if (restart) { logger.info(PC2LogCategory.PCSim2, subCat, "Starting servers."); startServers(); } } // Next reload the provisioning test script/policy/provisioning file table if (platformSettingsFile != null) { Properties platform = SystemSettings.getSettings(SettingConstants.PLATFORM); String cw = platform.getProperty(SettingConstants.CW_NUMBER); if (provDB == null) provDB = new ProvDatabase(cw); else provDB.load(cw); } // Now add all of the real devices in the platform settings to the // allowable registering devices table. addRegistrarClients(); } else { try { if (configsToProcess) { synchronized (dutConfigsToRead) { synchronized (dutConfigsToRemove) { if (dutConfigsToRead.size() > 0 || dutConfigsToRemove.size() > 0) { ListIterator<File> rmIter = dutConfigsToRemove.listIterator(); // Loop through the reads File read = null; if (dutConfigsToRead.size() > 0) read = dutConfigsToRead.removeFirst(); while (read != null) { int prevRmIndex = -1; // Make sure the read doesn't also appear in the // remove list while (rmIter.hasNext()) { File rm = rmIter.next(); if (rm.equals(read)) { prevRmIndex = rmIter.previousIndex(); } } // If the file appears in the remove list at the // same time we try to read, simply don't read // and remove from the remove list if (prevRmIndex != -1) { dutConfigsToRemove.remove(prevRmIndex); logger.warn(PC2LogCategory.Parser, subCat, "Skipping reading " + read.getName() + " because file was also found in DUT Config remove list."); } else { try { // Load the read file String neLabel = ss.loadDUTSettings(read.getAbsolutePath(), true, false); if (neLabel != null && neLabel.startsWith("UE")) { // Now obtains the DUT's IP address and the expected IP address for // it to register with Properties p = SystemSettings.getSettings(neLabel); if (p != null) { logNE(neLabel, p); LinkedList<String> puis = createRegistrarLabels(p); if (puis.size() > 0) { Stacks.addSIPRegistrarClient(neLabel, puis); // With the new design of using Public User Identifier we will need to // use the first entry in the puis as the key for the table // dutConfigFileToPUIIndex.put(read, puis.get(0)); if (SystemSettings.getBooleanSetting( SettingConstants.GLOBAL_REGISTRAR)) { logger.info(PC2LogCategory.Parser, subCat, "Loaded " + read.getName() + " for global registrar."); } else logger.info(PC2LogCategory.Parser, subCat, read .getName() + " not loaded for global registrar because registrar is disabled."); } else { logger.error(PC2LogCategory.Parser, subCat, "The DUT configuration file appears to not contain any Public User Identitier."); } } else { logger.warn(PC2LogCategory.Parser, subCat, "Failed to load " + read.getName() + " for global registrar."); } } else if (neLabel != null && neLabel.startsWith("CN")) { // Since the CN could contain the PCSCF that real UEs // need to register, temporarily load the file's // settings, add the clients and then remove them ss.setDUTProperties(read.getAbsolutePath()); addRegistrarClients(); ss.reset(); } else { logger.info(PC2LogCategory.Parser, subCat, "No elements added for global register for label " + neLabel + " from file " + read.getName() + "."); } } catch (Exception e) { logger.error(PC2LogCategory.PCSim2, subCat, "The DUT Configuration File defined by (" + read.getAbsolutePath() + ") could not be processed. File is being dropped."); } } read = null; if (dutConfigsToRead.size() > 0) read = dutConfigsToRead.removeFirst(); } File rm = null; if (dutConfigsToRemove.size() > 0) rm = dutConfigsToRemove.removeFirst(); while (rm != null) { try { String neLabel = ss.loadDUTSettings(rm.getAbsolutePath(), true, true); if (neLabel != null && neLabel.startsWith("UE")) { Properties p = SystemSettings.getSettings(neLabel); LinkedList<String> puis = createRegistrarLabels(p); Stacks.removeSIPRegistrarClient(neLabel, puis); logger.info(PC2LogCategory.Parser, subCat, "removing client defined by " + rm.getName() + " to list of accepted clients for global registrar"); } } catch (Exception e) { String err = "Simulator failed to sleep. Terminating test."; logger.fatal(PC2LogCategory.Parser, subCat, err, e); } rm = null; if (dutConfigsToRemove.size() > 0) rm = dutConfigsToRemove.removeFirst(); } dutConfigsToRead.clear(); dutConfigsToRemove.clear(); } } } } else { // Since there are aren't any dut and test script // files we can simply go to sleep and check again // later for any work. Thread.sleep(250); } } catch (InterruptedException ie) { String msg = "Simulator sleep interrupted."; logger.info(PC2LogCategory.Parser, subCat, msg); } catch (Exception e) { String err = "Simulator failed to sleep. Terminating test."; logger.fatal(PC2LogCategory.Parser, subCat, err, e); } } } LogAPI.shutdown(); } /** * Sets the extensions and services that may have been overwritten within * a single test script for the test * */ public void setExtensions(LinkedList<FSM> fsms) { ListIterator<FSM> iter = fsms.listIterator(); while (iter.hasNext()) { FSM fsm = iter.next(); NetworkElements nes = fsm.getNetworkElements(); ListIterator<String> extIter = nes.getDisableExtensions(); Extension e = Extension.DISABLED; while (extIter.hasNext()) { String ext = extIter.next(); if (ext != null) { if (ext.equals("gruu")) ss.setGRUUExtension(e); else if (ext.equals("precondition")) ss.setPreconditionExtension(e); else if (ext.equals("100rel")) ss.setReliabilityExtension(e); } } extIter = nes.getSupportedExtensions(); e = Extension.SUPPORTED; while (extIter.hasNext()) { String ext = extIter.next(); if (ext != null) { if (ext.equals("gruu")) ss.setGRUUExtension(e); else if (ext.equals("precondition")) ss.setPreconditionExtension(e); else if (ext.equals("100rel")) ss.setReliabilityExtension(e); } } extIter = nes.getRequireExtensions(); e = Extension.REQUIRED; while (extIter.hasNext()) { String ext = extIter.next(); if (ext != null) { if (ext.equals("gruu")) ss.setGRUUExtension(e); else if (ext.equals("precondition")) ss.setPreconditionExtension(e); else if (ext.equals("100rel")) ss.setReliabilityExtension(e); } } } } /** * Implementation for setting the platform settings file * and starting the servers from the user interface. * If the servers were already running, invocation of this * method will result in their restart. */ @Override public boolean setPlatformSettings(String fileName) { File f = new File(fileName); if (f.exists() && f.canRead() && f.isFile()) { pendingPSFile = fileName; return true; } return false; } /** * Global accessor to terminate the test. * */ public static void setTestComplete() { complete = true; if (mainThread != null) { mainThread.interrupt(); } if (isGUIActive()) ui.testComplete(); } /** * Updates the global test result with a new setting. Since * the value is && with the previous setting, a test that has * already encountered a failure condition will continue to * be marked as a failure. * * By default all tests start assuming that they will succeed * so all failures call this method to declare a test as a * failure. * @param flag - true test operations are operating as expected * false if an error has occurred. */ public static void setTestPassed(boolean flag) { // if (!flag) { // Throwable t = new Throwable(); // StackTraceElement [] ste = t.getStackTrace(); // boolean done = false; // String trace = ""; // for (int i = 1; i < ste.length && !done; i++) { // trace += "\n\t" + ste[i]; // if (i >= 4) // done = true; // } // logger.error(PC2LogCategory.PCSim2, subCat, // // "Test is being declared a failure by: " + trace); // } if (testPassed == null) testPassed = flag; else testPassed &= flag; if (complete) { displayResults(); } } /** * Cleans up the protocol stacks before terminating. * */ @Override public void shutdown() { shutdown = true; ListIterator<PC2Models> iter = activeModels.listIterator(); while (iter.hasNext()) { PC2Models m = iter.next(); if (m != null) m.shutdown(); } if (stacks != null) { stacks.shutdown(); } } /** * This method starts the protocol stacks and the global registrar if it is configured * to run. */ private void startServers() { stacks = Stacks.getInstance(); stacks.init(); dist = Stacks.getSipDistributor(); stun = Stacks.getStunDistributor(); boolean success = configGlobalRegistrar(); if (globalRegEnabled && !success) { logger.fatal(PC2LogCategory.Parser, subCat, "PCSim2 encountered error while trying to start the global registrar."); setTestPassed(false); setTestComplete(); //shutdown(); return; } else if (success) { logger.info(PC2LogCategory.Parser, subCat, "PCSim2 has started master globalRegistrar process."); } success = configPresenceServer(); if (presenceServerEnabled && !success) { logger.fatal(PC2LogCategory.Parser, subCat, "PCSim2 encountered error while trying to start the presence server."); setTestPassed(false); setTestComplete(); //shutdown(); return; } else if (success) { logger.info(PC2LogCategory.Parser, subCat, "PCSim2 has started presenceServer process."); } } @Override public boolean startTests(LinkedList<File> dutFiles, LinkedList<File> testCaseFiles, boolean dutPrimary) { ListIterator<File> iter = dutFiles.listIterator(); while (iter.hasNext()) { dutConfigFiles.add(iter.next().getAbsolutePath()); } iter = testCaseFiles.listIterator(); while (iter.hasNext()) { testScriptFiles.add(iter.next().getAbsolutePath()); } this.dutPrimary = dutPrimary; return true; } @Override public boolean stopTests() { ListIterator<PC2Models> models = activeModels.listIterator(); while (models.hasNext()) { PC2Models model = models.next(); logger.error(PC2LogCategory.LOG_MSG, subCat, "Shutting down test model " + model.getName()); model.shutdown(); } logger.error(PC2LogCategory.LOG_MSG, subCat, "User terminated testing."); setTestPassed(false); setTestComplete(); displayResults(); testsComplete(); return true; } private void testsComplete() { // We have attempted to execute all of the test pairs // now clear the two lists and the active files dutConfigFiles.clear(); testScriptFiles.clear(); activeDUTFile = null; activeTestScriptFile = null; if (isGUIActive()) ui.testsComplete(); } /** * This method validates that the file exists, is readible, * and if a file. * * @param fileName - the path and file name to test * @return true if valid file, false otherwise */ private String validateFile(String fileName) { String reason = null; File f = new File(fileName); if (!f.exists()) { reason = " does not exist."; logger.error(PC2LogCategory.Parser, subCat, "Looking for file in " + f.getAbsolutePath()); } else if (!f.isFile()) reason = " isn't a file."; else if (!f.canRead()) reason = " can't be read."; return reason; } /** * Starting point for the platform engine. It simply * passes the command-line arguments to the init method * */ public static void main(String[] args) { // First determine if the license has been agreed to // or not // With the new installation process license acceptance // occurs during install, not upon running. // PC2LicenseScreen splash = new PC2LicenseScreen(); // if (!splash.isAccepted()) { // splash.showLicense(); // splash.run(); // if (!splash.isAccepted()) { // System.out.println("PCSim2 is terminating because license" // + " has not been agreed to by user."); // System.exit(-1); // } // } PCSim2 sim = new PCSim2(); sim.init(args); // GLH Test Logger - // try { // LogAPI l = new LogAPI(); // l.unitTest(); // } // catch (IOException io) { // System.out.println("LogAPI failed to create application log file."); // } } /** * Allows Session FSMs to determine if an endpoint has * already registered with the system prior to it's * creation. * * @param ip - source address of the peer network element * @return - true if the device is registered, false otherwise. */ /* public static boolean isRegistered(String ip) { if (registrar != null) { return registrar.isRegistered(ip); } return false; }*/ }