001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.net.telnet;
018    import junit.framework.TestCase;
019    
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.io.OutputStream;
023    import java.io.PipedInputStream;
024    import java.io.PipedOutputStream;
025    
026    /***
027     * JUnit test class for TelnetClient.s
028     * Implements protocol compliance tests
029     * <p>
030     * @author Bruno D'Avanzo
031     ***/
032    public class TelnetClientTest 
033    extends TestCase implements TelnetNotificationHandler
034    {
035        /**
036         * Handy holder to hold both sides of the connection
037         * used in testing for clarity.
038         */
039        private class TestConnection {
040            TelnetTestSimpleServer server;
041            TelnetClient client;
042            int port;
043            TestConnection(
044                    TelnetTestSimpleServer server, 
045                    TelnetClient client, 
046                    int port) 
047            {
048                this.server = server;
049                this.client = client;
050                this.port = port;
051            }
052            protected void close() {
053                TelnetClientTest.this.closeConnection(
054                        this.server, this.client, this.port);
055            }  
056        }   
057        
058        // four connections with different properties
059        // to use in tests.
060        private TestConnection STANDARD;
061        private TestConnection OPTIONS;
062        private TestConnection ANSI;
063        private TestConnection NOREAD;
064        
065        private int NUM_CONNECTIONS = 4;
066        
067     
068        protected int numdo = 0;
069        protected int numdont = 0;
070        protected int numwill = 0;
071        protected int numwont = 0;
072    
073        /***
074         * main for running the test.
075         ***/
076        public static void main(String args[])
077        {
078            junit.textui.TestRunner.run(TelnetClientTest.class);
079        }
080    
081        /***
082         * open connections needed for the tests for the test.
083         ***/
084        @Override
085        protected void setUp() throws Exception 
086        {
087            super.setUp();
088            for (int port = 3333, socket = 0; socket < NUM_CONNECTIONS && port < 4000; port++) 
089            {
090                TelnetTestSimpleServer server = null;
091                TelnetClient client = null;
092               try {
093                   server = new TelnetTestSimpleServer(port);
094                    switch (socket) {
095                        case 0:
096                            client = new TelnetClient();
097                            // redundant but makes code clearer.
098                            client.setReaderThread(true);
099                            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    }