jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/401705 )

Change subject: Properly close HC client in WikibaseRepository
......................................................................


Properly close HC client in WikibaseRepository

This could be one of the cause for leaked threads detected in our unit
tests.

Bug: T178721
Change-Id: I882d886382fe73630cfc5d4f372de809e4ddeb29
---
A testTools/src/main/java/org/wikidata/query/rdf/test/CloseableRule.java
M tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
M 
tools/src/main/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepository.java
M 
tools/src/test/java/org/wikidata/query/rdf/tool/AbstractUpdaterIntegrationTestBase.java
M tools/src/test/java/org/wikidata/query/rdf/tool/RdfRepositoryForTesting.java
M 
tools/src/test/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepositoryIntegrationTest.java
6 files changed, 111 insertions(+), 44 deletions(-)

Approvals:
  Smalyshev: Looks good to me, approved
  jenkins-bot: Verified



diff --git 
a/testTools/src/main/java/org/wikidata/query/rdf/test/CloseableRule.java 
b/testTools/src/main/java/org/wikidata/query/rdf/test/CloseableRule.java
new file mode 100644
index 0000000..6e11979
--- /dev/null
+++ b/testTools/src/main/java/org/wikidata/query/rdf/test/CloseableRule.java
@@ -0,0 +1,48 @@
+package org.wikidata.query.rdf.test;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+
+/**
+ * A {@link TestRule} that will automatically close an object after tests.
+ *
+ * This makes it slightly nicer than having @After methods for each resource to
+ * close. It makes most sense when a test instantiate multiple {@link
+ * AutoCloseable} resources.
+ *
+ * @param <T>
+ */
+public final class CloseableRule<T extends AutoCloseable> implements TestRule {
+
+    private final T closeable;
+
+    public static <T extends AutoCloseable> CloseableRule<T> autoClose(T 
closeable) {
+        return new CloseableRule<>(closeable);
+    }
+
+    private CloseableRule(T closeable) {
+        this.closeable = closeable;
+    }
+
+    public T get() {
+        return closeable;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Statement apply(final Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                try {
+                    base.evaluate();
+                } finally {
+                    closeable.close();
+                }
+            }
+        };
+    }
+
+}
diff --git a/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java 
b/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
index 9ea247e..5d768ac 100644
--- a/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
+++ b/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
@@ -50,10 +50,11 @@
     public static void main(String[] args) throws Exception {
         RdfRepository rdfRepository = null;
         Updater<? extends Change.Batch> updater;
+        WikibaseRepository wikibaseRepository;
 
         try {
             UpdateOptions options = handleOptions(UpdateOptions.class, args);
-            WikibaseRepository wikibaseRepository = 
buildWikibaseRepository(options);
+            wikibaseRepository = buildWikibaseRepository(options);
             URI sparqlUri = sparqlUri(options);
             WikibaseUris uris = new WikibaseUris(options.wikibaseHost());
             rdfRepository = new RdfRepository(sparqlUri, uris);
@@ -67,13 +68,15 @@
             }
             throw e;
         }
-        try (RdfRepository r = rdfRepository) {
+        try (
+                WikibaseRepository w = wikibaseRepository;
+                RdfRepository r = rdfRepository;
+                Updater u = updater
+        ) {
             updater.run();
         } catch (Exception e) {
             log.error("Error during updater run.", e);
             throw e;
-        } finally {
-            updater.close();
         }
     }
 
diff --git 
a/tools/src/main/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepository.java
 
b/tools/src/main/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepository.java
index eeccbc5..58c3cfb 100644
--- 
a/tools/src/main/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepository.java
+++ 
b/tools/src/main/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepository.java
@@ -1,5 +1,6 @@
 package org.wikidata.query.rdf.tool.wikibase;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.InterruptedIOException;
@@ -72,7 +73,7 @@
  */
 // TODO fan out complexity
 @SuppressWarnings("checkstyle:classfanoutcomplexity")
-public class WikibaseRepository {
+public class WikibaseRepository implements Closeable {
     private static final Logger log = 
LoggerFactory.getLogger(WikibaseRepository.class);
 
     /**
@@ -416,6 +417,11 @@
         return name.matches("^[A-Za-z0-9:]+$");
     }
 
+    @Override
+    public void close() throws IOException {
+        client.close();
+    }
+
     /**
      * URIs used for accessing wikibase.
      */
diff --git 
a/tools/src/test/java/org/wikidata/query/rdf/tool/AbstractUpdaterIntegrationTestBase.java
 
b/tools/src/test/java/org/wikidata/query/rdf/tool/AbstractUpdaterIntegrationTestBase.java
index 22bf8eb..7851a48 100644
--- 
a/tools/src/test/java/org/wikidata/query/rdf/tool/AbstractUpdaterIntegrationTestBase.java
+++ 
b/tools/src/test/java/org/wikidata/query/rdf/tool/AbstractUpdaterIntegrationTestBase.java
@@ -1,5 +1,7 @@
 package org.wikidata.query.rdf.tool;
 
+import static org.wikidata.query.rdf.test.CloseableRule.autoClose;
+
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -8,6 +10,7 @@
 import org.junit.Rule;
 import org.junit.runner.RunWith;
 import org.wikidata.query.rdf.common.uri.WikibaseUris;
+import org.wikidata.query.rdf.test.CloseableRule;
 import org.wikidata.query.rdf.tool.change.Change;
 import org.wikidata.query.rdf.tool.change.IdRangeChangeSource;
 import org.wikidata.query.rdf.tool.rdf.Munger;
@@ -24,7 +27,8 @@
     /**
      * Wikibase test against.
      */
-    private final WikibaseRepository wikibaseRepository = new 
WikibaseRepository("https", "www.wikidata.org");
+    @Rule
+    public final CloseableRule<WikibaseRepository> wikibaseRepository = 
autoClose(new WikibaseRepository("https", "www.wikidata.org"));
     /**
      * Munger to test against.
      */
@@ -42,10 +46,9 @@
      */
     public void update(int from, int to) {
         Change.Source<?> source = IdRangeChangeSource.forItems(from, to, 30);
-        ExecutorService executorService = new ThreadPoolExecutor(0, 10, 0, 
TimeUnit.SECONDS,
-                new LinkedBlockingQueue<Runnable>());
+        ExecutorService executorService = new ThreadPoolExecutor(0, 10, 0, 
TimeUnit.SECONDS, new LinkedBlockingQueue<>());
         WikibaseUris uris = new WikibaseUris("www.wikidata.org");
-        try (Updater<?> updater = new Updater<>(source, wikibaseRepository, 
rdfRepository, munger, executorService, 0, uris, false)) {
+        try (Updater<?> updater = new Updater<>(source, 
wikibaseRepository.get(), rdfRepository, munger, executorService, 0, uris, 
false)) {
             updater.run();
         }
     }
diff --git 
a/tools/src/test/java/org/wikidata/query/rdf/tool/RdfRepositoryForTesting.java 
b/tools/src/test/java/org/wikidata/query/rdf/tool/RdfRepositoryForTesting.java
index 731942e..ab98668 100644
--- 
a/tools/src/test/java/org/wikidata/query/rdf/tool/RdfRepositoryForTesting.java
+++ 
b/tools/src/test/java/org/wikidata/query/rdf/tool/RdfRepositoryForTesting.java
@@ -84,6 +84,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public Statement apply(final Statement base, Description description) {
         return new Statement() {
             @Override
diff --git 
a/tools/src/test/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepositoryIntegrationTest.java
 
b/tools/src/test/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepositoryIntegrationTest.java
index bf4c887..85ff47e 100644
--- 
a/tools/src/test/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepositoryIntegrationTest.java
+++ 
b/tools/src/test/java/org/wikidata/query/rdf/tool/wikibase/WikibaseRepositoryIntegrationTest.java
@@ -8,8 +8,10 @@
 import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.isA;
 import static org.hamcrest.Matchers.not;
+import static org.wikidata.query.rdf.test.CloseableRule.autoClose;
 import static 
org.wikidata.query.rdf.tool.wikibase.WikibaseRepository.inputDateFormat;
 
+import java.io.IOException;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.Collection;
@@ -21,9 +23,11 @@
 import org.apache.commons.lang3.time.DateUtils;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
+import org.junit.Rule;
 import org.junit.Test;
 import org.openrdf.model.Statement;
 import org.wikidata.query.rdf.common.uri.WikibaseUris;
+import org.wikidata.query.rdf.test.CloseableRule;
 import org.wikidata.query.rdf.tool.change.Change;
 import org.wikidata.query.rdf.tool.exception.ContainedException;
 import org.wikidata.query.rdf.tool.exception.RetryableException;
@@ -36,8 +40,9 @@
  */
 public class WikibaseRepositoryIntegrationTest extends RandomizedTest {
     private static final String HOST = "test.wikidata.org";
-    private final WikibaseRepository repo = new WikibaseRepository("https", 
HOST);
-    private final WikibaseRepository proxyRepo = new 
WikibaseRepository("http", "localhost", 8812);
+    @Rule
+    public final CloseableRule<WikibaseRepository> repo = autoClose(new 
WikibaseRepository("https", HOST));
+    private final CloseableRule<WikibaseRepository> proxyRepo = autoClose(new 
WikibaseRepository("http", "localhost", 8812));
     private final WikibaseUris uris = new WikibaseUris(HOST);
 
     @Test
@@ -48,7 +53,7 @@
          * is probably ok.
          */
         int batchSize = randomIntBetween(3, 30);
-        JSONObject changes = repo.fetchRecentChanges(new 
Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)),
+        JSONObject changes = repo.get().fetchRecentChanges(new 
Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)),
                 null, batchSize);
         Map<String, Object> c = changes;
         assertThat(c, hasKey("continue"));
@@ -65,8 +70,8 @@
             assertThat(rc, hasEntry(equalTo("timestamp"), 
instanceOf(String.class)));
             assertThat(rc, hasEntry(equalTo("revid"), instanceOf(Long.class)));
         }
-        final Date nextDate = repo.getChangeFromContinue((Map<String, 
Object>)changes.get("continue")).timestamp();
-        changes = repo.fetchRecentChanges(nextDate, null, batchSize);
+        final Date nextDate = repo.get().getChangeFromContinue((Map<String, 
Object>)changes.get("continue")).timestamp();
+        changes = repo.get().fetchRecentChanges(nextDate, null, batchSize);
         assertThat(c, hasKey("query"));
         assertThat((Map<String, Object>) c.get("query"), 
hasKey("recentchanges"));
     }
@@ -78,7 +83,7 @@
          * This relies on there being very few changes in the current
          * second.
          */
-        JSONObject changes = repo.fetchRecentChanges(new 
Date(System.currentTimeMillis()), null, 500);
+        JSONObject changes = repo.get().fetchRecentChanges(new 
Date(System.currentTimeMillis()), null, 500);
         Map<String, Object> c = changes;
         assertThat(c, not(hasKey("continue")));
         assertThat(c, hasKey("query"));
@@ -103,7 +108,7 @@
         } catch (InterruptedException e) {
             // nothing to do here, sorry. I know it looks bad.
         }
-        JSONObject result = repo.fetchRecentChanges(date, null, batchSize);
+        JSONObject result = repo.get().fetchRecentChanges(date, null, 
batchSize);
         return (JSONArray) ((JSONObject) 
result.get("query")).get("recentchanges");
     }
 
@@ -111,8 +116,8 @@
     private void editShowsUpInRecentChangesTestCase(String label, String type) 
throws RetryableException,
             ContainedException {
         long now = System.currentTimeMillis();
-        String entityId = repo.firstEntityIdForLabelStartingWith(label, "en", 
type);
-        repo.setLabel(entityId, type, label + now, "en");
+        String entityId = repo.get().firstEntityIdForLabelStartingWith(label, 
"en", type);
+        repo.get().setLabel(entityId, type, label + now, "en");
         JSONArray changes = getRecentChanges(new Date(now - 10000), 10);
         boolean found = false;
         String title = entityId;
@@ -129,7 +134,7 @@
             }
         }
         assertTrue("Didn't find new page in recent changes", found);
-        Collection<Statement> statements = repo.fetchRdfForEntity(entityId);
+        Collection<Statement> statements = 
repo.get().fetchRdfForEntity(entityId);
         found = false;
         for (Statement statement : statements) {
             if (statement.getSubject().stringValue().equals(uris.entity() + 
entityId)) {
@@ -141,37 +146,38 @@
     }
 
     @Test
-    public void fetchIsNormalized() throws RetryableException, 
ContainedException {
+    public void fetchIsNormalized() throws RetryableException, 
ContainedException, IOException {
         long now = System.currentTimeMillis();
-        WikibaseRepository proxyRepo = new WikibaseRepository("http", 
"localhost", 8812);
-        String entityId = 
repo.firstEntityIdForLabelStartingWith("QueryTestItem", "en", "item");
-        repo.setLabel(entityId, "item", "QueryTestItem" + now, "en");
-        Collection<Statement> statements = 
proxyRepo.fetchRdfForEntity(entityId);
-        boolean foundBad = false;
-        boolean foundGood = false;
-        for (Statement statement : statements) {
-            if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology-beta#";))
 {
-                foundBad = true;
+        try (WikibaseRepository proxyRepo = new WikibaseRepository("http", 
"localhost", 8812)) {
+            String entityId = 
repo.get().firstEntityIdForLabelStartingWith("QueryTestItem", "en", "item");
+            repo.get().setLabel(entityId, "item", "QueryTestItem" + now, "en");
+            Collection<Statement> statements = 
proxyRepo.fetchRdfForEntity(entityId);
+            boolean foundBad = false;
+            boolean foundGood = false;
+            for (Statement statement : statements) {
+                if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology-beta#";))
 {
+                    foundBad = true;
+                }
+                if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology-0.0.1#";))
 {
+                    foundBad = true;
+                }
+                if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology#";))
 {
+                    foundBad = true;
+                }
+                if 
(statement.getObject().stringValue().contains("http://wikiba.se/ontology#";)) {
+                    foundGood = true;
+                }
             }
-            if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology-0.0.1#";))
 {
-                foundBad = true;
-            }
-            if 
(statement.getObject().stringValue().contains("http://www.wikidata.org/ontology#";))
 {
-                foundBad = true;
-            }
-            if 
(statement.getObject().stringValue().contains("http://wikiba.se/ontology#";)) {
-                foundGood = true;
-            }
+            assertTrue("Did not find correct ontology statements", foundGood);
+            assertFalse("Found incorrect ontology statements", foundBad);
         }
-        assertTrue("Did not find correct ontology statements", foundGood);
-        assertFalse("Found incorrect ontology statements", foundBad);
     }
 
     @Test
     public void continueWorks() throws RetryableException, ContainedException, 
ParseException, InterruptedException {
         long now = System.currentTimeMillis();
-        String entityId = 
repo.firstEntityIdForLabelStartingWith("QueryTestItem", "en", "item");
-        repo.setLabel(entityId, "item", "QueryTestItem" + now, "en");
+        String entityId = 
repo.get().firstEntityIdForLabelStartingWith("QueryTestItem", "en", "item");
+        repo.get().setLabel(entityId, "item", "QueryTestItem" + now, "en");
         JSONArray changes = getRecentChanges(new Date(now - 10000), 10);
         Change change = null;
         long oldRevid = 0;
@@ -192,7 +198,7 @@
         // Ensure this change is in different second
         Thread.sleep(1000);
         // make new edit now
-        repo.setLabel(entityId, "item", "QueryTestItem" + now + "updated", 
"en");
+        repo.get().setLabel(entityId, "item", "QueryTestItem" + now + 
"updated", "en");
         changes = getRecentChanges(DateUtils.addSeconds(change.timestamp(), 
1), 10);
         // check that new result does not contain old edit but contains new 
edit
         boolean found = false;
@@ -210,7 +216,7 @@
     @Test
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public void recentChangesWithErrors() throws RetryableException, 
ContainedException {
-        JSONObject changes = proxyRepo.fetchRecentChanges(new 
Date(System.currentTimeMillis()), null, 500);
+        JSONObject changes = proxyRepo.get().fetchRecentChanges(new 
Date(System.currentTimeMillis()), null, 500);
         Map<String, Object> c = changes;
         assertThat(c, not(hasKey("continue")));
         assertThat(c, hasKey("query"));

-- 
To view, visit https://gerrit.wikimedia.org/r/401705
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I882d886382fe73630cfc5d4f372de809e4ddeb29
Gerrit-PatchSet: 4
Gerrit-Project: wikidata/query/rdf
Gerrit-Branch: master
Gerrit-Owner: Gehel <guillaume.leder...@wikimedia.org>
Gerrit-Reviewer: Lucas Werkmeister (WMDE) <lucas.werkmeis...@wikimedia.de>
Gerrit-Reviewer: Smalyshev <smalys...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to