blob: 842bafd9df341643129872ac529c7bf2363edb90 [file] [log] [blame]
Sean Condond2c8d472017-02-17 17:09:39 +00001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Sean Condond2c8d472017-02-17 17:09:39 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Yuta HIGUCHIe3ae8212017-04-20 10:18:41 -070016package org.onosproject.netconf.ctl.impl;
Sean Condond2c8d472017-02-17 17:09:39 +000017
Aaron Kruglikov72db6422017-02-13 12:16:51 -080018import static org.hamcrest.Matchers.containsInAnyOrder;
Sean Condon54d82432017-07-26 22:27:25 +010019import static org.junit.Assert.assertEquals;
Sean Condond2c8d472017-02-17 17:09:39 +000020import static org.junit.Assert.assertNotNull;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080021import static org.junit.Assert.assertThat;
Sean Condond2c8d472017-02-17 17:09:39 +000022import static org.junit.Assert.assertTrue;
23import static org.junit.Assert.fail;
Shivani Vaidya48df84e2017-04-13 13:48:17 -070024import static org.junit.Assert.assertFalse;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -070025import static org.onosproject.netconf.DatastoreId.CANDIDATE;
26import static org.onosproject.netconf.DatastoreId.RUNNING;
Sean Condond2c8d472017-02-17 17:09:39 +000027
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070028import java.io.File;
Sean Condond2c8d472017-02-17 17:09:39 +000029import java.util.Arrays;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080030import java.util.Collection;
Sean Condond2c8d472017-02-17 17:09:39 +000031import java.util.Optional;
Sean Condon54d82432017-07-26 22:27:25 +010032import java.util.OptionalInt;
Sean Condond2c8d472017-02-17 17:09:39 +000033import java.util.concurrent.Callable;
34import java.util.concurrent.ExecutorService;
35import java.util.concurrent.Executors;
36import java.util.concurrent.FutureTask;
37import java.util.regex.Pattern;
38
Kamil Stasiak9f59f442017-05-02 11:02:24 +020039import com.google.common.collect.ImmutableList;
Sean Condond2c8d472017-02-17 17:09:39 +000040import org.apache.sshd.common.NamedFactory;
41import org.apache.sshd.server.Command;
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070042import org.apache.sshd.server.SshServer;
43import org.apache.sshd.server.auth.password.PasswordAuthenticator;
Sean Condond2c8d472017-02-17 17:09:39 +000044import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
45import org.apache.sshd.server.session.ServerSession;
46import org.junit.AfterClass;
47import org.junit.BeforeClass;
48import org.junit.Test;
49import org.onlab.junit.TestTools;
50import org.onlab.packet.Ip4Address;
Sean Condon54d82432017-07-26 22:27:25 +010051import org.onosproject.netconf.DatastoreId;
52import org.onosproject.netconf.NetconfController;
Sean Condond2c8d472017-02-17 17:09:39 +000053import org.onosproject.netconf.NetconfDeviceInfo;
54import org.onosproject.netconf.NetconfException;
55import org.onosproject.netconf.NetconfSession;
56import org.slf4j.Logger;
57import org.slf4j.LoggerFactory;
58
Aaron Kruglikov72db6422017-02-13 12:16:51 -080059
Sean Condond2c8d472017-02-17 17:09:39 +000060/**
61 * Unit tests for NetconfSession.
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070062 * <p>
Sean Condond2c8d472017-02-17 17:09:39 +000063 * Sets up an SSH Server with Apache SSHD and connects to it using 2 clients
64 * Truly verifies that the NETCONF flows are compliant with a NETCONF server.
65 */
66public class NetconfSessionImplTest {
67 private static final Logger log = LoggerFactory
68 .getLogger(NetconfStreamThread.class);
69
70 private static final int PORT_NUMBER = TestTools.findAvailablePort(50830);
71 private static final String TEST_USERNAME = "netconf";
72 private static final String TEST_PASSWORD = "netconf123";
73 private static final String TEST_HOSTNAME = "127.0.0.1";
Shivani Vaidya48df84e2017-04-13 13:48:17 -070074
Sean Condond2c8d472017-02-17 17:09:39 +000075 private static final String TEST_SERFILE =
76 System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "testkey.ser";
77
78 private static final String SAMPLE_REQUEST =
79 "<some-yang-element xmlns=\"some-namespace\">"
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070080 + "<some-child-element/>"
81 + "</some-yang-element>";
Sean Condond2c8d472017-02-17 17:09:39 +000082
Shivani Vaidya48df84e2017-04-13 13:48:17 -070083 private static final String EDIT_CONFIG_REQUEST =
84 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rpc message-id=\"6\" "
85 + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
86 + "<edit-config>\n"
87 + "<target><running/></target>\n"
88 + "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
89 + "<some-yang-element xmlns=\"some-namespace\">"
90 + "<some-child-element/></some-yang-element></config>\n"
91 + "</edit-config>\n"
92 + "</rpc>]]>]]>";
93
Sean Condond2c8d472017-02-17 17:09:39 +000094 private static NetconfSession session1;
95 private static NetconfSession session2;
Kamil Stasiak9f59f442017-05-02 11:02:24 +020096 private static NetconfSession session3;
97 private static NetconfSession session4;
Sean Condond2c8d472017-02-17 17:09:39 +000098 private static SshServer sshServerNetconf;
99
100 @BeforeClass
101 public static void setUp() throws Exception {
102 sshServerNetconf = SshServer.setUpDefaultServer();
Sean Condond2c8d472017-02-17 17:09:39 +0000103 sshServerNetconf.setPasswordAuthenticator(
104 new PasswordAuthenticator() {
105 @Override
106 public boolean authenticate(
107 String username,
108 String password,
109 ServerSession session) {
110 return TEST_USERNAME.equals(username) && TEST_PASSWORD.equals(password);
111 }
112 });
113 sshServerNetconf.setPort(PORT_NUMBER);
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700114 SimpleGeneratorHostKeyProvider provider = new SimpleGeneratorHostKeyProvider();
115 provider.setFile(new File(TEST_SERFILE));
116 sshServerNetconf.setKeyPairProvider(provider);
Sean Condond2c8d472017-02-17 17:09:39 +0000117 sshServerNetconf.setSubsystemFactories(
118 Arrays.<NamedFactory<Command>>asList(new NetconfSshdTestSubsystem.Factory()));
119 sshServerNetconf.open();
120 log.info("SSH Server opened on port {}", PORT_NUMBER);
121
Sean Condon54d82432017-07-26 22:27:25 +0100122 NetconfController netconfCtl = new NetconfControllerImpl();
123
124 NetconfDeviceInfo deviceInfo1 = new NetconfDeviceInfo(
Sean Condond2c8d472017-02-17 17:09:39 +0000125 TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), PORT_NUMBER);
126
Sean Condon54d82432017-07-26 22:27:25 +0100127 session1 = new NetconfSessionImpl(deviceInfo1, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
Sean Condond2c8d472017-02-17 17:09:39 +0000128 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session1.getSessionId());
129 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("-1"));
130 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("0"));
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200131 assertThat(session1.getDeviceCapabilitiesSet(), containsInAnyOrder(
132 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
Sean Condon54d82432017-07-26 22:27:25 +0100133
134 NetconfDeviceInfo deviceInfo2 = new NetconfDeviceInfo(
135 TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), PORT_NUMBER);
136 deviceInfo2.setConnectTimeoutSec(OptionalInt.of(11));
137 deviceInfo2.setReplyTimeoutSec(OptionalInt.of(10));
138 deviceInfo2.setIdleTimeoutSec(OptionalInt.of(12));
139 session2 = new NetconfSessionMinaImpl(deviceInfo2, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
Sean Condond2c8d472017-02-17 17:09:39 +0000140 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session2.getSessionId());
141 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("-1"));
142 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("0"));
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200143 assertThat(session2.getDeviceCapabilitiesSet(), containsInAnyOrder(
144 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
Sean Condon54d82432017-07-26 22:27:25 +0100145 session3 = new NetconfSessionImpl(deviceInfo1);
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200146 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session3.getSessionId());
147 assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("-1"));
148 assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("0"));
149 assertThat(session3.getDeviceCapabilitiesSet(), containsInAnyOrder(
150 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
Sean Condon54d82432017-07-26 22:27:25 +0100151 session4 = new NetconfSessionImpl(deviceInfo1);
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200152 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session4.getSessionId());
153 assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("-1"));
154 assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("0"));
155 assertThat(session4.getDeviceCapabilitiesSet(), containsInAnyOrder(
156 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000157 }
158
159 @AfterClass
160 public static void tearDown() throws Exception {
161 if (session1 != null) {
162 session1.close();
163 }
164 if (session2 != null) {
165 session2.close();
166 }
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200167 if (session3 != null) {
168 session3.close();
169 }
170 if (session4 != null) {
171 session4.close();
172 }
Sean Condond2c8d472017-02-17 17:09:39 +0000173
174 sshServerNetconf.stop();
175 }
176
177 @Test
178 public void testEditConfigRequest() {
179 log.info("Starting edit-config async");
180 assertNotNull("Incorrect sessionId", session1.getSessionId());
181 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700182 assertTrue("NETCONF edit-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200183 session1.editConfig(DatastoreId.RUNNING,
184 null, SAMPLE_REQUEST));
185 } catch (NetconfException e) {
186 e.printStackTrace();
187 fail("NETCONF edit-config test failed: " + e.getMessage());
188 }
189 log.info("Finishing edit-config async");
190 }
191
192 @Test
193 public void testEditConfigRequestWithChunkedFraming() {
194 log.info("Starting edit-config async");
195 assertNotNull("Incorrect sessionId", session3.getSessionId());
196 try {
197 assertTrue("NETCONF edit-config command failed",
198 session3.editConfig(DatastoreId.RUNNING,
199 null, SAMPLE_REQUEST));
Sean Condond2c8d472017-02-17 17:09:39 +0000200 } catch (NetconfException e) {
201 e.printStackTrace();
202 fail("NETCONF edit-config test failed: " + e.getMessage());
203 }
204 log.info("Finishing edit-config async");
205 }
206
207 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700208 public void testEditConfigRequestWithOnlyNewConfiguration() {
209 log.info("Starting edit-config async");
210 assertNotNull("Incorrect sessionId", session1.getSessionId());
211 try {
212 assertTrue("NETCONF edit-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200213 session1.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
214 } catch (NetconfException e) {
215 e.printStackTrace();
216 fail("NETCONF edit-config test failed: " + e.getMessage());
217 }
218 log.info("Finishing edit-config async");
219 }
220
221 @Test
222 public void testEditConfigRequestWithOnlyNewConfigurationWithChunkedFraming() {
223 log.info("Starting edit-config async");
224 assertNotNull("Incorrect sessionId", session3.getSessionId());
225 try {
226 assertTrue("NETCONF edit-config command failed",
227 session3.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700228 } catch (NetconfException e) {
229 e.printStackTrace();
230 fail("NETCONF edit-config test failed: " + e.getMessage());
231 }
232 log.info("Finishing edit-config async");
233 }
234
235 @Test
236 public void testDeleteConfigRequestWithRunningTargetConfiguration() {
237 log.info("Starting delete-config async");
238 assertNotNull("Incorrect sessionId", session1.getSessionId());
239 try {
240 assertFalse("NETCONF delete-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200241 session1.deleteConfig(DatastoreId.RUNNING));
242 } catch (NetconfException e) {
243 e.printStackTrace();
244 fail("NETCONF delete-config test failed: " + e.getMessage());
245 }
246 log.info("Finishing delete-config async");
247 }
248
249 @Test
250 public void testDeleteConfigRequestWithRunningTargetConfigurationWithChunkedFraming() {
251 log.info("Starting delete-config async");
252 assertNotNull("Incorrect sessionId", session3.getSessionId());
253 try {
254 assertFalse("NETCONF delete-config command failed",
255 session3.deleteConfig(DatastoreId.RUNNING));
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700256 } catch (NetconfException e) {
257 e.printStackTrace();
258 fail("NETCONF delete-config test failed: " + e.getMessage());
259 }
260 log.info("Finishing delete-config async");
261 }
262
263 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000264 public void testCopyConfigRequest() {
265 log.info("Starting copy-config async");
266 assertNotNull("Incorrect sessionId", session1.getSessionId());
267 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700268 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200269 session1.copyConfig(DatastoreId.RUNNING,
270 DatastoreId.CANDIDATE));
271 } catch (NetconfException e) {
272 e.printStackTrace();
273 fail("NETCONF copy-config test failed: " + e.getMessage());
274 }
275 log.info("Finishing copy-config async");
276 }
277
278 @Test
279 public void testCopyConfigRequestWithChunkedFraming() {
280 log.info("Starting copy-config async");
281 assertNotNull("Incorrect sessionId", session3.getSessionId());
282 try {
283 assertTrue("NETCONF copy-config command failed",
284 session3.copyConfig(DatastoreId.RUNNING,
285 DatastoreId.CANDIDATE));
Sean Condond2c8d472017-02-17 17:09:39 +0000286 } catch (NetconfException e) {
287 e.printStackTrace();
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700288 fail("NETCONF copy-config test failed: " + e.getMessage());
Sean Condond2c8d472017-02-17 17:09:39 +0000289 }
290 log.info("Finishing copy-config async");
291 }
292
293 @Test
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700294 public void testCopyConfigXml() {
295 log.info("Starting copy-config XML async");
296 assertNotNull("Incorrect sessionId", session1.getSessionId());
297 try {
298 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200299 session1.copyConfig(DatastoreId.RUNNING,
300 "<configuration><device-specific/></configuration>"));
301 } catch (NetconfException e) {
302 e.printStackTrace();
303 fail("NETCONF copy-config test failed: " + e.getMessage());
304 }
305 log.info("Finishing copy-config XML async");
306 }
307
308 @Test
309 public void testCopyConfigXmlWithChunkedFraming() {
310 log.info("Starting copy-config XML async");
311 assertNotNull("Incorrect sessionId", session3.getSessionId());
312 try {
313 assertTrue("NETCONF copy-config command failed",
314 session3.copyConfig(DatastoreId.RUNNING,
315 "<configuration><device-specific/></configuration>"));
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700316 } catch (NetconfException e) {
317 e.printStackTrace();
318 fail("NETCONF copy-config test failed: " + e.getMessage());
319 }
320 log.info("Finishing copy-config XML async");
321 }
322
323 // remove test when ready to dump bare XML String API.
324 @Test
325 public void testCopyConfigBareXml() {
326 log.info("Starting copy-config bare XML async");
327 assertNotNull("Incorrect sessionId", session1.getSessionId());
328 try {
329 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200330 session1.copyConfig(DatastoreId.RUNNING,
331 "<config>"
332 + "<configuration><device-specific/></configuration>"
333 + "</config>"));
334 } catch (NetconfException e) {
335 e.printStackTrace();
336 fail("NETCONF copy-config test failed: " + e.getMessage());
337 }
338 log.info("Finishing copy-config bare XML async");
339 }
340
341 @Test
342 public void testCopyConfigBareXmlWithChunkedFraming() {
343 log.info("Starting copy-config bare XML async");
344 assertNotNull("Incorrect sessionId", session3.getSessionId());
345 try {
346 assertTrue("NETCONF copy-config command failed",
347 session3.copyConfig(DatastoreId.RUNNING,
348 "<config>"
349 + "<configuration><device-specific/></configuration>"
350 + "</config>"));
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700351 } catch (NetconfException e) {
352 e.printStackTrace();
353 fail("NETCONF copy-config test failed: " + e.getMessage());
354 }
355 log.info("Finishing copy-config bare XML async");
356 }
357
358 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000359 public void testGetConfigRequest() {
360 log.info("Starting get-config async");
361 assertNotNull("Incorrect sessionId", session1.getSessionId());
362 try {
363 assertTrue("NETCONF get-config running command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200364 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING,
365 SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000366
367 assertTrue("NETCONF get-config candidate command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200368 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE,
369 SAMPLE_REQUEST)).matches());
370
371 } catch (NetconfException e) {
372 e.printStackTrace();
373 fail("NETCONF get-config test failed: " + e.getMessage());
374 }
375 log.info("Finishing get-config async");
376 }
377
378 @Test
379 public void testGetConfigRequestWithChunkedFraming() {
380 log.info("Starting get-config async");
381 assertNotNull("Incorrect sessionId", session3.getSessionId());
382 try {
383 assertTrue("NETCONF get-config running command failed. ",
384 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(RUNNING,
385 SAMPLE_REQUEST)).matches());
386
387 assertTrue("NETCONF get-config candidate command failed. ",
388 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(CANDIDATE,
389 SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000390
391 } catch (NetconfException e) {
392 e.printStackTrace();
393 fail("NETCONF get-config test failed: " + e.getMessage());
394 }
395 log.info("Finishing get-config async");
396 }
397
398 @Test
399 public void testGetRequest() {
400 log.info("Starting get async");
401 assertNotNull("Incorrect sessionId", session1.getSessionId());
402 try {
403 assertTrue("NETCONF get running command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200404 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST,
405 null)).matches());
406
407 } catch (NetconfException e) {
408 e.printStackTrace();
409 fail("NETCONF get test failed: " + e.getMessage());
410 }
411 log.info("Finishing get async");
412 }
413
414 @Test
415 public void testGetRequestWithChunkedFraming() {
416 log.info("Starting get async");
417 assertNotNull("Incorrect sessionId", session3.getSessionId());
418 try {
419 assertTrue("NETCONF get running command failed. ",
420 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.get(SAMPLE_REQUEST, null)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000421
422 } catch (NetconfException e) {
423 e.printStackTrace();
424 fail("NETCONF get test failed: " + e.getMessage());
425 }
426 log.info("Finishing get async");
427 }
428
429 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700430 public void testLockRequest() {
431 log.info("Starting lock async");
432 assertNotNull("Incorrect sessionId", session1.getSessionId());
433 try {
434 assertTrue("NETCONF lock request failed", session1.lock());
435 } catch (NetconfException e) {
436 e.printStackTrace();
437 fail("NETCONF lock test failed: " + e.getMessage());
438 }
439 log.info("Finishing lock async");
440 }
441
442 @Test
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200443 public void testLockRequestWithChunkedFraming() {
444 log.info("Starting lock async");
445 assertNotNull("Incorrect sessionId", session3.getSessionId());
446 try {
447 assertTrue("NETCONF lock request failed", session3.lock());
448 } catch (NetconfException e) {
449 e.printStackTrace();
450 fail("NETCONF lock test failed: " + e.getMessage());
451 }
452 log.info("Finishing lock async");
453 }
454
455 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700456 public void testUnLockRequest() {
457 log.info("Starting unlock async");
458 assertNotNull("Incorrect sessionId", session1.getSessionId());
459 try {
460 assertTrue("NETCONF unlock request failed", session1.unlock());
461 } catch (NetconfException e) {
462 e.printStackTrace();
463 fail("NETCONF unlock test failed: " + e.getMessage());
464 }
465 log.info("Finishing unlock async");
466 }
467
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200468 @Test
469 public void testUnLockRequestWithChunkedFraming() {
470 log.info("Starting unlock async");
471 assertNotNull("Incorrect sessionId", session3.getSessionId());
472 try {
473 assertTrue("NETCONF unlock request failed", session3.unlock());
474 } catch (NetconfException e) {
475 e.printStackTrace();
476 fail("NETCONF unlock test failed: " + e.getMessage());
477 }
478 log.info("Finishing unlock async");
479 }
480
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700481
482 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000483 public void testConcurrentSameSessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300484 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
485 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
Sean Condond2c8d472017-02-17 17:09:39 +0000486
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800487 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
488 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
Sean Condond2c8d472017-02-17 17:09:39 +0000489
490 ExecutorService executor = Executors.newFixedThreadPool(2);
491 log.info("Starting concurrent execution of copy-config through same session");
492 executor.execute(futureCopyConfig1);
493 executor.execute(futureCopyConfig2);
494
495 int count = 0;
496 while (count < 10) {
497 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
498 executor.shutdown();
499 log.info("Finished concurrent same session execution");
500 return;
501 }
502 Thread.sleep(100L);
503 count++;
504 }
505 fail("NETCONF test failed to complete.");
506 }
507
508 @Test
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200509 public void testConcurrentSameSessionAccessWithChunkedFraming() throws InterruptedException {
510 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
511 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session3, RUNNING, "startup");
512
513 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
514 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
515
516 ExecutorService executor = Executors.newFixedThreadPool(2);
517 log.info("Starting concurrent execution of copy-config through same session");
518 executor.execute(futureCopyConfig1);
519 executor.execute(futureCopyConfig2);
520
521 int count = 0;
522 while (count < 10) {
523 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
524 executor.shutdown();
525 log.info("Finished concurrent same session execution");
526 return;
527 }
528 Thread.sleep(100L);
529 count++;
530 }
531 fail("NETCONF test failed to complete.");
532 }
533
534 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000535 public void test2SessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300536 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
537 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000538
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800539 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
540 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
Sean Condond2c8d472017-02-17 17:09:39 +0000541
542 ExecutorService executor = Executors.newFixedThreadPool(2);
543 log.info("Starting concurrent execution of copy-config through 2 different sessions");
544 executor.execute(futureCopySession1);
545 executor.execute(futureCopySession2);
546
547 int count = 0;
548 while (count < 10) {
549 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
550 executor.shutdown();
551 log.info("Finished concurrent 2 session execution");
552 return;
553 }
554 Thread.sleep(100L);
555 count++;
556 }
557 fail("NETCONF test failed to complete.");
558 }
559
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200560 @Test
561 public void test2SessionAccessWithChunkedFraming() throws InterruptedException {
562 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
563 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session4, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000564
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200565 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
566 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
567
568 ExecutorService executor = Executors.newFixedThreadPool(2);
569 log.info("Starting concurrent execution of copy-config through 2 different sessions");
570 executor.execute(futureCopySession1);
571 executor.execute(futureCopySession2);
572
573 int count = 0;
574 while (count < 10) {
575 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
576 executor.shutdown();
577 log.info("Finished concurrent 2 session execution");
578 return;
579 }
580 Thread.sleep(100L);
581 count++;
582 }
583 fail("NETCONF test failed to complete.");
584 }
585
Sean Condon54d82432017-07-26 22:27:25 +0100586 @Test
587 public void testSessionTimeouts() {
588 assertTrue("SSH Client wrong", session1 instanceof NetconfSessionImpl);
589 assertEquals("Timeout wrong", 5, session1.timeoutConnectSec());
590 assertEquals("Timeout wrong", 5, session1.timeoutReplySec());
591 assertEquals("Timeout wrong", 5, session1.timeoutIdleSec());
592
593 assertTrue("SSH Client wrong", session2 instanceof NetconfSessionMinaImpl);
594 assertEquals("Timeout wrong", 11, session2.timeoutConnectSec());
595 assertEquals("Timeout wrong", 10, session2.timeoutReplySec());
596 assertEquals("Timeout wrong", 12, session2.timeoutIdleSec());
597 }
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200598
599 public static String getTestHelloReply(Optional<Long> sessionId, boolean useChunkedFraming) {
600 if (useChunkedFraming) {
601 return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1, sessionId);
602 } else {
603 return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES, sessionId);
604 }
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800605 }
606
607 public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
Sean Condond2c8d472017-02-17 17:09:39 +0000608 StringBuffer sb = new StringBuffer();
609
610 sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
611 sb.append("<capabilities>");
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800612 capabilities.forEach(capability -> {
613 sb.append("<capability>").append(capability).append("</capability>");
614 });
Sean Condond2c8d472017-02-17 17:09:39 +0000615 sb.append("</capabilities>");
616 if (sessionId.isPresent()) {
617 sb.append("<session-id>");
618 sb.append(sessionId.get().toString());
619 sb.append("</session-id>");
620 }
621 sb.append("</hello>");
622
623 return sb.toString();
624 }
625
626 public static String getOkReply(Optional<Integer> messageId) {
627 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
628 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
629 if (messageId.isPresent()) {
630 sb.append("message-id=\"");
631 sb.append(String.valueOf(messageId.get()));
632 sb.append("\">");
633 }
634 sb.append("<ok/>");
635 sb.append("</rpc-reply>");
636 return sb.toString();
637 }
638
639 public static String getGetReply(Optional<Integer> messageId) {
640 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
641 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
642 if (messageId.isPresent()) {
643 sb.append("message-id=\"");
644 sb.append(String.valueOf(messageId.get()));
645 sb.append("\">");
646 }
647 sb.append("<data>\n");
648 sb.append(SAMPLE_REQUEST);
649 sb.append("</data>\n");
650 sb.append("</rpc-reply>");
651 return sb.toString();
652 }
653
654 public static final Pattern HELLO_REQ_PATTERN =
655 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200656 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
657 + "( *)(<capabilities>)\\R?"
658 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
659 + "( *)(</capabilities>)\\R?"
660 + "(</hello>)\\R? *",
661 Pattern.DOTALL);
662
663 public static final Pattern HELLO_REQ_PATTERN_1_1 =
664 Pattern.compile("(<\\?xml).*"
665 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
666 + "( *)(<capabilities>)\\R?"
667 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
668 + "( *)(<capability>urn:ietf:params:netconf:base:1.1</capability>)\\R?"
669 + "( *)(</capabilities>)\\R?"
670 + "(</hello>)\\R? *",
Sean Condond2c8d472017-02-17 17:09:39 +0000671 Pattern.DOTALL);
672
673 public static final Pattern EDIT_CONFIG_REQ_PATTERN =
674 Pattern.compile("(<\\?xml).*"
675 + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
676 + "(<edit-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700677 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200678 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
679 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000680 + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
681 + ".*"
682 + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
683
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700684
685 public static final Pattern LOCK_REQ_PATTERN =
686 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200687 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
688 + "message-id=\")[0-9]*(\">)\\R?"
689 + "(<lock>)\\R?"
690 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
691 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
692 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
693 + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700694
695 public static final Pattern UNLOCK_REQ_PATTERN =
696 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200697 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
698 + "message-id=\")[0-9]*(\">)\\R?"
699 + "(<unlock>)\\R?"
700 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
701 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
702 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
703 + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700704
Sean Condond2c8d472017-02-17 17:09:39 +0000705 public static final Pattern COPY_CONFIG_REQ_PATTERN =
706 Pattern.compile("(<\\?xml).*"
707 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
708 + "(<copy-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700709 + "(<target>\\R?"
710 + "("
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200711 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
712 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
713 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700714 + ")\\R?"
715 + "</target>)\\R?"
716 + "(<source>)\\R?"
717 + "("
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200718 + "(<config>)(.*)(</config>)|"
719 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
720 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
721 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700722 + ")\\R?"
723 + "(</source>)\\R?"
724 + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Sean Condond2c8d472017-02-17 17:09:39 +0000725
726 public static final Pattern GET_CONFIG_REQ_PATTERN =
727 Pattern.compile("(<\\?xml).*"
728 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700729 + "(<get-config>)\\R?" + "(<source>)\\R?((<"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200730 + DatastoreId.CANDIDATE.toString()
731 + "/>)|(<" + DatastoreId.RUNNING.toString()
732 + "/>)|(<" + DatastoreId.STARTUP.toString()
733 + "/>))\\R?(</source>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000734 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
735 + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
736
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200737
Sean Condond2c8d472017-02-17 17:09:39 +0000738
739 public static final Pattern GET_REQ_PATTERN =
740 Pattern.compile("(<\\?xml).*"
741 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
742 + "(<get>)\\R?"
743 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
744 + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
745
746 public class NCCopyConfigCallable implements Callable<Boolean> {
747 private NetconfSession session;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700748 private DatastoreId target;
Sean Condond2c8d472017-02-17 17:09:39 +0000749 private String source;
750
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700751 public NCCopyConfigCallable(NetconfSession session, DatastoreId target, String source) {
Sean Condond2c8d472017-02-17 17:09:39 +0000752 this.session = session;
753 this.target = target;
754 this.source = source;
755 }
756
757 @Override
758 public Boolean call() throws Exception {
759 return session.copyConfig(target, source);
760 }
761 }
Sean Condon54d82432017-07-26 22:27:25 +0100762}