342382662f33a8b21732665c429a6750d9e39a73
[nonrtric/plt/ranpm.git] / datafilecollector / src / test / java / org / onap / dcaegen2 / collectors / datafile / ftp / FtpesClientTest.java
1 /*
2  * ============LICENSE_START======================================================================
3  * Copyright (C) 2018-2019 Nordix Foundation. All rights reserved.
4  * Copyright (C) 2020 Nokia. All rights reserved.
5  * ===============================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7  * in compliance with 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 distributed under the License
12  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing permissions and limitations under
14  * the License.
15  * ============LICENSE_END========================================================================
16  */
17
18 package org.onap.dcaegen2.collectors.datafile.ftp;
19
20 import static org.assertj.core.api.Assertions.assertThatThrownBy;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.Mockito.doReturn;
23 import static org.mockito.Mockito.doThrow;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.verifyNoMoreInteractions;
29 import static org.mockito.Mockito.when;
30
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36
37 import javax.net.ssl.KeyManager;
38 import javax.net.ssl.TrustManager;
39
40 import org.apache.commons.net.ftp.FTP;
41 import org.apache.commons.net.ftp.FTPSClient;
42 import org.junit.jupiter.api.BeforeEach;
43 import org.junit.jupiter.api.Test;
44 import org.mockito.ArgumentMatchers;
45 import org.onap.dcaegen2.collectors.datafile.commons.FileServerData;
46 import org.springframework.http.HttpStatus;
47
48 public class FtpesClientTest {
49
50     private static final String REMOTE_FILE_PATH = "/dir/sample.txt";
51     private static final Path LOCAL_FILE_PATH = Paths.get("target/sample.txt");
52     private static final String XNF_ADDRESS = "127.0.0.1";
53     private static final int PORT = 8021;
54     private static final String FTP_KEY_PATH = "ftpKeyPath";
55     private static final String FTP_KEY_PASSWORD = "ftpKeyPassword";
56     private static final Path TRUSTED_CA_PATH = Paths.get("trustedCaPath");
57     private static final String TRUSTED_CA_PASSWORD = "trustedCaPassword";
58
59     private static final String USERNAME = "bob";
60     private static final String PASSWORD = "123";
61
62     private FTPSClient ftpsClientMock = mock(FTPSClient.class);
63     private KeyManager keyManagerMock = mock(KeyManager.class);
64     private TrustManager trustManagerMock = mock(TrustManager.class);
65     private InputStream inputStreamMock = mock(InputStream.class);
66     private OutputStream outputStreamMock = mock(OutputStream.class);
67
68     FtpesClient clientUnderTestSpy;
69
70     private FileServerData createFileServerData() {
71         return FileServerData.builder() //
72             .serverAddress(XNF_ADDRESS) //
73             .userId(USERNAME).password(PASSWORD) //
74             .port(PORT) //
75             .build();
76     }
77
78     @BeforeEach
79     protected void setUp() throws Exception {
80         clientUnderTestSpy = spy(new FtpesClient(createFileServerData(), Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD,
81             TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD));
82         clientUnderTestSpy.realFtpsClient = ftpsClientMock;
83     }
84
85     private void verifyFtpsClientMock_openOk() throws Exception {
86         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
87
88         when(ftpsClientMock.retrieveFile(ArgumentMatchers.eq(REMOTE_FILE_PATH),
89             ArgumentMatchers.any(OutputStream.class))).thenReturn(true);
90         verify(ftpsClientMock).setNeedClientAuth(true);
91         verify(ftpsClientMock).setKeyManager(keyManagerMock);
92         verify(ftpsClientMock).setTrustManager(trustManagerMock);
93         verify(ftpsClientMock).connect(XNF_ADDRESS, PORT);
94         verify(ftpsClientMock).login(USERNAME, PASSWORD);
95         verify(ftpsClientMock).getReplyCode();
96         verify(ftpsClientMock, times(1)).enterLocalPassiveMode();
97         verify(ftpsClientMock).execPBSZ(0);
98         verify(ftpsClientMock).execPROT("P");
99         verify(ftpsClientMock).setFileType(FTP.BINARY_FILE_TYPE);
100         verify(ftpsClientMock).setBufferSize(1024 * 1024);
101     }
102
103     @Test
104     public void collectFile_allOk() throws Exception {
105
106         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
107         doReturn(trustManagerMock).when(clientUnderTestSpy).getTrustManager(TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD);
108         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
109         doReturn(true).when(ftpsClientMock).login(USERNAME, PASSWORD);
110         doReturn(HttpStatus.OK.value()).when(ftpsClientMock).getReplyCode();
111
112         clientUnderTestSpy.open();
113
114         doReturn(true).when(ftpsClientMock).retrieveFile(REMOTE_FILE_PATH, outputStreamMock);
115         clientUnderTestSpy.collectFile(REMOTE_FILE_PATH, LOCAL_FILE_PATH);
116
117         doReturn(true).when(ftpsClientMock).isConnected();
118         clientUnderTestSpy.close();
119
120         verifyFtpsClientMock_openOk();
121         verify(ftpsClientMock, times(1)).isConnected();
122         verify(ftpsClientMock, times(1)).logout();
123         verify(ftpsClientMock, times(1)).disconnect();
124         verify(ftpsClientMock, times(1)).retrieveFile(ArgumentMatchers.eq(REMOTE_FILE_PATH), any());
125         verifyNoMoreInteractions(ftpsClientMock);
126     }
127
128     @Test
129     public void collectFileFaultyOwnKey_shouldFail() throws Exception {
130
131         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
132         assertThatThrownBy(() -> clientUnderTestSpy.open())
133             .hasMessageContaining("Could not open connection: java.io.FileNotFoundException:");
134
135         verify(ftpsClientMock).setNeedClientAuth(true);
136
137         doReturn(false).when(ftpsClientMock).isConnected();
138         clientUnderTestSpy.close();
139         verify(ftpsClientMock).isConnected();
140         verifyNoMoreInteractions(ftpsClientMock);
141     }
142
143     @Test
144     public void collectFileFaultTrustedCA_shouldFail_no_trustedCA_file() throws Exception {
145
146         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
147         doThrow(new IOException("problem")).when(clientUnderTestSpy).createInputStream(TRUSTED_CA_PATH);
148
149         assertThatThrownBy(() -> clientUnderTestSpy.open())
150             .hasMessage("Could not open connection: java.io.IOException: problem");
151     }
152
153     @Test
154     public void collectFileFaultTrustedCA_shouldFail_empty_trustedCA_file() throws Exception {
155
156         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
157         doReturn(inputStreamMock).when(clientUnderTestSpy).createInputStream(TRUSTED_CA_PATH);
158
159         assertThatThrownBy(() -> clientUnderTestSpy.open())
160             .hasMessage("Could not open connection: java.io.EOFException");
161     }
162
163     @Test
164     public void collectFileFaultyLogin_shouldFail() throws Exception {
165
166         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
167         doReturn(trustManagerMock).when(clientUnderTestSpy).getTrustManager(TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD);
168         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
169         doReturn(false).when(ftpsClientMock).login(USERNAME, PASSWORD);
170
171         assertThatThrownBy(() -> clientUnderTestSpy.open()).hasMessage("Unable to log in to xNF. 127.0.0.1");
172
173         verify(ftpsClientMock).setNeedClientAuth(true);
174         verify(ftpsClientMock).setKeyManager(keyManagerMock);
175         verify(ftpsClientMock).setTrustManager(trustManagerMock);
176         verify(ftpsClientMock).connect(XNF_ADDRESS, PORT);
177         verify(ftpsClientMock).login(USERNAME, PASSWORD);
178     }
179
180     @Test
181     public void collectFileBadRequestResponse_shouldFail() throws Exception {
182         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
183         doReturn(trustManagerMock).when(clientUnderTestSpy).getTrustManager(TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD);
184         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
185         doReturn(true).when(ftpsClientMock).login(USERNAME, PASSWORD);
186         doReturn(503).when(ftpsClientMock).getReplyCode();
187
188         assertThatThrownBy(() -> clientUnderTestSpy.open())
189             .hasMessage("Unable to connect to xNF. 127.0.0.1 xNF reply code: 503");
190
191         verify(ftpsClientMock).setNeedClientAuth(true);
192         verify(ftpsClientMock).setKeyManager(keyManagerMock);
193         verify(ftpsClientMock).setTrustManager(trustManagerMock);
194         verify(ftpsClientMock).connect(XNF_ADDRESS, PORT);
195         verify(ftpsClientMock).login(USERNAME, PASSWORD);
196         verify(ftpsClientMock, times(2)).getReplyCode();
197         verifyNoMoreInteractions(ftpsClientMock);
198     }
199
200     @Test
201     public void collectFile_shouldFail() throws Exception {
202         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
203         doReturn(trustManagerMock).when(clientUnderTestSpy).getTrustManager(TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD);
204         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
205         doReturn(true).when(ftpsClientMock).login(USERNAME, PASSWORD);
206         doReturn(HttpStatus.OK.value()).when(ftpsClientMock).getReplyCode();
207         clientUnderTestSpy.open();
208
209         doReturn(false).when(ftpsClientMock).retrieveFile(REMOTE_FILE_PATH, outputStreamMock);
210
211         assertThatThrownBy(() -> clientUnderTestSpy.collectFile(REMOTE_FILE_PATH, LOCAL_FILE_PATH))
212             .hasMessageContaining(REMOTE_FILE_PATH).hasMessageContaining("No retry");
213
214         verifyFtpsClientMock_openOk();
215         verify(ftpsClientMock, times(1)).retrieveFile(ArgumentMatchers.eq(REMOTE_FILE_PATH), any());
216         verifyNoMoreInteractions(ftpsClientMock);
217     }
218
219     @Test
220     public void collectFile_shouldFail_ioexception() throws Exception {
221         doReturn(keyManagerMock).when(clientUnderTestSpy).getKeyManager(Paths.get(FTP_KEY_PATH), FTP_KEY_PASSWORD);
222         doReturn(trustManagerMock).when(clientUnderTestSpy).getTrustManager(TRUSTED_CA_PATH, TRUSTED_CA_PASSWORD);
223         doReturn(outputStreamMock).when(clientUnderTestSpy).createOutputStream(LOCAL_FILE_PATH);
224         doReturn(true).when(ftpsClientMock).login(USERNAME, PASSWORD);
225         doReturn(HttpStatus.OK.value()).when(ftpsClientMock).getReplyCode();
226         clientUnderTestSpy.open();
227         when(ftpsClientMock.isConnected()).thenReturn(false);
228
229         doThrow(new IOException("problem")).when(ftpsClientMock).retrieveFile(REMOTE_FILE_PATH, outputStreamMock);
230
231         assertThatThrownBy(() -> clientUnderTestSpy.collectFile(REMOTE_FILE_PATH, LOCAL_FILE_PATH))
232             .hasMessage("Could not fetch file: java.io.IOException: problem");
233
234         verifyFtpsClientMock_openOk();
235         verify(ftpsClientMock, times(1)).retrieveFile(ArgumentMatchers.eq(REMOTE_FILE_PATH), any());
236         verifyNoMoreInteractions(ftpsClientMock);
237     }
238 }