QChris has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/70050


Change subject: Add test infrastructure for tests that use logging and mocking
......................................................................

Add test infrastructure for tests that use logging and mocking

Change-Id: I5a38a5fd3256ca05e91d234c2bec7d18c06a75a2
---
M gerrit-server/BUCK
A 
gerrit-server/src/test/java/com/google/gerrit/testutil/FilesystemLoggingMockingTestCase.java
A 
gerrit-server/src/test/java/com/google/gerrit/testutil/LoggingMockingTestCase.java
A gerrit-server/src/test/java/com/google/gerrit/testutil/MockingTestCase.java
A 
gerrit-server/src/test/java/com/google/gerrit/testutil/PassThroughKeyUtilEncoder.java
A gerrit-server/src/test/java/com/google/gerrit/testutil/SetMatcher.java
A 
gerrit-server/src/test/java/com/google/gerrit/testutil/log/CollectionAppender.java
A gerrit-server/src/test/java/com/google/gerrit/testutil/log/LogUtil.java
M lib/BUCK
M lib/log/BUCK
M tools/eclipse/BUCK
11 files changed, 786 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/gerrit refs/changes/50/70050/1

diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK
index 95f5b11..1d7f925 100644
--- a/gerrit-server/BUCK
+++ b/gerrit-server/BUCK
@@ -84,11 +84,20 @@
     '//lib:gwtorm',
     '//lib:h2',
     '//lib:junit',
+    '//lib:powermock-api-easymock',
+    '//lib:powermock-api-support',
+    '//lib:powermock-core',
+    '//lib:powermock-module-junit4',
+    '//lib:powermock-module-junit4-common',
     '//lib/antlr:java_runtime',
     '//lib/guice:guice',
+    '//lib/guice:guice-assistedinject',
     '//lib/jgit:jgit',
     '//lib/jgit:junit',
+    '//lib/log:impl_log4j',
+    '//lib/log:log4j',
     '//lib/prolog:prolog-cafe',
   ],
   source_under_test = [':server'],
+  visibility = ['//tools/eclipse:classpath'],
 )
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/FilesystemLoggingMockingTestCase.java
 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/FilesystemLoggingMockingTestCase.java
new file mode 100644
index 0000000..0ccdae7
--- /dev/null
+++ 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/FilesystemLoggingMockingTestCase.java
@@ -0,0 +1,177 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+import org.eclipse.jgit.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+public abstract class FilesystemLoggingMockingTestCase extends 
LoggingMockingTestCase {
+
+  private Collection<File> toCleanup = Lists.newArrayList();
+
+  /**
+   * Asserts that a given file exists.
+   *
+   * @param file The file to test.
+   */
+  protected void assertExists(File file) {
+    assertTrue("File '" + file.getAbsolutePath() + "' does not exist",
+        file.exists());
+  }
+
+  /**
+   * Asserts that a given file does not exist.
+   *
+   * @param file The file to test.
+   */
+  protected void assertDoesNotExist(File file) {
+    assertFalse("File '" + file.getAbsolutePath() + "' exists", file.exists());
+  }
+
+  /**
+   * Asserts that a given file exists and is a directory.
+   *
+   * @param file The file to test.
+   */
+  protected void assertDirectory(File file) {
+    // Although isDirectory includes checking for existence, we nevertheless
+    // explicitly check for existence, to get more appropriate error messages
+    assertExists(file);
+    assertTrue("File '" + file.getAbsolutePath() + "' is not a directory",
+        file.isDirectory());
+  }
+
+  /**
+   * Asserts that creating a directory from the given file worked
+   *
+   * @param file The directory to create
+   */
+  protected void assertMkdirs(File file) {
+    assertTrue("Could not create directory '" + file.getAbsolutePath() + "'",
+        file.mkdirs());
+  }
+
+  /**
+   * Asserts that creating a directory from the specified file worked
+   *
+   * @param parent The parent of the directory to create
+   * @param name The name of the directoryto create (relative to {@code parent}
+   * @return The created directory
+   */
+  protected File assertMkdirs(File parent, String name) {
+    File file = new File(parent, name);
+    assertMkdirs(file);
+    return file;
+  }
+
+  /**
+   * Asserts that creating a file worked
+   *
+   * @param file The file to create
+   */
+  protected void assertCreateFile(File file) throws IOException {
+    assertTrue("Could not create file '" + file.getAbsolutePath() + "'",
+        file.createNewFile());
+  }
+
+  /**
+   * Asserts that creating a file worked
+   *
+   * @param parent The parent of the file to create
+   * @param name The name of the file to create (relative to {@code parent}
+   * @return The created file
+   */
+  protected File assertCreateFile(File parent, String name) throws IOException 
{
+    File file = new File(parent, name);
+    assertCreateFile(file);
+    return file;
+  }
+
+  /**
+   * Creates a file in the system's default folder for temporary files.
+   *
+   * The file/directory automatically gets removed during tearDown.
+   *
+   * The name of the created file begins with 'gerrit_test_', and is located
+   * in the system's default folder for temporary files.
+   *
+   * @param suffix Trailing part of the file name.
+   * @return The temporary file.
+   * @throws IOException If a file could not be created.
+   */
+  private File createTempFile(String suffix) throws IOException {
+    String prefix ="gerrit_test_";
+    if (!Strings.isNullOrEmpty(getName())) {
+      prefix += getName() + "_";
+    }
+    File tmp = File.createTempFile(prefix, suffix);
+    toCleanup.add(tmp);
+    return tmp;
+  }
+
+  /**
+   * Creates a file in the system's default folder for temporary files.
+   *
+   * The file/directory automatically gets removed during tearDown.
+   *
+   * The name of the created file begins with 'gerrit_test_', and is located
+   * in the system's default folder for temporary files.
+   *
+   * @return The temporary file.
+   * @throws IOException If a file could not be created.
+   */
+  protected File createTempFile() throws IOException {
+    return createTempFile("");
+  }
+
+  /**
+   * Creates a directory in the system's default folder for temporary files.
+   *
+   * The directory (and all it's contained files/directory) automatically get
+   * removed during tearDown.
+   *
+   * The name of the created directory begins with 'gerrit_test_', and is be
+   * located in the system's default folder for temporary files.
+   *
+   * @return The temporary directory.
+   * @throws IOException If a file could not be created.
+   */
+  protected File createTempDir() throws IOException {
+    File tmp = createTempFile(".dir");
+    if (!tmp.delete()) {
+      throw new IOException("Cannot delete temporary file '" + tmp.getPath()
+          + "'");
+    }
+    tmp.mkdir();
+    return tmp;
+  }
+
+  private void cleanupCreatedFiles() throws IOException {
+    for (File file : toCleanup) {
+      FileUtils.delete(file,  FileUtils.RECURSIVE);
+    }
+  }
+
+  public void tearDown() throws Exception {
+    cleanupCreatedFiles();
+    super.tearDown();
+  }
+}
\ No newline at end of file
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/LoggingMockingTestCase.java
 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/LoggingMockingTestCase.java
new file mode 100644
index 0000000..218fa0a
--- /dev/null
+++ 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/LoggingMockingTestCase.java
@@ -0,0 +1,134 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil;
+
+import com.google.common.collect.Lists;
+import com.google.gerrit.testutil.log.LogUtil;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+
+import java.util.Iterator;
+
+/**
+ * Testcase capturing associated logs and allowing to assert on them.
+ *
+ * For a test case SomeNameTest, the log for SomeName gets captured. Assertions
+ * on logs run against the coptured log events from this logger. After the
+ * tests, the logger are set back to their original settings.
+ */
+public abstract class LoggingMockingTestCase extends MockingTestCase {
+  private String loggerName;
+  private LogUtil.LoggerSettings loggerSettings;
+  private java.util.Collection<LoggingEvent> loggedEvents;
+
+  /**
+   * Assert a logged event with a given string.
+   * <p>
+   * If such a event is found, it is removed from the captured logs.
+   *
+   * @param needle The string to look for.
+   */
+  protected final void assertLogMessageContains(String needle) {
+    LoggingEvent hit = null;
+    Iterator<LoggingEvent> iter = loggedEvents.iterator();
+    while (hit == null && iter.hasNext()) {
+      LoggingEvent event = iter.next();
+      if (event.getRenderedMessage().contains(needle)) {
+        hit = event;
+      }
+    }
+    assertNotNull("Could not find log message containing '" + needle + "'",
+        hit);
+    assertTrue("Could not remove log message containing '" + needle + "'",
+        loggedEvents.remove(hit));
+  }
+
+  /**
+   * Assert a logged event whose throwable contains a given string
+   * <p>
+   * If such a event is found, it is removed from the captured logs.
+   *
+   * @param needle The string to look for.
+   */
+  protected final void assertLogThrowableMessageContains(String needle) {
+    LoggingEvent hit = null;
+    Iterator<LoggingEvent> iter = loggedEvents.iterator();
+    while (hit == null && iter.hasNext()) {
+      LoggingEvent event = iter.next();
+      if (event.getThrowableInformation().getThrowable().toString()
+          .contains(needle)) {
+        hit = event;
+      }
+    }
+    assertNotNull("Could not find log message with a Throwable containing '"
+        + needle + "'", hit);
+    assertTrue("Could not remove log message with a Throwable containing '"
+        + needle + "'", loggedEvents.remove(hit));
+  }
+
+  /**
+   * Assert that all logged events have been asserted
+   */
+  // As the PowerMock runner does not pass through runTest, we inject log
+  // verification through @After
+  @After
+  public final void assertNoUnassertedLogEvents() {
+    if (loggedEvents.size() > 0) {
+      LoggingEvent event = loggedEvents.iterator().next();
+      String msg = "Found untreated logged events. First one is:\n";
+      msg += event.getRenderedMessage();
+      if (event.getThrowableInformation() != null) {
+        msg += "\n" + event.getThrowableInformation().getThrowable();
+      }
+      fail(msg);
+    }
+  }
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    loggedEvents = Lists.newArrayList();
+
+    // The logger we're interested is class name without the trailing "Test".
+    // While this is not the most general approach it is sufficient for now,
+    // and we can improve later to allow tests to specify which loggers are
+    // to check.
+    loggerName = this.getClass().getCanonicalName();
+    loggerName = loggerName.substring(0, loggerName.length()-4);
+    loggerSettings = LogUtil.logToCollection(loggerName, loggedEvents);
+  }
+
+  @Override
+  protected void runTest() throws Throwable {
+    super.runTest();
+    // Plain JUnit runner does not pick up @After, so we add it here
+    // explicitly. Note, that we cannot put this into tearDown, as failure
+    // to verify mocks would bail out and might leave open resources from
+    // subclasses open.
+    assertNoUnassertedLogEvents();
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    if (loggerName != null && loggerSettings != null) {
+      Logger logger = LogManager.getLogger(loggerName);
+      loggerSettings.pushOntoLogger(logger);
+    }
+    super.tearDown();
+  }
+}
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/MockingTestCase.java 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/MockingTestCase.java
new file mode 100644
index 0000000..f0c7ce1
--- /dev/null
+++ 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/MockingTestCase.java
@@ -0,0 +1,155 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.After;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Test case with some support for automatically verifying mocks.
+ *
+ * This test case works transparently with EasyMock and PowerMock.
+ */
+public abstract class MockingTestCase extends TestCase {
+  private Collection<Object> mocks;
+  private Collection<IMocksControl> mockControls;
+  private boolean mocksReplayed;
+  private boolean usePowerMock;
+
+  /**
+   * Create and register a mock control.
+   *
+   * @return The mock control instance.
+   */
+  protected final IMocksControl createMockControl() {
+    IMocksControl mockControl = EasyMock.createControl();
+    assertTrue("Adding mock control failed", mockControls.add(mockControl));
+    return mockControl;
+  }
+
+  /**
+   * Create and register a mock.
+   *
+   * Creates a mock and registers it in the list of created mocks, so it gets
+   * treated automatically upon {@code replay} and {@code verify};
+   * @param toMock The class to create a mock for.
+   * @return The mock instance.
+   */
+  protected final <T> T createMock(Class<T> toMock) {
+    return createMock(toMock, null);
+  }
+
+  /**
+   * Create a mock for a mock control and register a mock.
+   *
+   * Creates a mock and registers it in the list of created mocks, so it gets
+   * treated automatically upon {@code replay} and {@code verify};
+   * @param toMock The class to create a mock for.
+   * @param control The mock control to create the mock on. If null, do not use
+   *    a specific control.
+   * @return The mock instance.
+   */
+  protected final <T> T createMock(Class<T> toMock, IMocksControl control) {
+    assertFalse("Mocks have already been set to replay", mocksReplayed);
+    final T mock;
+    if (control == null) {
+      if (usePowerMock) {
+        mock = PowerMock.createMock(toMock);
+      } else {
+        mock = EasyMock.createMock(toMock);
+      }
+      assertTrue("Adding " + toMock.getName() + " mock failed",
+          mocks.add(mock));
+    } else {
+      mock = control.createMock(toMock);
+    }
+    return mock;
+  }
+
+  /**
+   * Set all registered mocks to replay
+   */
+  protected final void replayMocks() {
+    assertFalse("Mocks have already been set to replay", mocksReplayed);
+    if (usePowerMock) {
+      PowerMock.replayAll();
+    } else {
+      EasyMock.replay(mocks.toArray());
+    }
+    for (IMocksControl mockControl : mockControls) {
+      mockControl.replay();
+    }
+    mocksReplayed = true;
+  }
+
+  /**
+   * Verify all registered mocks
+   *
+   * This method is called automatically at the end of a test. Nevertheless,
+   * it is safe to also call it beforehand, if this better meets the
+   * verification part of a test.
+   */
+  // As the PowerMock runner does not pass through runTest, we inject mock
+  // verification through @After
+  @After
+  public final void verifyMocks() {
+    if (!mocks.isEmpty() || !mockControls.isEmpty()) {
+      assertTrue("Created mocks have not been set to replay. Call replayMocks "
+          + "within the test", mocksReplayed);
+      if (usePowerMock) {
+        PowerMock.verifyAll();
+      } else {
+        EasyMock.verify(mocks.toArray());
+      }
+      for (IMocksControl mockControl : mockControls) {
+        mockControl.verify();
+      }
+    }
+  }
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+
+    usePowerMock = false;
+    RunWith runWith = this.getClass().getAnnotation(RunWith.class);
+    if (runWith != null) {
+      usePowerMock = PowerMockRunner.class.isAssignableFrom(runWith.value());
+    }
+
+    mocks = new ArrayList<Object>();
+    mockControls = new ArrayList<IMocksControl>();
+    mocksReplayed = false;
+  }
+
+  @Override
+  protected void runTest() throws Throwable {
+    super.runTest();
+    // Plain JUnit runner does not pick up @After, so we add it here
+    // explicitly. Note, that we cannot put this into tearDown, as failure
+    // to verify mocks would bail out and might leave open resources from
+    // subclasses open.
+    verifyMocks();
+  }
+}
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/PassThroughKeyUtilEncoder.java
 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/PassThroughKeyUtilEncoder.java
new file mode 100644
index 0000000..e008b78
--- /dev/null
+++ 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/PassThroughKeyUtilEncoder.java
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil;
+
+import com.google.gwtorm.client.KeyUtil.Encoder;
+
+public class PassThroughKeyUtilEncoder extends Encoder {
+  @Override
+  public String encode(String e) {
+    return e;
+  }
+
+  @Override
+  public String decode(String e) {
+    return e;
+  }
+}
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/SetMatcher.java 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/SetMatcher.java
new file mode 100644
index 0000000..2e6b68e
--- /dev/null
+++ b/gerrit-server/src/test/java/com/google/gerrit/testutil/SetMatcher.java
@@ -0,0 +1,55 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil;
+
+import com.google.common.collect.Sets;
+
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+
+import java.util.Set;
+
+/**
+ * Match for Iterables via set equals
+ *
+ * Converts both expected and actual parameter to a set and compares those two
+ * sets via equals to determine whether or not they match.
+ */
+public class SetMatcher<T> implements IArgumentMatcher {
+  public static <S extends Iterable<T>,T> S setEq(S expected) {
+    EasyMock.reportMatcher(new SetMatcher<T>(expected));
+    return null;
+  }
+
+  Set<T> expected;
+
+  public SetMatcher(Iterable<T> expected) {
+    this.expected = Sets.newHashSet(expected);
+  }
+
+  @Override
+  public boolean matches(Object actual) {
+    if (actual instanceof Iterable<?>) {
+      Set<?> actualSet = Sets.newHashSet((Iterable<?>)actual);
+      return expected.equals(actualSet);
+    }
+    return false;
+  }
+
+  @Override
+  public void appendTo(StringBuffer buffer) {
+    buffer.append(expected);
+  }
+}
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/log/CollectionAppender.java
 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/log/CollectionAppender.java
new file mode 100644
index 0000000..43179e3
--- /dev/null
+++ 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/log/CollectionAppender.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil.log;
+
+import com.google.common.collect.Lists;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Log4j appender that logs into a list
+ */
+public class CollectionAppender extends AppenderSkeleton {
+  private Collection<LoggingEvent> events;
+
+  public CollectionAppender() {
+    events = new LinkedList<LoggingEvent>();
+  }
+
+  public CollectionAppender(Collection<LoggingEvent> events) {
+    this.events = events;
+  }
+
+  @Override
+  public boolean requiresLayout() {
+    return false;
+  }
+
+  @Override
+  protected void append(LoggingEvent event) {
+    if (! events.add(event)) {
+      throw new RuntimeException("Could not append event " + event);
+    }
+  }
+
+  @Override
+  public void close() {
+  }
+
+  public Collection<LoggingEvent> getLoggedEvents() {
+    return Lists.newLinkedList(events);
+  }
+}
diff --git 
a/gerrit-server/src/test/java/com/google/gerrit/testutil/log/LogUtil.java 
b/gerrit-server/src/test/java/com/google/gerrit/testutil/log/LogUtil.java
new file mode 100644
index 0000000..f8b73fb
--- /dev/null
+++ b/gerrit-server/src/test/java/com/google/gerrit/testutil/log/LogUtil.java
@@ -0,0 +1,88 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.google.gerrit.testutil.log;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+
+public class LogUtil {
+  /**
+   * Change logger's setting so it only logs to a collection.
+   *
+   * @param logName Name of the logger to modify.
+   * @param collection The collection to log into.
+   * @return The logger's original settings.
+   */
+  public static LoggerSettings logToCollection(String logName,
+      Collection<LoggingEvent> collection) {
+    Logger logger = LogManager.getLogger(logName);
+    LoggerSettings loggerSettings = new LoggerSettings(logger);
+    logger.removeAllAppenders();
+    logger.setAdditivity(false);
+    CollectionAppender listAppender = new CollectionAppender(collection);
+    logger.addAppender(listAppender);
+    return loggerSettings;
+  }
+
+  /**
+   * Capsule for a logger's settings that get mangled by rerouting logging to 
a collection
+   */
+  public static class LoggerSettings {
+    private final boolean additive;
+    private final List<Appender> appenders;
+
+    /**
+     * Read off logger settings from an instance.
+     *
+     * @param logger The logger to read the settings off from.
+     */
+    private LoggerSettings(Logger logger) {
+      this.additive = logger.getAdditivity();
+
+      Enumeration<?> appenders = logger.getAllAppenders();
+      this.appenders = new ArrayList<Appender>();
+      while (appenders.hasMoreElements()) {
+        Object appender = appenders.nextElement();
+        if (appender instanceof Appender) {
+          this.appenders.add((Appender)appender);
+        } else {
+          throw new RuntimeException("getAllAppenders of " + logger
+              + " contained an object that is not an Appender");
+        }
+      }
+    }
+
+    /**
+     * Pushes this settings back onto a logger.
+     *
+     * @param logger the logger on which to push the settings.
+     */
+    public void pushOntoLogger(Logger logger) {
+      logger.setAdditivity(additive);
+
+      logger.removeAllAppenders();
+      for (Appender appender : appenders) {
+        logger.addAppender(appender);
+      }
+    }
+  }
+}
diff --git a/lib/BUCK b/lib/BUCK
index 5f55f70..8712078 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -270,3 +270,79 @@
     'META-INF/NOTICE.txt',
   ],
 )
+
+maven_jar(
+  name = 'powermock-module-junit4',
+  id = 'org.powermock:powermock-module-junit4:1.5',
+  sha1 = '9f6f8d0485249171f9d870e2b269048fa8cad43b',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':junit',
+    ':powermock-module-junit4-common',
+  ],
+)
+
+maven_jar(
+  name = 'powermock-module-junit4-common',
+  id = 'org.powermock:powermock-module-junit4-common:1.5',
+  sha1 = '43db4720ff57af42a1bd5c73fb5cdfebeebd564c',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':junit',
+    ':powermock-reflect',
+  ],
+)
+
+maven_jar(
+  name = 'powermock-reflect',
+  id = 'org.powermock:powermock-reflect:1.5',
+  sha1 = '8df1548eeabb8492ba97d4f3eb84ae4d5f69215e',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':junit',
+    ':objenesis',
+  ],
+)
+
+maven_jar(
+  name = 'powermock-api-easymock',
+  id = 'org.powermock:powermock-api-easymock:1.5',
+  sha1 = 'a485b570b9debb46b53459a8e866a40343b2cfe2',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':easymock',
+    ':powermock-api-support',
+  ],
+)
+
+maven_jar(
+  name = 'powermock-api-support',
+  id = 'org.powermock:powermock-api-support:1.5',
+  sha1 = '7c1b2e4555cfa333aec201c4612345c092820a38',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':junit',
+    ':powermock-core',
+    ':powermock-reflect',
+  ],
+)
+
+maven_jar(
+  name = 'powermock-core',
+  id = 'org.powermock:powermock-core:1.5',
+  sha1 = '4415337ff3fdb7ceb484f11fd08e39711e408976',
+  license = 'DO_NOT_DISTRIBUTE',
+  deps = [
+    ':junit',
+    ':powermock-reflect',
+    ':javassist-3.17.1-GA',
+  ],
+)
+
+maven_jar(
+  name = 'javassist-3.17.1-GA',
+  # The GWT version is still at 3.16.1-GA, so those do not match
+  id = 'org.javassist:javassist:3.17.1-GA',
+  sha1 = '30c30512115866b6e0123f1913bc7735b9f76d08',
+  license = 'DO_NOT_DISTRIBUTE',
+)
diff --git a/lib/log/BUCK b/lib/log/BUCK
index 5b541c4..50380e3 100644
--- a/lib/log/BUCK
+++ b/lib/log/BUCK
@@ -2,15 +2,15 @@
 
 maven_jar(
   name = 'api',
-  id = 'org.slf4j:slf4j-api:1.6.1',
-  sha1 = '6f3b8a24bf970f17289b234284c94f43eb42f0e4',
+  id = 'org.slf4j:slf4j-api:1.6.2',
+  sha1 = '8619e95939167fb37245b5670135e4feb0ec7d50',
   license = 'slf4j',
 )
 
 maven_jar(
   name = 'impl_log4j',
-  id = 'org.slf4j:slf4j-log4j12:1.6.1',
-  sha1 = 'bd245d6746cdd4e6203e976e21d597a46f115802',
+  id = 'org.slf4j:slf4j-log4j12:1.6.2',
+  sha1 = '7dd950c7eeb3004a91720ba8782aa0ded9037110',
   license = 'slf4j',
   deps = [':log4j'],
 )
diff --git a/tools/eclipse/BUCK b/tools/eclipse/BUCK
index f2b51a9..cf987d8 100644
--- a/tools/eclipse/BUCK
+++ b/tools/eclipse/BUCK
@@ -34,6 +34,7 @@
     '//gerrit-httpd:httpd_tests',
     '//gerrit-main:main_lib',
     '//gerrit-server:server__compile',
+    '//gerrit-server:server_tests',
     '//lib/prolog:compiler_lib',
   ] + scan_plugins(),
 )

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5a38a5fd3256ca05e91d234c2bec7d18c06a75a2
Gerrit-PatchSet: 1
Gerrit-Project: gerrit
Gerrit-Branch: wmf
Gerrit-Owner: QChris <christ...@quelltextlich.at>

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

Reply via email to