7cb1511a328c10c24b58351952b19d7dbcd76de1
[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.InvocationTargetException;
32 import java.lang.reflect.Method;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.Optional;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
43 import org.openecomp.sdc.common.errors.Messages;
44
45 public class SOL004ManifestOnboardingTest {
46
47     private Manifest manifest;
48
49     @Before
50     public void setUp() {
51         manifest = new SOL004ManifestOnboarding();
52     }
53
54     @Test
55     public void testSuccessfulParsing() throws IOException {
56         try (final InputStream manifestAsStream =
57             getClass().getResourceAsStream("/vspmanager.csar/manifest/ValidTosca.mf")) {
58             manifest.parse(manifestAsStream);
59             assertValidManifest(4, 5, Collections.emptyMap(), ResourceTypeEnum.VF);
60         }
61     }
62
63     @Test
64     public void testNoMetadataParsing() throws IOException {
65         try (final InputStream manifestAsStream = getClass()
66             .getResourceAsStream("/vspmanager.csar/manifest/invalid/no-metadata.mf")) {
67             manifest.parse(manifestAsStream);
68             final List<String> expectedErrorList = new ArrayList<>();
69             expectedErrorList.add(
70                 buildErrorMessage(3, "Source: MainServiceTemplate.yaml", Messages.MANIFEST_START_METADATA)
71             );
72             assertInvalidManifest(expectedErrorList);
73         }
74     }
75
76     @Test
77     public void testBrokenMDParsing() throws IOException {
78         try (final InputStream manifestAsStream =
79             getClass().getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca2.mf")) {
80             manifest.parse(manifestAsStream);
81             final List<String> expectedErrorList = new ArrayList<>();
82             expectedErrorList.add(Messages.MANIFEST_INVALID_LINE.formatMessage(9, "vnf_package_version: 1.0"));
83             assertInvalidManifest(expectedErrorList);
84         }
85     }
86
87     @Test
88     public void testNoMetaParsing() throws IOException {
89         try (final InputStream manifestAsStream = getClass()
90             .getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf")) {
91             manifest.parse(manifestAsStream);
92             final List<String> expectedErrorList = new ArrayList<>();
93             expectedErrorList.add(
94                 buildErrorMessage(4, "Source: MainServiceTemplate.yaml",
95                     Messages.MANIFEST_METADATA_INVALID_ENTRY1, "Source: MainServiceTemplate.yaml")
96             );
97             assertInvalidManifest(expectedErrorList);
98         }
99     }
100
101     @Test
102     public void testSuccessfulNonManoParsing() throws IOException {
103         try (final InputStream manifestAsStream = getClass()
104             .getResourceAsStream("/vspmanager.csar/manifest/ValidNonManoTosca.mf")) {
105             manifest.parse(manifestAsStream);
106             assertValidManifest(4, 5,
107                 ImmutableMap.of("foo_bar", 3, "prv.happy-nfv.cool", 3), ResourceTypeEnum.VF);
108         }
109     }
110
111     @Test
112     public void testInvalidNonManoParsing() throws IOException {
113         try (final InputStream manifestAsStream = getClass()
114             .getResourceAsStream("/vspmanager.csar/manifest/InValidNonManoTosca.mf")) {
115             manifest.parse(manifestAsStream);
116             final List<String> errorList = Collections.singletonList(
117                 buildErrorMessage(34, "vnf_product_name: Mock", Messages.MANIFEST_INVALID_NON_MANO_KEY,
118                     "vnf_product_name")
119             );
120             assertInvalidManifest(errorList);
121         }
122     }
123
124     private String buildErrorMessage(final int lineNumber, final String line, final Messages message,
125                                     final Object... params) {
126         return Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(message.formatMessage(params), lineNumber, line);
127     }
128
129     @Test
130     public void testNonManoParsingWithGarbage() throws IOException {
131         try (final InputStream manifestAsStream = getClass()
132             .getResourceAsStream("/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf")) {
133             manifest.parse(manifestAsStream);
134             final List<String> errorList = Collections.singletonList(
135                 Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(
136                     Messages.MANIFEST_INVALID_NON_MANO_KEY.formatMessage("some garbage"),
137                     34, "some garbage")
138             );
139             assertInvalidManifest(errorList);
140         }
141     }
142
143     @Test
144     public void testInvalidManifestFile() throws IOException {
145         try (final InputStream manifestAsStream = getClass()
146             .getResourceAsStream("/vspmanager.csar/manifest/SOME_WRONG_FILE")) {
147             manifest.parse(manifestAsStream);
148             assertInvalidManifest(Collections.singletonList(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage()));
149         }
150     }
151
152     @Test
153     public void testManifestSigned() throws IOException {
154         try (final InputStream manifestAsStream = getClass()
155             .getResourceAsStream("/vspmanager.csar/manifest/valid/signed.mf")) {
156             manifest.parse(manifestAsStream);
157             assertValidManifest(4, 3, Collections.emptyMap(), ResourceTypeEnum.VF);
158         }
159     }
160
161     @Test
162     public void testManifestSignedWithNonManoArtifacts() throws IOException {
163         try (final InputStream manifestAsStream = getClass()
164             .getResourceAsStream("/vspmanager.csar/manifest/valid/signed-with-non-mano.mf")) {
165             manifest.parse(manifestAsStream);
166             assertValidManifest(4, 3, ImmutableMap.of("foo_bar", 3), ResourceTypeEnum.VF);
167             manifest.getType().ifPresent(typeEnum -> assertSame(typeEnum, ResourceTypeEnum.VF));
168         }
169     }
170
171     @Test
172     public void testManifestWithPnf() throws IOException {
173         try (final InputStream manifestAsStream = getClass()
174             .getResourceAsStream("/vspmanager.csar/manifest/valid/metadata-pnfd.mf")) {
175             manifest.parse(manifestAsStream);
176             assertValidManifest(4, 3, new HashMap<>(), ResourceTypeEnum.PNF);
177         }
178     }
179
180     @Test
181     public void testMetadataWithNoValue() throws IOException {
182         try (final InputStream manifestAsStream = getClass()
183             .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-value.mf")) {
184             manifest.parse(manifestAsStream);
185
186             final List<String> expectedErrorList = new ArrayList<>();
187             expectedErrorList.add(
188                 buildErrorMessage(3, "vnf_provider_id", Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_provider_id")
189             );
190             assertInvalidManifest(expectedErrorList);
191         }
192     }
193
194     @Test
195     public void testMetadataWithValueButNoEntry() throws IOException {
196         try (final InputStream manifestAsStream = getClass()
197             .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-entry.mf")) {
198             manifest.parse(manifestAsStream);
199
200             final List<String> expectedErrorList = new ArrayList<>();
201             expectedErrorList.add(
202                 buildErrorMessage(3, ": no-entry-value", Messages.MANIFEST_METADATA_INVALID_ENTRY1, ": no-entry-value")
203             );
204             assertInvalidManifest(expectedErrorList);
205         }
206     }
207
208     @Test
209     public void testMetadataWithIncorrectEntry() throws IOException {
210         try (final InputStream manifestAsStream = getClass()
211             .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf")) {
212             manifest.parse(manifestAsStream);
213             final List<String> expectedErrorList = new ArrayList<>();
214             expectedErrorList.add(
215                 buildErrorMessage(4, "vnf_release_data_time: 2019-08-29T22:17:39.275281",
216                     Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_release_data_time: 2019-08-29T22:17:39.275281")
217             );
218             assertInvalidManifest(expectedErrorList);
219         }
220     }
221
222     @Test
223     public void testMetadataWithMixedEntries() throws IOException {
224         try (final InputStream manifestAsStream = getClass()
225             .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf")) {
226             manifest.parse(manifestAsStream);
227             final List<String> expectedErrorList = new ArrayList<>();
228             expectedErrorList.add(buildErrorMessage(6, "", Messages.MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE));
229             assertInvalidManifest(expectedErrorList);
230         }
231     }
232
233     @Test
234     public void testMetadataWithDuplicatedEntries() throws IOException {
235         try (final InputStream manifestAsStream =
236             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf")) {
237             manifest.parse(manifestAsStream);
238             final List<String> expectedErrorList = new ArrayList<>();
239             expectedErrorList.add(
240                 buildErrorMessage(4, "vnf_product_name: vPP", Messages.MANIFEST_METADATA_DUPLICATED_ENTRY,
241                     "vnf_product_name")
242             );
243             assertInvalidManifest(expectedErrorList);
244         }
245     }
246
247     @Test
248     public void testManifestNonManoKeyWithoutSources() throws IOException {
249         try (final InputStream manifestAsStream =
250             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf")) {
251             manifest.parse(manifestAsStream);
252             final List<String> expectedErrorList = new ArrayList<>();
253             expectedErrorList.add(
254                 buildErrorMessage(11, "", Messages.MANIFEST_EMPTY_NON_MANO_KEY,
255                     "foo_bar")
256             );
257             assertInvalidManifest(expectedErrorList);
258         }
259     }
260
261     @Test
262     public void testManifestNonManoKeyWithEmptySourceEntry() throws IOException {
263         try (final InputStream manifestAsStream =
264             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf")) {
265             manifest.parse(manifestAsStream);
266             final List<String> expectedErrorList = new ArrayList<>();
267             expectedErrorList.add(
268                 buildErrorMessage(11, "Source:", Messages.MANIFEST_EMPTY_NON_MANO_SOURCE)
269             );
270             assertInvalidManifest(expectedErrorList);
271         }
272     }
273
274     @Test
275     public void testManifestWithEmptyMetadata() throws IOException {
276         try (final InputStream manifestAsStream =
277             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata.mf")) {
278             manifest.parse(manifestAsStream);
279             final List<String> expectedErrorList = new ArrayList<>();
280             expectedErrorList.add(buildErrorMessage(2, "", Messages.MANIFEST_NO_METADATA));
281             assertInvalidManifest(expectedErrorList);
282         }
283     }
284
285     @Test
286     public void testManifestSourceAlgorithmWithoutHash() throws IOException {
287         try (final InputStream manifestAsStream =
288             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf")) {
289             manifest.parse(manifestAsStream);
290             final List<String> expectedErrorList = new ArrayList<>();
291             expectedErrorList.add(buildErrorMessage(9, "", Messages.MANIFEST_EXPECTED_HASH_ENTRY));
292             assertInvalidManifest(expectedErrorList);
293         }
294     }
295
296     @Test
297     public void testManifestSourceHashWithoutAlgorithm() throws IOException {
298         try (final InputStream manifestAsStream =
299             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf")) {
300             manifest.parse(manifestAsStream);
301             final List<String> expectedErrorList = new ArrayList<>();
302             expectedErrorList.add(buildErrorMessage(8, "Hash: 3b119b37da5b76ec7c933168b21cedd8", Messages.MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH));
303             assertInvalidManifest(expectedErrorList);
304         }
305     }
306
307     @Test
308     public void testManifestSourceAlgorithmWithoutValue() throws IOException {
309         try (final InputStream manifestAsStream =
310             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf")) {
311             manifest.parse(manifestAsStream);
312             final List<String> expectedErrorList = new ArrayList<>();
313             expectedErrorList.add(buildErrorMessage(8, "Algorithm:", Messages.MANIFEST_EXPECTED_ALGORITHM_VALUE));
314             assertInvalidManifest(expectedErrorList);
315         }
316     }
317
318     @Test
319     public void testManifestSourceHashWithoutValue() throws IOException {
320         try (final InputStream manifestAsStream =
321             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-value.mf")) {
322             manifest.parse(manifestAsStream);
323             final List<String> expectedErrorList = new ArrayList<>();
324             expectedErrorList.add(buildErrorMessage(9, "Hash:", Messages.MANIFEST_EXPECTED_HASH_VALUE));
325             assertInvalidManifest(expectedErrorList);
326         }
327     }
328
329     @Test
330     public void testEmptyManifest() throws IOException {
331         try (final InputStream manifestAsStream =
332             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-manifest.mf")) {
333             manifest.parse(manifestAsStream);
334             final List<String> expectedErrorList = new ArrayList<>();
335             expectedErrorList.add(Messages.MANIFEST_EMPTY.getErrorMessage());
336             assertInvalidManifest(expectedErrorList);
337         }
338     }
339
340     @Test
341     public void testManifestWithDuplicatedCmsSignature() throws IOException {
342         try (final InputStream manifestAsStream =
343             getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/double-signed.mf")) {
344             manifest.parse(manifestAsStream);
345             final List<String> expectedErrorList = new ArrayList<>();
346             expectedErrorList
347                 .add(buildErrorMessage(26, "-----BEGIN CMS-----", Messages.MANIFEST_DUPLICATED_CMS_SIGNATURE));
348             assertInvalidManifest(expectedErrorList);
349         }
350     }
351
352
353     @Test
354     public void testGetEntry() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
355         final Method getEntryMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryName", String.class);
356         getEntryMethod.setAccessible(true);
357         final Optional<String> noEntry = (Optional<String>) getEntryMethod.invoke(manifest, ":");
358         assertThat("Entry should not be present", noEntry.isPresent(), is(false));
359
360         final Optional<String> blankEntry = (Optional<String>) getEntryMethod.invoke(manifest, "        :");
361         assertThat("Entry should not be present", blankEntry.isPresent(), is(false));
362
363         final Optional<String> noColon = (Optional<String>) getEntryMethod.invoke(manifest, "anyKeyWithoutColon   ");
364         assertThat("Entry should not be present", noColon.isPresent(), is(false));
365
366         final Optional<String> blank = (Optional<String>) getEntryMethod.invoke(manifest, "   ");
367         assertThat("Entry should not be present", blank.isPresent(), is(false));
368
369         final Optional<String> empty = (Optional<String>) getEntryMethod.invoke(manifest, "");
370         assertThat("Entry should not be present", empty.isPresent(), is(false));
371
372         final Optional<String> nul1 = (Optional<String>) getEntryMethod.invoke(manifest, new Object[]{null});
373         assertThat("Entry should not be present", nul1.isPresent(), is(false));
374
375         final Optional<String> entry = (Optional<String>) getEntryMethod
376             .invoke(manifest, "      entry to     test     :       : a value ::: test test:   ");
377         assertThat("Entry should be present", entry.isPresent(), is(true));
378         assertThat("Entry should be as expected", entry.get(), equalTo("entry to     test"));
379     }
380
381     @Test
382     public void testGetValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
383         final Method getValueMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryValue", String.class);
384         getValueMethod.setAccessible(true);
385         final Optional<String> noValue = (Optional<String>) getValueMethod.invoke(manifest, ":");
386         assertThat("Value should not be present", noValue.isPresent(), is(false));
387
388         final Optional<String> blankValue = (Optional<String>) getValueMethod.invoke(manifest, ":          ");
389         assertThat("Value should not be present", blankValue.isPresent(), is(false));
390
391         final Optional<String> noColon = (Optional<String>) getValueMethod.invoke(manifest, "anyKeyWithoutColon   ");
392         assertThat("Value should not be present", noColon.isPresent(), is(false));
393
394         final Optional<String> blank = (Optional<String>) getValueMethod.invoke(manifest, "   ");
395         assertThat("Value should not be present", blank.isPresent(), is(false));
396
397         final Optional<String> empty = (Optional<String>) getValueMethod.invoke(manifest, "");
398         assertThat("Value should not be present", empty.isPresent(), is(false));
399
400         final Optional<String> nul1 = (Optional<String>) getValueMethod.invoke(manifest, new Object[]{null});
401         assertThat("Value should not be present", nul1.isPresent(), is(false));
402
403         final Optional<String> value = (Optional<String>) getValueMethod
404             .invoke(manifest, "attribute     :       : a value ::: test test:   ");
405         assertThat("Value should be present", value.isPresent(), is(true));
406         assertThat("Value should be as expected", value.get(), equalTo(": a value ::: test test:"));
407     }
408
409     private void assertValidManifest(final int expectedMetadataSize, final int expectedSourcesSize,
410                                      final Map<String, Integer> expectedNonManoKeySize,
411                                      final ResourceTypeEnum resourceType) {
412         assertThat("Should have no errors", manifest.getErrors(), is(empty()));
413         assertThat("Should be valid", manifest.isValid(), is(true));
414         assertThat("Metadata should have the expected size",
415             manifest.getMetadata().keySet(), hasSize(expectedMetadataSize));
416         assertThat("Sources should have the expected size", manifest.getSources(), hasSize(expectedSourcesSize));
417         assertThat("Non Mano Sources keys should have the expected size",
418             manifest.getNonManoSources().keySet(), hasSize(expectedNonManoKeySize.keySet().size()));
419         for (final Entry<String, Integer> nonManoKeyAndSize : expectedNonManoKeySize.entrySet()) {
420             final String nonManoKey = nonManoKeyAndSize.getKey();
421             assertThat("Should contain expected Non Mano Sources key",
422                 manifest.getNonManoSources().keySet(), hasItem(nonManoKey));
423             assertThat(String.format("Non Mano Sources keys %s should have the expected sources size", nonManoKey),
424                 manifest.getNonManoSources().get(nonManoKey).size(), equalTo(nonManoKeyAndSize.getValue()));
425         }
426         assertThat("Should have a type", manifest.getType().isPresent(), is(true));
427         assertThat("Type should be as expected", manifest.getType().get(), equalTo(resourceType));
428     }
429
430     private void assertInvalidManifest(final List<String> expectedErrorList) {
431         assertThat("Should be invalid", manifest.isValid(), is(false));
432         assertThat("Should have the expected error quantity", manifest.getErrors(), hasSize(expectedErrorList.size()));
433         assertThat("Should have expected errors", manifest.getErrors(),
434             containsInAnyOrder(expectedErrorList.toArray(new String[0])));
435     }
436 }