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