This is an automated email from the ASF dual-hosted git repository.
enorman pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-i18n.git
The following commit(s) were added to refs/heads/master by this push:
new 7437226 SLING-12310 Fix test compatibility with java 17 (#12)
7437226 is described below
commit 7437226790f34737f29c1e99fa219afdde9d44ad
Author: Eric Norman <[email protected]>
AuthorDate: Fri May 3 15:56:29 2024 -0700
SLING-12310 Fix test compatibility with java 17 (#12)
---
pom.xml | 120 +++---
.../ConcurrentJcrResourceBundleLoadingTest.java | 189 ++++-----
.../sling/i18n/impl/JcrResourceBundleTest.java | 471 +++------------------
.../sling/i18n/it/ResourceBundleLocatorIT.java | 4 +-
4 files changed, 197 insertions(+), 587 deletions(-)
diff --git a/pom.xml b/pom.xml
index e9780fa..8bb4f42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,8 @@
<properties>
<project.build.outputTimestamp>2023-02-15T06:46:23Z</project.build.outputTimestamp>
<org.ops4j.pax.exam.version>4.13.3</org.ops4j.pax.exam.version>
- <jackrabbit.version>2.14.3</jackrabbit.version>
+ <jackrabbit.version>2.20.0</jackrabbit.version>
+ <oak.version>1.22</oak.version>
</properties>
<scm>
@@ -79,6 +80,13 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
@@ -92,12 +100,9 @@
</executions>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
- <systemProperties>
- <property>
- <name>bundle.filename</name>
-
<value>${basedir}/target/${project.build.finalName}.jar</value>
- </property>
- </systemProperties>
+ <systemPropertyVariables>
+
<bundle.filename>${basedir}/target/${project.build.finalName}.jar</bundle.filename>
+ </systemPropertyVariables>
</configuration>
</plugin>
<plugin>
@@ -165,7 +170,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.11.0</version>
+ <version>2.16.4</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -187,20 +192,20 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.serviceusermapper</artifactId>
- <version>1.2.0</version>
+ <version>1.4.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.paxexam</artifactId>
- <version>3.1.0</version>
+ <version>4.0.0</version>
<scope>test</scope>
</dependency>
<!-- Apache Felix -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
- <version>6.0.3</version>
+ <version>7.0.5</version>
<scope>test</scope>
</dependency>
<!-- Testing -->
@@ -212,61 +217,10 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
- <version>3.3.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-module-junit4</artifactId>
- <version>2.0.9</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-mockito2</artifactId>
- <version>2.0.9</version>
- <scope>test</scope>
- </dependency>
-
- <!-- workaround SLING-7159 - the jackrabbit version from
o.a.sling.commons.testing is not compatible with java9+.
- remove this after the deprecated dependency to
o.a.sling.commons.testing has been replaced -->
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-api</artifactId>
- <version>${jackrabbit.version}</version>
- <scope>test</scope>
- </dependency>
- <!-- workaround SLING-7159 - the jackrabbit version from
o.a.sling.commons.testing is not compatible with java9+.
- remove this after the deprecated dependency to
o.a.sling.commons.testing has been replaced -->
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- <version>${jackrabbit.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.testing</artifactId>
- <version>2.1.2</version>
+ <version>5.11.0</version>
<scope>test</scope>
- <exclusions>
- <!-- slf4j simple implementation logs INFO + higher to stdout
(we don't want that behaviour) -->
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </exclusion>
- <!-- workaround SLING-7159 - the jackrabbit version is not
compatible with java9+
- so exclude these here and declare newer version of
jackrabbit artifacts above. -->
- <exclusion>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- </exclusion>
- </exclusions>
</dependency>
+
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -302,11 +256,41 @@
<version>${org.ops4j.pax.exam.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.jcr-mock</artifactId>
+ <version>1.6.14</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
- <version>3.0.0</version>
- <scope>test</scope>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.osgi-mock.junit4</artifactId>
+ <version>3.4.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.sling-mock.core</artifactId>
+ <version>3.4.18</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
+ <version>3.4.18</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.threads</artifactId>
+ <version>3.2.22</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
</dependency>
</dependencies>
</project>
diff --git
a/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java
b/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java
index 8292662..90c1372 100644
---
a/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java
+++
b/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java
@@ -19,121 +19,98 @@
package org.apache.sling.i18n.impl;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
-import static org.mockito.AdditionalMatchers.or;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.times;
-import static org.powermock.api.mockito.PowerMockito.doAnswer;
-import static org.powermock.api.mockito.PowerMockito.doReturn;
-import static org.powermock.api.mockito.PowerMockito.mock;
-import static org.powermock.api.mockito.PowerMockito.spy;
-import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
-
-import java.lang.annotation.Annotation;
+
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.scheduler.ScheduleOptions;
+import org.apache.sling.commons.scheduler.Scheduler;
import org.apache.sling.i18n.impl.JcrResourceBundleProvider.Key;
+import org.apache.sling.serviceusermapping.ServiceUserMapped;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.verification.VerificationMode;
-import org.osgi.framework.BundleContext;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
/**
* Test case to verify that each bundle is only loaded once, even
* if concurrent requests for the same bundle are made.
*/
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(Parameterized.class)
-@PrepareForTest(JcrResourceBundleProvider.class)
+@RunWith(Parameterized.class)
public class ConcurrentJcrResourceBundleLoadingTest {
+ @Rule
+ public final SlingContext context = new SlingContext();
+
@Parameterized.Parameters(name = "preload_bundles={0}")
public static Iterable<? extends Object> PRELOAD_BUNDLES() {
return Arrays.asList(Boolean.TRUE, Boolean.FALSE);
}
- @Mock JcrResourceBundle english;
- @Mock JcrResourceBundle german;
-
@Parameterized.Parameter public Boolean preload = Boolean.FALSE;
private JcrResourceBundleProvider provider;
@Before
public void setup() throws Exception {
- provider = spy(new JcrResourceBundleProvider());
- provider.activate(PowerMockito.mock(BundleContext.class), new Config()
{
-
- @Override
- public Class<? extends Annotation> annotationType() {
- return Config.class;
- }
-
- @Override
- public boolean preload_bundles() {
- return preload;
- }
-
- @Override
- public String locale_default() {
- return "en";
- }
-
- @Override
- public long invalidation_delay() {
- return 5000;
- }
-
- @Override
- public String[] included_paths() {
- return new String[] {"/libs", "/apps"};
- }
-
- @Override
- public String[] excluded_paths() {
- return new String[] {"/var/eventing"};
- }
- });
- doReturn(null).when(provider, "createResourceResolver");
- doReturn(english).when(provider, "createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.ENGLISH));
- doReturn(german).when(provider, "createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.GERMAN));
- Mockito.when(german.getLocale()).thenReturn(Locale.GERMAN);
- Mockito.when(english.getLocale()).thenReturn(Locale.ENGLISH);
- Mockito.when(german.getParent()).thenReturn(english);
+ // mock other required services
+ Scheduler mockScheduler = context.registerService(Scheduler.class,
Mockito.mock(Scheduler.class));
+ // mock this call to avoid a NPE during activation
+ Mockito.doAnswer(invocation -> {
+ return Mockito.mock(ScheduleOptions.class);
+ }).when(mockScheduler).NOW();
+ // Mock the schedule call so we do not wait for the
"ResourceBundleProvider: reload all resource bundles"
+ // scheduled job to be completed during activation. That background
schedule execution can interfere with
+ // the multi-threaded tests (i.e. the cache gets reset in the middle
of doing something)
+ Mockito.doAnswer(invocation -> {
+ Runnable runnable = invocation.getArgument(0, Runnable.class);
+ runnable.run();
+ return null;
+ }).when(mockScheduler).schedule(any(Runnable.class),
any(ScheduleOptions.class));
+ context.registerService(ServiceUserMapped.class,
Mockito.mock(ServiceUserMapped.class));
+
+ Map<String, Object> configMap = new HashMap<>();
+ configMap.put("preload.bundles", preload);
+ configMap.put("locale.default", "en");
+ configMap.put("invalidation.delay", 5000);
+ configMap.put("included.paths", new String[] {"/libs", "/apps"});
+ configMap.put("excluded.paths", new String[] {"/var/eventing"});
+ provider =
context.registerInjectActivateService(JcrResourceBundleProvider.class,
configMap);
}
@Test
public void loadBundlesOnlyOncePerLocale() throws Exception {
+ ResourceBundle english = provider.getResourceBundle(Locale.ENGLISH);
+ ResourceBundle german = provider.getResourceBundle(Locale.GERMAN);
assertEquals(english, provider.getResourceBundle(Locale.ENGLISH));
assertEquals(english, provider.getResourceBundle(Locale.ENGLISH));
assertEquals(german, provider.getResourceBundle(Locale.GERMAN));
assertEquals(german, provider.getResourceBundle(Locale.GERMAN));
-
- verifyPrivate(provider, times(2)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
any(Locale.class));
}
@Test
public void loadBundlesOnlyOnceWithConcurrentRequests() throws Exception {
+ Map<Locale, List<ResourceBundle>> rbMap = new ConcurrentHashMap<>();
final int numberOfThreads = 40;
final ExecutorService executor =
Executors.newFixedThreadPool(numberOfThreads / 2);
for (int i = 0; i < numberOfThreads; i++) {
@@ -141,51 +118,54 @@ public class ConcurrentJcrResourceBundleLoadingTest {
executor.submit(new Runnable() {
@Override
public void run() {
- provider.getResourceBundle(language);
+ ResourceBundle rb = provider.getResourceBundle(language);
+ List<ResourceBundle> list =
rbMap.computeIfAbsent(language, key -> new ArrayList<>());
+ list.add(rb);
}
});
}
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
- verifyPrivate(provider, times(1)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.ENGLISH));
- verifyPrivate(provider, times(1)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.GERMAN));
+ // convert to set to remove the duplicates
+ Set<ResourceBundle> englishSet = new
HashSet<>(rbMap.get(Locale.ENGLISH));
+ // should only be one uqique value
+ assertEquals(1, englishSet.size());
+ Set<ResourceBundle> germanSet = new
HashSet<>(rbMap.get(Locale.GERMAN));
+ assertEquals(1, germanSet.size());
}
@Test
public void newBundleUsedAfterReload() throws Exception {
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
+ ResourceBundle english = provider.getResourceBundle(Locale.ENGLISH);
+ ResourceBundle german = provider.getResourceBundle(Locale.GERMAN);
// reloading german should not reload any other bundle
provider.reloadBundle(new Key(null, Locale.GERMAN));
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
-
- verifyPrivate(provider, times(1)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.ENGLISH));
- verifyPrivate(provider, times(2)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.GERMAN));
+ assertSame(english, provider.getResourceBundle(Locale.ENGLISH));
+ ResourceBundle german2 = provider.getResourceBundle(Locale.GERMAN);
+ assertNotSame(german2, german);
+ assertSame(english, provider.getResourceBundle(Locale.ENGLISH));
+ assertSame(german2, provider.getResourceBundle(Locale.GERMAN));
+ assertSame(english, provider.getResourceBundle(Locale.ENGLISH));
+ assertSame(german2, provider.getResourceBundle(Locale.GERMAN));
}
@Test
public void newBundleUsedAsParentAfterReload() throws Exception {
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
+ ResourceBundle english = provider.getResourceBundle(Locale.ENGLISH);
+ ResourceBundle german = provider.getResourceBundle(Locale.GERMAN);
// reloading english should also reload german (because it has english
as a parent)
provider.reloadBundle(new Key(null, Locale.ENGLISH));
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
- provider.getResourceBundle(Locale.ENGLISH);
- provider.getResourceBundle(Locale.GERMAN);
-
- verifyPrivate(provider, times(2)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.ENGLISH));
- verifyPrivate(provider, times(2)).invoke("createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.GERMAN));
+ ResourceBundle english2 = provider.getResourceBundle(Locale.ENGLISH);
+ assertNotSame(english2, english);
+ ResourceBundle german2 = provider.getResourceBundle(Locale.GERMAN);
+ assertNotSame(german2, german);
+ assertSame(english2, provider.getResourceBundle(Locale.ENGLISH));
+ assertSame(german2, provider.getResourceBundle(Locale.GERMAN));
+ assertSame(english2, provider.getResourceBundle(Locale.ENGLISH));
+ assertSame(german2, provider.getResourceBundle(Locale.GERMAN));
}
/**
@@ -196,20 +176,14 @@ public class ConcurrentJcrResourceBundleLoadingTest {
*/
@Test
public void newBundleReplacesOldBundleAfterReload() throws Exception {
- provider.getResourceBundle(Locale.ENGLISH);
- final ResourceBundle newBundle = mock(JcrResourceBundle.class);
+ ResourceBundle english = provider.getResourceBundle(Locale.ENGLISH);
final CountDownLatch newBundleReturned = new CountDownLatch(1);
- doAnswer(invocationOnMock -> {
- Thread.sleep(1000);
- return newBundle;
- }).when(provider, "createResourceBundle",
or(ArgumentMatchers.isNull(), any(ResourceResolver.class)), eq(null),
eq(Locale.ENGLISH));
-
ScheduledExecutorService executorService =
Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(
() -> {
ResourceBundle currentBundle =
provider.getResourceBundle(Locale.ENGLISH);
- if (currentBundle == newBundle) {
+ if (currentBundle != english) {
// Shutdown the executor once we got the new
ResourceBundle. This will cancel the future and opens the gate below.
// Do not assert the returned bundle directly here, as
this may become flaky when the bundle returned by the
// mock above was returned but not yet put into the cache.
@@ -231,16 +205,7 @@ public class ConcurrentJcrResourceBundleLoadingTest {
}
// CancellationException expected
- // we expect getResourceBundleInternal() called once in the beginning
of the test and once again after reloading the bundle.
- final int expectedGetResourceBundleInternal = 2;
- VerificationMode verificationMode = preload
- // when preloading the calls to getResourceBundleInternal are
non-blocking and so more calls will happen while reloading.
- // assuming at least one more
- ? atLeast(expectedGetResourceBundleInternal + 1)
- : times(expectedGetResourceBundleInternal);
-
- verifyPrivate(provider,
verificationMode).invoke("getResourceBundleInternal",
- or(ArgumentMatchers.isNull(), any(ResourceResolver.class)),
eq(null), eq(Locale.ENGLISH), anyBoolean());
-
+ ResourceBundle english2 = provider.getResourceBundle(Locale.ENGLISH);
+ assertNotSame(english2, english);
}
}
\ No newline at end of file
diff --git
a/src/test/java/org/apache/sling/i18n/impl/JcrResourceBundleTest.java
b/src/test/java/org/apache/sling/i18n/impl/JcrResourceBundleTest.java
index 72c0a4d..267fe74 100644
--- a/src/test/java/org/apache/sling/i18n/impl/JcrResourceBundleTest.java
+++ b/src/test/java/org/apache/sling/i18n/impl/JcrResourceBundleTest.java
@@ -18,339 +18,91 @@
*/
package org.apache.sling.i18n.impl;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.jcr.Binary;
import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.RowIterator;
-import javax.naming.NamingException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.jackrabbit.JcrConstants;
-import org.apache.sling.api.resource.AbstractResource;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
+import javax.jcr.Session;
+import javax.jcr.util.TraversingItemVisitor;
+
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
-import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
-import org.apache.sling.commons.testing.jcr.RepositoryUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.sling.testing.mock.jcr.MockJcr;
+import org.apache.sling.testing.mock.jcr.MockQueryResult;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
/**
* Tests the {@link JcrResourceBundle} class.
*/
-public class JcrResourceBundleTest extends RepositoryTestBase {
+public class JcrResourceBundleTest {
- private static final Logger log =
LoggerFactory.getLogger(JcrResourceBundleTest.class);
+ @Rule
+ public final SlingContext context = new
SlingContext(ResourceResolverType.JCR_MOCK);
protected ResourceResolver resolver;
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- cleanRepository();
-
- RepositoryUtil.registerNodeType(getSession(), getClass()
- .getResourceAsStream("/SLING-INF/nodetypes/jcrlanguage.cnd"));
- RepositoryUtil.registerNodeType(getSession(), getClass()
- .getResourceAsStream("/SLING-INF/nodetypes/message.cnd"));
-
- resolver = new ResourceResolver() {
-
- @Override
- public Iterator<Resource> findResources(String query,
- String language) {
- try {
- final Query q =
getSession().getWorkspace().getQueryManager().createQuery(query, language);
- final QueryResult result = q.execute();
- final NodeIterator nodes = result.getNodes();
- return new Iterator<Resource>() {
- @Override
- public boolean hasNext() {
- return nodes.hasNext();
- }
-
- @Override
- public Resource next() {
- final Node node = nodes.nextNode();
- return new TestResource(resolver, node);
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
- };
- } catch (NamingException ne) {
- return null;
- } catch (RepositoryException re) {
- return null;
- }
- }
-
- @Override
- public Resource getResource(Resource base, String path) {
- return null;
- }
-
- @Override
- public Resource getResource(String path) {
- try {
- final Node n = getSession().getNode(path);
- return new TestResource(resolver, n);
-
- } catch (NamingException ne) {
- //ignore
- } catch (RepositoryException re) {
- //ignore
- }
- return null;
- }
-
- @Override
- public String[] getSearchPath() {
- return new String[] {"/apps/", "/libs/"};
- }
-
- @Override
- public Iterator<Resource> listChildren(final Resource parent) {
- try {
- final Node n = getSession().getNode(parent.getPath());
- final NodeIterator nodes = n.getNodes();
- return new Iterator<Resource>() {
- @Override
- public boolean hasNext() {
- return nodes.hasNext();
- }
-
- @Override
- public Resource next() {
- final Node node = nodes.nextNode();
- return new TestResource(resolver, node);
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
- };
- } catch ( final RepositoryException re) {
- // ignore
- return null;
- } catch ( final NamingException e) {
- // ignore
- return null;
- }
- }
-
- @Override
- public String map(HttpServletRequest request, String resourcePath)
{
- return null;
- }
-
- @Override
- public String map(String resourcePath) {
- return null;
- }
-
- @Override
- public Iterator<Map<String, Object>> queryResources(String query,
- String language) {
- try {
- final Query q =
getSession().getWorkspace().getQueryManager().createQuery(query, language);
- final QueryResult result = q.execute();
- final String[] colNames = result.getColumnNames();
- final RowIterator rows = result.getRows();
- return new Iterator<Map<String, Object>>() {
- @Override
- public boolean hasNext() {
- return rows.hasNext();
- }
-
- @Override
- public Map<String, Object> next() {
- Map<String, Object> row = new HashMap<String,
Object>();
- try {
- Value[] values = rows.nextRow().getValues();
- for (int i = 0; i < values.length; i++) {
- Value v = values[i];
- if (v != null) {
- row.put(colNames[i],
values[i].getString());
- }
- }
- } catch (RepositoryException re) {
- // ignore
- }
- return row;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
- };
- } catch (NamingException ne) {
- return null;
- } catch (RepositoryException re) {
- return null;
- }
- }
-
- @Override
- public Resource resolve(HttpServletRequest request, String
absPath) {
- return null;
- }
-
- @Override
- public Resource resolve(HttpServletRequest request) {
- return null;
- }
-
- @Override
- public Resource resolve(String absPath) {
- return null;
- }
-
- @Override
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return null;
- }
-
- @Override
- public void close() {
- // nothing to do
- }
-
- @Override
- public String getUserID() {
- return null;
- }
-
- @Override
- public boolean isLive() {
- return true;
- }
-
- @Override
- public ResourceResolver clone(Map<String, Object>
authenticationInfo) {
- return null;
- }
-
- @Override
- public Iterator<String> getAttributeNames() {
- return null;
- }
-
- @Override
- public Object getAttribute(String name) {
- return null;
- }
-
- @Override
- public Iterable<Resource> getChildren(Resource parent) {
- return null;
- }
-
- @Override
- public void delete(Resource resource) throws PersistenceException {
- }
-
- @Override
- public Resource create(Resource parent, String name,
- Map<String, Object> properties) throws
PersistenceException {
- return null;
- }
-
- @Override
- public void revert() {
- }
-
- @Override
- public void commit() throws PersistenceException {
- }
-
- @Override
- public boolean hasChanges() {
- return false;
- }
-
- @Override
- public String getParentResourceType(Resource resource) {
- return null;
- }
-
- @Override
- public String getParentResourceType(String resourceType) {
- return null;
- }
-
- @Override
- public boolean isResourceType(final Resource resource, final
String resourceType) {
- return resourceType.equals(resource.getResourceType());
- }
-
- @Override
- public void refresh() {
-
- }
-
- @Override
- public Resource getParent(Resource child) {
- return null;
- }
+ private Session getSession() {
+ return context.resourceResolver().adaptTo(Session.class);
+ }
- @Override
- public boolean hasChildren(Resource resource) {
- return false;
+ @Before
+ public void setUp() throws Exception {
+ Session session = getSession();
+ String[] cndResourcesToLoad = new String[] {
+ "/org/apache/jackrabbit/oak/builtin_nodetypes.cnd",
+ "/SLING-INF/nodetypes/jcrlanguage.cnd",
+ "/SLING-INF/nodetypes/message.cnd"
+ };
+ for (String resourceName : cndResourcesToLoad) {
+ URL cndUrl = getClass().getResource(resourceName);
+ if (cndUrl == null) {
+ fail("Failed to load CND nodetypes resource: " + resourceName);
}
-
- @Override
- public Resource copy(String srcAbsPath, String destAbsPath) throws
PersistenceException {
- return null;
+ try (Reader reader = new InputStreamReader(cndUrl.openStream())) {
+ MockJcr.loadNodeTypeDefs(session, reader);
}
+ }
- @Override
- public Resource move(String srcAbsPath, String destAbsPath) throws
PersistenceException {
- return null;
- }
- };
+ resolver = context.resourceResolver();
createTestContent();
- }
- public void cleanRepository() throws Exception {
- NodeIterator nodes = getSession().getRootNode().getNodes();
- while (nodes.hasNext()) {
- Node node = nodes.nextNode();
- if (!node.getDefinition().isProtected() &&
!node.getDefinition().isMandatory()) {
- try {
- node.remove();
- } catch (RepositoryException e) {
- log.error("Test clean repo: Cannot remove node: " +
node.getPath(), e);
- }
+ MockJcr.addQueryResultHandler(session, query -> {
+ List<Node> languageNodes = new ArrayList<>();
+ try {
+ session.getRootNode().accept(new
TraversingItemVisitor.Default() {
+ @Override
+ protected void entering(Node node, int level) throws
RepositoryException {
+ if (node.isNodeType("mix:language")) {
+ languageNodes.add(node);
+ }
+ }
+ });
+ } catch (RepositoryException e) {
+ fail("Failed to visit language nodes. Reason: " +
e.getMessage());
}
- }
- getSession().save();
+ return new MockQueryResult(languageNodes);
+ });
}
-
// test data to add to the repository (use linked hash map for insertion
order)
public static final Map<String, Message> MESSAGES_DE = new
LinkedHashMap<String, Message>();
public static final Map<String, Message> MESSAGES_EN = new
LinkedHashMap<String, Message>();
@@ -446,6 +198,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
// ---------------------------------------------------------------< tests >
+ @Test
public void test_getString() {
JcrResourceBundle bundle = new JcrResourceBundle(new Locale("de"),
null, resolver, null, new PathFilter());
for (Message msg : MESSAGES_DE.values()) {
@@ -468,6 +221,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
}
}
+ @Test
public void test_getObject() {
JcrResourceBundle bundle = new JcrResourceBundle(new Locale("de"),
null, resolver, null, new PathFilter());
for (Message msg : MESSAGES_DE.values()) {
@@ -475,6 +229,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
}
}
+ @Test
public void test_handle_missing_key() {
// test if key is returned if no entry found in repo
JcrResourceBundle bundle = new JcrResourceBundle(new Locale("de"),
null, resolver, null, new PathFilter());
@@ -482,6 +237,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals("missing", bundle.getString("missing"));
}
+ @Test
public void test_getKeys() {
JcrResourceBundle bundle = new JcrResourceBundle(new Locale("de"),
null, resolver, null, new PathFilter());
Enumeration<String> keys = bundle.getKeys();
@@ -494,6 +250,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals(MESSAGES_DE.size(), counter);
}
+ @Test
public void test_bundle_parenting() {
// set parent of resource bundle, test if passed through
JcrResourceBundle bundle = new JcrResourceBundle(new Locale("de"),
null, resolver, null, new PathFilter());
@@ -505,6 +262,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals("missing", bundle.getString("missing"));
}
+ @Test
public void test_search_path() throws Exception {
// overwrite stuff in apps
Node appsI18n =
getSession().getRootNode().addNode("apps").addNode("i18n", "nt:unstructured");
@@ -533,6 +291,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals(MESSAGES_DE.size(), counter);
}
+ @Test
public void test_outside_search_path() throws Exception {
Node libsI18n = getSession().getRootNode().getNode("libs/i18n");
libsI18n.remove();
@@ -580,6 +339,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals(MESSAGES_DE.size(), counter);
}
+ @Test
public void test_basename() throws Exception {
// create another de lib with a basename set
Node appsI18n = getSession().getRootNode().getNode("libs/i18n");
@@ -615,6 +375,7 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals(MESSAGES_DE.size(), counter);
}
+ @Test
public void test_json_dictionary() throws Exception {
Node appsI18n =
getSession().getRootNode().addNode("apps").addNode("i18n", "nt:unstructured");
Node deJson = appsI18n.addNode("de.json", "nt:file");
@@ -654,106 +415,4 @@ public class JcrResourceBundleTest extends
RepositoryTestBase {
assertEquals(MESSAGES_DE.size(), counter);
}
- private class TestResource extends AbstractResource {
-
- private final Node node;
-
- private final ResourceResolver resolver;
-
- public TestResource(final ResourceResolver resolver, final Node xnode)
{
- this.node = xnode;
- this.resolver = resolver;
- }
-
- @Override
- public String getResourceType() {
- try {
- return this.node.getPrimaryNodeType().getName();
- } catch ( final RepositoryException re) {
- return "<unknown>";
- }
- }
-
- @Override
- public String getResourceSuperType() {
- return null;
- }
-
- @Override
- public ResourceResolver getResourceResolver() {
- return this.resolver;
- }
-
- @Override
- public ResourceMetadata getResourceMetadata() {
- return new ResourceMetadata();
- }
-
- @Override
- public String getPath() {
- try {
- return node.getPath();
- } catch ( final RepositoryException re ) {
- throw new RuntimeException(re);
- }
- }
-
- @Override
- public <AdapterType> AdapterType adaptTo(
- Class<AdapterType> type) {
- if ( type == ValueMap.class) {
- try {
- final Map<String, Object> props = new HashMap<String,
Object>();
- if ( node.hasProperty(JcrResourceBundle.PROP_LANGUAGE) ) {
- props.put(JcrResourceBundle.PROP_LANGUAGE,
node.getProperty(JcrResourceBundle.PROP_LANGUAGE).getString());
- }
- if ( node.hasProperty(JcrResourceBundle.PROP_BASENAME) ) {
- Property propBasename =
node.getProperty(JcrResourceBundle.PROP_BASENAME);
- if (propBasename.isMultiple()) {
- String[] basenames = new
String[propBasename.getValues().length];
- int i=0;
- for (Value basename : propBasename.getValues()) {
- basenames[i++] = basename.getString();
- }
- props.put(JcrResourceBundle.PROP_BASENAME,
basenames);
- } else {
- props.put(JcrResourceBundle.PROP_BASENAME,
propBasename.getString());
- }
- }
- if ( node.hasProperty(JcrResourceBundle.PROP_KEY) ) {
- props.put(JcrResourceBundle.PROP_KEY,
node.getProperty(JcrResourceBundle.PROP_KEY).getString());
- }
- if ( node.hasProperty(JcrResourceBundle.PROP_VALUE) ) {
- props.put(JcrResourceBundle.PROP_VALUE,
node.getProperty(JcrResourceBundle.PROP_VALUE).getString());
- }
- if ( node.hasProperty(JcrResourceBundle.PROP_MIXINS) ) {
- final Value[] values =
node.getProperty(JcrResourceBundle.PROP_MIXINS).getValues();
- final String[] names = new String[values.length];
- for(int i=0;i<values.length;i++) {
- names[i] = values[i].getString();
- }
- props.put(JcrResourceBundle.PROP_MIXINS, names);
- }
- return (AdapterType)new ValueMapDecorator(props);
- } catch ( final RepositoryException re ) {
- throw new RuntimeException(re);
- }
- }
- if (type == InputStream.class) {
- try {
- if (node.hasNode(JcrConstants.JCR_CONTENT)) {
- return (AdapterType)
node.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getBinary().getStream();
- } else {
- return null;
- }
- } catch (RepositoryException e) {
- throw new RuntimeException(e);
- }
- }
- if (type == Node.class) {
- return (AdapterType)node;
- }
- return super.adaptTo(type);
- }
- };
}
diff --git
a/src/test/java/org/apache/sling/i18n/it/ResourceBundleLocatorIT.java
b/src/test/java/org/apache/sling/i18n/it/ResourceBundleLocatorIT.java
index e42f532..feab011 100644
--- a/src/test/java/org/apache/sling/i18n/it/ResourceBundleLocatorIT.java
+++ b/src/test/java/org/apache/sling/i18n/it/ResourceBundleLocatorIT.java
@@ -18,6 +18,7 @@
*/
package org.apache.sling.i18n.it;
+import static
org.apache.sling.testing.paxexam.SlingOptions.slingBundleresource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.ops4j.pax.exam.CoreOptions.composite;
@@ -134,7 +135,8 @@ public class ResourceBundleLocatorIT extends
I18nTestSupport {
}
}
- return composite(composite(super.configuration()),
+ return composite(composite(super.configuration()),
+ slingBundleresource(),
composite(bundle))
.getOptions();
}