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/guice:guice-servlet',
|
||||||
'//lib/jgit:jgit',
|
'//lib/jgit:jgit',
|
||||||
'//lib/jgit:junit',
|
'//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'],
|
visibility = ['PUBLIC'],
|
||||||
)
|
)
|
||||||
@@ -188,15 +198,16 @@ java_test(
|
|||||||
'//gerrit-reviewdb:server',
|
'//gerrit-reviewdb:server',
|
||||||
'//gerrit-server/src/main/prolog:common',
|
'//gerrit-server/src/main/prolog:common',
|
||||||
'//lib:args4j',
|
'//lib:args4j',
|
||||||
'//lib:easymock',
|
|
||||||
'//lib:guava',
|
'//lib:guava',
|
||||||
'//lib:gwtorm',
|
'//lib:gwtorm',
|
||||||
'//lib:junit',
|
'//lib:junit',
|
||||||
'//lib/guice:guice',
|
'//lib/guice:guice',
|
||||||
|
'//lib/guice:guice-assistedinject',
|
||||||
'//lib/jgit:jgit',
|
'//lib/jgit:jgit',
|
||||||
'//lib/jgit:junit',
|
'//lib/jgit:junit',
|
||||||
'//lib/joda:joda-time',
|
'//lib/joda:joda-time',
|
||||||
'//lib/prolog:prolog-cafe',
|
'//lib/prolog:prolog-cafe',
|
||||||
],
|
],
|
||||||
source_under_test = [':server'],
|
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,
|
attach_source = False,
|
||||||
visibility = ['//lib/jgit:jgit-archive'],
|
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-patch-jgit:jgit_patch_tests',
|
||||||
'//gerrit-plugin-gwtui:gwtui-api',
|
'//gerrit-plugin-gwtui:gwtui-api',
|
||||||
'//gerrit-server:server__compile',
|
'//gerrit-server:server__compile',
|
||||||
|
'//gerrit-server:server_tests',
|
||||||
'//lib/asciidoctor:asciidoc_lib',
|
'//lib/asciidoctor:asciidoc_lib',
|
||||||
'//lib/asciidoctor:doc_indexer_lib',
|
'//lib/asciidoctor:doc_indexer_lib',
|
||||||
'//lib/jetty:webapp',
|
'//lib/jetty:webapp',
|
||||||
|
Reference in New Issue
Block a user