Mercurial > hg > RemoteEditor > Eclipse
changeset 113:522c6bd9b11b
Merge test using JAVApathfinder
author | kent |
---|---|
date | Sun, 23 Dec 2007 16:14:06 +0900 |
parents | 65ba9545fa49 |
children | c59b0886061c |
files | src/pathfinder/mergetest/ChannelSimulator.java src/pathfinder/mergetest/EditorSimulator.java src/pathfinder/mergetest/EditorSimulatorAsync.java src/pathfinder/mergetest/NetworkSimulator.java src/pathfinder/mergetest/NetworkSimulatorwithSeMa.java src/pathfinder/mergetest/NetworkSimulatorwithoutSeMa.java src/pathfinder/mergetest/SeMaSimulator.java src/pathfinder/mergetest/TestMerger.java src/pathfinder/mergetest/Text.java |
diffstat | 9 files changed, 722 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/ChannelSimulator.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,73 @@ +package pathfinder.mergetest; + +import java.util.concurrent.BlockingQueue; + +public class ChannelSimulator<P> { + private BlockingQueue<P> qread; + private BlockingQueue<P> qwrite; + private NetworkSimulator<P> ns; + + public ChannelSimulator(NetworkSimulator<P> _ns, BlockingQueue<P> _a, BlockingQueue<P> _b){ + ns = _ns; + qread = _a; + qwrite = _b; + } + + /* read from Queue. */ + public P read(){ + try { + return qread.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + return null; + } + } + /* write to Queue. */ + public boolean write(P p){ + try { + synchronized (ns){ + qwrite.put(p); + ns.notifyAll(); + } + return true; + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } + } + /* polling read queue. write queue can be written any time. */ + public P poll() { + return qread.poll(); + } + + + /* accessor methods. */ + public BlockingQueue<P> getReadQ(){ + return qread; + } + public BlockingQueue<P> getWriteQ(){ + return qwrite; + } + public void setReadQ(BlockingQueue<P> bq){ + qread = bq; + } + public void setWriteQ(BlockingQueue<P> bq){ + qwrite = bq; + } + + /* return state of the Queue(debug) */ + public boolean readQisEmpty() { + return qread.isEmpty(); + } + public boolean writeQisEmpty() { + return qwrite.isEmpty(); + } + + + /* for Session Manager. */ + public ChannelSimulator<P> getServerChannel() { + return new ChannelSimulator<P>(ns, qwrite, qread); + } + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/EditorSimulator.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,121 @@ +package pathfinder.mergetest; + +import java.util.Queue; + +import remoteeditor.command.REPCommand; +import remoteeditor.network.REP; +import sample.merge.TranslaterImp1; + +public class EditorSimulator extends Thread{ + private int eid; + private int seq; + private boolean isOwner; + private NetworkSimulator<REPCommand> ns; + private ChannelSimulator<REPCommand> cs; + private Queue<REPCommand> CmdList; + private TranslaterImp1 translater; + private Text text; + private boolean running=true; + + public EditorSimulator(int _eid, NetworkSimulator<REPCommand> _ns, Queue<REPCommand> q, String _name) { + super(_name); + eid = _eid; + ns = _ns; + CmdList = q; + translater = new TranslaterImp1(_eid); + text = new Text(); + cs = ns.connect(); + } + + public void setOwner(boolean f){ + isOwner = f; + } + synchronized public void finish(){ + running = false; + } + + public void run(){ + System.out.println("Editor"+eid+" start."); + + // Send All Command that is included CmdList. + sendAllCommand(); + + // MainLoop, + while(running){ + REPCommand cmd = cs.read(); + REPCommand[] cmds; + + //終了条件 + if (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT){ + System.out.println("\tEditor"+eid+" catch QUIT command emited by itself."); + translater.transReceiveCmd(cmd); + running=false; break; + } + System.out.println("\tEditor"+eid+" catch command from "+cmd.eid+" NO."+cmd.seq); + + if (cmd.eid==eid){ + cmds = translater.catchOwnCommand(cmd); + for (int i=0; i<cmds.length; i++){ + cmd = cmds[i]; + System.out.println("\t\tEditor"+eid+" edit text. "); + text.edit(cmd); + } + } else { + cmds = translater.transReceiveCmd(cmd); + for (int i=0; i<cmds.length; i++){ + cmd = cmds[i]; + System.out.println("\t\tEditor"+eid+" edit text and pass Cmd. "); + text.edit(cmd); + cs.write(new REPCommand(cmd)); + } + } + } + + System.out.println("Editor"+eid+" finish."); + } + + private void sendOneCommand() { + REPCommand[] cmds; + REPCommand cmd = CmdList.poll(); + cmd.eid = eid; + cmds = translater.transSendCmd(cmd); + cmd.setString("this is inserted or replaced by Editor"+cmd.eid+":"+cmd.seq); + + if (isOwner) cmd.setThroughMaster(true); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(new REPCommand(cmds[i])); + } + } + private void sendAllCommand() { + REPCommand[] cmds; + for (REPCommand cmd: CmdList){ + cmd.seq = seq; + cmd.eid = eid; + cmds = translater.transSendCmd(cmd); + cmd.setString("this is inserted or replaced by Editor"+cmd.eid+":"+cmd.seq); + //if (isOwner) cmd.setThroughMaster(true); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(new REPCommand(cmds[i])); + } + } + + // Send Quit Command + cmds = translater.transSendCmd( new REPCommand(REP.SMCMD_QUIT, 0, eid, seq++, 0, 0, "QUIT by Editor"+eid)); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(new REPCommand(cmds[i])); + } + + } +/* + private boolean checkQuit(REPCommand cmd) { + // 最初に全部のコマンドを送信するから、自分のQUITが来るのは最後 + return (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT); + } +*/ + public Text getText(){ + return text; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/EditorSimulatorAsync.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,150 @@ +package pathfinder.mergetest; + +import java.util.Queue; + +import remoteeditor.command.REPCommand; +import remoteeditor.network.REP; +import sample.merge.TranslaterImp1; + +public class EditorSimulatorAsync extends EditorSimulator{ + private int eid; + private boolean isOwner; + private NetworkSimulator<REPCommand> ns; + private ChannelSimulator<REPCommand> cs; + private TranslaterImp1 translater; + private Text text; + private boolean running=true; + private User user; + + public EditorSimulatorAsync(int _eid, NetworkSimulator<REPCommand> _ns, Queue<REPCommand> q, String _name) { + super(_eid, _ns, q, _name); + eid = _eid; + ns = _ns; + cs = ns.connect(); + translater = new TranslaterImp1(_eid); + text = new Text(); + user = new User(translater, text, q, cs); + } + + public void run(){ + System.out.println("Editor"+eid+" start."); + user.start(); + + // MainLoop, + while(running){ + REPCommand cmd = cs.read(); + REPCommand[] cmds; + + //終了条件 + if (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT){ + System.out.println("\tEditor"+eid+" catch QUIT command emited by itself."); + translater.transReceiveCmd(cmd); + running=false; break; + } + System.out.println("\tEditor"+eid+" catch command from "+cmd.eid+" NO."+cmd.seq); + + if (cmd.eid==eid){ + cmds = translater.catchOwnCommand(cmd); + for (int i=0; i<cmds.length; i++){ + cmd = cmds[i]; + System.out.println("\t\tEditor"+eid+" edit text. "); + text.edit(cmd); + } + } else { + cmds = translater.transReceiveCmd(cmd); + for (int i=0; i<cmds.length; i++){ + cmd = cmds[i]; + System.out.println("\t\tEditor"+eid+" edit text and pass Cmd. "); + text.edit(cmd); + cs.write(cmd); + } + } + } + + try { user.join(); + } catch (InterruptedException e) { e.printStackTrace(); } + + System.out.println("Editor"+eid+" finish."); + } + +/* + private boolean checkQuit(REPCommand cmd) { + // 最初に全部のコマンドを送信するから、自分のQUITが来るのは最後 + return (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT); + } +*/ + public Text getText(){ + return text; + } + + + + public class User extends Thread{ + private Queue<REPCommand> CmdList; + private TranslaterImp1 translater; + private Text text; + private ChannelSimulator<REPCommand> cs; + + public User(TranslaterImp1 _translater, Text _text, Queue<REPCommand> q, ChannelSimulator<REPCommand> _cs){ + translater = _translater; + text = _text; + CmdList = q; + cs = _cs; + } + + public void run(){ + System.out.println("Editor"+eid+"'s writer thread start."); + while ( !CmdList.isEmpty() ){ + sendOneCommand(); + } + sendQuitCommand(); + System.out.println("Editor"+eid+"'s writer thread finish."); + } + + private void sendOneCommand() { + REPCommand[] cmds; + REPCommand cmd = CmdList.poll(); + cmd.eid = eid; + cmds = translater.transSendCmd(cmd); + cmd.setString("this is inserted or replaced by Editor"+cmd.eid+":"+cmd.seq); + + if (isOwner) cmd.setThroughMaster(true); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(cmds[i]); + } + } + + private void sendQuitCommand(){ + REPCommand[] cmds; + cmds = translater.transSendCmd( new REPCommand(REP.SMCMD_QUIT, 0, eid, 0, 0, 0, "QUIT by Editor"+eid)); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(cmds[i]); + } + } +/* + private void sendAllCommand() { + REPCommand[] cmds; + for (REPCommand cmd: CmdList){ + cmd.seq = seq; + cmd.eid = eid; + cmds = translater.transSendCmd(cmd); + cmd.setString("this is inserted or replaced by Editor"+cmd.eid+":"+cmd.seq); + //if (isOwner) cmd.setThroughMaster(true); + for (int i=0; i<cmds.length; i++){ + text.edit(cmds[i]); + cs.write(cmds[i]); + } + } + + } +*/ + } + + + + + + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/NetworkSimulator.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,14 @@ +package pathfinder.mergetest; + + +public interface NetworkSimulator<P> { + + /** + * Request to connect. + * Client editor use this method to connect SeMa. + * @param cs + */ + public ChannelSimulator<P> connect(); + public ChannelSimulator<P> accept(); + public boolean checkAllCS(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/NetworkSimulatorwithSeMa.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,55 @@ +package pathfinder.mergetest; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import remoteeditor.command.REPCommand; + +public class NetworkSimulatorwithSeMa<P> implements NetworkSimulator<P> { + + /** Waiting connectionRequest to be accepted by SessionManager. */ + private Queue<ChannelSimulator<P>> acceptList; + /** Established connection */ + private Queue<ChannelSimulator<P>> connectedList; + + //private SeMaSimulator<REPCommand> sema; + + public NetworkSimulatorwithSeMa(){ + acceptList = new LinkedList<ChannelSimulator<P>>(); + connectedList = new LinkedList<ChannelSimulator<P>>(); + } + + /** + * Establish connection. It's called by SeMa. + * @return + */ + public ChannelSimulator<P> accept(){ + ChannelSimulator<P> cs = acceptList.poll(); + if (cs==null) return null; + + connectedList.offer(cs); + return cs.getServerChannel(); + } + + /** + * Request to connect. + * Client editor use this method to connect SeMa. + * @param cs + */ + public ChannelSimulator<P> connect(){ + BlockingQueue<P> rq = new LinkedBlockingQueue<P>(); + BlockingQueue<P> wq = new LinkedBlockingQueue<P>(); + ChannelSimulator<P> cs = new ChannelSimulator<P>(this, rq, wq); + acceptList.offer(cs); + return cs; + } + + public boolean checkAllCS(){ + for(ChannelSimulator<P> cs: connectedList){ + if(!cs.readQisEmpty()) return false; + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/NetworkSimulatorwithoutSeMa.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,55 @@ +package pathfinder.mergetest; + +import java.util.LinkedList; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class NetworkSimulatorwithoutSeMa<P> implements NetworkSimulator<P> { + /** Established connection */ + private LinkedList<ChannelSimulator<P>> connectedList; + + public NetworkSimulatorwithoutSeMa(){ + connectedList = new LinkedList<ChannelSimulator<P>>(); + } + + /** + * Request to connect. + * Client editor use this method to connect SeMa. + * @param cs + */ + public ChannelSimulator<P> connect(){ + ChannelSimulator<P> cs; + if (connectedList.isEmpty()){ + BlockingQueue<P> q = new LinkedBlockingQueue<P>(); + cs = new ChannelSimulator<P>(this, q, q); + }else{ + BlockingQueue<P> rq = connectedList.getLast().getWriteQ(); + BlockingQueue<P> wq = new LinkedBlockingQueue<P>(); + connectedList.getFirst().setReadQ(wq); + +/* ChannelSimulator<P> lastcs = connectedList.getLast(); + BlockingQueue<P> rq = lastcs.getWriteQ(); + + BlockingQueue<P> wq = new LinkedBlockingQueue<P>(); + ChannelSimulator<P> firstcs = connectedList.getFirst(); + firstcs.setReadQ(wq); +*/ + cs = new ChannelSimulator<P>(this, rq, wq); + } + + connectedList.addLast(cs); + return cs; + } + + public ChannelSimulator<P> accept(){ + return null; + } + + public boolean checkAllCS(){ + for(ChannelSimulator<P> cs: connectedList){ + if(!cs.readQisEmpty()) return false; + } + return true; + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/SeMaSimulator.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,92 @@ +package pathfinder.mergetest; + +import java.util.ArrayList; +import java.util.List; + +public class SeMaSimulator<P> extends Thread { + private int MAX_PACKET; + private int MAX_CLIENT; + private boolean running=true; + private NetworkSimulator<P> ns; + private List<ChannelSimulator<P>> csList; + + public SeMaSimulator(NetworkSimulator<P> _ns, int max_client, int max_packet){ + ns = _ns; + MAX_CLIENT = max_client; + MAX_PACKET = max_packet; + csList = new ArrayList<ChannelSimulator<P>>(); + } + public SeMaSimulator(NetworkSimulator<P> _ns, int max_client){ + this(_ns, max_client, 0); + } + public SeMaSimulator(NetworkSimulator<P> _ns){ + this(_ns, 2); + } + + synchronized public void finish(){ + synchronized(ns){ + running = false; + ns.notify(); + } + } + + /** + * Check whether the NetworkSimulator hold waiting connections. + */ + private void checkAccept(){ + ChannelSimulator<P> cs; + while((cs=ns.accept())!=null){ + csList.add(cs); + } + } + + public void run(){ + int i=0; + int count=0; + P packet; + + while(csList.size()<MAX_CLIENT){ checkAccept(); Thread.yield(); } + System.out.println("SessionManager start."); + + /* Main Loop */ + ChannelSimulator<P> cs = csList.get(i); + while(running + && (MAX_PACKET==0 || count<MAX_PACKET)){ + synchronized(ns){ + int prev_i=i; + while((packet=cs.poll())==null && running){ + i = (i+1)%csList.size(); // i++ + cs = csList.get(i); // 次のChennelをゲット + if(i==prev_i) try { ns.wait(); } catch (InterruptedException e) { e.printStackTrace(); } + } + } + if(!running) break; + + System.out.println("SeMa pass packet to "+i+":>> "+packet.toString()); + i = (i+1)%csList.size(); // i++ + cs = csList.get(i); // 次のChennelをゲット + + if ( !cs.write(packet) ){ + System.err.println("Session Manager failed to write."); + } + count++; + } +/* + ChannelSimulator<P> cs = csList.get(i); + while(running + && MAX_PACKET==0 || count<MAX_PACKET){ + packet=cs.poll(); // [i]からread + //if(packet!=null) System.out.println("SeMa catch packet to "+i+":>> "+packet.toString()); + i = (i+1)%csList.size(); // i++ + cs = csList.get(i); // 次のChennelをゲット + if (packet!=null) { + System.out.println("SeMa pass packet to "+i+":>> "+packet.toString()); + cs.write(packet); // readできていたならそれを書き込む + count++; + } + //if (i==0) checkAccept(); //全部回ったらaccept待ちをチェック + } +*/ + System.out.println("SessionManager finish."); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/TestMerger.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,102 @@ +package pathfinder.mergetest; + +import java.util.LinkedList; +import remoteeditor.command.REPCommand; +import remoteeditor.network.REP; + +public class TestMerger { + static public int cmdNO[] = { REP.REPCMD_INSERT, REP.REPCMD_REPLACE, REP.REPCMD_DELETE }; + private NetworkSimulator<REPCommand> ns=null; + private LinkedList<EditorSimulator> editors; + private SeMaSimulator<REPCommand> sema; + + public TestMerger(){ + editors = new LinkedList<EditorSimulator>(); + } + + public static void main(String[] args){ + TestMerger tm; + int i = (args.length>0) ? Integer.parseInt(args[0]) : 2; + System.out.println("number of Editor = "+i); + int j = (args.length>1) ? Integer.parseInt(args[1]) : 3; + System.out.println("number of Packet = "+i); + tm = new TestMerger(); + + tm.init(false, i, j); + tm.startTest(); + + tm.printAllTexts(); + //if (!tm.checkCS()) + // System.out.println("Error!! :some ChannelSimulator still have packet!"); + if (!tm.checkEquality()) + System.out.println("Error!! :all Editor's text is NOT mutch!"); + assert tm.checkEquality(); + } + + private void startTest() { + for (EditorSimulator ee: editors){ + ee.start(); + } + if (sema!=null) sema.start(); + + for (EditorSimulator ee: editors){ + try { + ee.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (sema!=null) sema.finish(); + } + + private void init(boolean sm, int ne, int np){ + if (sm){ + ns = new NetworkSimulatorwithSeMa<REPCommand>(); + sema = new SeMaSimulator<REPCommand>(ns, ne); + } else { + ns = new NetworkSimulatorwithoutSeMa<REPCommand>(); + sema = null; + } + + for (int i=0; i<ne; i++){ + LinkedList<REPCommand> cmds = new LinkedList<REPCommand>(); + // 各エディタが送信するコマンド列を生成 + + for (int j=0; j<np; j++){ + String str = "created by Editor"+i+":"+j; + REPCommand cmd = new REPCommand(REP.REPCMD_INSERT, + 0, i, j, + 10, //Verify.random(text.size()-1), //size-1? + str.length(), str); + cmds.add( cmd); + } + + EditorSimulator ee = new EditorSimulator(i, ns, cmds, "Editor"+i); + if(i==0) ee.setOwner(true); + editors.add(ee); + } + } + + private void printAllTexts(){ + for(EditorSimulator ee: editors){ + System.out.println("--"+ee.getName()+"------------------------"); + ee.getText().printAllText(); + } + } +/* + private boolean checkCS(){ + return ns.checkAllCS(); + } +*/ + private boolean checkEquality(){ + /* + Text ee0 = editors.remove().getText(); + return editors.remove().getText().equals(ee0); + */ + Text text0 = editors.element().getText(); + for(EditorSimulator ee: editors){ + if (!text0.equals(ee.getText())) return false; + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pathfinder/mergetest/Text.java Sun Dec 23 16:14:06 2007 +0900 @@ -0,0 +1,60 @@ +package pathfinder.mergetest; + +import java.util.Arrays; +import java.util.LinkedList; + +import remoteeditor.command.REPCommand; +import remoteeditor.network.REP; + +public class Text { + static private String[] text0 = { + "aaa", "bbb", "ccc", "ddd", "eee", + "fff", "ggg", "hhh", "iii", "jjj", + "kkk", "lll", "mmm", "nnn", "ooo", + "ppp", "qqq", "rrr", "sss", "ttt", + "uuu", "vvv", "www", "xxx", "yyy", "zzz" + }; + LinkedList<String> strList; + + public Text(){ + this(Text.text0); + } + public Text(String[] _strings){ + strList = new LinkedList<String>(Arrays.asList(_strings)); + } + + synchronized public void insert(int i, String str){ + assert 0<i && i<strList.size(); + strList.add(i, str); + } + synchronized public void delete(int i){ + assert 0<i && i<strList.size(); + strList.remove(i); + } + synchronized public void replace(int i, String str){ + assert 0<i && i<strList.size(); + strList.set(i, str); + } + public String get(int i){ + assert 0<i && i<strList.size(); + return strList.get(i); + } + public void edit(REPCommand cmd){ + if (cmd.cmd==REP.REPCMD_INSERT) insert(cmd.lineno, cmd.string); + else if (cmd.cmd==REP.REPCMD_REPLACE) replace(cmd.lineno, cmd.string); + else if (cmd.cmd==REP.REPCMD_DELETE) delete(cmd.lineno); + //else assert false; + } + + public int size(){ + return strList.size(); + } + public void printAllText(){ + for( String str: strList){ + System.out.println(str); + } + } + public boolean equals(Text _target){ + return strList.equals(_target.strList); + } +}