blob: 1b5e7fa75b2a11af34dd781a68b0dae8c51c8ba6 [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 Condond2c8d472017-02-17 17:09:39 +000019import static org.junit.Assert.assertNotNull;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080020import static org.junit.Assert.assertThat;
Sean Condond2c8d472017-02-17 17:09:39 +000021import static org.junit.Assert.assertTrue;
22import static org.junit.Assert.fail;
Shivani Vaidya48df84e2017-04-13 13:48:17 -070023import static org.junit.Assert.assertFalse;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -070024import static org.onosproject.netconf.DatastoreId.CANDIDATE;
25import static org.onosproject.netconf.DatastoreId.RUNNING;
Sean Condond2c8d472017-02-17 17:09:39 +000026
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070027import java.io.File;
Sean Condond2c8d472017-02-17 17:09:39 +000028import java.util.Arrays;
Aaron Kruglikov72db6422017-02-13 12:16:51 -080029import java.util.Collection;
Sean Condond2c8d472017-02-17 17:09:39 +000030import java.util.Optional;
31import java.util.concurrent.Callable;
32import java.util.concurrent.ExecutorService;
33import java.util.concurrent.Executors;
34import java.util.concurrent.FutureTask;
35import java.util.regex.Pattern;
36
Kamil Stasiak9f59f442017-05-02 11:02:24 +020037import com.google.common.collect.ImmutableList;
Sean Condond2c8d472017-02-17 17:09:39 +000038import org.apache.sshd.common.NamedFactory;
39import org.apache.sshd.server.Command;
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070040import org.apache.sshd.server.SshServer;
41import org.apache.sshd.server.auth.password.PasswordAuthenticator;
Sean Condond2c8d472017-02-17 17:09:39 +000042import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
43import org.apache.sshd.server.session.ServerSession;
44import org.junit.AfterClass;
45import org.junit.BeforeClass;
46import org.junit.Test;
47import org.onlab.junit.TestTools;
48import org.onlab.packet.Ip4Address;
49import org.onosproject.netconf.NetconfDeviceInfo;
50import org.onosproject.netconf.NetconfException;
51import org.onosproject.netconf.NetconfSession;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -070052import org.onosproject.netconf.DatastoreId;
Sean Condond2c8d472017-02-17 17:09:39 +000053import org.slf4j.Logger;
54import org.slf4j.LoggerFactory;
55
Aaron Kruglikov72db6422017-02-13 12:16:51 -080056
Sean Condond2c8d472017-02-17 17:09:39 +000057/**
58 * Unit tests for NetconfSession.
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070059 * <p>
Sean Condond2c8d472017-02-17 17:09:39 +000060 * Sets up an SSH Server with Apache SSHD and connects to it using 2 clients
61 * Truly verifies that the NETCONF flows are compliant with a NETCONF server.
62 */
63public class NetconfSessionImplTest {
64 private static final Logger log = LoggerFactory
65 .getLogger(NetconfStreamThread.class);
66
67 private static final int PORT_NUMBER = TestTools.findAvailablePort(50830);
68 private static final String TEST_USERNAME = "netconf";
69 private static final String TEST_PASSWORD = "netconf123";
70 private static final String TEST_HOSTNAME = "127.0.0.1";
Shivani Vaidya48df84e2017-04-13 13:48:17 -070071
Sean Condond2c8d472017-02-17 17:09:39 +000072 private static final String TEST_SERFILE =
73 System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "testkey.ser";
74
75 private static final String SAMPLE_REQUEST =
76 "<some-yang-element xmlns=\"some-namespace\">"
Andrea Campanella7bbe7b12017-05-03 16:03:38 -070077 + "<some-child-element/>"
78 + "</some-yang-element>";
Sean Condond2c8d472017-02-17 17:09:39 +000079
Shivani Vaidya48df84e2017-04-13 13:48:17 -070080 private static final String EDIT_CONFIG_REQUEST =
81 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rpc message-id=\"6\" "
82 + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
83 + "<edit-config>\n"
84 + "<target><running/></target>\n"
85 + "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
86 + "<some-yang-element xmlns=\"some-namespace\">"
87 + "<some-child-element/></some-yang-element></config>\n"
88 + "</edit-config>\n"
89 + "</rpc>]]>]]>";
90
Sean Condond2c8d472017-02-17 17:09:39 +000091 private static NetconfSession session1;
92 private static NetconfSession session2;
Kamil Stasiak9f59f442017-05-02 11:02:24 +020093 private static NetconfSession session3;
94 private static NetconfSession session4;
Sean Condond2c8d472017-02-17 17:09:39 +000095 private static SshServer sshServerNetconf;
96
97 @BeforeClass
98 public static void setUp() throws Exception {
99 sshServerNetconf = SshServer.setUpDefaultServer();
Sean Condond2c8d472017-02-17 17:09:39 +0000100 sshServerNetconf.setPasswordAuthenticator(
101 new PasswordAuthenticator() {
102 @Override
103 public boolean authenticate(
104 String username,
105 String password,
106 ServerSession session) {
107 return TEST_USERNAME.equals(username) && TEST_PASSWORD.equals(password);
108 }
109 });
110 sshServerNetconf.setPort(PORT_NUMBER);
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700111 SimpleGeneratorHostKeyProvider provider = new SimpleGeneratorHostKeyProvider();
112 provider.setFile(new File(TEST_SERFILE));
113 sshServerNetconf.setKeyPairProvider(provider);
Sean Condond2c8d472017-02-17 17:09:39 +0000114 sshServerNetconf.setSubsystemFactories(
115 Arrays.<NamedFactory<Command>>asList(new NetconfSshdTestSubsystem.Factory()));
116 sshServerNetconf.open();
117 log.info("SSH Server opened on port {}", PORT_NUMBER);
118
119 NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo(
120 TEST_USERNAME, TEST_PASSWORD, Ip4Address.valueOf(TEST_HOSTNAME), PORT_NUMBER);
121
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200122 session1 = new NetconfSessionImpl(deviceInfo, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
Sean Condond2c8d472017-02-17 17:09:39 +0000123 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session1.getSessionId());
124 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("-1"));
125 assertTrue("Incorrect sessionId", !session1.getSessionId().equalsIgnoreCase("0"));
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200126 assertThat(session1.getDeviceCapabilitiesSet(), containsInAnyOrder(
127 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
128 session2 = new NetconfSessionImpl(deviceInfo, ImmutableList.of("urn:ietf:params:netconf:base:1.0"));
Sean Condond2c8d472017-02-17 17:09:39 +0000129 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session2.getSessionId());
130 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("-1"));
131 assertTrue("Incorrect sessionId", !session2.getSessionId().equalsIgnoreCase("0"));
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200132 assertThat(session2.getDeviceCapabilitiesSet(), containsInAnyOrder(
133 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES.toArray()));
134 session3 = new NetconfSessionImpl(deviceInfo);
135 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session3.getSessionId());
136 assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("-1"));
137 assertTrue("Incorrect sessionId", !session3.getSessionId().equalsIgnoreCase("0"));
138 assertThat(session3.getDeviceCapabilitiesSet(), containsInAnyOrder(
139 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
140 session4 = new NetconfSessionImpl(deviceInfo);
141 log.info("Started NETCONF Session {} with test SSHD server in Unit Test", session4.getSessionId());
142 assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("-1"));
143 assertTrue("Incorrect sessionId", !session4.getSessionId().equalsIgnoreCase("0"));
144 assertThat(session4.getDeviceCapabilitiesSet(), containsInAnyOrder(
145 NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1.toArray()));
Sean Condond2c8d472017-02-17 17:09:39 +0000146 }
147
148 @AfterClass
149 public static void tearDown() throws Exception {
150 if (session1 != null) {
151 session1.close();
152 }
153 if (session2 != null) {
154 session2.close();
155 }
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200156 if (session3 != null) {
157 session3.close();
158 }
159 if (session4 != null) {
160 session4.close();
161 }
Sean Condond2c8d472017-02-17 17:09:39 +0000162
163 sshServerNetconf.stop();
164 }
165
166 @Test
167 public void testEditConfigRequest() {
168 log.info("Starting edit-config async");
169 assertNotNull("Incorrect sessionId", session1.getSessionId());
170 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700171 assertTrue("NETCONF edit-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200172 session1.editConfig(DatastoreId.RUNNING,
173 null, SAMPLE_REQUEST));
174 } catch (NetconfException e) {
175 e.printStackTrace();
176 fail("NETCONF edit-config test failed: " + e.getMessage());
177 }
178 log.info("Finishing edit-config async");
179 }
180
181 @Test
182 public void testEditConfigRequestWithChunkedFraming() {
183 log.info("Starting edit-config async");
184 assertNotNull("Incorrect sessionId", session3.getSessionId());
185 try {
186 assertTrue("NETCONF edit-config command failed",
187 session3.editConfig(DatastoreId.RUNNING,
188 null, SAMPLE_REQUEST));
Sean Condond2c8d472017-02-17 17:09:39 +0000189 } catch (NetconfException e) {
190 e.printStackTrace();
191 fail("NETCONF edit-config test failed: " + e.getMessage());
192 }
193 log.info("Finishing edit-config async");
194 }
195
196 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700197 public void testEditConfigRequestWithOnlyNewConfiguration() {
198 log.info("Starting edit-config async");
199 assertNotNull("Incorrect sessionId", session1.getSessionId());
200 try {
201 assertTrue("NETCONF edit-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200202 session1.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
203 } catch (NetconfException e) {
204 e.printStackTrace();
205 fail("NETCONF edit-config test failed: " + e.getMessage());
206 }
207 log.info("Finishing edit-config async");
208 }
209
210 @Test
211 public void testEditConfigRequestWithOnlyNewConfigurationWithChunkedFraming() {
212 log.info("Starting edit-config async");
213 assertNotNull("Incorrect sessionId", session3.getSessionId());
214 try {
215 assertTrue("NETCONF edit-config command failed",
216 session3.editConfig(NetconfSessionMinaImplTest.EDIT_CONFIG_REQUEST));
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700217 } catch (NetconfException e) {
218 e.printStackTrace();
219 fail("NETCONF edit-config test failed: " + e.getMessage());
220 }
221 log.info("Finishing edit-config async");
222 }
223
224 @Test
225 public void testDeleteConfigRequestWithRunningTargetConfiguration() {
226 log.info("Starting delete-config async");
227 assertNotNull("Incorrect sessionId", session1.getSessionId());
228 try {
229 assertFalse("NETCONF delete-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200230 session1.deleteConfig(DatastoreId.RUNNING));
231 } catch (NetconfException e) {
232 e.printStackTrace();
233 fail("NETCONF delete-config test failed: " + e.getMessage());
234 }
235 log.info("Finishing delete-config async");
236 }
237
238 @Test
239 public void testDeleteConfigRequestWithRunningTargetConfigurationWithChunkedFraming() {
240 log.info("Starting delete-config async");
241 assertNotNull("Incorrect sessionId", session3.getSessionId());
242 try {
243 assertFalse("NETCONF delete-config command failed",
244 session3.deleteConfig(DatastoreId.RUNNING));
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700245 } catch (NetconfException e) {
246 e.printStackTrace();
247 fail("NETCONF delete-config test failed: " + e.getMessage());
248 }
249 log.info("Finishing delete-config async");
250 }
251
252 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000253 public void testCopyConfigRequest() {
254 log.info("Starting copy-config async");
255 assertNotNull("Incorrect sessionId", session1.getSessionId());
256 try {
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700257 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200258 session1.copyConfig(DatastoreId.RUNNING,
259 DatastoreId.CANDIDATE));
260 } catch (NetconfException e) {
261 e.printStackTrace();
262 fail("NETCONF copy-config test failed: " + e.getMessage());
263 }
264 log.info("Finishing copy-config async");
265 }
266
267 @Test
268 public void testCopyConfigRequestWithChunkedFraming() {
269 log.info("Starting copy-config async");
270 assertNotNull("Incorrect sessionId", session3.getSessionId());
271 try {
272 assertTrue("NETCONF copy-config command failed",
273 session3.copyConfig(DatastoreId.RUNNING,
274 DatastoreId.CANDIDATE));
Sean Condond2c8d472017-02-17 17:09:39 +0000275 } catch (NetconfException e) {
276 e.printStackTrace();
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700277 fail("NETCONF copy-config test failed: " + e.getMessage());
Sean Condond2c8d472017-02-17 17:09:39 +0000278 }
279 log.info("Finishing copy-config async");
280 }
281
282 @Test
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700283 public void testCopyConfigXml() {
284 log.info("Starting copy-config XML async");
285 assertNotNull("Incorrect sessionId", session1.getSessionId());
286 try {
287 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200288 session1.copyConfig(DatastoreId.RUNNING,
289 "<configuration><device-specific/></configuration>"));
290 } catch (NetconfException e) {
291 e.printStackTrace();
292 fail("NETCONF copy-config test failed: " + e.getMessage());
293 }
294 log.info("Finishing copy-config XML async");
295 }
296
297 @Test
298 public void testCopyConfigXmlWithChunkedFraming() {
299 log.info("Starting copy-config XML async");
300 assertNotNull("Incorrect sessionId", session3.getSessionId());
301 try {
302 assertTrue("NETCONF copy-config command failed",
303 session3.copyConfig(DatastoreId.RUNNING,
304 "<configuration><device-specific/></configuration>"));
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700305 } catch (NetconfException e) {
306 e.printStackTrace();
307 fail("NETCONF copy-config test failed: " + e.getMessage());
308 }
309 log.info("Finishing copy-config XML async");
310 }
311
312 // remove test when ready to dump bare XML String API.
313 @Test
314 public void testCopyConfigBareXml() {
315 log.info("Starting copy-config bare XML async");
316 assertNotNull("Incorrect sessionId", session1.getSessionId());
317 try {
318 assertTrue("NETCONF copy-config command failed",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200319 session1.copyConfig(DatastoreId.RUNNING,
320 "<config>"
321 + "<configuration><device-specific/></configuration>"
322 + "</config>"));
323 } catch (NetconfException e) {
324 e.printStackTrace();
325 fail("NETCONF copy-config test failed: " + e.getMessage());
326 }
327 log.info("Finishing copy-config bare XML async");
328 }
329
330 @Test
331 public void testCopyConfigBareXmlWithChunkedFraming() {
332 log.info("Starting copy-config bare XML async");
333 assertNotNull("Incorrect sessionId", session3.getSessionId());
334 try {
335 assertTrue("NETCONF copy-config command failed",
336 session3.copyConfig(DatastoreId.RUNNING,
337 "<config>"
338 + "<configuration><device-specific/></configuration>"
339 + "</config>"));
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700340 } catch (NetconfException e) {
341 e.printStackTrace();
342 fail("NETCONF copy-config test failed: " + e.getMessage());
343 }
344 log.info("Finishing copy-config bare XML async");
345 }
346
347 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000348 public void testGetConfigRequest() {
349 log.info("Starting get-config async");
350 assertNotNull("Incorrect sessionId", session1.getSessionId());
351 try {
352 assertTrue("NETCONF get-config running command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200353 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(RUNNING,
354 SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000355
356 assertTrue("NETCONF get-config candidate command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200357 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.getConfig(CANDIDATE,
358 SAMPLE_REQUEST)).matches());
359
360 } catch (NetconfException e) {
361 e.printStackTrace();
362 fail("NETCONF get-config test failed: " + e.getMessage());
363 }
364 log.info("Finishing get-config async");
365 }
366
367 @Test
368 public void testGetConfigRequestWithChunkedFraming() {
369 log.info("Starting get-config async");
370 assertNotNull("Incorrect sessionId", session3.getSessionId());
371 try {
372 assertTrue("NETCONF get-config running command failed. ",
373 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(RUNNING,
374 SAMPLE_REQUEST)).matches());
375
376 assertTrue("NETCONF get-config candidate command failed. ",
377 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.getConfig(CANDIDATE,
378 SAMPLE_REQUEST)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000379
380 } catch (NetconfException e) {
381 e.printStackTrace();
382 fail("NETCONF get-config test failed: " + e.getMessage());
383 }
384 log.info("Finishing get-config async");
385 }
386
387 @Test
388 public void testGetRequest() {
389 log.info("Starting get async");
390 assertNotNull("Incorrect sessionId", session1.getSessionId());
391 try {
392 assertTrue("NETCONF get running command failed. ",
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200393 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session1.get(SAMPLE_REQUEST,
394 null)).matches());
395
396 } catch (NetconfException e) {
397 e.printStackTrace();
398 fail("NETCONF get test failed: " + e.getMessage());
399 }
400 log.info("Finishing get async");
401 }
402
403 @Test
404 public void testGetRequestWithChunkedFraming() {
405 log.info("Starting get async");
406 assertNotNull("Incorrect sessionId", session3.getSessionId());
407 try {
408 assertTrue("NETCONF get running command failed. ",
409 NetconfSessionMinaImplTest.GET_REPLY_PATTERN.matcher(session3.get(SAMPLE_REQUEST, null)).matches());
Sean Condond2c8d472017-02-17 17:09:39 +0000410
411 } catch (NetconfException e) {
412 e.printStackTrace();
413 fail("NETCONF get test failed: " + e.getMessage());
414 }
415 log.info("Finishing get async");
416 }
417
418 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700419 public void testLockRequest() {
420 log.info("Starting lock async");
421 assertNotNull("Incorrect sessionId", session1.getSessionId());
422 try {
423 assertTrue("NETCONF lock request failed", session1.lock());
424 } catch (NetconfException e) {
425 e.printStackTrace();
426 fail("NETCONF lock test failed: " + e.getMessage());
427 }
428 log.info("Finishing lock async");
429 }
430
431 @Test
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200432 public void testLockRequestWithChunkedFraming() {
433 log.info("Starting lock async");
434 assertNotNull("Incorrect sessionId", session3.getSessionId());
435 try {
436 assertTrue("NETCONF lock request failed", session3.lock());
437 } catch (NetconfException e) {
438 e.printStackTrace();
439 fail("NETCONF lock test failed: " + e.getMessage());
440 }
441 log.info("Finishing lock async");
442 }
443
444 @Test
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700445 public void testUnLockRequest() {
446 log.info("Starting unlock async");
447 assertNotNull("Incorrect sessionId", session1.getSessionId());
448 try {
449 assertTrue("NETCONF unlock request failed", session1.unlock());
450 } catch (NetconfException e) {
451 e.printStackTrace();
452 fail("NETCONF unlock test failed: " + e.getMessage());
453 }
454 log.info("Finishing unlock async");
455 }
456
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200457 @Test
458 public void testUnLockRequestWithChunkedFraming() {
459 log.info("Starting unlock async");
460 assertNotNull("Incorrect sessionId", session3.getSessionId());
461 try {
462 assertTrue("NETCONF unlock request failed", session3.unlock());
463 } catch (NetconfException e) {
464 e.printStackTrace();
465 fail("NETCONF unlock test failed: " + e.getMessage());
466 }
467 log.info("Finishing unlock async");
468 }
469
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700470
471 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000472 public void testConcurrentSameSessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300473 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
474 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session1, RUNNING, "startup");
Sean Condond2c8d472017-02-17 17:09:39 +0000475
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800476 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
477 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
Sean Condond2c8d472017-02-17 17:09:39 +0000478
479 ExecutorService executor = Executors.newFixedThreadPool(2);
480 log.info("Starting concurrent execution of copy-config through same session");
481 executor.execute(futureCopyConfig1);
482 executor.execute(futureCopyConfig2);
483
484 int count = 0;
485 while (count < 10) {
486 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
487 executor.shutdown();
488 log.info("Finished concurrent same session execution");
489 return;
490 }
491 Thread.sleep(100L);
492 count++;
493 }
494 fail("NETCONF test failed to complete.");
495 }
496
497 @Test
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200498 public void testConcurrentSameSessionAccessWithChunkedFraming() throws InterruptedException {
499 NCCopyConfigCallable testCopyConfig1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
500 NCCopyConfigCallable testCopyConfig2 = new NCCopyConfigCallable(session3, RUNNING, "startup");
501
502 FutureTask<Boolean> futureCopyConfig1 = new FutureTask<>(testCopyConfig1);
503 FutureTask<Boolean> futureCopyConfig2 = new FutureTask<>(testCopyConfig2);
504
505 ExecutorService executor = Executors.newFixedThreadPool(2);
506 log.info("Starting concurrent execution of copy-config through same session");
507 executor.execute(futureCopyConfig1);
508 executor.execute(futureCopyConfig2);
509
510 int count = 0;
511 while (count < 10) {
512 if (futureCopyConfig1.isDone() && futureCopyConfig2.isDone()) {
513 executor.shutdown();
514 log.info("Finished concurrent same session execution");
515 return;
516 }
517 Thread.sleep(100L);
518 count++;
519 }
520 fail("NETCONF test failed to complete.");
521 }
522
523 @Test
Sean Condond2c8d472017-02-17 17:09:39 +0000524 public void test2SessionAccess() throws InterruptedException {
Andrei Mihaescuac542ca2017-03-26 21:36:25 +0300525 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session1, RUNNING, "candidate");
526 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session2, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000527
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800528 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
529 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
Sean Condond2c8d472017-02-17 17:09:39 +0000530
531 ExecutorService executor = Executors.newFixedThreadPool(2);
532 log.info("Starting concurrent execution of copy-config through 2 different sessions");
533 executor.execute(futureCopySession1);
534 executor.execute(futureCopySession2);
535
536 int count = 0;
537 while (count < 10) {
538 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
539 executor.shutdown();
540 log.info("Finished concurrent 2 session execution");
541 return;
542 }
543 Thread.sleep(100L);
544 count++;
545 }
546 fail("NETCONF test failed to complete.");
547 }
548
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200549 @Test
550 public void test2SessionAccessWithChunkedFraming() throws InterruptedException {
551 NCCopyConfigCallable testCopySession1 = new NCCopyConfigCallable(session3, RUNNING, "candidate");
552 NCCopyConfigCallable testCopySession2 = new NCCopyConfigCallable(session4, RUNNING, "candidate");
Sean Condond2c8d472017-02-17 17:09:39 +0000553
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200554 FutureTask<Boolean> futureCopySession1 = new FutureTask<>(testCopySession1);
555 FutureTask<Boolean> futureCopySession2 = new FutureTask<>(testCopySession2);
556
557 ExecutorService executor = Executors.newFixedThreadPool(2);
558 log.info("Starting concurrent execution of copy-config through 2 different sessions");
559 executor.execute(futureCopySession1);
560 executor.execute(futureCopySession2);
561
562 int count = 0;
563 while (count < 10) {
564 if (futureCopySession1.isDone() && futureCopySession2.isDone()) {
565 executor.shutdown();
566 log.info("Finished concurrent 2 session execution");
567 return;
568 }
569 Thread.sleep(100L);
570 count++;
571 }
572 fail("NETCONF test failed to complete.");
573 }
574
575
576 public static String getTestHelloReply(Optional<Long> sessionId, boolean useChunkedFraming) {
577 if (useChunkedFraming) {
578 return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES_1_1, sessionId);
579 } else {
580 return getTestHelloReply(NetconfSessionMinaImplTest.DEFAULT_CAPABILITIES, sessionId);
581 }
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800582 }
583
584 public static String getTestHelloReply(Collection<String> capabilities, Optional<Long> sessionId) {
Sean Condond2c8d472017-02-17 17:09:39 +0000585 StringBuffer sb = new StringBuffer();
586
587 sb.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
588 sb.append("<capabilities>");
Aaron Kruglikov72db6422017-02-13 12:16:51 -0800589 capabilities.forEach(capability -> {
590 sb.append("<capability>").append(capability).append("</capability>");
591 });
Sean Condond2c8d472017-02-17 17:09:39 +0000592 sb.append("</capabilities>");
593 if (sessionId.isPresent()) {
594 sb.append("<session-id>");
595 sb.append(sessionId.get().toString());
596 sb.append("</session-id>");
597 }
598 sb.append("</hello>");
599
600 return sb.toString();
601 }
602
603 public static String getOkReply(Optional<Integer> messageId) {
604 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
605 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
606 if (messageId.isPresent()) {
607 sb.append("message-id=\"");
608 sb.append(String.valueOf(messageId.get()));
609 sb.append("\">");
610 }
611 sb.append("<ok/>");
612 sb.append("</rpc-reply>");
613 return sb.toString();
614 }
615
616 public static String getGetReply(Optional<Integer> messageId) {
617 StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
618 sb.append("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
619 if (messageId.isPresent()) {
620 sb.append("message-id=\"");
621 sb.append(String.valueOf(messageId.get()));
622 sb.append("\">");
623 }
624 sb.append("<data>\n");
625 sb.append(SAMPLE_REQUEST);
626 sb.append("</data>\n");
627 sb.append("</rpc-reply>");
628 return sb.toString();
629 }
630
631 public static final Pattern HELLO_REQ_PATTERN =
632 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200633 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
634 + "( *)(<capabilities>)\\R?"
635 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
636 + "( *)(</capabilities>)\\R?"
637 + "(</hello>)\\R? *",
638 Pattern.DOTALL);
639
640 public static final Pattern HELLO_REQ_PATTERN_1_1 =
641 Pattern.compile("(<\\?xml).*"
642 + "(<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
643 + "( *)(<capabilities>)\\R?"
644 + "( *)(<capability>urn:ietf:params:netconf:base:1.0</capability>)\\R?"
645 + "( *)(<capability>urn:ietf:params:netconf:base:1.1</capability>)\\R?"
646 + "( *)(</capabilities>)\\R?"
647 + "(</hello>)\\R? *",
Sean Condond2c8d472017-02-17 17:09:39 +0000648 Pattern.DOTALL);
649
650 public static final Pattern EDIT_CONFIG_REQ_PATTERN =
651 Pattern.compile("(<\\?xml).*"
652 + "(<rpc message-id=\")[0-9]*(\") *(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
653 + "(<edit-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700654 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200655 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
656 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000657 + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
658 + ".*"
659 + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
660
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700661
662 public static final Pattern LOCK_REQ_PATTERN =
663 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200664 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
665 + "message-id=\")[0-9]*(\">)\\R?"
666 + "(<lock>)\\R?"
667 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
668 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
669 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
670 + "(</lock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700671
672 public static final Pattern UNLOCK_REQ_PATTERN =
673 Pattern.compile("(<\\?xml).*"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200674 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
675 + "message-id=\")[0-9]*(\">)\\R?"
676 + "(<unlock>)\\R?"
677 + "(<target>\\R?((<" + DatastoreId.CANDIDATE.toString() + "/>)|"
678 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
679 + "(<" + DatastoreId.STARTUP.toString() + "/>))\\R?</target>)\\R?"
680 + "(</unlock>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700681
Sean Condond2c8d472017-02-17 17:09:39 +0000682 public static final Pattern COPY_CONFIG_REQ_PATTERN =
683 Pattern.compile("(<\\?xml).*"
684 + "(<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\")[0-9]*(\">)\\R?"
685 + "(<copy-config>)\\R?"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700686 + "(<target>\\R?"
687 + "("
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200688 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
689 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
690 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700691 + ")\\R?"
692 + "</target>)\\R?"
693 + "(<source>)\\R?"
694 + "("
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200695 + "(<config>)(.*)(</config>)|"
696 + "(<" + DatastoreId.CANDIDATE.toString() + "/>)|"
697 + "(<" + DatastoreId.RUNNING.toString() + "/>)|"
698 + "(<" + DatastoreId.STARTUP.toString() + "/>)"
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700699 + ")\\R?"
700 + "(</source>)\\R?"
701 + "(</copy-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
Sean Condond2c8d472017-02-17 17:09:39 +0000702
703 public static final Pattern GET_CONFIG_REQ_PATTERN =
704 Pattern.compile("(<\\?xml).*"
705 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
Shivani Vaidya48df84e2017-04-13 13:48:17 -0700706 + "(<get-config>)\\R?" + "(<source>)\\R?((<"
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200707 + DatastoreId.CANDIDATE.toString()
708 + "/>)|(<" + DatastoreId.RUNNING.toString()
709 + "/>)|(<" + DatastoreId.STARTUP.toString()
710 + "/>))\\R?(</source>)\\R?"
Sean Condond2c8d472017-02-17 17:09:39 +0000711 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
712 + "(</get-config>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
713
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200714
Sean Condond2c8d472017-02-17 17:09:39 +0000715
716 public static final Pattern GET_REQ_PATTERN =
717 Pattern.compile("(<\\?xml).*"
718 + "(<rpc message-id=\")[0-9]*(\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
719 + "(<get>)\\R?"
720 + "(<filter type=\"subtree\">).*(</filter>)\\R?"
721 + "(</get>)\\R?(</rpc>)\\R?", Pattern.DOTALL);
722
723 public class NCCopyConfigCallable implements Callable<Boolean> {
724 private NetconfSession session;
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700725 private DatastoreId target;
Sean Condond2c8d472017-02-17 17:09:39 +0000726 private String source;
727
Yuta HIGUCHI89111d92017-05-04 11:29:17 -0700728 public NCCopyConfigCallable(NetconfSession session, DatastoreId target, String source) {
Sean Condond2c8d472017-02-17 17:09:39 +0000729 this.session = session;
730 this.target = target;
731 this.source = source;
732 }
733
734 @Override
735 public Boolean call() throws Exception {
736 return session.copyConfig(target, source);
737 }
738 }
Kamil Stasiak9f59f442017-05-02 11:02:24 +0200739}