You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2022/08/22 12:31:39 UTC

[sling-org-apache-sling-testing-sling-mock] branch master updated: SLING-11548 Introduce RESOURCEPROVIDER_MOCK resource resolver type (#15)

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

sseifert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git


The following commit(s) were added to refs/heads/master by this push:
     new 0bc35f0  SLING-11548 Introduce RESOURCEPROVIDER_MOCK resource resolver type (#15)
0bc35f0 is described below

commit 0bc35f0540a67a5e31eaca2fb29c3428118f929a
Author: Stefan Seifert <st...@users.noreply.github.com>
AuthorDate: Mon Aug 22 14:31:35 2022 +0200

    SLING-11548 Introduce RESOURCEPROVIDER_MOCK resource resolver type (#15)
---
 core/pom.xml                                       |   2 +-
 ...java => RPMockMockResourceResolverAdapter.java} |  20 +-
 .../sling/RRMockMockResourceResolverAdapter.java   |  10 +-
 .../RRMockResourceResolverFactoryWrapper.java      | 132 ---------
 .../mock/sling/RRMockResourceResolverWrapper.java  | 299 ---------------------
 .../testing/mock/sling/ResourceResolverType.java   |  40 +--
 .../context/ContextResourceResolverFactory.java    |  38 ---
 .../testing/mock/sling/loader/ContentLoader.java   |  46 +++-
 .../sling/testing/mock/sling/package-info.java     |   2 +-
 .../mock/sling/context/models/ResourceModel.java}  |  24 +-
 .../AbstractContentLoaderFolderJsonTest.java       |  18 ++
 .../AbstractSlingCrudResourceResolverTest.java     |  10 +
 .../context/SlingContextImplTest.java}             |   8 +-
 .../loader/ContentLoaderAutoCommitTest.java}       |   9 +-
 .../loader/ContentLoaderBinaryTest.java}           |   8 +-
 .../loader/ContentLoaderFileVaultXmlTest.java}     |   8 +-
 .../ContentLoaderFolderFileVaultXmlTest.java       |   4 +-
 .../loader/ContentLoaderFolderJsonTest.java        |   4 +-
 .../loader/ContentLoaderJsonDamTest.java}          |   8 +-
 .../loader/ContentLoaderJsonTest.java}             |   8 +-
 .../resource/MultipleResourceResolverTest.java}    |   8 +-
 .../resource/SlingCrudResourceResolverTest.java    |  50 ++++
 .../resource/UniqueRootTest.java}                  |   8 +-
 .../src/test/resources/test-content/parent.json    |   0
 junit4/pom.xml                                     |   6 +-
 .../sling/junit/SlingContextDefaultRRTypeTest.java |  57 ----
 junit5/pom.xml                                     |   6 +-
 .../mock/sling/junit5/SlingContextTest.java        |  22 +-
 parent/pom.xml                                     |  10 +-
 pom.xml                                            |   2 +-
 relocate/pom.xml                                   |   2 +-
 31 files changed, 216 insertions(+), 653 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index 6b126a5..bd76e69 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-        <version>3.3.3-SNAPSHOT</version>
+        <version>3.4.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
 
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RPMockMockResourceResolverAdapter.java
similarity index 66%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
copy to core/src/main/java/org/apache/sling/testing/mock/sling/RPMockMockResourceResolverAdapter.java
index ccb2c2e..50a140c 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RPMockMockResourceResolverAdapter.java
@@ -20,31 +20,27 @@ package org.apache.sling.testing.mock.sling;
 
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
 import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter;
-import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
-import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions;
+import org.apache.sling.testing.resourceresolver.MockResourceProvider;
 import org.osgi.framework.BundleContext;
 
 /**
- * Resource resolver type adapter for Sling Resource Resolver Mock implementation.
+ * Resource resolver type adapter for Sling Resource Resolver Mock implementation using {@link MockResourceProvider}.
  */
-class RRMockMockResourceResolverAdapter implements ResourceResolverTypeAdapter {
-
-    private final MockResourceResolverFactoryOptions options;
-    private final BundleContext bundleContext;
+class RPMockMockResourceResolverAdapter implements ResourceResolverTypeAdapter {
 
     /**
      * Constructor
      */
-    public RRMockMockResourceResolverAdapter(BundleContext bundleContext) {
-        this.options = new MockResourceResolverFactoryOptions();
-        this.options.setMangleNamespacePrefixes(true);
-        this.bundleContext = bundleContext;
+    public RPMockMockResourceResolverAdapter(BundleContext bundleContext) {
+        // register resource provider from resourceresolver-mock and use Sling ResourceResolver implementation
+        MockOsgi.registerInjectActivateService(MockResourceProvider.class, bundleContext);
     }
 
     @Override
     public ResourceResolverFactory newResourceResolverFactory() {
-        return new RRMockResourceResolverFactoryWrapper(new MockResourceResolverFactory(options), bundleContext);
+        return null;
     }
 
     @Override
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
index ccb2c2e..1b5388a 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
@@ -26,25 +26,23 @@ import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOpti
 import org.osgi.framework.BundleContext;
 
 /**
- * Resource resolver type adapter for Sling Resource Resolver Mock implementation.
+ * Resource resolver type adapter for Sling Resource Resolver Mock implementation using {@link org.apache.sling.testing.resourceresolver.MockResourceResolver}.
  */
 class RRMockMockResourceResolverAdapter implements ResourceResolverTypeAdapter {
 
     private final MockResourceResolverFactoryOptions options;
-    private final BundleContext bundleContext;
 
     /**
      * Constructor
      */
     public RRMockMockResourceResolverAdapter(BundleContext bundleContext) {
-        this.options = new MockResourceResolverFactoryOptions();
-        this.options.setMangleNamespacePrefixes(true);
-        this.bundleContext = bundleContext;
+        options = new MockResourceResolverFactoryOptions();
+        options.setMangleNamespacePrefixes(true);
     }
 
     @Override
     public ResourceResolverFactory newResourceResolverFactory() {
-        return new RRMockResourceResolverFactoryWrapper(new MockResourceResolverFactory(options), bundleContext);
+        return new MockResourceResolverFactory(options);
     }
 
     @Override
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
deleted file mode 100644
index 1aa591a..0000000
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.testing.mock.sling;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-/**
- * Wraps the ResourceResolverFactory from ResourceResolverMock to add a service tracker
- * for ResourceProvider (e.g. injected by ContentLoader for mounting filesystem folders).
- */
-class RRMockResourceResolverFactoryWrapper implements ResourceResolverFactory,
-        ServiceTrackerCustomizer<ResourceProvider, ResourceProvider> {
-
-    private final ResourceResolverFactory delegate;
-    private final BundleContext bundleContext;
-    private final ServiceTracker<ResourceProvider, ResourceProvider> serviceTracker;
-    private final ConcurrentMap<String, ResourceProvider> resourceProviders = new ConcurrentHashMap<>();
-
-    @SuppressWarnings("null")
-    RRMockResourceResolverFactoryWrapper(ResourceResolverFactory delegate, BundleContext bundleContext) {
-        this.delegate = delegate;
-        this.bundleContext = bundleContext;
-        // track registered resource provider implementations
-        this.serviceTracker = new ServiceTracker<ResourceProvider, ResourceProvider>(bundleContext, ResourceProvider.class, this);
-        this.serviceTracker.open();
-    }
-
-    @Override
-    public @NotNull ResourceResolver getResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
-        return wrap(delegate.getResourceResolver(authenticationInfo));
-    }
-
-    @Override
-    @Deprecated
-    public @NotNull ResourceResolver getAdministrativeResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
-        return wrap(delegate.getAdministrativeResourceResolver(authenticationInfo));
-    }
-
-    @Override
-    public @NotNull ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
-        return wrap(delegate.getServiceResourceResolver(authenticationInfo));
-    }
-
-    @Override
-    public @Nullable ResourceResolver getThreadResourceResolver() {
-        return wrap(delegate.getThreadResourceResolver());
-    }
-
-    private ResourceResolver wrap(ResourceResolver resourceResolver) {
-        return new RRMockResourceResolverWrapper(resourceResolver, resourceProviders);
-    }
-
-    @Override
-    public ResourceProvider addingService(ServiceReference<ResourceProvider> reference) {
-        String rootPath = getRootPath(reference);
-        ResourceProvider service = bundleContext.getService(reference);
-        if (rootPath != null) {
-            resourceProviders.put(rootPath, service);
-        }
-        return service;
-    }
-
-    @Override
-    public void modifiedService(ServiceReference<ResourceProvider> reference, ResourceProvider service) {
-        // ignore
-    }
-
-    @Override
-    public void removedService(ServiceReference<ResourceProvider> reference, ResourceProvider service) {
-        String rootPath = getRootPath(reference);
-        if (rootPath != null) {
-            resourceProviders.remove(rootPath);
-        }
-    }
-
-    private String getRootPath(ServiceReference<ResourceProvider> reference) {
-        Object value = reference.getProperty(ResourceProvider.PROPERTY_ROOT);
-        if (value instanceof String) {
-            return (String)value;
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unchecked")
-    public @NotNull List<String> getSearchPath() {
-        // call delegate method via reflection, as it is not available in earlier versions of Sling API
-        try {
-            Method getSearchPathMethod = ResourceResolverFactory.class.getMethod("getSearchPath");
-            return (List)getSearchPathMethod.invoke(delegate);
-        }
-        catch (NoSuchMethodException | SecurityException ex) {
-            // earlier version of Sling API - return empty list
-            return Collections.emptyList();
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
-            throw new RuntimeException("Unable to call getSearchPath on delegate.", ex);
-        }
-    }
-
-}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
deleted file mode 100644
index 540cf0e..0000000
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.testing.mock.sling;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.wrappers.ResourceResolverWrapper;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Wraps resource resolver form ResourceResolverMock to check for resource provider implementations
- * registered to specific path. This is a very simplified implementation to overlay the mocked
- * resource tree with resource providers, but should be sufficient for unit tests.
- */
-class RRMockResourceResolverWrapper extends ResourceResolverWrapper implements ResolveContext {
-
-    private final ConcurrentMap<String, ResourceProvider> resourceProviders;
-
-    RRMockResourceResolverWrapper(ResourceResolver delegate, ConcurrentMap<String, ResourceProvider> resourceProviders) {
-        super(delegate);
-        this.resourceProviders = resourceProviders;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Resource getResource(@NotNull String path) {
-        if (resourceProviders.isEmpty()) {
-            return super.getResource(path);
-        }
-        List<String> normalizedPaths = getNormalizedPaths(path);
-        for (String normalizedPath : normalizedPaths) {
-            ResourceProvider resourceProvider = getMatchingResourceProvider(normalizedPath);
-            if (resourceProvider != null) {
-                return resourceProvider.getResource(this, normalizedPath, ResourceContext.EMPTY_CONTEXT, null);
-            }
-            return super.getResource(path);
-        }
-        return null;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Resource getResource(Resource base, @NotNull String path) {
-        if (resourceProviders.isEmpty()) {
-            return super.getResource(base, path);
-        }
-        String normalizedPath = ResourceUtil.normalize(base.getPath() + "/" + path);
-        if (normalizedPath != null) {
-            ResourceProvider resourceProvider = getMatchingResourceProvider(normalizedPath);
-            if (resourceProvider != null) {
-                return resourceProvider.getResource(this, normalizedPath, ResourceContext.EMPTY_CONTEXT, null);
-            }
-            return super.getResource(path);
-        }
-        return null;
-    }
-
-    // duplicated method from MockResourceResolver to ensure resources from resource providers are respected as well
-    @Override
-    public Resource getParent(@NotNull Resource child) {
-        final String parentPath = ResourceUtil.getParent(child.getPath());
-        if (parentPath == null) {
-            return null;
-        }
-        return this.getResource(parentPath);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public @NotNull Iterator<Resource> listChildren(@NotNull Resource parent) {
-        if (resourceProviders.isEmpty()) {
-            return super.listChildren(parent);
-        }
-        ResourceProvider resourceProvider = getMatchingResourceProvider(parent.getPath());
-        if (resourceProvider != null) {
-            Iterator<Resource> result = resourceProvider.listChildren(this,  parent);
-            if (result == null) {
-                return Collections.emptyIterator();
-            }
-            else {
-                return result;
-            }
-        }
-        return super.listChildren(parent);
-    }
-
-    @Override
-    public @NotNull Iterable<Resource> getChildren(@NotNull Resource parent) {
-        return () -> listChildren(parent);
-    }
-
-    @Override
-    public boolean hasChildren(@NotNull Resource resource) {
-        return listChildren(resource).hasNext();
-    }
-
-
-
-    private ResourceProvider getMatchingResourceProvider(String path) {
-        ResourceProvider provider = resourceProviders.get(path);
-        if (provider != null) {
-            return provider;
-        }
-        String parentPath = ResourceUtil.getParent(path);
-        if (parentPath != null) {
-            return getMatchingResourceProvider(parentPath);
-        }
-        else {
-            return null;
-        }
-    }
-
-    @Override
-    public @NotNull ResourceResolver getResourceResolver() {
-        return this;
-    }
-
-    @Override
-    public @Nullable Object getProviderState() {
-        return null;
-    }
-
-    @Override
-    public @Nullable ResolveContext getParentResolveContext() {
-        return null;
-    }
-
-    @Override
-    public @Nullable ResourceProvider getParentResourceProvider() {
-        return null;
-    }
-
-    private List<String> getNormalizedPaths(String path) {
-        List<String> result = new ArrayList<>();
-        if (StringUtils.startsWith(path, "/")) {
-            result.add(ResourceUtil.normalize(path));
-        }
-        else {
-            for (String searchPath : getSearchPath()) {
-                String combinedPath = StringUtils.removeEnd(searchPath, "/") + "/" + path;
-                result.add(ResourceUtil.normalize(combinedPath));
-            }
-        }
-        return result;
-    }
-
-    // duplicated method from MockResourceResolver to ensure resources from resource providers are respected as well
-    @Override
-    public boolean isResourceType(Resource resource, String resourceType) {
-        if (resourceProviders.isEmpty()) {
-            return super.isResourceType(resource, resourceType);
-        }
-        boolean result = false;
-        if ( resource != null && resourceType != null ) {
-             // Check if the resource is of the given type. This method first checks the
-             // resource type of the resource, then its super resource type and continues
-             //  to go up the resource super type hierarchy.
-             if (ResourceTypeUtil.areResourceTypesEqual(resourceType, resource.getResourceType(), getSearchPath())) {
-                 result = true;
-             } else {
-                 Set<String> superTypesChecked = new HashSet<>();
-                 String superType = this.getParentResourceType(resource);
-                 while (!result && superType != null) {
-                     if (ResourceTypeUtil.areResourceTypesEqual(resourceType, superType, getSearchPath())) {
-                         result = true;
-                     } else {
-                         superTypesChecked.add(superType);
-                         superType = this.getParentResourceType(superType);
-                         if (superType != null && superTypesChecked.contains(superType)) {
-                             throw new SlingException("Cyclic dependency for resourceSuperType hierarchy detected on resource " + resource.getPath()) {
-                                // anonymous class to avoid problem with null cause
-                                private static final long serialVersionUID = 1L;
-                             };
-                         }
-                     }
-                 }
-             }
-
-        }
-        return result;
-    }
-
-    // duplicated method from MockResourceResolver to ensure resources from resource providers are respected as well
-    @Override
-    public String getParentResourceType(Resource resource) {
-        if (resourceProviders.isEmpty()) {
-            return super.getParentResourceType(resource);
-        }
-        String resourceSuperType = null;
-        if ( resource != null ) {
-            resourceSuperType = resource.getResourceSuperType();
-            if (resourceSuperType == null) {
-                resourceSuperType = this.getParentResourceType(resource.getResourceType());
-            }
-        }
-        return resourceSuperType;
-    }
-
-    // duplicated method from MockResourceResolver to ensure resources from resource providers are respected as well
-    @Override
-    public String getParentResourceType(String resourceType) {
-        if (resourceProviders.isEmpty()) {
-            return super.getParentResourceType(resourceType);
-        }
-        // normalize resource type to a path string
-        final String rtPath = (resourceType == null ? null : ResourceUtil.resourceTypeToPath(resourceType));
-        // get the resource type resource and check its super type
-        String resourceSuperType = null;
-        if ( rtPath != null ) {
-            final Resource rtResource = getResource(rtPath);
-            if (rtResource != null) {
-                resourceSuperType = rtResource.getResourceSuperType();
-            }
-        }
-        return resourceSuperType;
-    }
-
-
-
-    /**
-     * Some helper methods for doing comparisons on resource types.
-     * This class is private the resource resolver bundle.
-     * Consumers should rely on {@link Resource#isResourceType(String)} or {@link ResourceResolver#isResourceType(Resource, String)} instead.
-     *
-     * <p>
-     *   This is a copy of org.apache.sling.resourceresolver.impl.ResourceTypeUtil which is an internal class
-     *   and its signature has changed between releases.
-     * </p>
-     */
-    static class ResourceTypeUtil {
-
-        /**
-         * Returns <code>true</code> if the given resource type are equal.
-         *
-         * In case the value of any of the given resource types
-         * starts with one of the resource resolver's search paths
-         * it is converted to a relative resource type by stripping off
-         * the resource resolver's search path before doing the comparison.
-         *
-         * @param resourceType A resource type
-         * @param anotherResourceType Another resource type to compare with {@link resourceType}.
-         * @return <code>true</code> if the resource type equals the given resource type.
-         */
-        public static boolean areResourceTypesEqual(@NotNull String resourceType, @NotNull String anotherResourceType, String @NotNull [] searchPath) {
-            return relativizeResourceType(resourceType, searchPath).equals(relativizeResourceType(anotherResourceType, searchPath));
-        }
-
-        /**
-         * Makes the given resource type relative by stripping off any prefix which equals one of the given search paths.
-         * In case the given resource type does not start with any of the given search paths it is returned unmodified.
-         * @param resourceType the resourceType to relativize.
-         * @param searchPath the search paths to strip off from the given resource type.
-         * @return the relative resource type
-         */
-        public static String relativizeResourceType(@NotNull String resourceType, String @NotNull [] searchPath) {
-            if (resourceType.startsWith("/")) {
-                for (String prefix : searchPath) {
-                    if (resourceType.startsWith(prefix)) {
-                        return resourceType.substring(prefix.length());
-                    }
-                }
-            }
-            return resourceType;
-        }
-
-    }
-
-}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java b/core/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java
index cacd0a1..e715829 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java
@@ -28,25 +28,34 @@ import org.jetbrains.annotations.NotNull;
 public enum ResourceResolverType {
 
     /**
-     * Uses Sling "resourceresolver-mock" implementation, no underlying JCR
-     * repository.
+     * Uses Sling "resourceresolver-mock" implementation, no underlying JCR repository.
      * <ul>
-     * <li>Simulates an In-Memory resource tree, does not provide adaptions to
-     * JCR.</li>
-     * <li>You can use it to make sure the code you want to test does not
-     * contain references to JCR API.</li>
-     * <li>Behaves slightly different from JCR resource mapping e.g. handling
-     * binary and date values.</li>
+     * <li>Simulates an In-Memory resource tree, does not provide adaptions to JCR.</li>
+     * <li>You can use it to make sure the code you want to test does not contain references to JCR API.</li>
+     * <li>Behaves slightly different from JCR resource mapping e.g. handling binary and date values.</li>
      * <li>This resource resolver type is very fast.</li>
      * </ul>
      */
     RESOURCERESOLVER_MOCK(RRMockMockResourceResolverAdapter.class.getName(), null, NodeTypeMode.NOT_SUPPORTED),
 
+    /**
+     * Uses Sling "resourceresolver-mock" implementation, no underlying JCR repository.
+     * <ul>
+     * <li>Uses the real Sling Resource Resolver and JCR Resource mapping implementation.
+     *  This allows using multiple resource providers and loading folders for JSON or FileVault XML content.</li>
+     * <li>Simulates an In-Memory resource tree, does not provide adaptions to JCR.</li>
+     * <li>You can use it to make sure the code you want to test does not contain references to JCR API.</li>
+     * <li>Behaves slightly different from JCR resource mapping e.g. handling binary and date values.</li>
+     * <li>This resource resolver type is quite fast.</li>
+     * </ul>
+     */
+    RESOURCEPROVIDER_MOCK(RPMockMockResourceResolverAdapter.class.getName(), null, NodeTypeMode.NOT_SUPPORTED),
+
     /**
      * Uses a simple JCR "in-memory" mock as underlying repository.
      * <ul>
-     * <li>Uses the real Sling Resource Resolver and JCR Resource mapping
-     * implementation.</li>
+     * <li>Uses the real Sling Resource Resolver and JCR Resource mapping implementation.
+     *  This allows using multiple resource providers and loading folders for JSON or FileVault XML content.</li>
      * <li>The mock JCR implementation from Apache Sling is used.</li>
      * <li>It supports the most important, but not all JCR features. Extended
      * features like Versioning, Eventing, Search, Transaction handling etc. are
@@ -59,12 +68,10 @@ public enum ResourceResolverType {
     /**
      * Uses a real JCR Jackrabbit Oak repository.
      * <ul>
-     * <li>Uses the real Sling Resource Resolver and JCR Resource mapping
-     * implementation.</li>
-     * <li>The JCR repository is started on first access, this may take some
-     * seconds.</li>
-     * <li>The <code>MemoryNodeStore</code> implementation is used, with no
-     * customizations.</li>
+     * <li>Uses the real Sling Resource Resolver and JCR Resource mapping implementation.
+     *  This allows using multiple resource providers and loading folders for JSON or FileVault XML content.</li>
+     * <li>The JCR repository is started on first access, this may take some seconds.</li>
+     * <li>The <code>MemoryNodeStore</code> implementation is used, with no customizations.</li>
      * </ul>
      */
     JCR_OAK("org.apache.sling.testing.mock.sling.oak.OakMockResourceResolverAdapter",
@@ -81,7 +88,6 @@ public enum ResourceResolverType {
     NONE(MockNoneResourceResolverAdapter.class.getName(), null, NodeTypeMode.NOT_SUPPORTED);
 
 
-
     private final @NotNull String resourceResolverTypeAdapterClass;
     private final @NotNull String artifactCoordinates;
     private final @NotNull NodeTypeMode nodeTypeMode;
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java b/core/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java
index f4048dc..bea7051 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java
@@ -18,9 +18,6 @@
  */
 package org.apache.sling.testing.mock.sling.context;
 
-import javax.jcr.RepositoryException;
-
-import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.testing.mock.sling.MockSling;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
@@ -50,26 +47,7 @@ final class ContextResourceResolverFactory {
         try {
             log.debug("Start initialize resource resolver factory, bundleContext={}", bundleContext);
             ResourceResolverFactory factory = MockSling.newResourceResolverFactory(type, bundleContext);
-
-            switch (type) {
-            case JCR_MOCK:
-                initializeJcrMock(factory);
-                break;
-            case JCR_OAK:
-                initializeJcrOak(factory);
-                break;
-            case RESOURCERESOLVER_MOCK:
-                initializeResourceResolverMock(factory);
-                break;
-            case NONE:
-                initializeResourceResolverNone(factory);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid resource resolver type: " + type);
-            }
-
             log.debug("Finished initializing resource resolver factory, bundleContext={}", bundleContext);
-
             return factory;
         } catch (Throwable ex) {
             log.error("Failed initializing resource resolver factory, bundleContext={}", bundleContext, ex);
@@ -77,20 +55,4 @@ final class ContextResourceResolverFactory {
         }
     }
 
-    private static void initializeJcrMock(@NotNull ResourceResolverFactory factory) throws RepositoryException, LoginException {
-        // nothing to do
-    }
-
-    private static void initializeJcrOak(@NotNull ResourceResolverFactory factory) {
-        // register sling node types?
-    }
-
-    private static void initializeResourceResolverMock(@NotNull ResourceResolverFactory factory) {
-        // nothing to do
-    }
-
-    private static void initializeResourceResolverNone(@NotNull ResourceResolverFactory factory) {
-        // nothing to do
-    }
-
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
index 687ea78..4127352 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
@@ -38,6 +38,7 @@ import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.commons.mime.MimeTypeService;
 import org.apache.sling.contentparser.api.ContentParser;
@@ -52,6 +53,7 @@ import org.apache.sling.testing.mock.osgi.MapUtil;
 import org.apache.sling.testing.mock.osgi.MockOsgi;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.builder.ImmutableValueMap;
+import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.osgi.framework.BundleContext;
@@ -548,19 +550,13 @@ public final class ContentLoader {
      * @param mountFolder Root folder to mount
      * @param destPath Path to mount folder into
      */
-    @SuppressWarnings("null")
     public void folderJson(@NotNull File mountFolder, @NotNull String destPath) {
-        if (bundleContext == null) {
-            throw new IllegalArgumentException("No bundle context given for content loader.");
-        }
-        Dictionary<String, Object> serviceProperties = MapUtil.toDictionary(
+        registerFileSystemResourceProvider(
                 "provider.file", mountFolder.getAbsolutePath(),
                 "provider.root", destPath,
                 "provider.fs.mode", "INITIAL_CONTENT",
                 "provider.initial.content.import.options", "overwrite:=true;ignoreImportProviders:=\"xml\"",
                 "provider.checkinterval", 0);
-        FsResourceProvider service = MockOsgi.activateInjectServices(FsResourceProvider.class, bundleContext, serviceProperties);
-        bundleContext.registerService(ResourceProvider.class, service, serviceProperties);
     }
 
     /**
@@ -597,18 +593,12 @@ public final class ContentLoader {
      * @param mountFolder Root folder to mount. Path needs to point to the root folder of the content package structure.
      * @param destPath Subtree path that should be mounted from FileVault XML structure
      */
-    @SuppressWarnings("null")
     public void folderFileVaultXml(@NotNull File mountFolder, @NotNull String destPath) {
-        if (bundleContext == null) {
-            throw new IllegalArgumentException("No bundle context given for content loader.");
-        }
-        Dictionary<String, Object> serviceProperties = MapUtil.toDictionary(
+        registerFileSystemResourceProvider(
                 "provider.file", mountFolder.getAbsolutePath(),
                 "provider.root", destPath,
                 "provider.fs.mode", "FILEVAULT_XML",
                 "provider.checkinterval", 0);
-        FsResourceProvider service = MockOsgi.activateInjectServices(FsResourceProvider.class, bundleContext, serviceProperties);
-        bundleContext.registerService(ResourceProvider.class, service, serviceProperties);
     }
 
     /**
@@ -635,4 +625,32 @@ public final class ContentLoader {
         }
     }
 
+    @SuppressWarnings("null")
+    private void registerFileSystemResourceProvider(Object... serviceProperties) {
+        if (bundleContext == null) {
+            throw new IllegalStateException("No bundle context given for content loader.");
+        }
+        if (isUsingMockResourceResolverFactory()) {
+            throw new IllegalStateException("Loading folder content is not supported with RESOURCERESOLVER_MOCK resource resolver type. "
+                    + "Use RESOURCEPROVIDER_MOCK or one of the other types.");
+        }
+        Dictionary<String,Object> props = MapUtil.toDictionary(serviceProperties);
+        FsResourceProvider service = MockOsgi.activateInjectServices(FsResourceProvider.class, bundleContext, props);
+        bundleContext.registerService(ResourceProvider.class, service, props);
+    }
+
+    private boolean isUsingMockResourceResolverFactory() {
+        ServiceReference<ResourceResolverFactory> serviceReference = bundleContext.getServiceReference(ResourceResolverFactory.class);
+        if (serviceReference == null) {
+            throw new IllegalStateException("No resource resolver factory service present.");
+        }
+        try {
+            ResourceResolverFactory resourceResolverFactory = bundleContext.getService(serviceReference);
+            return resourceResolverFactory instanceof MockResourceResolverFactory;
+        }
+        finally {
+            bundleContext.ungetService(serviceReference);
+        }
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java b/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
index ad0ba1e..6ed7c8f 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Mock implementation of selected Sling APIs.
  */
-@org.osgi.annotation.versioning.Version("3.3.1")
+@org.osgi.annotation.versioning.Version("3.4.0")
 package org.apache.sling.testing.mock.sling;
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/context/models/ResourceModel.java
similarity index 65%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/context/models/ResourceModel.java
index ad0ba1e..4ffb667 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/context/models/ResourceModel.java
@@ -16,8 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Mock implementation of selected Sling APIs.
- */
-@org.osgi.annotation.versioning.Version("3.3.1")
-package org.apache.sling.testing.mock.sling;
+package org.apache.sling.testing.mock.sling.context.models;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Model;
+
+@Model(adaptables = Resource.class)
+public class ResourceModel {
+    
+    private final Resource resource;
+
+    public ResourceModel(Resource resource) {
+        this.resource = resource;
+    }
+
+    public Resource getAdaptable() {
+        return resource;
+    }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java
index f70549d..dfb486d 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java
@@ -108,4 +108,22 @@ public abstract class AbstractContentLoaderFolderJsonTest {
         assertTrue(context.resourceResolver().isResourceType(resource, "core/components/superResource"));
     }
 
+    @Test
+    public void testResourceOperationsOnMountedFolder() {
+        String root = context.uniqueRoot().content() + "/test-content";
+        context.load().folderJson("src/test/resources/test-content", root);
+
+        Resource parent = context.resourceResolver().getResource(root + "/parent");
+        assertNotNull( "Expected to resolve the 'parent' resource.", parent);
+        assertNotNull("Expected to resolver the 'child' resource.", parent.getChild("child"));
+
+        Resource uniqueRoot = context.resourceResolver().getParent(parent);
+        assertNotNull("Expected to resolve the unique root.", uniqueRoot);
+        assertEquals("The resolved unique root is not identical to the created unique root.", root, uniqueRoot.getPath());
+
+        assertTrue("Expected to see a list of children.", context.resourceResolver().listChildren(parent).hasNext());
+        assertTrue("Expected to get a list of children.", context.resourceResolver().getChildren(parent).iterator().hasNext());
+        assertTrue("Expected to see a list of children.", parent.hasChildren());
+    }
+
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/resource/AbstractSlingCrudResourceResolverTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/resource/AbstractSlingCrudResourceResolverTest.java
index c97c660..29d50d4 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/resource/AbstractSlingCrudResourceResolverTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/resource/AbstractSlingCrudResourceResolverTest.java
@@ -43,6 +43,7 @@ import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.builder.ContentBuilder;
+import org.apache.sling.testing.mock.sling.context.models.ResourceModel;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -340,4 +341,13 @@ public abstract class AbstractSlingCrudResourceResolverTest {
         assertNotNull(noResourceType.getResourceType());
     }
 
+    @Test
+    public void testResourceInsideAndOutsideModel() {
+        Resource resource = context.currentResource("/");
+        assertNotNull(resource);
+        ResourceModel model = resource.adaptTo(ResourceModel.class);
+        assertNotNull(model);
+        assertEquals(resource, model.getAdaptable());
+    }
+
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/context/SlingContextImplTest.java
similarity index 76%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/context/SlingContextImplTest.java
index 01f0c5c..8cc858c 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/context/SlingContextImplTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.context;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.context.AbstractSlingContextImplTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class SlingContextImplTest extends AbstractSlingContextImplTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderAutoCommitTest.java
similarity index 81%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderAutoCommitTest.java
index 01f0c5c..f3eae33 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderAutoCommitTest.java
@@ -16,16 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderAutoCommitTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class ContentLoaderAutoCommitTest extends AbstractContentLoaderAutoCommitTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
-
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderBinaryTest.java
similarity index 81%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderBinaryTest.java
index 01f0c5c..8ba3996 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderBinaryTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderBinaryTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class ContentLoaderBinaryTest extends AbstractContentLoaderBinaryTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFileVaultXmlTest.java
similarity index 81%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFileVaultXmlTest.java
index 01f0c5c..376b2a7 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFileVaultXmlTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFileVaultXmlTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class ContentLoaderFileVaultXmlTest extends AbstractContentLoaderFileVaultXmlTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderFileVaultXmlTest.java
similarity index 90%
rename from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
rename to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderFileVaultXmlTest.java
index 89e34c2..3d48e81 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderFileVaultXmlTest.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderFileVaultXmlTest;
@@ -25,7 +25,7 @@ public class ContentLoaderFolderFileVaultXmlTest extends AbstractContentLoaderFo
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderJsonTest.java
similarity index 90%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderJsonTest.java
index 01f0c5c..74666dd 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderFolderJsonTest.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
@@ -25,7 +25,7 @@ public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJson
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonDamTest.java
similarity index 81%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonDamTest.java
index 01f0c5c..0af6579 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonDamTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderJsonDamTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class ContentLoaderJsonDamTest extends AbstractContentLoaderJsonDamTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonTest.java
similarity index 81%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonTest.java
index 01f0c5c..c64d6de 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/loader/ContentLoaderJsonTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.loader;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderJsonTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class ContentLoaderJsonTest extends AbstractContentLoaderJsonTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/MultipleResourceResolverTest.java
similarity index 76%
copy from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/MultipleResourceResolverTest.java
index 01f0c5c..ea55c37 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/MultipleResourceResolverTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.resource;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.resource.AbstractMultipleResourceResolverTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class MultipleResourceResolverTest extends AbstractMultipleResourceResolverTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/SlingCrudResourceResolverTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/SlingCrudResourceResolverTest.java
new file mode 100644
index 0000000..e9c629f
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/SlingCrudResourceResolverTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling.rpmock.resource;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.resource.AbstractSlingCrudResourceResolverTest;
+import org.junit.Test;
+
+public class SlingCrudResourceResolverTest extends AbstractSlingCrudResourceResolverTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
+    }
+
+    @Test
+    @SuppressWarnings({ "null", "unchecked" })
+    public void testResourceResolverFactory_GetSearchPath() throws Exception {
+        // ensure there is a method getSearchPaths in resource resolver factory, although it is not part of the API we are compiling against (keeping backward compatibility)
+        ResourceResolverFactory factory = context.getService(ResourceResolverFactory.class);
+        Class clazz = factory.getClass();
+        Method getSearchPathMethod = clazz.getMethod("getSearchPath");
+        getSearchPathMethod.setAccessible(true);
+        List<String> searchPaths = (List)getSearchPathMethod.invoke(factory);
+        assertNotNull(searchPaths);
+    }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/UniqueRootTest.java
similarity index 76%
rename from core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
rename to core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/UniqueRootTest.java
index 01f0c5c..5a9a935 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rpmock/resource/UniqueRootTest.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.testing.mock.sling.rrmock.loader;
+package org.apache.sling.testing.mock.sling.rpmock.resource;
 
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
-import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+import org.apache.sling.testing.mock.sling.resource.AbstractUniqueRootTest;
 
-public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+public class UniqueRootTest extends AbstractUniqueRootTest {
 
     @Override
     protected ResourceResolverType getResourceResolverType() {
-        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+        return ResourceResolverType.RESOURCEPROVIDER_MOCK;
     }
 
 }
diff --git a/junit5/src/test/resources/test-content/parent.json b/core/src/test/resources/test-content/parent.json
similarity index 100%
rename from junit5/src/test/resources/test-content/parent.json
rename to core/src/test/resources/test-content/parent.json
diff --git a/junit4/pom.xml b/junit4/pom.xml
index 1e9cd61..ecf3ce0 100644
--- a/junit4/pom.xml
+++ b/junit4/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-        <version>3.3.3-SNAPSHOT</version>
+        <version>3.4.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
 
@@ -37,13 +37,13 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock.core</artifactId>
-            <version>3.3.3-SNAPSHOT</version>
+            <version>3.4.0-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock.core</artifactId>
-            <version>3.3.3-SNAPSHOT</version>
+            <version>3.4.0-SNAPSHOT</version>
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
diff --git a/junit4/src/test/java/org/apache/sling/testing/mock/sling/junit/SlingContextDefaultRRTypeTest.java b/junit4/src/test/java/org/apache/sling/testing/mock/sling/junit/SlingContextDefaultRRTypeTest.java
deleted file mode 100644
index 40a1c9b..0000000
--- a/junit4/src/test/java/org/apache/sling/testing/mock/sling/junit/SlingContextDefaultRRTypeTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.testing.mock.sling.junit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.sling.api.resource.Resource;
-import org.junit.Rule;
-import org.junit.Test;
-
-public class SlingContextDefaultRRTypeTest {
-
-    @Rule
-    public SlingContext context = new SlingContext();
-
-    @Test
-    public void testRequest() {
-        assertNotNull(context.request());
-    }
-
-    @Test
-    public void testResourceOperationsOnMountedFolder() {
-        String root = context.uniqueRoot().content() + "/test-content";
-        context.load().folderJson("src/test/resources/test-content", root);
-
-        Resource parent = context.resourceResolver().getResource(root + "/parent");
-        assertNotNull( "Expected to resolve the 'parent' resource.", parent);
-        assertNotNull("Expected to resolver the 'child' resource.", parent.getChild("child"));
-
-        Resource uniqueRoot = context.resourceResolver().getParent(parent);
-        assertNotNull("Expected to resolve the unique root.", uniqueRoot);
-        assertEquals("The resolved unique root is not identical to the created unique root.", root, uniqueRoot.getPath());
-
-        assertTrue("Expected to see a list of children.", context.resourceResolver().listChildren(parent).hasNext());
-        assertTrue("Expected to get a list of children.", context.resourceResolver().getChildren(parent).iterator().hasNext());
-        assertTrue("Expected to see a list of children.", parent.hasChildren());
-    }
-
-}
diff --git a/junit5/pom.xml b/junit5/pom.xml
index 2cb5fdd..883c7fc 100644
--- a/junit5/pom.xml
+++ b/junit5/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-        <version>3.3.3-SNAPSHOT</version>
+        <version>3.4.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
 
@@ -37,13 +37,13 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock.core</artifactId>
-            <version>3.3.3-SNAPSHOT</version>
+            <version>3.4.0-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock.core</artifactId>
-            <version>3.3.3-SNAPSHOT</version>
+            <version>3.4.0-SNAPSHOT</version>
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
diff --git a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
index a39204c..866cd0a 100644
--- a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
+++ b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
@@ -19,8 +19,6 @@
 package org.apache.sling.testing.mock.sling.junit5;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
@@ -51,30 +49,12 @@ class SlingContextTest {
     }
 
     @Test
-    public void testSlingModelClasspathRegistered(SlingContext context) {
+    void testSlingModelClasspathRegistered(SlingContext context) {
         context.request().setAttribute("prop1", "myValue");
         ClasspathRegisteredModel model = context.request().adaptTo(ClasspathRegisteredModel.class);
         assertEquals("myValue", model.getProp1());
     }
 
-    @Test
-    void testResourceOperationsOnMountedFolder(SlingContext context) {
-        String root = context.uniqueRoot().content() + "/test-content";
-        context.load().folderJson("src/test/resources/test-content", root);
-
-        Resource parent = context.resourceResolver().getResource(root + "/parent");
-        assertNotNull(parent, "Expected to resolve the 'parent' resource.");
-        assertNotNull(parent.getChild("child"), "Expected to resolver the 'child' resource.");
-
-        Resource uniqueRoot = context.resourceResolver().getParent(parent);
-        assertNotNull(uniqueRoot, "Expected to resolve the unique root");
-        assertEquals(root, uniqueRoot.getPath(), "The resolved unique root is not identical to the created unique root.");
-
-        assertTrue(context.resourceResolver().listChildren(parent).hasNext(), "Expected to get a list of children.");
-        assertTrue(context.resourceResolver().getChildren(parent).iterator().hasNext(), "Expected to get a list of children.");
-        assertTrue(parent.hasChildren(), "Expected to get a list of children.");
-    }
-
     @AfterEach
     void tearDown(SlingContext context) throws Exception {
         Resource resource = context.resourceResolver().getResource("/content/test");
diff --git a/parent/pom.xml b/parent/pom.xml
index 44e2994..7a5ec33 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-    <version>3.3.3-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <name>Apache Sling Testing Sling Mock Parent</name>
@@ -37,12 +37,12 @@
     <properties>
         <osgi-mock.version>3.3.0</osgi-mock.version>
         <jcr-mock.version>1.6.0</jcr-mock.version>
-        <resourceresolver-mock.version>1.3.0</resourceresolver-mock.version>
+        <resourceresolver-mock.version>1.4.0-SNAPSHOT</resourceresolver-mock.version>
         <logging-mock.version>2.0.0</logging-mock.version>
         <servlet-helpers.version>1.4.2</servlet-helpers.version>
         <resourcebuilder.version>1.0.4</resourcebuilder.version>
 
-        <project.build.outputTimestamp>2022-06-30T07:15:29Z</project.build.outputTimestamp>
+        <project.build.outputTimestamp>2022-08-18T11:38:28Z</project.build.outputTimestamp>
     </properties>
 
     <dependencies>
@@ -268,12 +268,12 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>4.5.1</version>
+            <version>4.7.0</version>
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-junit-jupiter</artifactId>
-            <version>4.5.1</version>
+            <version>4.7.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
diff --git a/pom.xml b/pom.xml
index 20f8914..82fb517 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-        <version>3.3.3-SNAPSHOT</version>
+        <version>3.4.0-SNAPSHOT</version>
         <relativePath>parent/pom.xml</relativePath>
     </parent>
 
diff --git a/relocate/pom.xml b/relocate/pom.xml
index e411d2d..5aa28be 100644
--- a/relocate/pom.xml
+++ b/relocate/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.testing.sling-mock.parent</artifactId>
-        <version>3.3.3-SNAPSHOT</version>
+        <version>3.4.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>