d582163774cfd3185ea29cb8433a813934229bf5
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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  */
16
17 package org.openecomp.sdc.tosca.csar;
18
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;
27
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;
38 import java.util.Map;
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;
45
46 public class SOL004ManifestOnboardingTest {
47
48     private Manifest manifest;
49
50     @Before
51     public void setUp() {
52         manifest = new SOL004ManifestOnboarding();
53     }
54
55     @Test
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);
61         }
62     }
63
64     @Test
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)
72             );
73             assertInvalidManifest(expectedErrorList);
74         }
75     }
76
77     @Test
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);
85         }
86     }
87
88     @Test
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")
97             );
98             assertInvalidManifest(expectedErrorList);
99         }
100     }
101
102     @Test
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);
109         }
110     }
111
112     @Test
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,
119                     "vnf_product_name")
120             );
121             assertInvalidManifest(errorList);
122         }
123     }
124
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);
128     }
129
130     @Test
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"),
138                     34, "some garbage")
139             );
140             assertInvalidManifest(errorList);
141         }
142     }
143
144     @Test
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()));
150         }
151     }
152
153     @Test
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);
159         }
160     }
161
162     @Test
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));
169         }
170     }
171
172     @Test
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);
178         }
179     }
180
181     @Test
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);
186
187             final List<String> expectedErrorList = new ArrayList<>();
188             expectedErrorList.add(
189                 buildErrorMessage(3, "vnf_provider_id", Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_provider_id")
190             );
191             assertInvalidManifest(expectedErrorList);
192         }
193     }
194
195     @Test
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);
200
201             final List<String> expectedErrorList = new ArrayList<>();
202             expectedErrorList.add(
203                 buildErrorMessage(3, ": no-entry-value", Messages.MANIFEST_METADATA_INVALID_ENTRY1, ": no-entry-value")
204             );
205             assertInvalidManifest(expectedErrorList);
206         }
207     }
208
209     @Test
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")
218             );
219             assertInvalidManifest(expectedErrorList);
220         }
221     }
222
223     @Test
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);
231         }
232     }
233
234     @Test
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,
242                     "vnf_product_name")
243             );
244             assertInvalidManifest(expectedErrorList);
245         }
246     }
247
248     @Test
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,
256                     "foo_bar")
257             );
258             assertInvalidManifest(expectedErrorList);
259         }
260     }
261
262     @Test
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)
270             );
271             assertInvalidManifest(expectedErrorList);
272         }
273     }
274
275     @Test
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);
283         }
284     }
285
286     @Test
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);
294         }
295     }
296
297     @Test
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);
305         }
306     }
307
308     @Test
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);
316         }
317     }
318
319     @Test
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);
327         }
328     }
329
330     @Test
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);
338         }
339     }
340
341     @Test
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);
351
352             final List<String> expectedErrorList = new ArrayList<>();
353             expectedErrorList
354                 .add(buildErrorMessage(18, "-----BEGIN CMS-----", Messages.MANIFEST_SIGNATURE_DUPLICATED));
355             assertInvalidManifest(expectedErrorList);
356         }
357     }
358
359     @Test
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));
365
366         final Optional<String> blankEntry = (Optional<String>) getEntryMethod.invoke(manifest, "        :");
367         assertThat("Entry should not be present", blankEntry.isPresent(), is(false));
368
369         final Optional<String> noColon = (Optional<String>) getEntryMethod.invoke(manifest, "anyKeyWithoutColon   ");
370         assertThat("Entry should not be present", noColon.isPresent(), is(false));
371
372         final Optional<String> blank = (Optional<String>) getEntryMethod.invoke(manifest, "   ");
373         assertThat("Entry should not be present", blank.isPresent(), is(false));
374
375         final Optional<String> empty = (Optional<String>) getEntryMethod.invoke(manifest, "");
376         assertThat("Entry should not be present", empty.isPresent(), is(false));
377
378         final Optional<String> nul1 = (Optional<String>) getEntryMethod.invoke(manifest, new Object[]{null});
379         assertThat("Entry should not be present", nul1.isPresent(), is(false));
380
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"));
385     }
386
387     @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));
393
394         final Optional<String> blankValue = (Optional<String>) getValueMethod.invoke(manifest, ":          ");
395         assertThat("Value should not be present", blankValue.isPresent(), is(false));
396
397         final Optional<String> noColon = (Optional<String>) getValueMethod.invoke(manifest, "anyKeyWithoutColon   ");
398         assertThat("Value should not be present", noColon.isPresent(), is(false));
399
400         final Optional<String> blank = (Optional<String>) getValueMethod.invoke(manifest, "   ");
401         assertThat("Value should not be present", blank.isPresent(), is(false));
402
403         final Optional<String> empty = (Optional<String>) getValueMethod.invoke(manifest, "");
404         assertThat("Value should not be present", empty.isPresent(), is(false));
405
406         final Optional<String> nul1 = (Optional<String>) getValueMethod.invoke(manifest, new Object[]{null});
407         assertThat("Value should not be present", nul1.isPresent(), is(false));
408
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:"));
413     }
414
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()));
431         }
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));
435     }
436
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])));
442     }
443 }