2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.openecomp.sdc.tosca.csar;
19 import static junit.framework.TestCase.assertSame;
20 import static org.hamcrest.Matchers.containsInAnyOrder;
21 import static org.hamcrest.Matchers.empty;
22 import static org.hamcrest.Matchers.equalTo;
23 import static org.hamcrest.Matchers.hasItem;
24 import static org.hamcrest.Matchers.hasSize;
25 import static org.hamcrest.core.Is.is;
26 import static org.junit.Assert.assertThat;
28 import com.google.common.collect.ImmutableMap;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.lang.reflect.Field;
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import java.util.Optional;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
44 import org.openecomp.sdc.common.errors.Messages;
46 public class SOL004ManifestOnboardingTest {
48 private Manifest manifest;
52 manifest = new SOL004ManifestOnboarding();
56 public void testSuccessfulParsing() throws IOException {
57 try (final InputStream manifestAsStream =
58 getClass().getResourceAsStream("/vspmanager.csar/manifest/ValidTosca.mf")) {
59 manifest.parse(manifestAsStream);
60 assertValidManifest(4, 5, Collections.emptyMap(), ResourceTypeEnum.VF, false);
65 public void testNoMetadataParsing() throws IOException {
66 try (final InputStream manifestAsStream = getClass()
67 .getResourceAsStream("/vspmanager.csar/manifest/invalid/no-metadata.mf")) {
68 manifest.parse(manifestAsStream);
69 final List<String> expectedErrorList = new ArrayList<>();
70 expectedErrorList.add(
71 buildErrorMessage(3, "Source: MainServiceTemplate.yaml", Messages.MANIFEST_START_METADATA)
73 assertInvalidManifest(expectedErrorList);
78 public void testBrokenMDParsing() throws IOException {
79 try (final InputStream manifestAsStream =
80 getClass().getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca2.mf")) {
81 manifest.parse(manifestAsStream);
82 final List<String> expectedErrorList = new ArrayList<>();
83 expectedErrorList.add(Messages.MANIFEST_INVALID_LINE.formatMessage(9, "vnf_package_version: 1.0"));
84 assertInvalidManifest(expectedErrorList);
89 public void testNoMetaParsing() throws IOException {
90 try (final InputStream manifestAsStream = getClass()
91 .getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf")) {
92 manifest.parse(manifestAsStream);
93 final List<String> expectedErrorList = new ArrayList<>();
94 expectedErrorList.add(
95 buildErrorMessage(4, "Source: MainServiceTemplate.yaml",
96 Messages.MANIFEST_METADATA_INVALID_ENTRY1, "Source: MainServiceTemplate.yaml")
98 assertInvalidManifest(expectedErrorList);
103 public void testSuccessfulNonManoParsing() throws IOException {
104 try (final InputStream manifestAsStream = getClass()
105 .getResourceAsStream("/vspmanager.csar/manifest/ValidNonManoTosca.mf")) {
106 manifest.parse(manifestAsStream);
107 assertValidManifest(4, 5,
108 ImmutableMap.of("foo_bar", 3, "prv.happy-nfv.cool", 3), ResourceTypeEnum.VF, false);
113 public void testInvalidNonManoParsing() throws IOException {
114 try (final InputStream manifestAsStream = getClass()
115 .getResourceAsStream("/vspmanager.csar/manifest/InValidNonManoTosca.mf")) {
116 manifest.parse(manifestAsStream);
117 final List<String> errorList = Collections.singletonList(
118 buildErrorMessage(34, "vnf_product_name: Mock", Messages.MANIFEST_INVALID_NON_MANO_KEY,
121 assertInvalidManifest(errorList);
125 private String buildErrorMessage(final int lineNumber, final String line, final Messages message,
126 final Object... params) {
127 return Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(message.formatMessage(params), lineNumber, line);
131 public void testNonManoParsingWithGarbage() throws IOException {
132 try (final InputStream manifestAsStream = getClass()
133 .getResourceAsStream("/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf")) {
134 manifest.parse(manifestAsStream);
135 final List<String> errorList = Collections.singletonList(
136 Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(
137 Messages.MANIFEST_INVALID_NON_MANO_KEY.formatMessage("some garbage"),
140 assertInvalidManifest(errorList);
145 public void testInvalidManifestFile() throws IOException {
146 try (final InputStream manifestAsStream = getClass()
147 .getResourceAsStream("/vspmanager.csar/manifest/SOME_WRONG_FILE")) {
148 manifest.parse(manifestAsStream);
149 assertInvalidManifest(Collections.singletonList(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage()));
154 public void testManifestSigned() throws IOException {
155 try (final InputStream manifestAsStream = getClass()
156 .getResourceAsStream("/vspmanager.csar/manifest/valid/signed.mf")) {
157 manifest.parse(manifestAsStream);
158 assertValidManifest(4, 3, Collections.emptyMap(), ResourceTypeEnum.VF, true);
163 public void testManifestSignedWithNonManoArtifacts() throws IOException {
164 try (final InputStream manifestAsStream = getClass()
165 .getResourceAsStream("/vspmanager.csar/manifest/valid/signed-with-non-mano.mf")) {
166 manifest.parse(manifestAsStream);
167 assertValidManifest(4, 3, ImmutableMap.of("foo_bar", 3), ResourceTypeEnum.VF, true);
168 manifest.getType().ifPresent(typeEnum -> assertSame(typeEnum, ResourceTypeEnum.VF));
173 public void testManifestWithPnf() throws IOException {
174 try (final InputStream manifestAsStream = getClass()
175 .getResourceAsStream("/vspmanager.csar/manifest/valid/metadata-pnfd.mf")) {
176 manifest.parse(manifestAsStream);
177 assertValidManifest(4, 3, new HashMap<>(), ResourceTypeEnum.PNF, true);
182 public void testMetadataWithNoValue() throws IOException {
183 try (final InputStream manifestAsStream = getClass()
184 .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-value.mf")) {
185 manifest.parse(manifestAsStream);
187 final List<String> expectedErrorList = new ArrayList<>();
188 expectedErrorList.add(
189 buildErrorMessage(3, "vnf_provider_id", Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_provider_id")
191 assertInvalidManifest(expectedErrorList);
196 public void testMetadataWithValueButNoEntry() throws IOException {
197 try (final InputStream manifestAsStream = getClass()
198 .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-entry.mf")) {
199 manifest.parse(manifestAsStream);
201 final List<String> expectedErrorList = new ArrayList<>();
202 expectedErrorList.add(
203 buildErrorMessage(3, ": no-entry-value", Messages.MANIFEST_METADATA_INVALID_ENTRY1, ": no-entry-value")
205 assertInvalidManifest(expectedErrorList);
210 public void testMetadataWithIncorrectEntry() throws IOException {
211 try (final InputStream manifestAsStream = getClass()
212 .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf")) {
213 manifest.parse(manifestAsStream);
214 final List<String> expectedErrorList = new ArrayList<>();
215 expectedErrorList.add(
216 buildErrorMessage(4, "vnf_release_data_time: 2019-08-29T22:17:39.275281",
217 Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_release_data_time: 2019-08-29T22:17:39.275281")
219 assertInvalidManifest(expectedErrorList);
224 public void testMetadataWithMixedEntries() throws IOException {
225 try (final InputStream manifestAsStream = getClass()
226 .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf")) {
227 manifest.parse(manifestAsStream);
228 final List<String> expectedErrorList = new ArrayList<>();
229 expectedErrorList.add(buildErrorMessage(6, "", Messages.MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE));
230 assertInvalidManifest(expectedErrorList);
235 public void testMetadataWithDuplicatedEntries() throws IOException {
236 try (final InputStream manifestAsStream =
237 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf")) {
238 manifest.parse(manifestAsStream);
239 final List<String> expectedErrorList = new ArrayList<>();
240 expectedErrorList.add(
241 buildErrorMessage(4, "vnf_product_name: vPP", Messages.MANIFEST_METADATA_DUPLICATED_ENTRY,
244 assertInvalidManifest(expectedErrorList);
249 public void testManifestNonManoKeyWithoutSources() throws IOException {
250 try (final InputStream manifestAsStream =
251 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf")) {
252 manifest.parse(manifestAsStream);
253 final List<String> expectedErrorList = new ArrayList<>();
254 expectedErrorList.add(
255 buildErrorMessage(11, "", Messages.MANIFEST_EMPTY_NON_MANO_KEY,
258 assertInvalidManifest(expectedErrorList);
263 public void testManifestNonManoKeyWithEmptySourceEntry() throws IOException {
264 try (final InputStream manifestAsStream =
265 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf")) {
266 manifest.parse(manifestAsStream);
267 final List<String> expectedErrorList = new ArrayList<>();
268 expectedErrorList.add(
269 buildErrorMessage(11, "Source:", Messages.MANIFEST_EMPTY_NON_MANO_SOURCE)
271 assertInvalidManifest(expectedErrorList);
276 public void testManifestWithEmptyMetadata() throws IOException {
277 try (final InputStream manifestAsStream =
278 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata.mf")) {
279 manifest.parse(manifestAsStream);
280 final List<String> expectedErrorList = new ArrayList<>();
281 expectedErrorList.add(buildErrorMessage(2, "", Messages.MANIFEST_NO_METADATA));
282 assertInvalidManifest(expectedErrorList);
287 public void testManifestSourceAlgorithmWithoutHash() throws IOException {
288 try (final InputStream manifestAsStream =
289 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf")) {
290 manifest.parse(manifestAsStream);
291 final List<String> expectedErrorList = new ArrayList<>();
292 expectedErrorList.add(buildErrorMessage(9, "", Messages.MANIFEST_EXPECTED_HASH_ENTRY));
293 assertInvalidManifest(expectedErrorList);
298 public void testManifestSourceHashWithoutAlgorithm() throws IOException {
299 try (final InputStream manifestAsStream =
300 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf")) {
301 manifest.parse(manifestAsStream);
302 final List<String> expectedErrorList = new ArrayList<>();
303 expectedErrorList.add(buildErrorMessage(8, "Hash: 3b119b37da5b76ec7c933168b21cedd8", Messages.MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH));
304 assertInvalidManifest(expectedErrorList);
309 public void testManifestSourceAlgorithmWithoutValue() throws IOException {
310 try (final InputStream manifestAsStream =
311 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf")) {
312 manifest.parse(manifestAsStream);
313 final List<String> expectedErrorList = new ArrayList<>();
314 expectedErrorList.add(buildErrorMessage(8, "Algorithm:", Messages.MANIFEST_EXPECTED_ALGORITHM_VALUE));
315 assertInvalidManifest(expectedErrorList);
320 public void testManifestSourceHashWithoutValue() throws IOException {
321 try (final InputStream manifestAsStream =
322 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-value.mf")) {
323 manifest.parse(manifestAsStream);
324 final List<String> expectedErrorList = new ArrayList<>();
325 expectedErrorList.add(buildErrorMessage(9, "Hash:", Messages.MANIFEST_EXPECTED_HASH_VALUE));
326 assertInvalidManifest(expectedErrorList);
331 public void testEmptyManifest() throws IOException {
332 try (final InputStream manifestAsStream =
333 getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-manifest.mf")) {
334 manifest.parse(manifestAsStream);
335 final List<String> expectedErrorList = new ArrayList<>();
336 expectedErrorList.add(Messages.MANIFEST_EMPTY.getErrorMessage());
337 assertInvalidManifest(expectedErrorList);
342 public void testManifestWithDuplicatedCmsSignature()
343 throws IOException, NoSuchFieldException, IllegalAccessException {
344 try (final InputStream manifestAsStream =
345 getClass().getResourceAsStream("/vspmanager.csar/manifest/valid/signed.mf")) {
346 //forcing an existing signature
347 final Field cmsSignatureField = AbstractOnboardingManifest.class.getDeclaredField("cmsSignature");
348 cmsSignatureField.setAccessible(true);
349 cmsSignatureField.set(manifest, "any value");
350 manifest.parse(manifestAsStream);
352 final List<String> expectedErrorList = new ArrayList<>();
354 .add(buildErrorMessage(18, "-----BEGIN CMS-----", Messages.MANIFEST_SIGNATURE_DUPLICATED));
355 assertInvalidManifest(expectedErrorList);
360 public void testGetEntry() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
361 final Method getEntryMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryName", String.class);
362 getEntryMethod.setAccessible(true);
363 final Optional<String> noEntry = (Optional<String>) getEntryMethod.invoke(manifest, ":");
364 assertThat("Entry should not be present", noEntry.isPresent(), is(false));
366 final Optional<String> blankEntry = (Optional<String>) getEntryMethod.invoke(manifest, " :");
367 assertThat("Entry should not be present", blankEntry.isPresent(), is(false));
369 final Optional<String> noColon = (Optional<String>) getEntryMethod.invoke(manifest, "anyKeyWithoutColon ");
370 assertThat("Entry should not be present", noColon.isPresent(), is(false));
372 final Optional<String> blank = (Optional<String>) getEntryMethod.invoke(manifest, " ");
373 assertThat("Entry should not be present", blank.isPresent(), is(false));
375 final Optional<String> empty = (Optional<String>) getEntryMethod.invoke(manifest, "");
376 assertThat("Entry should not be present", empty.isPresent(), is(false));
378 final Optional<String> nul1 = (Optional<String>) getEntryMethod.invoke(manifest, new Object[]{null});
379 assertThat("Entry should not be present", nul1.isPresent(), is(false));
381 final Optional<String> entry = (Optional<String>) getEntryMethod
382 .invoke(manifest, " entry to test : : a value ::: test test: ");
383 assertThat("Entry should be present", entry.isPresent(), is(true));
384 assertThat("Entry should be as expected", entry.get(), equalTo("entry to test"));
388 public void testGetValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
389 final Method getValueMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryValue", String.class);
390 getValueMethod.setAccessible(true);
391 final Optional<String> noValue = (Optional<String>) getValueMethod.invoke(manifest, ":");
392 assertThat("Value should not be present", noValue.isPresent(), is(false));
394 final Optional<String> blankValue = (Optional<String>) getValueMethod.invoke(manifest, ": ");
395 assertThat("Value should not be present", blankValue.isPresent(), is(false));
397 final Optional<String> noColon = (Optional<String>) getValueMethod.invoke(manifest, "anyKeyWithoutColon ");
398 assertThat("Value should not be present", noColon.isPresent(), is(false));
400 final Optional<String> blank = (Optional<String>) getValueMethod.invoke(manifest, " ");
401 assertThat("Value should not be present", blank.isPresent(), is(false));
403 final Optional<String> empty = (Optional<String>) getValueMethod.invoke(manifest, "");
404 assertThat("Value should not be present", empty.isPresent(), is(false));
406 final Optional<String> nul1 = (Optional<String>) getValueMethod.invoke(manifest, new Object[]{null});
407 assertThat("Value should not be present", nul1.isPresent(), is(false));
409 final Optional<String> value = (Optional<String>) getValueMethod
410 .invoke(manifest, "attribute : : a value ::: test test: ");
411 assertThat("Value should be present", value.isPresent(), is(true));
412 assertThat("Value should be as expected", value.get(), equalTo(": a value ::: test test:"));
415 private void assertValidManifest(final int expectedMetadataSize, final int expectedSourcesSize,
416 final Map<String, Integer> expectedNonManoKeySize,
417 final ResourceTypeEnum resourceType, final boolean isSigned) {
418 assertThat("Should have no errors", manifest.getErrors(), is(empty()));
419 assertThat("Should be valid", manifest.isValid(), is(true));
420 assertThat("Metadata should have the expected size",
421 manifest.getMetadata().keySet(), hasSize(expectedMetadataSize));
422 assertThat("Sources should have the expected size", manifest.getSources(), hasSize(expectedSourcesSize));
423 assertThat("Non Mano Sources keys should have the expected size",
424 manifest.getNonManoSources().keySet(), hasSize(expectedNonManoKeySize.keySet().size()));
425 for (final Entry<String, Integer> nonManoKeyAndSize : expectedNonManoKeySize.entrySet()) {
426 final String nonManoKey = nonManoKeyAndSize.getKey();
427 assertThat("Should contain expected Non Mano Sources key",
428 manifest.getNonManoSources().keySet(), hasItem(nonManoKey));
429 assertThat(String.format("Non Mano Sources keys %s should have the expected sources size", nonManoKey),
430 manifest.getNonManoSources().get(nonManoKey).size(), equalTo(nonManoKeyAndSize.getValue()));
432 assertThat("Should have a type", manifest.getType().isPresent(), is(true));
433 assertThat("Type should be as expected", manifest.getType().get(), equalTo(resourceType));
434 assertThat("Signature status should be as expected", manifest.isSigned(), is(isSigned));
437 private void assertInvalidManifest(final List<String> expectedErrorList) {
438 assertThat("Should be invalid", manifest.isValid(), is(false));
439 assertThat("Should have the expected error quantity", manifest.getErrors(), hasSize(expectedErrorList.size()));
440 assertThat("Should have expected errors", manifest.getErrors(),
441 containsInAnyOrder(expectedErrorList.toArray(new String[0])));