/* Author: Jeff Dalton * Updated: Tue Dec 4 00:39:38 2001 by Jeff Dalton * Copyright: (c) 2001, AIAI, University of Edinburgh */ package ix.itest; import java.awt.Container; import java.awt.event.*; import javax.swing.*; import java.util.*; import ix.iface.util.LogoPanel; import ix.icore.*; import ix.icore.process.StatusValues; import ix.util.*; import ix.util.lisp.*; /** * The generic I-TEST class and application main program.

* * Its IPC name can be given by the "-ipc-name" command-line argument. * For example, to pretend to be I-DEEL: *

 *    java ix.test.BasicItest -ipc -ipc-name=I-DEEL
 * 
* */ public class BasicItest extends IXAgent implements StatusValues { protected String ipcName = "ITEST"; protected String displayName = "I-TEST"; protected Object[] builtinDestinations = {}; protected ItestFrame frame; protected SendPanel sendPanel; protected ReceivePanel receivePanel; public Object getAgentIPCName() { return ipcName; } public BasicItest() { this("I-TEST"); } public BasicItest(String frameTitle) { displayName = frameTitle; } /** * Command-line argument processing used by all versions of I-TEST. *
     *    -ipc-name=name
     * 
* * @see ix.icore.IXAgent#processCommandLineArguments() */ protected void processCommandLineArguments() { if (Parameters.haveParameter("ipc-name")) { ipcName = Parameters.getParameter("ipc-name"); Debug.noteln("Pretending to be", ipcName); } // N.B. need to do this after setting ipcName, because // super method sets up IPC. super.processCommandLineArguments(); } /** * Completes basic I-TEST setup and initialization. */ public void startup() { super.startup(); frame = new ItestFrame(displayName); sendPanel = new SendPanel(this); receivePanel = new ReceivePanel(this); setupFrame(); addTests(); frame.pack(); frame.setVisible(true); } /** * Main program. */ public static void main(String[] argv) { Util.printGreeting("Basic I-TEST"); new BasicItest().mainStartup(argv); } /** * Gives the main I-TEST frame its contents */ public void setupFrame() { Container contentPane = frame.getContentPane(); contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); contentPane.add(sendPanel); contentPane.add(receivePanel); contentPane.add(makeLogoPanel()); } /** * Creates a standard logo panel for I-TEST. * Overridden in subclasses that have, say, a picture to use instead. */ public JPanel makeLogoPanel() { return new LogoPanel("I-TEST", "I-X Test Agent"); } /** * Handles external input in the form of an IPC.InputMessage * that contains an Issue or Report object. */ public void handleInput(IPC.InputMessage message) { receivePanel.handleInput(message); } /** * Adds any tests common to all versions of I-TEST. */ protected void addTests() { } /* * Test utilities */ /** * Adds a test that sends a single issue to a designated agent. */ protected void addIssueTest(String toName, String issueText) { addIssueTest(toName, PRIORITY_MEDIUM, issueText); } /** * Adds a test that sends a single issue to a designated agent. */ protected void addIssueTest(final String toName, int priority, String issueText) { String buttonText = "Send to " + toName + " " + Util.quote(issueText); final Issue issue = new BasicIssue(issueText); issue.setPriority(priority); issue.setSenderId((String)getAgentIPCName()); frame.addTest(buttonText, new ActionListener() { public void actionPerformed(ActionEvent e) { IPC.exceptionlessSend(toName, issue); } }); } /** * Adds a test that sends a series of reports to a designated agent. */ protected void addReportSequenceTest(String buttonText, String toName, String ref, List messageTexts) { frame.addTest(buttonText, new TestSequenceListener(toName, ref, messageTexts)); } /** * Adds a test that sends a series of reports to a designated agent. */ protected void addReportSequenceTest(String buttonText, String toName, String ref, String[] messageTexts) { addReportSequenceTest (buttonText, toName, ref, Seq.toLList(Seq.elements((Object[])messageTexts))); } /** * ActionListener for AbstractButtons that send a sequence of messages. */ public class TestSequenceListener implements ActionListener { SendingThread sender; String toName; String ref; List messageTexts; List reports; public TestSequenceListener(String toName, String ref, List messageTexts) { this.toName = toName; this.ref = ref; this.messageTexts = messageTexts; this.reports = makeReports(messageTexts); } public void actionPerformed(ActionEvent event) { AbstractButton button = (AbstractButton)event.getSource(); String command = event.getActionCommand(); if (command.startsWith("Send")) { sender = new SendingThread(button, toName, reports); sender.start(); } else if (command.startsWith("Stop")) { sender.exit = true; Debug.noteln("Stopped messages to", toName); } else Debug.noteln("Strange test button action", command); } public List makeReports(List messageTexts) { List result = new LinkedList(); for (Iterator i = messageTexts.iterator(); i.hasNext();) { String text = (String)i.next(); Report report = new Report(text); report.setSenderId((String)getAgentIPCName()); report.setRef(ref); result.add(report); } return result; } } /** * Stoppable thread for sending a series of messages. * Stop by doing thread.exit = true. */ public static class SendingThread extends Thread { AbstractButton button; Object destination; List messages; // These delays should be at a higher level so that its // easy to specify them in the code that creates the test. /\/ public int defaultDelay = 2000; // milliseconds between messages public int initialDelay = 10*1000; // extra delay before 1st message volatile boolean exit = false; // gets the thread to exit. public SendingThread(AbstractButton button, Object destination, List messages) { this.button = button; this.destination = destination; this.messages = messages; // We assume the thread will be started pretty much // right away. changeButtonVerb(button, "Send", "Stop sending"); } public void run() { Debug.noteln("Sending to " + destination, messages); List sent = new LListCollector(); // Initial delay (need for screen cams) try { Thread.sleep(initialDelay); } catch (InterruptedException e) {} messageLoop: for (Iterator i = messages.iterator(); !exit && i.hasNext();) { Object message = i.next(); Debug.noteln("Sending", message); try { IPC.sendObject(destination, message); } catch (IPC.IPCException e) { Debug.noteln("Stopped sending because " + e.getMessage()); break messageLoop; } sent.add(message); try { Thread.sleep(defaultDelay); } catch (InterruptedException e) {} } Debug.noteln("Sent to " + destination, sent); SwingUtilities.invokeLater(new Runnable() { public void run() { changeButtonVerb(button, "Stop sending", "Send"); } }); } } /** * Changes the an initial segment of an abstract button's text. */ public static void changeButtonVerb(AbstractButton button, String from, String to) { String text = button.getText(); Debug.assert(text.startsWith(""), "expected " + Util.quote(from) + " to begin " + Util.quote(text)); String newText = to + text.substring(from.length()); button.setText(newText); } }