You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/06/09 12:30:20 UTC

[sling-org-apache-sling-feature-cpconverter] 01/01: SLING-10468 : Converted content package is missing some .content.xml

This is an automated email from the ASF dual-hosted git repository.

angela pushed a commit to branch SLING-10468
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git

commit d0dddcbc46bec71a74dc38b7f5516ab3f78e30b9
Author: angela <an...@adobe.com>
AuthorDate: Wed Jun 9 14:30:01 2021 +0200

    SLING-10468 : Converted content package is missing some .content.xml
---
 .../handlers/AbstractUserEntryHandler.java         |  30 +++++-
 .../cpconverter/handlers/AbstractUserParser.java   |   7 +-
 .../cpconverter/handlers/UsersEntryHandler.java    |  10 +-
 .../ContentPackage2FeatureModelConverterTest.java  | 107 +++++++++++++++------
 .../feature/cpconverter/handlers/TestUtils.java    |  13 +--
 .../apache/sling/feature/cpconverter/demo-cp.zip   | Bin 0 -> 16491 bytes
 6 files changed, 121 insertions(+), 46 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
index cc2eb1c..6dfdb5f 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
@@ -16,18 +16,29 @@
  */
 package org.apache.sling.feature.cpconverter.handlers;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
 import org.apache.jackrabbit.vault.util.PlatformNameFormat;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
 import org.apache.sling.feature.cpconverter.shared.RepoPath;
+import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
 import org.jetbrains.annotations.NotNull;
 
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.regex.Matcher;
 
 abstract class AbstractUserEntryHandler extends AbstractRegexEntryHandler {
 
+    private final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+    
+    // FIXME: use first segment of 'systemUserRelPath' config value instead of hardcoding 
+    private static final String SYSTEM_USER_SEGMENT = "/system/";
+
     AbstractUserEntryHandler(@NotNull String rexex) {
         super(rexex);
     }
@@ -37,14 +48,23 @@ abstract class AbstractUserEntryHandler extends AbstractRegexEntryHandler {
             throws Exception {
         Matcher matcher = getPattern().matcher(path);
         if (matcher.matches()) {
-            path = matcher.group(1);
-
-            RepoPath originalPath = new RepoPath(PlatformNameFormat.getRepositoryPath(path));
+            RepoPath originalPath = new RepoPath(PlatformNameFormat.getRepositoryPath(matcher.group(1)));
             RepoPath intermediatePath = originalPath.getParent();
 
+            byte[] tmp = IOUtils.toByteArray((archive.openInputStream(entry)));
             AbstractUserParser parser = createParser(converter, originalPath, intermediatePath);
-            try (InputStream input = archive.openInputStream(entry)) {
-                parser.parse(input);
+            boolean converted = parser.parse(new ByteArrayInputStream(tmp));
+            if (!converted && !path.contains(SYSTEM_USER_SEGMENT)) {
+                // write back regular users, groups and their intermediate folders that did not get converted into
+                // repo-init statements to the content package
+                VaultPackageAssembler assembler = converter.getMainPackageAssembler();
+                // FIXME: assembler is null when handler is called from RecollectorVaultPackageScanner (???)
+                if (assembler != null) {
+                    try (InputStream input = new ByteArrayInputStream(tmp);
+                         OutputStream output = assembler.createEntry(path)){
+                        IOUtils.copy(input, output);
+                    }
+                }
             }
         }
     }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
index 354e9fa..338d3f8 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
@@ -22,7 +22,7 @@ import org.apache.sling.feature.cpconverter.shared.RepoPath;
 import org.jetbrains.annotations.NotNull;
 import org.xml.sax.Attributes;
 
-abstract class AbstractUserParser extends AbstractJcrNodeParser<Void> {
+abstract class AbstractUserParser extends AbstractJcrNodeParser<Boolean> {
 
     private static final String REP_AUTHORIZABLE_ID = "rep:authorizableId";
 
@@ -54,8 +54,9 @@ abstract class AbstractUserParser extends AbstractJcrNodeParser<Void> {
     }
 
     @Override
-    protected Void getParsingResult() {
-        return null;
+    protected Boolean getParsingResult() {
+        // false for all intermediate paths, regular users and groups
+        return false;
     }
 
     abstract void handleUser(@NotNull String id, @NotNull Attributes attributes);
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
index c55f9f7..e1090ed 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
@@ -47,6 +47,8 @@ public final class UsersEntryHandler extends AbstractUserEntryHandler {
 
         private static final String REP_SYSTEM_USER = "rep:SystemUser";
         private static final String REP_USER = "rep:User";
+        
+        private boolean isSystemUser = false;
 
         /**
          * @param converter - the converter to use.
@@ -64,8 +66,14 @@ public final class UsersEntryHandler extends AbstractUserEntryHandler {
                 converter.getAclManager().addUser(new User(id, path, intermediatePath, disabledReason));
             } else {
                 converter.getAclManager().addSystemUser(new SystemUser(id, path, intermediatePath, disabledReason));
+                isSystemUser = true;
             }
         }
-    }
 
+        @Override
+        protected Boolean getParsingResult() {
+            // intermediate paths and regular users are never handled by repo-init
+            return isSystemUser;
+        }
+    }
 }
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
index 36b0d32..32a39b6 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -71,6 +71,7 @@ import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager
 import org.apache.sling.feature.cpconverter.handlers.EntryHandlersManager;
 import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.jetbrains.annotations.NotNull;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -81,11 +82,11 @@ public class ContentPackage2FeatureModelConverterTest {
      * Test package A-1.0. Depends on B and C-1.X
      * Test package B-1.0. Depends on C
      */
-    private static String[] TEST_PACKAGES_INPUT = { "test_c-1.0.zip", "test_a-1.0.zip", "test_b-1.0.zip" };
+    private static final String[] TEST_PACKAGES_INPUT = { "test_c-1.0.zip", "test_a-1.0.zip", "test_b-1.0.zip" };
 
-    private static String[] TEST_PACKAGES_OUTPUT = { "my_packages:test_c:1.0", "my_packages:test_b:1.0", "my_packages:test_a:1.0" };
+    private static final String[] TEST_PACKAGES_OUTPUT = { "my_packages:test_c:1.0", "my_packages:test_b:1.0", "my_packages:test_a:1.0" };
 
-    private static String[] TEST_PACKAGES_CYCLIC_DEPENDENCY = { "test_d-1.0.zip",
+    private static final String[] TEST_PACKAGES_CYCLIC_DEPENDENCY = { "test_d-1.0.zip",
                                                                 "test_c-1.0.zip",
                                                                 "test_a-1.0.zip",
                                                                 "test_b-1.0.zip",
@@ -156,8 +157,8 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all.json",
                             "asd.sample:asd.retail.all:slingosgifeature:0.0.1",
-                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
-                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+                            Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+                            Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                             Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                             "asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
                                             "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
@@ -165,14 +166,14 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-author.json",
                             "asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
                             Collections.emptyList(),
                             Collections.emptyList());
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-publish.json",
                             "asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
-                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+                            Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                             Collections.emptyList());
 
             // verify the runmode.mapper integrity
@@ -237,21 +238,20 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all.json",
                             "asd.sample:asd.retail.all:slingosgifeature:0.0.1",
-                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
-                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
-                            Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
-                                            "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
+                            Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+                            Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+                            Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1", "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-author.json",
                             "asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
                             Collections.emptyList(),
                             Collections.emptyList());
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-publish.json",
                             "asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
-                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+                            Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                             Collections.emptyList());
 
             // verify the runmode.mapper integrity
@@ -309,21 +309,21 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all.json",
                             "asd.sample:asd.retail.all:slingosgifeature:0.0.1",
-                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
-                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+                            Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+                            Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                             Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                     "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-author.json",
                             "asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
                             Collections.emptyList(),
                             Collections.emptyList());
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-publish.json",
                             "asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
-                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
-                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+                            Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                             Collections.emptyList());
 
             // verify the runmode.mapper integrity
@@ -584,10 +584,16 @@ public class ContentPackage2FeatureModelConverterTest {
     }
 
     private void verifyContentPackage(File contentPackage, String...expectedEntries) throws Exception {
+        verifyContentPackage(contentPackage, Collections.emptySet(), expectedEntries);
+    }
+    
+    private void verifyContentPackage(File contentPackage, @NotNull Set<String> notExpected, String...expectedEntries) throws Exception {
         try (ZipFile zipFile = new ZipFile(contentPackage)) {
             for (String expectedEntry : expectedEntries) {
-                assertNotNull("Expected entry not found: " + expectedEntry + " in file " + contentPackage,
-                              zipFile.getEntry(expectedEntry));
+                assertNotNull("Expected entry not found: " + expectedEntry + " in file " + contentPackage, zipFile.getEntry(expectedEntry));
+            }
+            for (String notExpectedEntry : notExpected) {
+                assertNull("Not expected entry found: " + notExpectedEntry + " in file " + contentPackage, zipFile.getEntry(notExpectedEntry));
             }
         }
     }
@@ -750,7 +756,7 @@ public class ContentPackage2FeatureModelConverterTest {
         try {
             converter.setBundlesDeployer(new LocalMavenRepositoryArtifactsDeployer(outDir))
             .setFeaturesManager(new DefaultFeaturesManager(false, 5, outDir, null, null, null, new DefaultAclManager())
-                    .setAPIRegions(Arrays.asList("a.b.c")))
+                    .setAPIRegions(Collections.singletonList("a.b.c")))
             .setEmitter(DefaultPackagesEventsEmitter.open(outDir))
             .convert(cpFile);
 
@@ -798,8 +804,8 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all.json",
                             "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0:${project.version}",
-                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
-                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+                            Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+                            Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                             Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                             "asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
                                             "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
@@ -807,14 +813,14 @@ public class ContentPackage2FeatureModelConverterTest {
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-author.json",
                             "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-author:${project.version}",
-                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
                             Collections.emptyList(),
                             Collections.emptyList());
             verifyFeatureFile(outputDirectory,
                             "asd.retail.all-publish.json",
                             "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-publish:${project.version}",
-                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
-                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+                            Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+                            Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                             Collections.emptyList());
 
             verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.all/0.0.1/asd.retail.all-0.0.1-cp2fm-converted.zip"),
@@ -978,4 +984,49 @@ public class ContentPackage2FeatureModelConverterTest {
         return loadedResources;
     }
 
+    @Test
+    public void testConvertPackageWithUsersGroupsAndServiceUsers() throws Exception {
+        URL packageUrl = getClass().getResource("demo-cp.zip");
+        File packageFile = FileUtils.toFile(packageUrl);
+        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
+        try {
+            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
+                    .setBundlesDeployer(new LocalMavenRepositoryArtifactsDeployer(outputDirectory))
+                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
+                    .convert(packageFile);
+
+            File converted = new File(outputDirectory, "my_packages/demo-cp/0.0.0/demo-cp-0.0.0-cp2fm-converted.zip");
+            Set<String> notExpected = new HashSet<>();
+            notExpected.add("jcr_root/apps/demo-cp/.content.xml");
+            notExpected.add("jcr_root/home/users/demo-cp/_rep_policy.xml");
+            notExpected.add("jcr_root/home/groups/demo-cp/_rep_policy.xml");
+            notExpected.add("jcr_root/home/users/system/.content.xml");
+            notExpected.add("jcr_root/home/users/system/_cq_services/.content.xml");
+            notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/.content.xml");
+            notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/qStDu7IQBLa95gURmer1/.content.xml");
+            notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/qStDu7IQBLa95gURmer1/_rep_principalPolicy.xml");
+            verifyContentPackage(converted, 
+                    notExpected,
+                    "META-INF/vault/properties.xml",
+                    "META-INF/vault/config.xml",
+                    "META-INF/vault/filter.xml",
+                    "jcr_root/.content.xml",
+                    "jcr_root/demo-cp/.content.xml",
+                    "jcr_root/demo-cp/_rep_policy.xml",
+                    "jcr_root/apps/.content.xml",
+                    "jcr_root/home/.content.xml",
+                    "jcr_root/home/users/demo-cp/.content.xml",
+                    "jcr_root/home/users/demo-cp/XPXhA_RKMFRKNO8ViIhn/.content.xml",
+                    "jcr_root/home/users/demo-cp/XPXhA_RKMFRKNO8ViIhn/_rep_policy.xml",
+                    "jcr_root/home/groups/.content.xml",
+                    "jcr_root/home/groups/demo-cp/.content.xml",
+                    "jcr_root/home/groups/demo-cp/EsYrXeBdSRkna2kqbxjl/.content.xml",
+                    "jcr_root/home/groups/demo-cp/EsYrXeBdSRkna2kqbxjl/_rep_policy.xml"
+                    );
+
+        } finally {
+            deleteDirTree(outputDirectory);
+        }
+    }
+    
 }
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
index a532490..f470427 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
@@ -26,15 +26,13 @@ import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
 import org.apache.sling.feature.cpconverter.features.FeaturesManager;
 import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.security.acl.Acl;
 import java.util.Collections;
 
 import static org.mockito.ArgumentMatchers.anyString;
@@ -49,17 +47,14 @@ class TestUtils {
     private TestUtils() {}
 
     static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is) throws Exception {
-        return createRepoInitExtension(handler, aclManager, path, is, null);
+        return createRepoInitExtension(handler, aclManager, path, is, new ByteArrayOutputStream());
     }
 
-    static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is, @Nullable OutputStream out) throws Exception {
+    static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is, @NotNull OutputStream out) throws Exception {
         Archive archive = mock(Archive.class);
         Archive.Entry entry = mock(Archive.Entry.class);
         VaultPackageAssembler packageAssembler = mock(VaultPackageAssembler.class);
-        if (out != null) {
-            when(packageAssembler.createEntry(anyString())).thenReturn(out);
-        }
-
+        when(packageAssembler.createEntry(anyString())).thenReturn(out);
         when(archive.openInputStream(entry)).thenReturn(is);
 
         Feature feature = new Feature(new ArtifactId("org.apache.sling", "org.apache.sling.cp2fm", "0.0.1", null, null));
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip
new file mode 100644
index 0000000..8143f45
Binary files /dev/null and b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip differ