Add test infrastructure for tests that use logging and mocking
Change-Id: I5a38a5fd3256ca05e91d234c2bec7d18c06a75a2
This commit is contained in:
		
				
					committed by
					
						
						David Pursehouse
					
				
			
			
				
	
			
			
			
						parent
						
							d1b1a8801b
						
					
				
				
					commit
					e362959d05
				
			@@ -101,6 +101,16 @@ java_library(
 | 
			
		||||
    '//lib/guice:guice-servlet',
 | 
			
		||||
    '//lib/jgit:jgit',
 | 
			
		||||
    '//lib/jgit:junit',
 | 
			
		||||
    '//lib/log:impl_log4j',
 | 
			
		||||
    '//lib/log:log4j',
 | 
			
		||||
  ],
 | 
			
		||||
  exported_deps = [
 | 
			
		||||
    '//lib:easymock',
 | 
			
		||||
    '//lib:powermock-api-easymock',
 | 
			
		||||
    '//lib:powermock-api-support',
 | 
			
		||||
    '//lib:powermock-core',
 | 
			
		||||
    '//lib:powermock-module-junit4',
 | 
			
		||||
    '//lib:powermock-module-junit4-common',
 | 
			
		||||
  ],
 | 
			
		||||
  visibility = ['PUBLIC'],
 | 
			
		||||
)
 | 
			
		||||
@@ -188,15 +198,16 @@ java_test(
 | 
			
		||||
    '//gerrit-reviewdb:server',
 | 
			
		||||
    '//gerrit-server/src/main/prolog:common',
 | 
			
		||||
    '//lib:args4j',
 | 
			
		||||
    '//lib:easymock',
 | 
			
		||||
    '//lib:guava',
 | 
			
		||||
    '//lib:gwtorm',
 | 
			
		||||
    '//lib:junit',
 | 
			
		||||
    '//lib/guice:guice',
 | 
			
		||||
    '//lib/guice:guice-assistedinject',
 | 
			
		||||
    '//lib/jgit:jgit',
 | 
			
		||||
    '//lib/jgit:junit',
 | 
			
		||||
    '//lib/joda:joda-time',
 | 
			
		||||
    '//lib/prolog:prolog-cafe',
 | 
			
		||||
  ],
 | 
			
		||||
  source_under_test = [':server'],
 | 
			
		||||
  visibility = ['//tools/eclipse:classpath'],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								lib/BUCK
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								lib/BUCK
									
									
									
									
									
								
							@@ -258,3 +258,80 @@ maven_jar(
 | 
			
		||||
  attach_source = False,
 | 
			
		||||
  visibility = ['//lib/jgit:jgit-archive'],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ java_library(
 | 
			
		||||
    '//gerrit-patch-jgit:jgit_patch_tests',
 | 
			
		||||
    '//gerrit-plugin-gwtui:gwtui-api',
 | 
			
		||||
    '//gerrit-server:server__compile',
 | 
			
		||||
    '//gerrit-server:server_tests',
 | 
			
		||||
    '//lib/asciidoctor:asciidoc_lib',
 | 
			
		||||
    '//lib/asciidoctor:doc_indexer_lib',
 | 
			
		||||
    '//lib/jetty:webapp',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user