1   /*
2    * Copyright 2003-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.net.telnet;
17  import junit.framework.TestCase;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.OutputStream;
22  import java.io.PipedInputStream;
23  import java.io.PipedOutputStream;
24  
25  /***
26   * JUnit test class for TelnetClient.s
27   * Implements protocol compliance tests
28   * <p>
29   * @author Bruno D'Avanzo
30   ***/
31  public class TelnetClientTest 
32  extends TestCase implements TelnetNotificationHandler
33  {
34      /**
35       * Handy holder to hold both sides of the connection
36       * used in testing for clarity.
37       */
38      private class TestConnection {
39          TelnetTestSimpleServer server;
40          TelnetClient client;
41          int port;
42          TestConnection(
43                  TelnetTestSimpleServer server, 
44                  TelnetClient client, 
45                  int port) 
46          {
47              this.server = server;
48              this.client = client;
49              this.port = port;
50          }
51          protected void close() {
52              TelnetClientTest.this.closeConnection(
53                      this.server, this.client, this.port);
54          }  
55      }   
56      
57      // four connections with different properties
58      // to use in tests.
59      private TestConnection STANDARD;
60      private TestConnection OPTIONS;
61      private TestConnection ANSI;
62      private TestConnection NOREAD;
63      
64      private int NUM_CONNECTIONS = 4;
65      
66   
67      protected int numdo = 0;
68      protected int numdont = 0;
69      protected int numwill = 0;
70      protected int numwont = 0;
71  
72      /***
73       * main for running the test.
74       ***/
75      public static void main(String args[])
76      {
77          junit.textui.TestRunner.run(TelnetClientTest.class);
78      }
79  
80      /***
81       * open connections needed for the tests for the test.
82       ***/
83      protected void setUp() throws Exception 
84      {
85          super.setUp();
86          for (int port = 3333, socket = 0; socket < NUM_CONNECTIONS && port < 4000; port++) 
87          {
88              TelnetTestSimpleServer server = null;
89              TelnetClient client = null;
90             try {
91                 server = new TelnetTestSimpleServer(port);
92                  switch (socket) {
93                 		case 0:
94                 		    client = new TelnetClient();
95                          // redundant but makes code clearer.
96                          client.setReaderThread(true);
97                 		    break;
98                 		case 1:
99                 		    client = new TelnetClient();
100                         TerminalTypeOptionHandler ttopt = 
101                             new TerminalTypeOptionHandler("VT100", false, false, true, false);
102                         EchoOptionHandler echoopt = 
103                             new EchoOptionHandler(true, false, true, false);
104                         SuppressGAOptionHandler gaopt = 
105                             new SuppressGAOptionHandler(true, true, true, true);
106 
107                         client.addOptionHandler(ttopt);
108                         client.addOptionHandler(echoopt);
109                         client.addOptionHandler(gaopt);
110                		    break;
111                		case 2:
112                         client = new TelnetClient("ANSI");
113                		    break;
114                		case 3:
115                         client = new TelnetClient();
116                         client.setReaderThread(false);
117                		    break;
118                }
119                client.connect("127.0.0.1", port);
120                switch (socket) {
121                		case 0:
122                		    STANDARD = new TestConnection(server, client, port);
123                		    break;
124                		case 1:
125                		    OPTIONS = new TestConnection(server, client, port);
126                		    break;
127                		case 2:
128                		    ANSI = new TestConnection(server, client, port);
129                		    break;
130                		case 3:
131                		    NOREAD = new TestConnection(server, client, port);
132                		    break;
133                		    
134                }
135                
136                // only increment socket number on success
137                socket++;
138            } catch (IOException e) {
139                closeConnection(server, client, port);
140                System.err.println("failed to open client-server connection on port " + port);
141            }
142        }
143        Thread.sleep(1000);
144     }
145     
146     /* 
147      * @throws java.lang.Exception
148      */
149     protected void tearDown() throws Exception {
150         NOREAD.close();
151         ANSI.close();
152         OPTIONS.close();
153         STANDARD.close();
154         try {
155             Thread.sleep(1000);
156         } catch (InterruptedException ie) {
157             //do nothing
158         }
159         super.tearDown();
160     }
161     
162 
163    
164     void closeConnection(TelnetTestSimpleServer server, TelnetClient client, int port) {
165         if (server != null) {
166             server.disconnect();
167             server.stop();
168         }
169         try {
170             if (client != null) {
171                 client.disconnect();
172             }
173         } catch (IOException e) {
174             System.err.println("failed to close client-server connection on port " + port);
175             System.err.println("ERROR in closeConnection(), "+ e.getMessage());
176         }
177         
178     }
179 
180     /***
181      * tests the initial condition of the sessions
182      ***/
183     public void testInitial() throws Exception
184     {
185         boolean connect1_ok = false;
186         boolean connect2_ok = false;
187         boolean connect3_ok = false;
188         boolean init2_ok = false;
189         boolean add_invalid_ok1 = false;
190         boolean add_invalid_ok2 = false;
191         byte buffread2[] = new byte[9];
192         byte expected2[] =
193         {
194             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, 
195             (byte) TelnetOption.ECHO,
196             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, 
197             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
198             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
199             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
200         };
201 
202         SimpleOptionHandler hand = new SimpleOptionHandler(550);
203         try
204         {
205             STANDARD.client.addOptionHandler(hand);
206         }
207         catch (Exception e)
208         {
209             add_invalid_ok1 = true;
210         }
211 
212         try
213         {
214             OPTIONS.client.addOptionHandler(hand);
215         }
216         catch (Exception e)
217         {
218             add_invalid_ok2 = true;
219         }
220 
221         InputStream is1 = STANDARD.server.getInputStream();
222         Thread.sleep(1000);
223         if(is1.available() == 0)
224         {
225             connect1_ok = true;
226         }
227 
228         Thread.sleep(1000);
229         InputStream is2 = OPTIONS.server.getInputStream();
230         if(is2.available() == 9)
231         {
232             is2.read(buffread2);
233             connect2_ok = true;
234 
235             if(equalBytes(buffread2, expected2))
236                  init2_ok = true;
237         }
238 
239         InputStream is3 = ANSI.server.getInputStream();
240         Thread.sleep(1000);
241         if(is3.available() == 0)
242         {
243             connect3_ok = true;
244         }
245 
246 
247         assertTrue(connect1_ok);
248         assertTrue(connect2_ok);
249         assertTrue(connect3_ok);
250         assertTrue(!STANDARD.client.getLocalOptionState(TelnetOption.ECHO));
251         assertTrue(!STANDARD.client.getRemoteOptionState(TelnetOption.ECHO));
252         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.ECHO));
253         assertTrue(!OPTIONS.client.getRemoteOptionState(TelnetOption.ECHO));
254         assertTrue(!ANSI.client.getLocalOptionState(TelnetOption.TERMINAL_TYPE));
255         assertTrue(!ANSI.client.getRemoteOptionState(TelnetOption.TERMINAL_TYPE));
256         assertTrue(init2_ok);
257         assertTrue(add_invalid_ok1);
258         assertTrue(add_invalid_ok2);
259     }
260 
261     /***
262      * protocol compliance test for option negotiation
263      ***/
264     public void testOptionNegotiation() throws Exception
265     {
266         boolean negotiation1_ok = false;
267         byte buffread1[] = new byte[6];
268         byte send1[] =
269         {
270             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, (byte) 15,
271             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, (byte) 15,
272         };
273         byte expected1[] =
274         {
275             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, (byte) 15,
276             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, (byte) 15,
277         };
278 
279         boolean negotiation2_ok = false;
280         byte buffread2[] = new byte[9];
281         byte send2[] =
282         {
283             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
284             (byte) TelnetOption.TERMINAL_TYPE,
285             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
286             (byte) TelnetOption.ECHO,
287             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
288             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
289             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
290             (byte) TelnetOption.SUPPRESS_GO_AHEAD
291         };
292         byte expected2[] =
293         {
294             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, 
295             (byte) TelnetOption.TERMINAL_TYPE,
296             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
297             (byte) TelnetOption.ECHO,
298             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
299             (byte) TelnetOption.SUPPRESS_GO_AHEAD
300         };
301 
302         byte buffread2b[] = new byte[11];
303         byte send2b[] =
304         {
305             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SB, 
306             (byte) TelnetOption.TERMINAL_TYPE,
307             (byte) 1, (byte) TelnetCommand.IAC, (byte) TelnetCommand.SE,
308         };
309         byte expected2b[] =
310         {
311             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SB, 
312             (byte) TelnetOption.TERMINAL_TYPE,
313             (byte) 0, (byte) 'V', (byte) 'T', (byte) '1', (byte) '0', 
314             (byte) '0', 
315             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SE,
316         };
317 
318         boolean negotiation3_ok = false;
319         byte buffread3[] = new byte[6];
320         byte send3[] =
321         {
322             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
323             (byte) TelnetOption.TERMINAL_TYPE,
324             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO,
325             (byte) TelnetOption.SUPPRESS_GO_AHEAD
326         };
327         byte expected3[] =
328         {
329             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, 
330             (byte) TelnetOption.TERMINAL_TYPE,
331             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
332             (byte) TelnetOption.SUPPRESS_GO_AHEAD
333         };
334         byte buffread3b[] = new byte[10];
335         byte send3b[] =
336         {
337             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SB, 
338             (byte) TelnetOption.TERMINAL_TYPE,
339             (byte) 1, (byte) TelnetCommand.IAC, (byte) TelnetCommand.SE,
340         };
341         byte expected3b[] =
342         {
343             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SB, 
344             (byte) TelnetOption.TERMINAL_TYPE,
345             (byte) 0, (byte) 'A', (byte) 'N', (byte) 'S', (byte) 'I', 
346             (byte) TelnetCommand.IAC, (byte) TelnetCommand.SE,
347         };
348 
349 
350         InputStream is1 = STANDARD.server.getInputStream();
351         OutputStream os1 = STANDARD.server.getOutputStream();
352         is1.skip(is1.available());
353         os1.write(send1);
354         os1.flush();
355         Thread.sleep(1000);
356         if(is1.available() == 6)
357         {
358             is1.read(buffread1);
359 
360             if(equalBytes(buffread1, expected1))
361                 negotiation1_ok = true;
362         }
363 
364         InputStream is2 = OPTIONS.server.getInputStream();
365         OutputStream os2 = OPTIONS.server.getOutputStream();
366         Thread.sleep(1000);
367         is2.skip(is2.available());
368         os2.write(send2);
369         os2.flush();
370         Thread.sleep(1000);
371         if(is2.available() == 9)
372         {
373             is2.read(buffread2);
374 
375             if(equalBytes(buffread2, expected2))
376                 negotiation2_ok = true;
377 
378             if(negotiation2_ok)
379             {
380                 negotiation2_ok = false;
381                 os2.write(send2b);
382                 os2.flush();
383                 Thread.sleep(1000);
384                 if(is2.available() == 11)
385                 {
386                     is2.read(buffread2b);
387 
388                     if(equalBytes(buffread2b, expected2b))
389                         negotiation2_ok = true;
390                 }
391             }
392         }
393 
394         InputStream is3 = ANSI.server.getInputStream();
395         OutputStream os3 = ANSI.server.getOutputStream();
396         Thread.sleep(1000);
397         is3.skip(is3.available());
398         os3.write(send3);
399         os3.flush();
400         Thread.sleep(1000);
401         if(is3.available() == 6)
402         {
403             is3.read(buffread3);
404 
405             if(equalBytes(buffread3, expected3))
406                 negotiation3_ok = true;
407 
408             if(negotiation3_ok)
409             {
410                 negotiation3_ok = false;
411                 os3.write(send3b);
412                 os3.flush();
413                 Thread.sleep(1000);
414                 if(is3.available() == 10)
415                 {
416                     is3.read(buffread3b);
417                     if(equalBytes(buffread3b, expected3b))
418                             negotiation3_ok = true;
419                 }
420             }
421         }
422 
423         assertTrue(negotiation1_ok);
424         assertTrue(negotiation2_ok);
425         assertTrue(negotiation3_ok);
426         assertTrue(!STANDARD.client.getLocalOptionState(15));
427         assertTrue(!STANDARD.client.getRemoteOptionState(15));
428         assertTrue(!STANDARD.client.getLocalOptionState(TelnetOption.TERMINAL_TYPE));
429         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.ECHO));
430         assertTrue(!OPTIONS.client.getRemoteOptionState(TelnetOption.ECHO));
431         assertTrue(OPTIONS.client.getLocalOptionState(TelnetOption.SUPPRESS_GO_AHEAD));
432         assertTrue(!OPTIONS.client.getRemoteOptionState(TelnetOption.SUPPRESS_GO_AHEAD));
433         assertTrue(OPTIONS.client.getLocalOptionState(TelnetOption.TERMINAL_TYPE));
434         assertTrue(ANSI.client.getLocalOptionState(TelnetOption.TERMINAL_TYPE));
435         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.ECHO));
436     }
437 
438 
439     /***
440      * protocol compliance test for option renegotiation
441      ***/
442     public void testOptionRenegotiation() throws Exception
443     {
444         boolean negotiation1_ok = false;
445 
446         byte buffread[] = new byte[6];
447         byte send[] =
448         {
449             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
450             (byte) TelnetOption.ECHO,
451             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
452             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
453             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
454             (byte) TelnetOption.SUPPRESS_GO_AHEAD
455         };
456         byte expected[] =
457         {
458             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
459             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
460             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
461             (byte) TelnetOption.SUPPRESS_GO_AHEAD
462         };
463 
464         byte buffread2[] = new byte[3];
465         byte send2[] =
466         {
467             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
468             (byte) TelnetOption.ECHO,
469         };
470         byte expected2[] =
471         {
472             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
473             (byte) TelnetOption.ECHO,
474         };
475 
476 
477         InputStream is = OPTIONS.server.getInputStream();
478         OutputStream os = OPTIONS.server.getOutputStream();
479         Thread.sleep(1000);
480         is.skip(is.available());
481         os.write(send);
482         os.flush();
483         Thread.sleep(1000);
484         if(is.available() == 6)
485         {
486             is.read(buffread);
487 
488             if(equalBytes(buffread, expected))
489                 negotiation1_ok = true;
490 
491             if(negotiation1_ok)
492             {
493                 negotiation1_ok = false;
494                 os.write(send2);
495                 os.flush();
496                 Thread.sleep(1000);
497                 if(is.available() == 3)
498                 {
499                     is.read(buffread2);
500                     if(equalBytes(buffread2, expected2))
501                             negotiation1_ok = true;
502                 }
503             }
504         }
505 
506         assertTrue(negotiation1_ok);
507         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.ECHO));
508     }
509 
510     /***
511      * test of option negotiation notification
512      ***/
513     public void testNotification() throws Exception
514     {
515         byte buffread1[] = new byte[6];
516         byte send1[] =
517         {
518             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, (byte) 15,
519             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, (byte) 15,
520         };
521 
522         byte buffread2[] = new byte[9];
523         byte send2[] =
524         {
525             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
526             (byte) TelnetOption.TERMINAL_TYPE,
527             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
528             (byte) TelnetOption.ECHO,
529             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
530             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
531             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
532             (byte) TelnetOption.SUPPRESS_GO_AHEAD
533         };
534 
535         byte buffread2b[] = new byte[11];
536 
537 
538         numdo = 0;
539         numdont = 0;
540         numwill = 0;
541         numwont = 0;
542         OPTIONS.client.registerNotifHandler(this);
543 
544         InputStream is1 = STANDARD.server.getInputStream();
545         OutputStream os1 = STANDARD.server.getOutputStream();
546         is1.skip(is1.available());
547         os1.write(send1);
548         os1.flush();
549         Thread.sleep(500);
550         if(is1.available() > 0)
551         {
552             is1.read(buffread1);
553         }
554 
555         InputStream is2 = OPTIONS.server.getInputStream();
556         OutputStream os2 = OPTIONS.server.getOutputStream();
557         Thread.sleep(500);
558         is2.skip(is2.available());
559         os2.write(send2);
560         os2.flush();
561         Thread.sleep(500);
562         if(is2.available() > 0)
563         {
564             is2.read(buffread2);
565                 Thread.sleep(1000);
566                 if(is2.available() > 0)
567                 {
568                     is2.read(buffread2b);
569                 }
570         }
571 
572 
573         assertTrue(numdo == 2);
574         assertTrue(numdont == 1);
575         assertTrue(numwont == 1);
576         assertTrue(numwill == 0);
577     }
578 
579 
580     /***
581      * protocol compliance test in case of option handler removal
582      ***/
583     public void testDeleteOptionHandler() throws Exception
584     {
585         boolean remove_ok = false;
586         boolean remove_invalid_ok1 = false;
587         boolean remove_invalid_ok2 = false;
588 
589         byte buffread[] = new byte[6];
590         byte send[] =
591         {
592             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
593             (byte) TelnetOption.ECHO,
594             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, 
595             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
596             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, 
597             (byte) TelnetOption.SUPPRESS_GO_AHEAD
598         };
599 
600         byte expected[] =
601         {
602             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, 
603             (byte) TelnetOption.SUPPRESS_GO_AHEAD,
604             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, 
605             (byte) TelnetOption.SUPPRESS_GO_AHEAD
606         };
607 
608         InputStream is = OPTIONS.server.getInputStream();
609         OutputStream os = OPTIONS.server.getOutputStream();
610         Thread.sleep(1000);
611         is.skip(is.available());
612         os.write(send);
613         os.flush();
614         Thread.sleep(1000);
615         if(is.available() == 0)
616         {
617             OPTIONS.client.deleteOptionHandler(TelnetOption.SUPPRESS_GO_AHEAD);
618             Thread.sleep(1000);
619             if(is.available() == 6)
620             {
621                 is.read(buffread);
622                 if(equalBytes(buffread, expected))
623                     remove_ok = true;
624             }
625         }
626 
627         try
628         {
629             OPTIONS.client.deleteOptionHandler(TelnetOption.SUPPRESS_GO_AHEAD);
630         }
631         catch (Exception e)
632         {
633             remove_invalid_ok1 = true;
634         }
635 
636         try
637         {
638             OPTIONS.client.deleteOptionHandler(550);
639         }
640         catch (Exception e)
641         {
642             remove_invalid_ok2 = true;
643         }
644 
645         assertTrue(remove_ok);
646         assertTrue(remove_invalid_ok1);
647         assertTrue(remove_invalid_ok2);
648         assertTrue(OPTIONS.client.getLocalOptionState(TelnetOption.ECHO));
649         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.SUPPRESS_GO_AHEAD));
650         assertTrue(!OPTIONS.client.getLocalOptionState(TelnetOption.SUPPRESS_GO_AHEAD));
651     }
652 
653 
654     /***
655      * test of AYT functionality
656      ***/
657     public void testAYT() throws Exception
658     {
659         boolean ayt_true_ok = false;
660         boolean ayt_false_ok = false;
661 
662 
663         byte AYT[] = { (byte) TelnetCommand.IAC, (byte) TelnetCommand.AYT };
664         byte response[] = 
665             { (byte) '[', (byte) 'Y', (byte) 'e', (byte) 's', (byte) ']' };
666         String inputs[] = new String[1];
667         String outputs[] = new String[1];
668         inputs[0] = new String (AYT);
669         outputs[0] = new String (response);
670 
671 
672         OutputStream os = ANSI.server.getOutputStream();
673         InputStream is = ANSI.server.getInputStream();
674         TelnetTestResponder tr = 
675             new TelnetTestResponder(is, os, inputs, outputs, 30000);
676         assertNotNull(tr);
677         boolean res1 = ANSI.client.sendAYT(2000);
678 
679         if(res1 == true)
680             ayt_true_ok=true;
681 
682         Thread.sleep(1000);
683         is.skip(is.available());
684 
685         boolean res2 = ANSI.client.sendAYT(2000);
686 
687         if(res2 == false)
688             ayt_false_ok=true;
689 
690 
691         assertTrue(ayt_true_ok);
692         assertTrue(ayt_false_ok);
693     }
694 
695     /***
696      * test of Spy functionality
697      ***/
698     public void testSpy() throws Exception
699     {
700         boolean test1spy_ok = false;
701         boolean test2spy_ok = false;
702         boolean stopspy_ok = false;
703         byte expected1[] = 
704         	{ (byte) 't', (byte) 'e', (byte) 's', (byte) 't', (byte) '1' };
705         byte expected2[] = 
706         	{ (byte) 't', (byte) 'e', (byte) 's', (byte) 't', (byte) '2' };
707 
708 
709         PipedOutputStream po = new PipedOutputStream();
710         PipedInputStream pi = new PipedInputStream(po);
711 
712         OutputStream os = STANDARD.server.getOutputStream();
713         OutputStream ostc = STANDARD.client.getOutputStream();
714 
715         STANDARD.client.registerSpyStream(po);
716 
717         os.write("test1".getBytes());
718         os.flush();
719 
720         Thread.sleep(1000);
721         byte buffer[] = new byte[5];
722 
723         if(pi.available() == 5)
724         {
725             pi.read(buffer);
726             if(equalBytes(buffer, expected1))
727                 test1spy_ok = true;
728         }
729 
730         ostc.write("test2".getBytes());
731         ostc.flush();
732 
733         Thread.sleep(1000);
734 
735         if(pi.available() == 5)
736         {
737             pi.read(buffer);
738             if(equalBytes(buffer, expected2))
739                 test2spy_ok = true;
740         }
741 
742         STANDARD.client.stopSpyStream();
743         os.write("test1".getBytes());
744         os.flush();
745         ostc.write("test2".getBytes());
746         ostc.flush();
747         Thread.sleep(1000);
748         if(pi.available() == 0)
749         {
750             stopspy_ok = true;
751         }
752 
753 
754         assertTrue(test1spy_ok);
755         assertTrue(test2spy_ok);
756         assertTrue(stopspy_ok);
757     }
758 
759     /***
760      * test of setReaderThread
761      ***/
762     public void testSetReaderThread() throws Exception
763     {
764         boolean negotiation1_ok = false;
765         boolean negotiation2_ok = false;
766         boolean read_ok = false;
767         byte buffread1[] = new byte[6];
768         byte send1[] =
769         {
770             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DO, (byte) 15,
771             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WILL, (byte) 15,
772         };
773         byte expected1[] =
774         {
775             (byte) TelnetCommand.IAC, (byte) TelnetCommand.WONT, (byte) 15,
776             (byte) TelnetCommand.IAC, (byte) TelnetCommand.DONT, (byte) 15,
777         };
778 
779 
780         InputStream is1 = NOREAD.server.getInputStream();
781         OutputStream os1 = NOREAD.server.getOutputStream();
782         is1.skip(is1.available());
783         os1.write(send1);
784         os1.flush();
785         os1.write("A".getBytes());
786         os1.flush();
787         Thread.sleep(1000);
788         InputStream instr = NOREAD.client.getInputStream();
789         byte[] buff = new byte[4];
790         int ret_read = 0;
791 
792         ret_read = instr.read(buff);
793         if((ret_read == 1) && (buff[0] == 'A'))
794         {
795             read_ok = true;
796         }
797 
798        // if(is1.available() == 6)
799         //{
800             is1.read(buffread1);
801 
802             if(equalBytes(buffread1, expected1))
803                 negotiation1_ok = true;
804         //}
805         
806 
807         InputStream is2 = STANDARD.server.getInputStream();
808         OutputStream os2 = STANDARD.server.getOutputStream();
809         Thread.sleep(1000);
810         is2.skip(is2.available());
811         os2.write(send1);
812         os2.flush();
813         Thread.sleep(1000);
814         //if(is2.available() == 6)
815         //{
816             is2.read(buffread1);
817 
818             if(equalBytes(buffread1, expected1))
819                 negotiation2_ok = true;
820         //}
821 
822         assertTrue(!NOREAD.client.getReaderThread());
823         assertTrue(STANDARD.client.getReaderThread());
824         assertTrue("Expected read_ok to be true, got " + read_ok, read_ok);
825         assertTrue("Expected negotiation1_ok to be true, got " + negotiation1_ok, negotiation1_ok);
826         assertTrue("Expected negotiation2_ok to be true, got " + negotiation2_ok, negotiation2_ok);
827     }
828 
829 
830     /***
831      * Helper method. compares two arrays of int
832      ***/
833     protected boolean equalBytes(byte a1[], byte a2[])
834     {
835         if(a1.length != a2.length)
836         {
837             return(false);
838         }
839         else
840         {
841             boolean result = true;
842             for(int ii=0; ii<a1.length; ii++)
843             {
844             	
845                 if(a1[ii]!= a2[ii])
846                 	result = false;
847             }
848             return(result);
849         }
850     }
851 
852     /***
853      * Callback method called when TelnetClient receives an option
854      * negotiation command.
855      * <p>
856      * @param negotiation_code - type of negotiation command received
857      * (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT)
858      * <p>
859      * @param option_code - code of the option negotiated
860      * <p>
861      ***/
862     public void receivedNegotiation(int negotiation_code, int option_code)
863     {
864         if(negotiation_code == TelnetNotificationHandler.RECEIVED_DO)
865         {
866             numdo++;
867         }
868         else if(negotiation_code == TelnetNotificationHandler.RECEIVED_DONT)
869         {
870             numdont++;
871         }
872         else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WILL)
873         {
874             numwill++;
875         }
876         else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WONT)
877         {
878             numwont++;
879         }
880     }
881 
882 }