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