Unit tests for send methods
[appc.git] / appc-config / appc-config-adaptor / provider / src / test / java / org / onap / appc / ccadaptor / SshJcraftWrapperTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.ccadaptor;
26
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.assertFalse;
31 import static org.junit.Assert.fail;
32 import static org.mockito.BDDMockito.given;
33 import static org.mockito.Matchers.any;
34 import static org.mockito.Matchers.anyInt;
35 import static org.mockito.Matchers.anyString;
36 import static org.mockito.Mockito.atLeastOnce;
37 import static org.mockito.Mockito.doThrow;
38 import static org.mockito.Mockito.inOrder;
39 import static org.mockito.Mockito.mock;
40 import static org.mockito.Mockito.times;
41 import static org.mockito.Mockito.verify;
42 import static org.mockito.Mockito.verifyNoMoreInteractions;
43 import static org.mockito.Mockito.verifyZeroInteractions;
44
45 import com.jcraft.jsch.ChannelShell;
46 import com.jcraft.jsch.ChannelSubsystem;
47 import com.jcraft.jsch.JSch;
48 import com.jcraft.jsch.JSchException;
49 import com.jcraft.jsch.Session;
50 import com.jcraft.jsch.UserInfo;
51 import java.io.File;
52 import java.io.FileNotFoundException;
53 import java.io.IOException;
54 import java.io.InputStream;
55 import java.io.OutputStream;
56 import java.net.URL;
57
58 import org.apache.commons.lang.StringUtils;
59 import org.junit.Assert;
60 import org.junit.Before;
61 import org.junit.Ignore;
62 import org.junit.Test;
63 import org.junit.runner.RunWith;
64 import org.mockito.InOrder;
65 import org.mockito.Mock;
66 import org.mockito.runners.MockitoJUnitRunner;
67 import org.apache.commons.io.IOUtils;
68
69 @RunWith(MockitoJUnitRunner.class)
70 public class SshJcraftWrapperTest {
71
72     private static final String USER = "username";
73     private static final String PASS = "pass";
74     private static final String HOST = "hostname";
75     private static final String SUBSYSTEM = "netconf";
76     private static final String PROMPT = "]]>]]>";
77     private static final String SEARCH_STR = "</rpc-reply>";
78     private static final int READ_TIMEOUT = 180_000;
79     private static final int PORT_NUM = 23;
80     private static final int SESSION_TIMEOUT = 30_000;
81     private static final int READ_INTERVAL_MS = 1;
82     private static final int READ_BUFFER_SIZE = 10;
83
84     private SshJcraftWrapper cut;
85     @Mock
86     private JSch jSchMock;
87     @Mock
88     private Session session;
89     @Mock
90     private ChannelShell channelShell;
91     @Mock
92     private ChannelSubsystem channelSubsystem;
93     @Mock
94     private InputStream channelIs;
95     @Mock
96     private OutputStream channelOs;
97
98     @Before
99     public void setUpTest() throws Exception {
100         InputStream is = IOUtils.toInputStream("test input stream:~#", "UTF-8");
101         given(channelShell.getInputStream()).willReturn(is);
102         given(channelSubsystem.getInputStream()).willReturn(is);
103         given(session.openChannel(SshJcraftWrapper.CHANNEL_SHELL_TYPE)).willReturn(channelShell);
104         given(session.openChannel(SshJcraftWrapper.CHANNEL_SUBSYSTEM_TYPE)).willReturn(channelSubsystem);
105         given(jSchMock.getSession(anyString(), anyString(), anyInt())).willReturn(session);
106         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, READ_BUFFER_SIZE);
107     }
108
109     @Ignore
110     @Test
111     public void TestCheckIfReceivedStringMatchesDelimeter(){
112         SshJcraftWrapper wrapper = new SshJcraftWrapper();
113         wrapper.getTheDate();
114         boolean result = wrapper.checkIfReceivedStringMatchesDelimeter("#", "test#", "test#");
115         Assert.assertEquals(true, result);
116     }
117
118     @Ignore
119     @Test
120     public void testRemoveWhiteSpaceAndNewLineCharactersAroundString(){
121         SshJcraftWrapper wrapper = new SshJcraftWrapper();
122         String nameSpace = wrapper.removeWhiteSpaceAndNewLineCharactersAroundString("namespace ");
123         Assert.assertEquals("namespace", nameSpace);
124     }
125
126     @Ignore
127     @Test
128     public void testStripOffCmdFromRouterResponse(){
129         SshJcraftWrapper wrapper = new SshJcraftWrapper();
130         String result = wrapper.stripOffCmdFromRouterResponse("test\nsuccess");
131         Assert.assertEquals("success\n", result);
132     }
133
134     //@Test
135     public void testGetLastFewLinesOfFile() throws FileNotFoundException, IOException{
136         SshJcraftWrapper wrapper = new SshJcraftWrapper();
137         URL path = SshJcraftWrapperTest.class.getResource("Test");
138         File file = new File(path.getFile());
139         String value = wrapper.getLastFewLinesOfFile(file,1);
140         Assert.assertEquals("\nTest data 3", value);
141     }
142
143     @Ignore
144     @Test(expected=Exception.class)
145     public void testSetRouterCommandType() throws IOException{
146         SshJcraftWrapper wrapper = new SshJcraftWrapper();
147         wrapper.setRouterCommandType("test");
148         wrapper.receiveUntil("test", 2, "test");
149     }
150
151     @Ignore
152     @Test
153     public void testValues() throws IOException{
154         SshJcraftWrapper wrapper = new SshJcraftWrapper();
155         wrapper.setEquipNameCode("testcode");
156         wrapper.setRouterCommandType("testcommand");
157         String equipName = wrapper.getEquipNameCode();
158         wrapper.getHostName();
159         wrapper.getPassWord();
160         wrapper.getRouterName();
161         wrapper.getUserName();
162         wrapper.getTheDate();
163         Assert.assertEquals("testcode", equipName);
164     }
165
166     @Ignore
167     @Test(expected=Exception.class)
168     public void testSetRouterCommandType2() throws IOException{
169         SshJcraftWrapper wrapper = new SshJcraftWrapper();
170         wrapper.appendToRouterFile("test", 2);
171         StringBuilder sb = new StringBuilder();
172         sb.append("test");
173         wrapper.appendToRouterFile("Test.txt", sb);
174         wrapper.receiveUntilBufferFlush(3, 4, "test");
175     }
176
177     @Ignore
178     @Test(expected=Exception.class)
179     public void testSetRouterCommandType3() throws IOException{
180         SshJcraftWrapper wrapper = new SshJcraftWrapper();
181         wrapper.checkIfReceivedStringMatchesDelimeter(3, "test");
182     }
183
184     //real jUnits
185     @Test(expected = IOException.class)
186     public void connect_shouldThrowIOException_whenJSchFails() throws Exception {
187         //given
188         given(jSchMock.getSession(anyString(), anyString(), anyInt())).willThrow(new JSchException());
189
190         //when
191         cut.connect(HOST, USER, PASS);
192
193         //then
194         fail("IOException should be thrown");
195     }
196
197     @Test
198     public void connect_shouldSetVariables() throws Exception {
199         //when
200         cut.connect(HOST, USER, PASS);
201
202         //then
203         assertEquals(HOST, cut.getHostName());
204         assertEquals(HOST, cut.getRouterName());
205         assertEquals(USER, cut.getUserName());
206         assertEquals(PASS, cut.getPassWord());
207     }
208
209     @Test
210     public void connect_shouldSetUpSessionWithProperInvocationOrder() throws Exception {
211         //given
212         InOrder inOrder =  inOrder(session, channelShell);
213
214         //when
215         cut.connect(HOST, USER, PASS);
216
217         //then
218         verifySessionConfigurationOrderForChannelShellOpenning(
219             inOrder, USER, HOST, PASS, SshJcraftWrapper.DEFAULT_PORT, SESSION_TIMEOUT);
220     }
221
222     @Test
223     public void connect_shouldFinishSuccessfully_whenExceptionThrownDuringReceivingPhase() throws Exception {
224         //given
225         doThrow(new JSchException()).when(session).setTimeout(anyInt());
226
227         //when
228         cut.connect(HOST, USER, PASS);
229
230         //then
231         verify(session).setTimeout(anyInt());
232     }
233
234     @Test(expected = IOException.class)
235     public void connect_withSubsystem_shouldThrowIOException_whenJSchFails() throws Exception {
236         //given
237         given(jSchMock.getSession(anyString(), anyString(), anyInt())).willThrow(new JSchException());
238
239         //when
240         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
241
242         //then
243         fail("IOException should be thrown");
244     }
245
246     @Test
247     public void connect_withSubsystem_shouldSetRouterName() throws Exception {
248         //when
249         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
250
251         //then
252         assertEquals(HOST, cut.getRouterName());
253     }
254
255     @Test
256     public void connect_withSubsystem_shouldSetUpSessionWithProperInvocationOrder() throws Exception {
257         //given
258         InOrder inOrder =  inOrder(session, channelSubsystem);
259
260         //when
261         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
262
263         //then
264         verify(jSchMock).getSession(USER, HOST, PORT_NUM);
265         inOrder.verify(session).setPassword(PASS);
266         inOrder.verify(session).setUserInfo(any(UserInfo.class));
267         inOrder.verify(session).setConfig(SshJcraftWrapper.STRICT_HOST_CHECK_KEY, SshJcraftWrapper.STRICT_HOST_CHECK_VALUE);
268         inOrder.verify(session).connect(SESSION_TIMEOUT);
269         inOrder.verify(session).setServerAliveCountMax(0);
270         inOrder.verify(session).openChannel(SshJcraftWrapper.CHANNEL_SUBSYSTEM_TYPE);
271         inOrder.verify(channelSubsystem).getInputStream();
272         inOrder.verify(channelSubsystem).connect(anyInt());
273         inOrder.verifyNoMoreInteractions();
274         verifyNoMoreInteractions(jSchMock);
275     }
276
277     @Test(expected = IOException.class)
278     public void connect_withPrompt_shouldThrowIOException_whenJSchFails() throws Exception {
279         //given
280         given(jSchMock.getSession(anyString(), anyString(), anyInt())).willThrow(new JSchException());
281
282         //when
283         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT);
284
285         //then
286         fail("IOException should be thrown");
287     }
288
289     @Test
290     public void connect_withPrompt_shouldSetVariables() throws Exception {
291         //when
292         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT);
293
294         //then
295         assertEquals(HOST, cut.getHostName());
296         assertEquals(HOST, cut.getRouterName());
297         assertEquals(USER, cut.getUserName());
298         assertEquals(PASS, cut.getPassWord());
299     }
300
301     @Test
302     public void connect_withPrompt_shouldFinishSuccessfully_whenExceptionThrownDuringReceivingPhase() throws Exception {
303         //given
304         doThrow(new JSchException()).when(session).setTimeout(anyInt());
305
306         //when
307         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT);
308
309         //then
310         verify(session).setTimeout(anyInt());
311     }
312
313     @Test
314     public void connect_withPrompt_shouldSetUpSessionWithProperInvocationOrder() throws Exception {
315         //given
316         InOrder inOrder =  inOrder(session, channelShell);
317
318         //when
319         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT);
320
321         //then
322         verifySessionConfigurationOrderForChannelShellOpenning(
323             inOrder, USER, HOST, PASS, SshJcraftWrapper.DEFAULT_PORT, SESSION_TIMEOUT);
324     }
325
326     @Test(expected = IOException.class)
327     public void connect_withPort_shouldThrowIOException_whenJSchFails() throws Exception {
328         //given
329         given(jSchMock.getSession(anyString(), anyString(), anyInt())).willThrow(new JSchException());
330
331         //when
332         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT, PORT_NUM);
333
334         //then
335         fail("IOException should be thrown");
336     }
337
338     @Test
339     public void connect_withPort_shouldSetVariables() throws Exception {
340         //when
341         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT, PORT_NUM);
342
343         //then
344         assertEquals(HOST, cut.getHostName());
345         assertEquals(HOST, cut.getRouterName());
346         assertEquals(USER, cut.getUserName());
347         assertEquals(PASS, cut.getPassWord());
348     }
349
350     @Test
351     public void connect_withPort_shouldFinishSuccessfully_whenExceptionThrownDuringReceivingPhase() throws Exception {
352         //given
353         doThrow(new JSchException()).when(session).setTimeout(anyInt());
354
355         //when
356         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT, PORT_NUM);
357
358         //then
359         verify(session).setTimeout(anyInt());
360     }
361
362     @Test
363     public void connect_withPort_shouldSetUpSessionWithProperInvocationOrder() throws Exception {
364         //given
365         InOrder inOrder =  inOrder(session, channelShell);
366
367         //when
368         cut.connect(HOST, USER, PASS, PROMPT, SESSION_TIMEOUT, PORT_NUM);
369
370         //then
371         verifySessionConfigurationOrderForChannelShellOpenning(inOrder, USER, HOST, PASS, PORT_NUM, SESSION_TIMEOUT);
372     }
373
374     private void verifySessionConfigurationOrderForChannelShellOpenning(InOrder inOrder, String user, String host, String pass, int port, int sessionTimeout) throws Exception {
375         verify(jSchMock).getSession(user, host, port);
376         inOrder.verify(session).setPassword(pass);
377         inOrder.verify(session).setUserInfo(any(UserInfo.class));
378         inOrder.verify(session).setConfig(SshJcraftWrapper.STRICT_HOST_CHECK_KEY, SshJcraftWrapper.STRICT_HOST_CHECK_VALUE);
379         inOrder.verify(session).connect(sessionTimeout);
380         inOrder.verify(session).setServerAliveCountMax(0);
381         inOrder.verify(session).openChannel(SshJcraftWrapper.CHANNEL_SHELL_TYPE);
382         inOrder.verify(channelShell).getInputStream();
383         inOrder.verify(channelShell).connect();
384         inOrder.verify(session).setTimeout(anyInt());
385         inOrder.verifyNoMoreInteractions();
386         verifyNoMoreInteractions(jSchMock);
387     }
388
389     @Test
390     public void closeConnection_shouldCloseReaderChannelAndSession_inAGivenOrder() throws Exception {
391         //given
392         provideConnectedSubsystemInstance();
393         InOrder inOrder = inOrder(channelIs, channelSubsystem, session);
394
395         //when
396         cut.closeConnection();
397
398         //then
399         inOrder.verify(channelIs).close();
400         inOrder.verify(channelSubsystem).disconnect();
401         inOrder.verify(session).disconnect();
402         inOrder.verifyNoMoreInteractions();
403     }
404
405     @Test
406     public void closeConnection_shouldCloseChannelAndSession_whenClosingReaderFails() throws Exception {
407         //given
408         doThrow(new IOException("failed to close reader")).when(channelIs).close();
409         provideConnectedSubsystemInstance();
410
411         //when
412         cut.closeConnection();
413
414         //then
415         verify(channelIs).close();
416         verify(channelSubsystem).disconnect();
417         verify(session).disconnect();
418     }
419
420     @Test
421     public void closeConnection_shouldBeIdempotent_whenRunOnNewInstance() throws Exception {
422         //given
423         assertFalse(cut.isConnected());
424
425         //when
426         cut.closeConnection();
427
428         //then
429         assertFalse(cut.isConnected());
430     }
431
432     @Test
433     public void closeConnection_shouldBeIdempotent_whenRunTwiceOnConnectedInstance() throws Exception {
434         //given
435         provideConnectedSubsystemInstance();
436
437         //when
438         cut.closeConnection();
439         cut.closeConnection();
440
441         //then
442         assertFalse(cut.isConnected());
443     }
444
445     @Test
446     public void closeConnection_shouldCloseResourcesOnce_whenRunTwiceOnConnectedInstance() throws Exception {
447         //given
448         provideConnectedSubsystemInstance();
449
450         //when
451         cut.closeConnection();
452         cut.closeConnection();
453
454         //then
455         verify(channelIs, times(1)).close();
456         verify(channelSubsystem, times(1)).disconnect();
457         verify(session, times(1)).disconnect();
458     }
459
460     private void provideConnectedSubsystemInstance() throws Exception {
461         given(channelSubsystem.getInputStream()).willReturn(channelIs);
462         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
463         assertTrue(cut.isConnected());
464     }
465
466     //receiveUntil tests begin
467     @Test(expected = IllegalStateException.class)
468     public void receiveUntil_shouldThrowIllegalStateException_whenInstanceIsNotConnected() throws Exception {
469         //given
470         assertFalse(cut.isConnected());
471
472         //when
473         cut.receiveUntil(SEARCH_STR, READ_TIMEOUT, "");
474
475         //then
476         fail("IllegalStateException should be thrown");
477     }
478
479     @Test(expected = IllegalStateException.class)
480     public void receiveUntil_shouldThrowIllegalStateException_whenJschReaderStreamIsNotAvailable() throws Exception {
481         //given
482         provideConnectedSubsystemInstance();
483         given(channelIs.available()).willReturn(0);
484
485         //when
486         cut.receiveUntil(SEARCH_STR, READ_TIMEOUT, "");
487
488         //then
489         fail("IllegalStateException should be thrown");
490     }
491
492     @Test(expected = TimedOutException.class)
493     public void receiveUntil_shouldThrowTimedOutException_whenSessionFails() throws Exception {
494         //given
495         given(channelSubsystem.getInputStream()).willReturn(IOUtils.toInputStream("test input stream:~#", "UTF-8"));
496         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
497         assertTrue(cut.isConnected());
498         doThrow(new JSchException("Session is not available")).when(session).setTimeout(anyInt());
499
500         //when
501         cut.receiveUntil(SEARCH_STR, READ_TIMEOUT, "");
502
503         //then
504         fail("TimedOutException should be thrown");
505     }
506
507     @Test(expected = TimedOutException.class)
508     public void receiveUntil_shouldThrowTimedOutException_whenReadFails() throws Exception {
509         //given
510         provideConnectedSubsystemInstance();
511         given(channelIs.available()).willReturn(1);
512         given(channelIs.read(any(), anyInt(), anyInt())).willThrow(new IOException("Could not read stream"));
513
514         //when
515         cut.receiveUntil(SEARCH_STR, READ_TIMEOUT, "");
516
517         //then
518         fail("TimedOutException should be thrown");
519     }
520
521     @Test(expected = TimedOutException.class)
522     public void receiveUntil_shouldThrowException_whenTimeoutIsReached() throws Exception {
523         //given
524         String streamContent = "test input stream:~#";
525         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
526
527         //when
528         cut.receiveUntil(SEARCH_STR, -1000, " Some fake command\n");
529
530         //then
531         fail("TimedOutException should be thrown");
532     }
533
534     @Test(expected = TimedOutException.class)
535     public void receiveUntil_shouldThrowException_whenReachedEndOfStream_andCouldNotReadMoreBytes() throws Exception {
536         //given
537         provideConnectedSubsystemInstance();
538         given(channelIs.available()).willReturn(1);
539         given(channelIs.read(any(), anyInt(), anyInt())).willReturn(-1);
540
541         //when
542         cut.receiveUntil(SEARCH_STR, READ_TIMEOUT, "");
543
544         //then
545         fail("TimedOutException should be thrown");
546     }
547
548     @Test
549     public void receiveUntil_shouldReadUnderlyingStream_andStripOffFirstLine() throws Exception {
550         //given
551         String command = "Command"+SshJcraftWrapper.EOL;
552         String reply = "Reply"+SshJcraftWrapper.EOL;
553         String streamContent = command+reply+PROMPT;
554         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
555
556         //when
557         String result = cut.receiveUntil(PROMPT, SESSION_TIMEOUT, command);
558
559         //then
560         assertEquals(reply+PROMPT, result);
561     }
562
563     @Test
564     public void receiveUntil_shouldReadUnderlyingStream_andReturnWholeReadString() throws Exception {
565         //given
566         String streamContent = "Command and Reply in just one line"+PROMPT;
567         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
568
569         //when
570         String result = cut.receiveUntil(PROMPT, SESSION_TIMEOUT, streamContent);
571
572         //then
573         assertEquals(streamContent, result);
574     }
575
576     @Test
577     public void receiveUntil_shouldCutOffSpecialCharactersFromStream() throws Exception {
578         //given
579         char special1 = Character.UNASSIGNED;
580         char special2 = Character.ENCLOSING_MARK;
581         char special3 = Character.LINE_SEPARATOR;
582         char special4 = Character.MODIFIER_SYMBOL;
583         StringBuilder sb = new StringBuilder("Command");
584         sb.append(special1).append("With").append(special2).append("Special")
585             .append(special3).append("Characters").append(special4).append("Set").append(PROMPT);
586
587         provideConnectedSubsystemInstanceWithStreamContent(sb.toString());
588
589         //when
590         String result = cut.receiveUntil(PROMPT, SESSION_TIMEOUT, "");
591
592         //then
593         assertEquals("CommandWithSpecialCharactersSet"+PROMPT, result);
594     }
595
596     @Test
597     public void receiveUntil_shouldReadUnderlyingStream_untilCLIDelimiterFound_whenProperDelimiterSet() throws Exception {
598         //given
599         String cliDelimiter = "#$";
600         String delimiters = PROMPT+SshJcraftWrapper.DELIMITERS_SEPARATOR+cliDelimiter;
601         String streamContent = "Command for CLI invocation #";
602         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
603
604         //when
605         String result = cut.receiveUntil(delimiters, SESSION_TIMEOUT, streamContent);
606
607         //then
608         assertEquals(streamContent, result);
609     }
610
611     @Test
612     public void receiveUntil_shouldReadUnderlyingStream_untilCLIDelimiterFound_whenCLICommandSet() throws Exception {
613         //given
614         String streamContent = "Command for CLI invocation #";
615         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
616         cut.setRouterCommandType("CLI");
617
618         //when
619         String result = cut.receiveUntil("", SESSION_TIMEOUT, streamContent);
620
621         //then
622         assertEquals(streamContent, result);
623     }
624
625     @Test
626     public void receiveUntil_shouldReadUnderlyingStream_untilCLIDelimiterFound_forShowConfigCommand() throws Exception {
627         //given
628         String streamContent = "show config\nconfig content#";
629         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
630
631         //when
632         String result = cut.receiveUntil("#", SESSION_TIMEOUT, streamContent);
633
634         //then
635         assertEquals("config content#", result);
636     }
637
638     @Test
639     public void receiveUntil_shouldWriteOutputToRouterFile_whenReadingIOSXRswConfigFile_confirmFromFile() throws Exception {
640         receiveUntil_shouldWriteOutputToRouterFile_whenReadingIOSXRswConfigFile();
641     }
642
643     @Test
644     public void receiveUntil_shouldWriteOutputToRouterFile_whenReadingIOSXRswConfigFile_confirmFromBuffer() throws Exception {
645         //given
646         int biggerBufferSize = 32;
647         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, biggerBufferSize);
648
649         receiveUntil_shouldWriteOutputToRouterFile_whenReadingIOSXRswConfigFile();
650     }
651
652     private void receiveUntil_shouldWriteOutputToRouterFile_whenReadingIOSXRswConfigFile() throws Exception {
653         //given
654         String routerName = "router";
655         String command = "RP/0/RP0/CPU0: "+routerName+" #IOS_XR_uploadedSwConfigCmd";
656         String configFileEnding = "\nXML>";
657         String streamContent = "Config file\ncontent"+configFileEnding;
658         provideConnectedSubsystemInstanceWithStreamContent(streamContent);
659
660         //when
661         String result = cut.receiveUntil("", SESSION_TIMEOUT, command);
662
663         //then
664         assertNull(result); //TO-DO: it would be better to return empty string in this situation
665         assertFileExist(routerName);
666
667         //after
668         teardownFile(routerName);
669     }
670
671     private void provideConnectedSubsystemInstanceWithStreamContent( String streamContent) throws Exception {
672         given(channelSubsystem.getInputStream()).willReturn(IOUtils.toInputStream(streamContent, "UTF-8"));
673         cut.connect(HOST, USER, PASS, SESSION_TIMEOUT, PORT_NUM, SUBSYSTEM);
674         assertTrue(cut.isConnected());
675     }
676
677     private void teardownFile(String routerName) {
678         File file = new File(routerName);
679         if(file.exists() && file.isFile()) {
680             file.delete();
681         }
682     }
683
684     private void assertFileExist(String fileName) {
685         File file = new File(fileName);
686         assertTrue(file.exists());
687         assertTrue(file.isFile());
688     }
689
690     @Test
691     public void send_withReceive_shouldWriteCommandToChannelOutputStream_andReturnReceivedCommand() throws Exception {
692         //given
693         String command = "sdc";
694         String delimiter = ":";
695         InOrder inOrder = inOrder(channelOs);
696         provideConnectedSubsystemInstanceWithStreamContent(command+delimiter);
697         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
698
699         //when
700         String result = cut.send(command, delimiter);
701
702         //then
703         verifySdcCommandSent(inOrder);
704         assertEquals(command+delimiter, result);
705     }
706
707     @Test
708     public void send_shouldWriteCommandToChannelOutputStream() throws Exception {
709         //given
710         String command = "sdc";
711         InOrder inOrder = inOrder(channelOs);
712         provideConnectedSubsystemInstance();
713         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
714
715         //when
716         cut.send(command);
717
718         //then
719         verifySdcCommandSent(inOrder);
720     }
721
722     private void verifySdcCommandSent(InOrder inOrder) throws IOException {
723         inOrder.verify(channelOs).write('s');
724         inOrder.verify(channelOs).write('d');
725         inOrder.verify(channelOs).write('c');
726         inOrder.verify(channelOs, atLeastOnce()).flush();
727         inOrder.verify(channelOs, atLeastOnce()).close();
728         inOrder.verifyNoMoreInteractions();
729     }
730
731     @Test
732     public void send_withReceive_shouldWriteCommandInChunksToChannelOutputStream_andReturnReceivedCommand() throws Exception {
733         //given
734         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, 1);
735         cut.setCharsChunkSize(1);
736         String command = "sdc";
737         String delimiter = ":";
738         int timeout = 9000;
739         provideConnectedSubsystemInstanceWithStreamContent(command+delimiter+SshJcraftWrapper.EOL);
740         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
741         InOrder inOrder = inOrder(channelOs, session);
742
743         //when
744         String result = cut.send(command, delimiter);
745
746         //then
747         verifySdcCommandSentInChunk(inOrder, timeout);
748         assertEquals(command+delimiter, result);
749     }
750
751     @Test
752     public void send_shouldWriteCommandInChunksToChannelOutputStream() throws Exception {
753         //given
754         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, 1);
755         cut.setCharsChunkSize(1);
756         String command = "sdc";
757         int timeout = 9000;
758         provideConnectedSubsystemInstanceWithStreamContent(command+SshJcraftWrapper.EOL);
759         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
760         InOrder inOrder = inOrder(channelOs, session);
761
762         //when
763         cut.send(command);
764
765         //then
766         verifySdcCommandSentInChunk(inOrder, timeout);
767     }
768
769     private void verifySdcCommandSentInChunk(InOrder inOrder, int timeout) throws Exception{
770         inOrder.verify(channelOs).write('s');
771         inOrder.verify(channelOs).flush();
772         inOrder.verify(session).setTimeout(timeout);
773         inOrder.verify(channelOs).write('d');
774         inOrder.verify(channelOs).flush();
775         inOrder.verify(session).setTimeout(timeout);
776         inOrder.verify(channelOs).write('c');
777         inOrder.verify(channelOs).flush();
778         inOrder.verify(session).setTimeout(timeout);
779         inOrder.verify(channelOs, atLeastOnce()).flush();
780         inOrder.verify(channelOs, atLeastOnce()).close();
781         inOrder.verifyNoMoreInteractions();
782     }
783
784     @Test
785     public void send_withReceive_shouldReturnActualResult_whenTimeoutReached() throws Exception {
786         //given
787         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, 1);
788         cut.setCharsChunkSize(1);
789         cut.setSessionTimeoutMs(-1);
790         String command = "sdc";
791         String delimiter = ":";
792         provideConnectedSubsystemInstanceWithStreamContent(command+SshJcraftWrapper.EOL);
793         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
794
795         //when
796         String result = cut.send(command, delimiter);
797
798         //then
799         assertEquals(StringUtils.EMPTY, result);
800     }
801
802     @Test
803     public void send_withReceive_shouldReturnActualResult_whenCouldNotSetSessionTimeout() throws Exception {
804         //given
805         cut = new SshJcraftWrapper(jSchMock, READ_INTERVAL_MS, 1);
806         cut.setCharsChunkSize(1);
807         String command = "sdc";
808         String delimiter = ":";
809         provideConnectedSubsystemInstanceWithStreamContent(command+SshJcraftWrapper.EOL);
810         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
811         doThrow(new JSchException("failed to set session timeout")).when(session).setTimeout(anyInt());
812
813         //when
814         String result = cut.send(command, delimiter);
815
816         //then
817         assertEquals(StringUtils.EMPTY, result);
818     }
819
820     @Test
821     public void sendChar_shouldWriteCharacterToChannelOutputStream() throws Exception {
822         //given
823         int charNum = 100;
824         provideConnectedSubsystemInstance();
825         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
826         InOrder inOrder = inOrder(channelOs);
827
828         //when
829         cut.sendChar(charNum);
830
831         //then
832         inOrder.verify(channelOs).write(charNum);
833         inOrder.verify(channelOs, atLeastOnce()).flush();
834         inOrder.verify(channelOs, atLeastOnce()).close();
835         inOrder.verifyNoMoreInteractions();
836     }
837
838     @Test(expected = IOException.class)
839     public void sendChar_shouldRethrowIOException_whenOccurs() throws Exception {
840         //given
841         int charNum = 100;
842         provideConnectedSubsystemInstance();
843         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
844         doThrow(new IOException()).when(channelOs).write(charNum);
845
846         //when
847         cut.sendChar(charNum);
848
849         //then
850         fail("IOException should be thrown");
851     }
852
853     @Test
854     public void send_withByteBuffer_shouldWriteBufferToChannelOutputStream() throws Exception {
855         //given
856         byte[] buffer = "Command".getBytes();
857         int offset = 5;
858         provideConnectedSubsystemInstance();
859         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
860         InOrder inOrder = inOrder(channelOs);
861
862         //when
863         cut.send(buffer,offset,buffer.length);
864
865         //then
866         inOrder.verify(channelOs).write(buffer, offset, buffer.length);
867         inOrder.verify(channelOs, atLeastOnce()).flush();
868         inOrder.verify(channelOs, atLeastOnce()).close();
869         inOrder.verifyNoMoreInteractions();
870     }
871
872     @Test(expected = IOException.class)
873     public void send_withByteBuffer_shouldRethrowIOException_whenOccurs() throws Exception {
874         //given
875         byte[] buffer = "Command".getBytes();
876         int offset = 5;
877         provideConnectedSubsystemInstance();
878         given(channelSubsystem.getOutputStream()).willReturn(channelOs);
879         doThrow(new IOException()).when(channelOs).write(buffer, offset, buffer.length);
880
881         //when
882         cut.send(buffer,offset,buffer.length);
883
884         //then
885         fail("IOException should be thrown");
886     }
887 }