2 * Copyright (c) 2018 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netconf.mdsal.connector.ops;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import static org.opendaylight.yangtools.yang.test.util.YangParserTestUtils.parseYangResources;
16 import java.io.FileInputStream;
17 import java.net.MalformedURLException;
19 import org.junit.Rule;
20 import org.junit.Test;
21 import org.junit.rules.TemporaryFolder;
22 import org.opendaylight.netconf.api.DocumentedException;
23 import org.opendaylight.netconf.api.DocumentedException.ErrorSeverity;
24 import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
25 import org.opendaylight.netconf.api.DocumentedException.ErrorType;
26 import org.opendaylight.netconf.api.xml.XmlUtil;
27 import org.opendaylight.netconf.util.test.XmlFileLoader;
28 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
29 import org.w3c.dom.Document;
30 import org.xml.sax.SAXException;
32 public class CopyConfigTest extends AbstractNetconfOperationTest {
34 public TemporaryFolder tmpDir = new TemporaryFolder();
37 protected SchemaContext getSchemaContext() {
38 return parseYangResources(CopyConfigTest.class,
39 "/yang/mdsal-netconf-mapping-test.yang");
44 public void testTargetMissing() throws Exception {
46 copyConfig("messages/mapping/copyConfigs/copyConfig_no_target.xml");
47 fail("Should have failed - <target> element is missing");
48 } catch (final DocumentedException e) {
49 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
50 assertTrue(e.getErrorTag() == ErrorTag.MISSING_ATTRIBUTE);
51 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
56 public void testSourceMissing() throws Exception {
58 copyConfig("messages/mapping/copyConfigs/copyConfig_no_source.xml");
59 fail("Should have fanode1iled - <source> element is missing");
60 } catch (final DocumentedException e) {
61 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
62 assertTrue(e.getErrorTag() == ErrorTag.MISSING_ELEMENT);
63 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
68 public void testConfigMissing() throws Exception {
70 copyConfig("messages/mapping/copyConfigs/copyConfig_no_config.xml");
71 fail("Should have failed - neither <config> nor <url> element is present");
72 } catch (final DocumentedException e) {
73 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
74 assertTrue(e.getErrorTag() == ErrorTag.MISSING_ELEMENT);
75 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
80 public void testRunning() throws Exception {
82 copyConfig("messages/mapping/copyConfigs/copyConfig_running.xml");
83 fail("Should have failed - copy config on running datastore is not supported");
84 } catch (final DocumentedException e) {
85 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
86 assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
87 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
92 public void testCandidateTransaction() throws Exception {
93 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_top_modules.xml"), RPC_REPLY_OK);
94 verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
95 "messages/mapping/copyConfigs/copyConfig_top_modules_control.xml"));
96 assertEmptyDatastore(getConfigRunning());
98 verifyResponse(discardChanges(), RPC_REPLY_OK);
99 assertEmptyDatastore(getConfigCandidate());
103 public void testWithCommit() throws Exception {
104 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_top_modules.xml"), RPC_REPLY_OK);
105 final Document expectedConfig = XmlFileLoader.xmlFileToDocument(
106 "messages/mapping/copyConfigs/copyConfig_top_modules_control.xml");
107 verifyResponse(getConfigCandidate(), expectedConfig);
109 verifyResponse(commit(), RPC_REPLY_OK);
110 verifyResponse(getConfigRunning(), expectedConfig);
114 public void testDeleteSubtree() throws Exception {
115 // Initialize datastore
116 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_delete_setup.xml"), RPC_REPLY_OK);
117 verifyResponse(commit(), RPC_REPLY_OK);
118 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
119 "messages/mapping/copyConfigs/copyConfig_delete_setup_control.xml"));
121 // Issue second copy-config, this time without top container
122 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_delete.xml"), RPC_REPLY_OK);
123 verifyResponse(commit(), RPC_REPLY_OK);
124 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
125 "messages/mapping/copyConfigs/copyConfig_delete_control.xml"));
129 public void testList() throws Exception {
130 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_list_setup.xml"), RPC_REPLY_OK);
131 verifyResponse(commit(), RPC_REPLY_OK);
132 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
133 "messages/mapping/copyConfigs/copyConfig_list_setup_control.xml"));
135 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_list_update.xml"), RPC_REPLY_OK);
136 verifyResponse(commit(), RPC_REPLY_OK);
137 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
138 "messages/mapping/copyConfigs/copyConfig_list_update_control.xml"));
142 public void testOrderedList() throws Exception {
143 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_ordered_list_setup.xml"),
145 verifyResponse(commit(), RPC_REPLY_OK);
146 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
147 "messages/mapping/copyConfigs/copyConfig_ordered_list_setup_control.xml"));
149 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_ordered_list_update.xml"),
151 verifyResponse(commit(), RPC_REPLY_OK);
152 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
153 "messages/mapping/copyConfigs/copyConfig_ordered_list_update_control.xml"));
157 public void testToplevelList() throws Exception {
158 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_toplevel_list_setup.xml"),
160 verifyResponse(commit(), RPC_REPLY_OK);
161 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
162 "messages/mapping/copyConfigs/copyConfig_toplevel_list_setup_control.xml"));
164 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_toplevel_list_update.xml"),
166 verifyResponse(commit(), RPC_REPLY_OK);
167 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
168 "messages/mapping/copyConfigs/copyConfig_toplevel_list_update_control.xml"));
172 public void testEmptyContainer() throws Exception {
173 // Check that empty non-presence container is removed.
174 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_empty_container.xml"),
176 verifyResponse(commit(), RPC_REPLY_OK);
177 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
178 "messages/mapping/copyConfigs/copyConfig_empty_container_control.xml"));
182 public void testEmptyPresenceContainer() throws Exception {
183 // Check that empty presence container is not removed.
184 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_empty_presence_container.xml"),
186 verifyResponse(commit(), RPC_REPLY_OK);
187 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
188 "messages/mapping/copyConfigs/copyConfig_empty_presence_container_control.xml"));
192 public void testAugmentations() throws Exception {
193 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_top_augmentation.xml"),
195 verifyResponse(commit(), RPC_REPLY_OK);
196 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
197 "messages/mapping/copyConfigs/copyConfig_top_augmentation_control.xml"));
201 public void testChoices() throws Exception {
202 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_choices1.xml"), RPC_REPLY_OK);
203 verifyResponse(commit(), RPC_REPLY_OK);
204 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_choices2.xml"), RPC_REPLY_OK);
205 verifyResponse(commit(), RPC_REPLY_OK);
206 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_choices3.xml"), RPC_REPLY_OK);
207 verifyResponse(commit(), RPC_REPLY_OK);
208 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_choices4.xml"), RPC_REPLY_OK);
209 verifyResponse(commit(), RPC_REPLY_OK);
210 verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
211 "messages/mapping/copyConfigs/copyConfig_choices_control.xml"));
215 public void testConfigFromFile() throws Exception {
216 // Ask class loader for URI of config file and use it as <url> in <copy-config> RPC:
217 final String template = XmlFileLoader.fileToString("messages/mapping/copyConfigs/copyConfig_from_file.xml");
218 final URI uri = getClass().getClassLoader()
219 .getResource("messages/mapping/copyConfigs/config_file_valid.xml").toURI();
220 final String copyConfig = template.replaceFirst("URL", uri.toString());
221 final Document request = XmlUtil.readXmlToDocument(copyConfig);
223 verifyResponse(copyConfig(request), RPC_REPLY_OK);
224 verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
225 "messages/mapping/copyConfigs/copyConfig_from_file_control.xml"));
229 public void testConfigFromInvalidUrl() throws Exception {
231 copyConfig("messages/mapping/copyConfigs/copyConfig_invalid_url.xml");
232 fail("Should have failed - provided <url> is not valid");
233 } catch (final DocumentedException e) {
234 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
235 assertTrue(e.getErrorTag() == ErrorTag.INVALID_VALUE);
236 assertTrue(e.getErrorType() == ErrorType.APPLICATION);
237 assertTrue(e.getCause() instanceof MalformedURLException);
242 public void testExternalConfigInvalid() throws Exception {
244 // Ask class loader for URI of config file and use it as <url> in <copy-config> RPC:
245 final String template = XmlFileLoader.fileToString("messages/mapping/copyConfigs/copyConfig_from_file.xml");
246 final URI uri = getClass().getClassLoader()
247 .getResource("messages/mapping/copyConfigs/config_file_invalid.xml").toURI();
248 final String copyConfig = template.replaceFirst("URL", uri.toString());
249 final Document request = XmlUtil.readXmlToDocument(copyConfig);
251 fail("Should have failed - provided config is not valid XML");
252 } catch (final DocumentedException e) {
253 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
254 assertTrue(e.getErrorTag() == ErrorTag.OPERATION_FAILED);
255 assertTrue(e.getErrorType() == ErrorType.APPLICATION);
256 assertTrue(e.getCause() instanceof SAXException);
261 public void testCopyToFile() throws Exception {
262 // Initialize config:
263 verifyResponse(copyConfig("messages/mapping/copyConfigs/copyConfig_top_modules.xml"), RPC_REPLY_OK);
264 verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
265 "messages/mapping/copyConfigs/copyConfig_top_modules_control.xml"));
267 // Load copy-config template and replace URL with the URI of target file:
268 final String template = XmlFileLoader.fileToString("messages/mapping/copyConfigs/copyConfig_to_file.xml");
269 final File outFile = new File(tmpDir.getRoot(),"test-copy-to-file.xml");
270 final String copyConfig = template.replaceFirst("URL", outFile.toURI().toString());
271 final Document request = XmlUtil.readXmlToDocument(copyConfig);
273 // Invoke copy-config RPC:
274 verifyResponse(copyConfig(request), RPC_REPLY_OK);
276 // Check if outFile was created with expected content:
277 verifyResponse(XmlUtil.readXmlToDocument(new FileInputStream(outFile)),
278 XmlFileLoader.xmlFileToDocument("messages/mapping/copyConfigs/copyConfig_to_file_control.xml"));
282 public void testUnsupportedTargetUrlProtocol() throws Exception {
284 copyConfig("messages/mapping/copyConfigs/copyConfig_to_unsupported_url_protocol.xml");
285 fail("Should have failed - exporting config to http server is not supported");
286 } catch (final DocumentedException e) {
287 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
288 assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
289 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
294 public void testCopyToFileFromRunning() throws Exception {
295 // Load copy-config template and replace URL with the URI of target file:
296 final String template =
297 XmlFileLoader.fileToString("messages/mapping/copyConfigs/copyConfig_to_file_from_running.xml");
298 final File outFile = new File(tmpDir.getRoot(),"test-copy-to-file-from-running.xml");
299 final String copyConfig = template.replaceFirst("URL", outFile.toURI().toString());
300 final Document request = XmlUtil.readXmlToDocument(copyConfig);
302 // Invoke copy-config RPC:
303 verifyResponse(copyConfig(request), RPC_REPLY_OK);
305 // Check if outFile was created with expected content:
306 verifyResponse(XmlUtil.readXmlToDocument(new FileInputStream(outFile)),
307 XmlFileLoader.xmlFileToDocument(
308 "messages/mapping/copyConfigs/copyConfig_to_file_from_running_control.xml"));
313 public void testRemoteToRemoteOperationIsNotSupported() throws Exception {
315 copyConfig("messages/mapping/copyConfigs/copyConfig_url_remote_to_remote.xml");
316 fail("Should have failed - remote to remote operations are not supported");
317 } catch (final DocumentedException e) {
318 assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
319 assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
320 assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
324 private Document copyConfig(final String resource) throws Exception {
325 final CopyConfig copyConfig = new CopyConfig(SESSION_ID_FOR_REPORTING, getCurrentSchemaContext(),
326 getTransactionProvider());
327 return executeOperation(copyConfig, resource);
330 private Document copyConfig(final Document request) throws Exception {
331 final CopyConfig copyConfig = new CopyConfig(SESSION_ID_FOR_REPORTING, getCurrentSchemaContext(),
332 getTransactionProvider());
333 return executeOperation(copyConfig, request);