Merge branch 'stable-2.12' into stable-2.13 * stable-2.12: Change copyright to AOSP Build with API version 2.11.7 Change-Id: Ie648d90c75376b41f4da8ec5836cf5258dcb9849
diff --git a/BUCK b/BUCK index b7fea48..7b55bc0 100644 --- a/BUCK +++ b/BUCK
@@ -1,5 +1,6 @@ include_defs('//bucklets/gerrit_plugin.bucklet') include_defs('//bucklets/java_sources.bucklet') +include_defs('//bucklets/maven_jar.bucklet') SOURCES = glob(['src/main/java/**/*.java']) RESOURCES = glob(['src/main/resources/**/*']) @@ -7,11 +8,9 @@ '//lib:gson', '//lib/commons:dbcp', ] -TEST_DEPS = GERRIT_PLUGIN_API + [ +TEST_DEPS = GERRIT_PLUGIN_API + DEPS + GERRIT_TESTS + [ ':events-log__plugin', - '//lib/easymock:easymock', - '//lib:gson', - '//lib:truth', + ':mockito', ] gerrit_plugin( @@ -30,7 +29,7 @@ java_library( name = 'classpath', - deps = list(set(DEPS) | set(TEST_DEPS)) + deps = TEST_DEPS, ) java_test( @@ -44,3 +43,30 @@ name = 'events-log-sources', srcs = SOURCES + RESOURCES, ) + +maven_jar( + name = 'mockito', + id = 'org.mockito:mockito-core:2.5.0', + sha1 = 'be28d46a52c7f2563580adeca350145e9ce916f8', + license = 'MIT', + deps = [ + ':byte-buddy', + ':objenesis', + ], +) + +maven_jar( + name = 'byte-buddy', + id = 'net.bytebuddy:byte-buddy:1.5.12', + sha1 = 'b1ba1d15f102b36ed43b826488114678d6d413da', + license = 'DO_NOT_DISTRIBUTE', + attach_source = False, +) + +maven_jar( + name = 'objenesis', + id = 'org.objenesis:objenesis:2.4', + sha1 = '2916b6c96b50c5b3ec4452ed99401db745aabb27', + license = 'DO_NOT_DISTRIBUTE', + attach_source = False, +)
diff --git a/lib/BUCK b/lib/BUCK index 190d931..06f7c02 100644 --- a/lib/BUCK +++ b/lib/BUCK
@@ -6,37 +6,3 @@ sha1 = 'ecb6e1f8e4b0e84c4b886c2f14a1500caf309757', license = 'Apache2.0', ) - -maven_jar( - name = 'guava', - id = 'com.google.guava:guava:19.0-rc1', - sha1 = '0364538ac107b8943a1f4d68ac50f1b0421bb983', - license = 'Apache2.0', -) - -maven_jar( - name = 'junit', - id = 'junit:junit:4.11', - sha1 = '4e031bb61df09069aeb2bffb4019e7a5034a4ee0', - license = 'DO_NOT_DISTRIBUTE', - exported_deps = [':hamcrest-core'], -) - -maven_jar( - name = 'hamcrest-core', - id = 'org.hamcrest:hamcrest-core:1.3', - sha1 = '42a25dc3219429f0e5d060061f71acb49bf010a0', - license = 'DO_NOT_DISTRIBUTE', - visibility = ['//lib:junit'], -) - -maven_jar( - name = 'truth', - id = 'com.google.truth:truth:0.27', - sha1 = 'bd17774d2dc0fffa884d42c07d2537e86c67acd6', - license = 'DO_NOT_DISTRIBUTE', - exported_deps = [ - ':guava', - ':junit', - ], -)
diff --git a/lib/easymock/BUCK b/lib/easymock/BUCK deleted file mode 100644 index 11d95a4..0000000 --- a/lib/easymock/BUCK +++ /dev/null
@@ -1,29 +0,0 @@ -include_defs('//bucklets/maven_jar.bucklet') - -maven_jar( - name = 'easymock', - id = 'org.easymock:easymock:3.3.1', - sha1 = 'a497d7f00c9af78b72b6d8f24762d9210309148a', - license = 'DO_NOT_DISTRIBUTE', - deps = [ - ':cglib-2_2', - ':objenesis', - ], -) - -maven_jar( - name = 'cglib-2_2', - id = 'cglib:cglib-nodep:2.2.2', - sha1 = '00d456bb230c70c0b95c76fb28e429d42f275941', - license = 'DO_NOT_DISTRIBUTE', - attach_source = False, -) - -maven_jar( - name = 'objenesis', - id = 'org.objenesis:objenesis:2.1', - sha1 = '87c0ea803b69252868d09308b4618f766f135a96', - license = 'DO_NOT_DISTRIBUTE', - visibility = ['//lib/powermock:powermock-reflect'], - attach_source = False, -)
diff --git a/lib/gerrit/BUCK b/lib/gerrit/BUCK index 0a0b2bc..f83d917 100644 --- a/lib/gerrit/BUCK +++ b/lib/gerrit/BUCK
@@ -1,12 +1,21 @@ include_defs('//bucklets/maven_jar.bucklet') -VER = '2.12' +VER = '2.13' REPO = MAVEN_CENTRAL maven_jar( + name = 'acceptance-framework', + id = 'com.google.gerrit:gerrit-acceptance-framework:' + VER, + sha1 = 'a6913a61196a8fccdb45e761f43a0b7e21867c90', + license = 'Apache2.0', + attach_source = False, + repository = REPO, +) + +maven_jar( name = 'plugin-api', id = 'com.google.gerrit:gerrit-plugin-api:' + VER, - sha1 = '8ce1f6e65078bbcf03a1758f96b3ebca19b7fe3c', + sha1 = 'e25d55b8f41627c4ae6b9d2069ec398638b219a3', license = 'Apache2.0', attach_source = False, repository = REPO,
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventModule.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventModule.java index 7619a82..6148522 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventModule.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventModule.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; +/** Configures handling for an event queue while providing its pool. */ public class EventModule extends AbstractModule { @Override
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventPool.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventPool.java index c51ac02..97324df 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventPool.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventPool.java
@@ -20,6 +20,9 @@ import java.lang.annotation.Retention; +/** + * Annotation applied to a ScheduledThreadPoolExecutor. + */ @Retention(RUNTIME) @BindingAnnotation public @interface EventPool {
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java index 22287e6..8432be4 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java
@@ -132,6 +132,7 @@ return maxTries; } + /** @return the local-store (database) driver which happens to be h2 */ public String getLocalStoreDriver() { return DEFAULT_DRIVER; }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogException.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogException.java index 2137a95..8227d22 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogException.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogException.java
@@ -14,6 +14,7 @@ package com.ericsson.gerrit.plugins.eventslog; +/** Custom exception for events log. */ public class EventsLogException extends Exception { private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/HttpModule.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/HttpModule.java index a75eb73..c1db514 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/HttpModule.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/HttpModule.java
@@ -16,7 +16,7 @@ import com.google.gerrit.httpd.plugins.HttpPluginModule; -public class HttpModule extends HttpPluginModule { +class HttpModule extends HttpPluginModule { @Override protected void configureServlets() { serve("/events/").with(EventsRestApiServlet.class);
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/MalformedQueryException.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/MalformedQueryException.java index 56c0c73..17caa1a 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/MalformedQueryException.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/MalformedQueryException.java
@@ -14,6 +14,7 @@ package com.ericsson.gerrit.plugins.eventslog; +/** Custom exception for malformed queries. */ public class MalformedQueryException extends EventsLogException { private static final long serialVersionUID = 1L; private static final String MESSAGE =
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/QueryMaker.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/QueryMaker.java index 0fdf74c..bd55dbc 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/QueryMaker.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/QueryMaker.java
@@ -16,6 +16,7 @@ import java.util.Map; +/** Helps build well-formed database query strings. */ public interface QueryMaker { /**
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java index 6286f50..9242ab3 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java
@@ -24,11 +24,14 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import com.google.common.base.Supplier; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import com.google.gerrit.server.events.ProjectEvent; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.inject.Inject; +import com.google.gerrit.server.events.SupplierSerializer; import com.ericsson.gerrit.plugins.eventslog.EventsLogException; import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException; @@ -47,6 +50,7 @@ class SQLClient { private static final Logger log = LoggerFactory.getLogger(SQLClient.class); + private final Gson gson; private BasicDataSource ds; @Inject @@ -55,6 +59,8 @@ ds.setDriverClassName(storeDriver); ds.setUrl(storeUrl); ds.setConnectionProperties(urlOptions); + gson = new GsonBuilder() + .registerTypeAdapter(Supplier.class, new SupplierSerializer()).create(); } /** @@ -145,8 +151,7 @@ void storeEvent(ProjectEvent event) throws SQLException { storeEvent(event.getProjectNameKey().get(), new Timestamp(SECONDS.toMillis(event.eventCreatedOn)), - new Gson().toJson(event)); - + gson.toJson(event)); } /**
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLQueryMaker.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLQueryMaker.java index 93c6569..8ad81be 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLQueryMaker.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLQueryMaker.java
@@ -86,15 +86,14 @@ private Date[] parseDates(String dateOne, String dateTwo) throws MalformedQueryException, ParseException { - Calendar cal = Calendar.getInstance(); - if (dateOne == null & dateTwo == null) { + if (dateOne == null && dateTwo == null) { throw new MalformedQueryException(); } + Calendar cal = Calendar.getInstance(); + Date dOne = dateOne == null ? cal.getTime() : parseDate(dateOne); + Date dTwo = dateTwo == null ? cal.getTime() : parseDate(dateTwo); Date[] dates = new Date[TWO]; - Date dOne = - dateOne == null && dateTwo != null ? cal.getTime() : parseDate(dateOne); - Date dTwo = - dateTwo == null && dateOne != null ? cal.getTime() : parseDate(dateTwo); + dates[0] = dOne.compareTo(dTwo) < 0 ? dOne : dTwo; dates[1] = dOne.compareTo(dTwo) < 0 ? dTwo : dOne; return dates;
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java index 0699160..b7beda8 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java +++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
@@ -114,21 +114,21 @@ throw new ServiceUnavailableException(); } List<SQLEntry> entries = new ArrayList<>(); - Project.NameKey project = null; + for (Entry<String, Collection<SQLEntry>> entry : eventsDb.getEvents(query).asMap().entrySet()) { + String projectName = entry.getKey(); try { - project = new Project.NameKey(entry.getKey()); - if (projectControlFactory.controlFor(project, + if (projectControlFactory.controlFor(new Project.NameKey(projectName), userProvider.get()).isVisible()) { entries.addAll(entry.getValue()); } } catch (NoSuchProjectException e) { - log.warn("Database contains a non-existing project, " + project.get() + log.warn("Database contains a non-existing project, " + projectName + ", removing project from database"); - eventsDb.removeProjectEvents(project.get()); + eventsDb.removeProjectEvents(projectName); } catch (IOException e) { - log.warn("Cannot get project visibility info for " + project.get() + log.warn("Cannot get project visibility info for " + projectName + " from cache", e); } } @@ -167,21 +167,25 @@ if (e.getCause() instanceof ConnectException || e.getMessage().contains("terminating connection")) { done = false; - retryIfAllowed(failedConnections); + try { + retryIfAllowed(failedConnections); + } catch (InterruptedException e1) { + log.warn("Cannot store ChangeEvent for: " + projectName.get() + + ": Interrupted"); + Thread.currentThread().interrupt(); + return; + } failedConnections++; } } } } - private void retryIfAllowed(int failedConnections) { + private void retryIfAllowed(int failedConnections) + throws InterruptedException { if (failedConnections < maxTries - 1) { log.info("Retrying store event"); - try { - Thread.sleep(waitTime); - } catch (InterruptedException e1) { - return; - } + Thread.sleep(waitTime); } else { log.error("Failed to store event " + maxTries + " times"); setOnline(false); @@ -270,12 +274,12 @@ } private boolean checkConnection() { - log.info("Checking database connection..."); + log.debug("Checking database connection..."); try { eventsDb.queryOne(); return true; } catch (SQLException e) { - log.debug("Problem checking database connection", e); + log.error("Problem checking database connection", e); return false; } }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventHandlerTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventHandlerTest.java index 67ff28b..b6c773b 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventHandlerTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventHandlerTest.java
@@ -15,55 +15,50 @@ package com.ericsson.gerrit.plugins.eventslog; import static com.google.common.truth.Truth.assertThat; -import static org.easymock.EasyMock.expectLastCall; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; -import com.google.gerrit.common.EventListener; import com.google.gerrit.server.events.ChangeEvent; import com.google.gerrit.server.events.Event; -import org.easymock.EasyMockSupport; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import java.util.concurrent.ScheduledThreadPoolExecutor; +@RunWith(MockitoJUnitRunner.class) public class EventHandlerTest { - private EasyMockSupport easyMock = new EasyMockSupport(); + @Mock private EventStore storeMock; - private EventListener listener; - private ScheduledThreadPoolExecutor poolMock; + private EventHandler eventHandler; @Before public void setUp() { - storeMock = easyMock.createMock(EventStore.class); + ScheduledThreadPoolExecutor poolMock = new PoolMock(); + eventHandler = new EventHandler(storeMock, poolMock); } @Test public void passEventToStore() { - ChangeEvent eventMock = easyMock.createNiceMock(ChangeEvent.class); - easyMock.resetAll(); - storeMock.storeEvent(eventMock); - expectLastCall().once(); - easyMock.replayAll(); - poolMock = new PoolMock(1); - listener = new EventHandler(storeMock, poolMock); - listener.onEvent(eventMock); - easyMock.verifyAll(); + ChangeEvent eventMock = mock(ChangeEvent.class); + eventHandler.onEvent(eventMock); + verify(storeMock).storeEvent(eventMock); } @Test public void nonProjectEvent() { - poolMock = easyMock.createMock(ScheduledThreadPoolExecutor.class); - Event eventMock = easyMock.createMock(Event.class); - easyMock.replayAll(); - listener = new EventHandler(storeMock, poolMock); - listener.onEvent(eventMock); - easyMock.verifyAll(); + Event eventMock = mock(Event.class); + eventHandler.onEvent(eventMock); + verifyZeroInteractions(storeMock); } class PoolMock extends ScheduledThreadPoolExecutor { - PoolMock(int corePoolSize) { - super(corePoolSize); + PoolMock() { + super(1); } @Override public void execute(Runnable command) {
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java index 9388319..f4cd273 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java
@@ -13,6 +13,7 @@ // limitations under the License. package com.ericsson.gerrit.plugins.eventslog; + import static com.ericsson.gerrit.plugins.eventslog.EventsLogConfig.CONFIG_CONN_TIME; import static com.ericsson.gerrit.plugins.eventslog.EventsLogConfig.CONFIG_COPY_LOCAL; import static com.ericsson.gerrit.plugins.eventslog.EventsLogConfig.CONFIG_DRIVER; @@ -36,91 +37,108 @@ import static com.ericsson.gerrit.plugins.eventslog.EventsLogConfig.DEFAULT_URL; import static com.ericsson.gerrit.plugins.eventslog.EventsLogConfig.DEFAULT_WAIT_TIME; import static com.google.common.truth.Truth.assertThat; -import static org.easymock.EasyMock.expect; +import static org.mockito.Mockito.when; import com.google.common.base.Joiner; import com.google.gerrit.server.config.PluginConfig; import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.config.SitePaths; -import org.easymock.EasyMock; -import org.easymock.EasyMockSupport; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import java.io.IOException; import java.nio.file.Files; +@RunWith(MockitoJUnitRunner.class) public class EventsLogConfigTest { + private static final String PLUGIN_NAME = "eventsLog"; + private static final int CUSTOM_EVICT_IDLE_TIME = 10000; + private SitePaths site; private EventsLogConfig config; - private PluginConfigFactory cfgFactoryMock; - private PluginConfig configMock; - private EasyMockSupport easyMock; private String defaultLocalStorePath; private String localStorePath; - private String [] urlOptions = new String[]{"a=b", "c=d"}; + private String[] urlOptions = new String[] {"DB_CLOSE_DELAY=10"}; - private static final int CUSTOM_EVICT_IDLE_TIME = 10000; + @Mock + private PluginConfigFactory cfgFactoryMock; + @Mock + private PluginConfig configMock; @Rule public TemporaryFolder gerrit_site = new TemporaryFolder(); @Before public void setUp() throws IOException { - easyMock = new EasyMockSupport(); site = new SitePaths(gerrit_site.getRoot().toPath()); Files.createDirectories(site.etc_dir); defaultLocalStorePath = site.site_path.toString() + "/events-db/"; - configMock = easyMock.createMock(PluginConfig.class); - cfgFactoryMock = easyMock.createMock(PluginConfigFactory.class); - expect(cfgFactoryMock.getFromGerritConfig(EasyMock.anyString(), - EasyMock.anyBoolean())).andStubReturn(configMock); + when(cfgFactoryMock.getFromGerritConfig(PLUGIN_NAME, true)) + .thenReturn(configMock); } private void setUpDefaults() { - expect(configMock.getBoolean(CONFIG_COPY_LOCAL, DEFAULT_COPY_LOCAL)).andReturn(DEFAULT_COPY_LOCAL); - expect(configMock.getInt(CONFIG_MAX_AGE, DEFAULT_MAX_AGE)).andReturn(DEFAULT_MAX_AGE); - expect(configMock.getInt(CONFIG_MAX_TRIES, DEFAULT_MAX_TRIES)).andReturn(DEFAULT_MAX_TRIES); - expect(configMock.getInt(CONFIG_RETURN_LIMIT, DEFAULT_RETURN_LIMIT)).andReturn(DEFAULT_RETURN_LIMIT); - expect(configMock.getInt(CONFIG_CONN_TIME, DEFAULT_CONN_TIME)).andReturn(DEFAULT_CONN_TIME); - expect(configMock.getInt(CONFIG_WAIT_TIME, DEFAULT_WAIT_TIME)).andReturn(DEFAULT_WAIT_TIME); - expect(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)).andReturn(DEFAULT_DRIVER); - expect(configMock.getString(CONFIG_URL, DEFAULT_URL)).andReturn(DEFAULT_URL); - expect(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)).andReturn(defaultLocalStorePath); - expect(configMock.getStringList(CONFIG_URL_OPTIONS)).andReturn(new String[0]); - expect(configMock.getString(CONFIG_USERNAME)).andReturn(null); - expect(configMock.getString(CONFIG_PASSWORD)).andReturn(null); - expect(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)).andReturn(DEFAULT_EVICT_IDLE_TIME); - - easyMock.replayAll(); + when(configMock.getBoolean(CONFIG_COPY_LOCAL, DEFAULT_COPY_LOCAL)) + .thenReturn(DEFAULT_COPY_LOCAL); + when(configMock.getInt(CONFIG_MAX_AGE, DEFAULT_MAX_AGE)) + .thenReturn(DEFAULT_MAX_AGE); + when(configMock.getInt(CONFIG_MAX_TRIES, DEFAULT_MAX_TRIES)) + .thenReturn(DEFAULT_MAX_TRIES); + when(configMock.getInt(CONFIG_RETURN_LIMIT, DEFAULT_RETURN_LIMIT)) + .thenReturn(DEFAULT_RETURN_LIMIT); + when(configMock.getInt(CONFIG_CONN_TIME, DEFAULT_CONN_TIME)) + .thenReturn(DEFAULT_CONN_TIME); + when(configMock.getInt(CONFIG_WAIT_TIME, DEFAULT_WAIT_TIME)) + .thenReturn(DEFAULT_WAIT_TIME); + when(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)) + .thenReturn(DEFAULT_DRIVER); + when(configMock.getString(CONFIG_URL, DEFAULT_URL)).thenReturn(DEFAULT_URL); + when(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)) + .thenReturn(defaultLocalStorePath); + when(configMock.getStringList(CONFIG_URL_OPTIONS)) + .thenReturn(new String[] {}); + when(configMock.getString(CONFIG_USERNAME)).thenReturn(null); + when(configMock.getString(CONFIG_PASSWORD)).thenReturn(null); + when(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)) + .thenReturn(DEFAULT_EVICT_IDLE_TIME); } private void setUpCustom() { localStorePath = "~/gerrit/events-db/"; - expect(configMock.getBoolean(CONFIG_COPY_LOCAL, DEFAULT_COPY_LOCAL)).andReturn(true); - expect(configMock.getInt(CONFIG_MAX_AGE, DEFAULT_MAX_AGE)).andReturn(20); - expect(configMock.getInt(CONFIG_MAX_TRIES, DEFAULT_MAX_TRIES)).andReturn(5); - expect(configMock.getInt(CONFIG_RETURN_LIMIT, DEFAULT_RETURN_LIMIT)).andReturn(10000); - expect(configMock.getInt(CONFIG_CONN_TIME, DEFAULT_CONN_TIME)).andReturn(5000); - expect(configMock.getInt(CONFIG_WAIT_TIME, DEFAULT_WAIT_TIME)).andReturn(5000); - expect(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)).andReturn("org.h2.Driver2"); - expect(configMock.getString(CONFIG_URL, DEFAULT_URL)).andReturn("jdbc:h2:~/gerrit/db"); - expect(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)).andReturn(localStorePath); - expect(configMock.getStringList(CONFIG_URL_OPTIONS)).andReturn(urlOptions); - expect(configMock.getString(CONFIG_USERNAME)).andReturn("testUsername"); - expect(configMock.getString(CONFIG_PASSWORD)).andReturn("testPassword"); - expect(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)).andReturn(CUSTOM_EVICT_IDLE_TIME); + when(configMock.getBoolean(CONFIG_COPY_LOCAL, DEFAULT_COPY_LOCAL)) + .thenReturn(true); + when(configMock.getInt(CONFIG_MAX_AGE, DEFAULT_MAX_AGE)).thenReturn(20); + when(configMock.getInt(CONFIG_MAX_TRIES, DEFAULT_MAX_TRIES)).thenReturn(5); + when(configMock.getInt(CONFIG_RETURN_LIMIT, DEFAULT_RETURN_LIMIT)) + .thenReturn(10000); + when(configMock.getInt(CONFIG_CONN_TIME, DEFAULT_CONN_TIME)) + .thenReturn(5000); + when(configMock.getInt(CONFIG_WAIT_TIME, DEFAULT_WAIT_TIME)) + .thenReturn(5000); + when(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)) + .thenReturn("org.h2.Driver2"); + when(configMock.getString(CONFIG_URL, DEFAULT_URL)) + .thenReturn("jdbc:h2:~/gerrit/db"); + when(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)) + .thenReturn(localStorePath); + when(configMock.getStringList(CONFIG_URL_OPTIONS)).thenReturn(urlOptions); + when(configMock.getString(CONFIG_USERNAME)).thenReturn("testUsername"); + when(configMock.getString(CONFIG_PASSWORD)).thenReturn("testPassword"); + when(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)) + .thenReturn(CUSTOM_EVICT_IDLE_TIME); - easyMock.replayAll(); } @Test public void shouldReturnDefaultsWhenMissingConfig() { setUpDefaults(); - config = new EventsLogConfig(cfgFactoryMock, site, null); + config = new EventsLogConfig(cfgFactoryMock, site, PLUGIN_NAME); assertThat(config.getCopyLocal()).isFalse(); assertThat(config.getMaxAge()).isEqualTo(30); assertThat(config.getMaxTries()).isEqualTo(3); @@ -128,7 +146,8 @@ assertThat(config.getConnectTime()).isEqualTo(1000); assertThat(config.getWaitTime()).isEqualTo(1000); assertThat(config.getLocalStoreDriver()).isEqualTo(DEFAULT_DRIVER); - assertThat(config.getLocalStorePath().toString() + "/").isEqualTo(defaultLocalStorePath); + assertThat(config.getLocalStorePath().toString() + "/") + .isEqualTo(defaultLocalStorePath); assertThat(config.getStoreDriver()).isEqualTo(DEFAULT_DRIVER); assertThat(config.getStoreUrl()).isEqualTo(DEFAULT_URL); assertThat(config.getUrlOptions()).isEmpty(); @@ -140,7 +159,7 @@ @Test public void shouldReturnConfigValues() { setUpCustom(); - config = new EventsLogConfig(cfgFactoryMock, site, null); + config = new EventsLogConfig(cfgFactoryMock, site, PLUGIN_NAME); assertThat(config.getCopyLocal()).isTrue(); assertThat(config.getMaxAge()).isEqualTo(20); assertThat(config.getMaxTries()).isEqualTo(5); @@ -148,10 +167,12 @@ assertThat(config.getConnectTime()).isEqualTo(5000); assertThat(config.getWaitTime()).isEqualTo(5000); assertThat(config.getLocalStoreDriver()).isEqualTo(DEFAULT_DRIVER); - assertThat(config.getLocalStorePath().toString() + "/").isEqualTo(localStorePath); + assertThat(config.getLocalStorePath().toString() + "/") + .isEqualTo(localStorePath); assertThat(config.getStoreDriver()).isEqualTo("org.h2.Driver2"); assertThat(config.getStoreUrl()).isEqualTo("jdbc:h2:~/gerrit/db"); - assertThat(config.getUrlOptions()).isEqualTo(Joiner.on(";").join(urlOptions)); + assertThat(config.getUrlOptions()) + .isEqualTo(Joiner.on(";").join(urlOptions)); assertThat(config.getStoreUsername()).isEqualTo("testUsername"); assertThat(config.getStorePassword()).isEqualTo("testPassword"); assertThat(config.getEvictIdleTime()).isEqualTo(CUSTOM_EVICT_IDLE_TIME);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogIT.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogIT.java new file mode 100644 index 0000000..cfb1cce --- /dev/null +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogIT.java
@@ -0,0 +1,41 @@ +// Copyright (C) 2015 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.ericsson.gerrit.plugins.eventslog; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.acceptance.GerritConfig; +import com.google.gerrit.acceptance.PluginDaemonTest; + +import org.junit.Test; + +public class EventsLogIT extends PluginDaemonTest { + + @Test + @GerritConfig(name = "plugin.events-log.storeUrl", value = "jdbc:h2:mem:db") + public void getEventsShallBeConsistent() throws Exception { + String events = "/plugins/events-log/events/?t1=1970-01-01;t2=2999-01-01"; + String change1 = "refs/changes/01/1/1"; + + createChange(); + String response = adminRestSession.get(events).getEntityContent(); + assertThat(response).contains(change1); + + createChange(); + response = adminRestSession.get(events).getEntityContent(); + assertThat(response).contains(change1); + assertThat(response).contains("refs/changes/02/2/1"); + } +}
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsRestApiServletTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsRestApiServletTest.java index 2e51106..bcccd07 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsRestApiServletTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsRestApiServletTest.java
@@ -15,143 +15,112 @@ package com.ericsson.gerrit.plugins.eventslog; import static com.google.common.truth.Truth.assertThat; -import static org.easymock.EasyMock.newCapture; -import static org.easymock.EasyMock.capture; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.expectLastCall; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gerrit.server.CurrentUser; +import com.google.inject.Provider; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.easymock.Capture; -import org.easymock.EasyMock; -import org.easymock.EasyMockSupport; -import org.junit.Before; -import org.junit.Test; - -import com.google.gerrit.server.CurrentUser; -import com.google.inject.Provider; - -import com.ericsson.gerrit.plugins.eventslog.EventsRestApiServlet; -import com.ericsson.gerrit.plugins.eventslog.EventStore; -import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException; -import com.ericsson.gerrit.plugins.eventslog.QueryMaker; - +@RunWith(MockitoJUnitRunner.class) public class EventsRestApiServletTest { - private EasyMockSupport easyMock; + private static final String RANDOM_QUERY = "random query"; + + @Mock private EventStore storeMock; + @Mock private QueryMaker queryMakerMock; + @Mock private Provider<CurrentUser> userProviderMock; + @Mock private CurrentUser userMock; + @Mock private HttpServletRequest reqMock; + @Mock private HttpServletResponse rspMock; + @Captor + private ArgumentCaptor<Map<String, String>> captor; + private EventsRestApiServlet eventServlet; - @SuppressWarnings("unchecked") @Before public void setUp() { - easyMock = new EasyMockSupport(); - storeMock = easyMock.createNiceMock(EventStore.class); - queryMakerMock = easyMock.createNiceMock(QueryMaker.class); - userProviderMock = easyMock.createNiceMock(Provider.class); - userMock = easyMock.createNiceMock(CurrentUser.class); - reqMock = easyMock.createNiceMock(HttpServletRequest.class); - rspMock = easyMock.createNiceMock(HttpServletResponse.class); - easyMock.replayAll(); - eventServlet = new EventsRestApiServlet(storeMock, queryMakerMock, - userProviderMock); + eventServlet = + new EventsRestApiServlet(storeMock, queryMakerMock, userProviderMock); + + when(userProviderMock.get()).thenReturn(userMock); + when(userMock.isIdentifiedUser()).thenReturn(true); } @Test public void queryStringSplitting() throws Exception { - String queryStringMock = "a=1;b=2"; - Map<String, String> paramMock = new HashMap<>(); - paramMock.put("a", "1"); - paramMock.put("b", "2"); - Capture<Map<String, String>> catcher = newCapture(); - easyMock.resetAll(); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(userMock.isIdentifiedUser()).andStubReturn(true); - expect(reqMock.getQueryString()).andStubReturn(queryStringMock); - expect(queryMakerMock.formQueryFromRequestParameters(capture(catcher))) - .andStubReturn("random query"); - expect(storeMock.queryChangeEvents("random query")).andStubReturn( - new ArrayList<String>()); - easyMock.replayAll(); + when(reqMock.getQueryString()).thenReturn("a=1;b=2"); + when(queryMakerMock.formQueryFromRequestParameters(captor.capture())) + .thenReturn(RANDOM_QUERY); + when(storeMock.queryChangeEvents(RANDOM_QUERY)) + .thenReturn(new ArrayList<String>()); eventServlet.doGet(reqMock, rspMock); - Map<String, String> capturedParam = catcher.getValue(); - assertThat(paramMock).isEqualTo(capturedParam); + assertThat(ImmutableMap.of("a", "1", "b", "2")) + .isEqualTo(captor.getValue()); } @Test public void badQueryString() throws Exception { - String queryStringMock = "a;b"; - Capture<Map<String, String>> catcher = newCapture(); - easyMock.resetAll(); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(userMock.isIdentifiedUser()).andStubReturn(true); - expect(reqMock.getQueryString()).andStubReturn(queryStringMock); - expect(queryMakerMock.formQueryFromRequestParameters(capture(catcher))) - .andStubReturn("random query"); - expect(storeMock.queryChangeEvents("random query")).andStubReturn( - new ArrayList<String>()); - easyMock.replayAll(); + when(reqMock.getQueryString()).thenReturn("a;b"); + when(queryMakerMock.formQueryFromRequestParameters(captor.capture())) + .thenReturn(RANDOM_QUERY); + when(storeMock.queryChangeEvents(RANDOM_QUERY)) + .thenReturn(new ArrayList<String>()); eventServlet.doGet(reqMock, rspMock); - Map<String, String> capturedParam = catcher.getValue(); - assertThat(capturedParam).isEmpty(); + assertThat(captor.getValue()).isEmpty(); } @Test public void testUnAuthorizedCode() throws Exception { - easyMock.resetAll(); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(userMock.isIdentifiedUser()).andStubReturn(false); - rspMock.sendError(HttpServletResponse.SC_UNAUTHORIZED); - expectLastCall().once(); - easyMock.replayAll(); + when(userMock.isIdentifiedUser()).thenReturn(false); eventServlet.doGet(reqMock, rspMock); - easyMock.verifyAll(); + verify(rspMock).sendError(HttpServletResponse.SC_UNAUTHORIZED); } @Test public void testBadRequestCode() throws Exception { - easyMock.resetAll(); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(userMock.isIdentifiedUser()).andStubReturn(true); - expect(queryMakerMock.formQueryFromRequestParameters( - EasyMock.<Map<String, String>> anyObject())).andStubThrow( - new MalformedQueryException()); - rspMock.sendError(HttpServletResponse.SC_BAD_REQUEST); - expectLastCall().once(); - easyMock.replayAll(); + when(reqMock.getQueryString()).thenReturn("@@"); + Map<String, String> emptyParams = ImmutableMap.of(); + when(queryMakerMock.formQueryFromRequestParameters(emptyParams)) + .thenThrow(new MalformedQueryException()); eventServlet.doGet(reqMock, rspMock); - easyMock.verifyAll(); + verify(rspMock).sendError(HttpServletResponse.SC_BAD_REQUEST); } @Test public void queryDatabaseAndWrite() throws Exception { - PrintWriter outMock = easyMock.createMock(PrintWriter.class); - List<String> listMock = new ArrayList<>(); - listMock.add("event one"); - listMock.add("event two"); - easyMock.resetAll(); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(userMock.isIdentifiedUser()).andStubReturn(true); - expect(rspMock.getWriter()).andStubReturn(outMock); - expect(storeMock.queryChangeEvents(EasyMock.anyString())).andReturn( - listMock); - outMock.write(listMock.get(0) + "\n"); - expectLastCall().once(); - outMock.write(listMock.get(1) + "\n"); - expectLastCall().once(); - easyMock.replayAll(); + when(reqMock.getQueryString()).thenReturn("@@"); + PrintWriter outMock = mock(PrintWriter.class); + List<String> listMock = ImmutableList.of("event one", "event two"); + when(rspMock.getWriter()).thenReturn(outMock); + when(queryMakerMock.formQueryFromRequestParameters(captor.capture())) + .thenReturn(RANDOM_QUERY); + when(storeMock.queryChangeEvents(RANDOM_QUERY)).thenReturn(listMock); eventServlet.doGet(reqMock, rspMock); - easyMock.verifyAll(); + verify(outMock).write(listMock.get(0) + "\n"); + verify(outMock).write(listMock.get(1) + "\n"); } }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/QueryMakerTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/QueryMakerTest.java index bad6ccf..c7ec5d3 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/QueryMakerTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/QueryMakerTest.java
@@ -15,106 +15,98 @@ package com.ericsson.gerrit.plugins.eventslog.sql; import static com.google.common.truth.Truth.assertThat; -import static org.easymock.EasyMock.expect; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableMap; import com.ericsson.gerrit.plugins.eventslog.EventsLogConfig; import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException; import com.ericsson.gerrit.plugins.eventslog.QueryMaker; -import com.ericsson.gerrit.plugins.eventslog.sql.SQLQueryMaker; -import org.easymock.EasyMockSupport; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; -import java.util.HashMap; -import java.util.Map; - +@RunWith(MockitoJUnitRunner.class) public class QueryMakerTest { - private static QueryMaker queryMaker; - private static String defaultQuery; + private static final String T2 = "t2"; + private static final String T1 = "t1"; + private static final String OLD_DATE = "2013-10-10 10:00:00"; + private static final String NEW_DATE = "2014-10-10 10:00:00"; - @BeforeClass - public static void setUp() throws Exception { - EasyMockSupport easyMock = new EasyMockSupport(); - EventsLogConfig cfgMock = easyMock.createMock(EventsLogConfig.class); - expect(cfgMock.getReturnLimit()).andReturn(10); - easyMock.replayAll(); + private QueryMaker queryMaker; + private String defaultQuery; + + @Mock + private EventsLogConfig cfgMock; + + private String query; + + @Before + public void setUp() throws Exception { + when(cfgMock.getReturnLimit()).thenReturn(10); queryMaker = new SQLQueryMaker(cfgMock); defaultQuery = queryMaker.getDefaultQuery(); } @Test - public void returnDefaultforNullMap() throws Exception { - assertThat(queryMaker.formQueryFromRequestParameters(null)).isEqualTo(defaultQuery); + public void returnDefaultQueryforNullMap() throws Exception { + assertThat(queryMaker.formQueryFromRequestParameters(null)) + .isEqualTo(defaultQuery); } @Test(expected = MalformedQueryException.class) public void badParameters() throws Exception { - Map<String, String> params = new HashMap<>(); - params.put("t1", "bad format"); - params.put("t2", "bad format"); - queryMaker.formQueryFromRequestParameters(params); + queryMaker.formQueryFromRequestParameters( + ImmutableMap.of(T1, "13/13/32", T2, "14/10/10")); } @Test public void dateOneOnly() throws Exception { - Map<String, String> params = new HashMap<>(); - String oldDate = "1990-10-10 10:00:00"; - params.put("t1", oldDate); - String query = queryMaker.formQueryFromRequestParameters(params); - assertThat(query).contains(String.format("'%s' and ", oldDate)); + query = queryMaker + .formQueryFromRequestParameters(ImmutableMap.of(T1, OLD_DATE)); + assertThat(query).contains(String.format("'%s' and ", OLD_DATE)); } @Test public void dateTwoOnly() throws Exception { - Map<String, String> params = new HashMap<>(); - String oldDate = "1990-10-10 10:00:00"; - params.put("t2", oldDate); - String query = queryMaker.formQueryFromRequestParameters(params); - assertThat(query).contains(String.format("'%s' and ", oldDate)); + query = queryMaker + .formQueryFromRequestParameters(ImmutableMap.of(T2, OLD_DATE)); + assertThat(query).contains(String.format("'%s' and ", OLD_DATE)); } @Test(expected = MalformedQueryException.class) public void noDate() throws Exception { - Map<String, String> params = new HashMap<>(); - queryMaker.formQueryFromRequestParameters(params); + queryMaker + .formQueryFromRequestParameters(ImmutableMap.<String, String> of()); } @Test public void dateOrdering() throws Exception { - String query; - Map<String, String> params = new HashMap<>(); - String olderDate = "2013-10-10 10:00:00"; - String newerDate = "2014-10-10 10:00:00"; + query = queryMaker.formQueryFromRequestParameters( + ImmutableMap.of(T1, OLD_DATE, T2, NEW_DATE)); + assertThat(query) + .contains(String.format("'%s' and '%s'", OLD_DATE, NEW_DATE)); - params.put("t1", olderDate); - params.put("t2", newerDate); - query = queryMaker.formQueryFromRequestParameters(params); - assertThat(query).contains(String.format("'%s' and '%s'", - olderDate, newerDate)); - - params.put("t1", newerDate); - params.put("t2", olderDate); - query = queryMaker.formQueryFromRequestParameters(params); - assertThat(query).contains(String.format("'%s' and '%s'", - olderDate, newerDate)); + query = queryMaker.formQueryFromRequestParameters( + ImmutableMap.of(T1, NEW_DATE, T2, OLD_DATE)); + assertThat(query) + .contains(String.format("'%s' and '%s'", OLD_DATE, NEW_DATE)); } @Test public void bothDateTime() throws Exception { - Map<String, String> params = new HashMap<>(); - params.put("t1", "2013-10-10 10:00:00"); - params.put("t2", "2014-10-10 10:00:00"); - String query = queryMaker.formQueryFromRequestParameters(params); + query = queryMaker.formQueryFromRequestParameters( + ImmutableMap.of(T1, OLD_DATE, T2, NEW_DATE)); assertThat(query).isNotEqualTo(defaultQuery); } @Test public void onlyDateNoTime() throws Exception { - Map<String, String> params = new HashMap<>(); - params.put("t1", "2013-10-10"); - params.put("t2", "2014-10-10"); - String query = queryMaker.formQueryFromRequestParameters(params); + String query = queryMaker.formQueryFromRequestParameters( + ImmutableMap.of(T1, "2013-10-10", T2, "2014-10-10")); assertThat(query).isNotEqualTo(defaultQuery); } }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java index ebc18e4..4b674d5 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
@@ -16,13 +16,18 @@ import static com.ericsson.gerrit.plugins.eventslog.sql.SQLTable.TABLE_NAME; import static com.google.common.truth.Truth.assertThat; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.expectLastCall; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -import com.google.gerrit.reviewdb.client.Change.Key; +import com.google.common.collect.ImmutableList; import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.client.Project.NameKey; import com.google.gerrit.server.CurrentUser; -import com.google.gerrit.server.events.ChangeEvent; +import com.google.gerrit.server.events.ProjectEvent; import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectControl; import com.google.gson.Gson; @@ -31,16 +36,14 @@ import com.ericsson.gerrit.plugins.eventslog.EventsLogConfig; import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException; import com.ericsson.gerrit.plugins.eventslog.ServiceUnavailableException; -import com.ericsson.gerrit.plugins.eventslog.sql.SQLClient; -import com.ericsson.gerrit.plugins.eventslog.sql.SQLEntry; -import com.ericsson.gerrit.plugins.eventslog.sql.SQLStore; -import org.easymock.EasyMock; -import org.easymock.EasyMockSupport; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,52 +54,50 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +@RunWith(MockitoJUnitRunner.class) public class SQLStoreTest { private static final Logger log = LoggerFactory.getLogger(SQLStoreTest.class); private static final String TEST_URL = "jdbc:h2:mem:" + TABLE_NAME; - private static final String TEST_LOCAL_URL = "jdbc:h2:mem:test:"; + private static final String TEST_LOCAL_URL = "jdbc:h2:mem:test"; private static final String TEST_DRIVER = "org.h2.Driver"; - private static final String TEST_OPTIONS = "DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false"; + private static final String TEST_OPTIONS = + "DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false"; private static final String TERM_CONN_MSG = "terminating connection"; private static final String MSG = "message"; private static final String GENERIC_QUERY = "SELECT * FROM " + TABLE_NAME; + private static final boolean PROJECT_VISIBLE_TO_USER = true; + private static final boolean PROJECT_NOT_VISIBLE_TO_USER = false; - private EasyMockSupport easyMock; + @Mock private ProjectControl.GenericFactory pcFactoryMock; + @Mock private Provider<CurrentUser> userProviderMock; + @Mock private EventsLogConfig cfgMock; private SQLClient eventsDb; private SQLClient localEventsDb; private SQLStore store; private ScheduledThreadPoolExecutor poolMock; - private String path = TEST_URL + ";" + TEST_OPTIONS; - private Connection conn; private Statement stat; - private List<SQLEntry> results; @Rule public TemporaryFolder testFolder = new TemporaryFolder(); - @SuppressWarnings("unchecked") @Before public void setUp() throws SQLException { - conn = DriverManager.getConnection(path); + Connection conn = + DriverManager.getConnection(TEST_URL + ";" + TEST_OPTIONS); stat = conn.createStatement(); - results = new ArrayList<>(); - poolMock = new PoolMock(1); - easyMock = new EasyMockSupport(); - pcFactoryMock = easyMock.createNiceMock(ProjectControl.GenericFactory.class); - userProviderMock = easyMock.createNiceMock(Provider.class); - cfgMock = easyMock.createNiceMock(EventsLogConfig.class); - expect(cfgMock.getMaxAge()).andReturn(5); - expect(cfgMock.getLocalStorePath()).andReturn(testFolder.getRoot().toPath()).atLeastOnce(); + poolMock = new PoolMock(); + when(cfgMock.getMaxAge()).thenReturn(5); + when(cfgMock.getLocalStorePath()).thenReturn(testFolder.getRoot().toPath()); } public void tearDown() throws Exception { @@ -107,76 +108,65 @@ private void setUpClient() { eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS); localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); } - private void setUpClientMock(boolean reset) throws SQLException { - eventsDb = easyMock.createNiceMock(SQLClient.class); - localEventsDb = easyMock.createNiceMock(SQLClient.class); - expect(localEventsDb.dbExists()).andReturn(true).anyTimes(); - if (reset) { - easyMock.resetAll(); - } + private void setUpClientMock() throws SQLException { + eventsDb = mock(SQLClient.class); + localEventsDb = mock(SQLClient.class); + when(localEventsDb.dbExists()).thenReturn(true); } @Test public void storeThenQueryVisible() throws Exception { - MockEvent mockEvent = new MockEvent(); - ProjectControl pcMock = easyMock.createNiceMock(ProjectControl.class); - CurrentUser userMock = easyMock.createNiceMock(CurrentUser.class); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(pcFactoryMock.controlFor(mockEvent.getProjectNameKey(), userMock)) - .andStubReturn(pcMock); - expect(pcMock.isVisible()).andStubReturn(true); - easyMock.replayAll(); - setUpClient(); + MockEvent mockEvent = setUpMocks(PROJECT_VISIBLE_TO_USER); store.storeEvent(mockEvent); List<String> events = store.queryChangeEvents(GENERIC_QUERY); - Gson gson = new Gson(); - String json = gson.toJson(mockEvent); + String json = new Gson().toJson(mockEvent); assertThat(events).containsExactly(json); tearDown(); } @Test public void storeThenQueryNotVisible() throws Exception { - MockEvent mockEvent = new MockEvent(); - ProjectControl pcMock = easyMock.createNiceMock(ProjectControl.class); - CurrentUser userMock = easyMock.createNiceMock(CurrentUser.class); - expect(userProviderMock.get()).andStubReturn(userMock); - expect(pcFactoryMock.controlFor(mockEvent.getProjectNameKey(), userMock)) - .andStubReturn(pcMock); - expect(pcMock.isVisible()).andStubReturn(false); - easyMock.replayAll(); - setUpClient(); + MockEvent mockEvent = setUpMocks(PROJECT_NOT_VISIBLE_TO_USER); store.storeEvent(mockEvent); List<String> events = store.queryChangeEvents(GENERIC_QUERY); assertThat(events).isEmpty(); tearDown(); } + private MockEvent setUpMocks(boolean isVisible) + throws NoSuchProjectException, IOException { + MockEvent mockEvent = new MockEvent(); + ProjectControl pcMock = mock(ProjectControl.class); + CurrentUser userMock = mock(CurrentUser.class); + when(userProviderMock.get()).thenReturn(userMock); + when(pcFactoryMock.controlFor(mockEvent.getProjectNameKey(), userMock)) + .thenReturn(pcMock); + when(pcMock.isVisible()).thenReturn(isVisible); + setUpClient(); + return mockEvent; + } + @Test(expected = MalformedQueryException.class) public void throwBadRequestTriggerOnBadQuery() throws Exception { - easyMock.replayAll(); setUpClient(); String badQuery = "bad query"; store.queryChangeEvents(badQuery); - easyMock.verifyAll(); } @Test public void notReturnEventOfNonExistingProject() throws Exception { MockEvent mockEvent = new MockEvent(); - Project.NameKey projectMock = easyMock.createMock(Project.NameKey.class); - expect(projectMock.get()).andStubReturn(" "); - expect( - pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class), - EasyMock.anyObject(CurrentUser.class))) - .andThrow(new NoSuchProjectException(projectMock)); - easyMock.replayAll(); + Project.NameKey projectMock = mock(Project.NameKey.class); + CurrentUser userMock = mock(CurrentUser.class); + when(userProviderMock.get()).thenReturn(userMock); + NameKey projectNameKey = mockEvent.getProjectNameKey(); + doThrow(new NoSuchProjectException(projectMock)).when(pcFactoryMock) + .controlFor(projectNameKey, userMock); setUpClient(); store.storeEvent(mockEvent); List<String> events = store.queryChangeEvents(GENERIC_QUERY); @@ -187,12 +177,11 @@ @Test public void notReturnEventWithNoVisibilityInfo() throws Exception { MockEvent mockEvent = new MockEvent(); - Project.NameKey projectMock = easyMock.createMock(Project.NameKey.class); - expect(projectMock.get()).andStubReturn(" "); - expect( - pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class), - EasyMock.anyObject(CurrentUser.class))).andThrow(new IOException()); - easyMock.replayAll(); + CurrentUser userMock = mock(CurrentUser.class); + when(userProviderMock.get()).thenReturn(userMock); + NameKey projectNameKey = mockEvent.getProjectNameKey(); + doThrow(new IOException()).when(pcFactoryMock).controlFor(projectNameKey, + userMock); setUpClient(); store.storeEvent(mockEvent); List<String> events = store.queryChangeEvents(GENERIC_QUERY); @@ -203,93 +192,78 @@ @Test public void retryOnConnectException() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(false); - EasyMock.reset(eventsDb, localEventsDb); - expect(cfgMock.getMaxTries()).andReturn(3).once(); - eventsDb.storeEvent(mockEvent); - expectLastCall().andThrow(new SQLException(new ConnectException())) - .times(3); - expect(localEventsDb.getAll()).andStubReturn(results); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + when(cfgMock.getMaxTries()).thenReturn(3); + Throwable[] exceptions = new Throwable[3]; + Arrays.fill(exceptions, new SQLException(new ConnectException())); + setUpClientMock(); + doThrow(exceptions).doNothing().when(eventsDb).storeEvent(mockEvent); + doThrow(exceptions).doNothing().when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(eventsDb, times(3)).storeEvent(mockEvent); + verify(localEventsDb).storeEvent(mockEvent); } @Test public void retryOnMessage() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(false); - expect(cfgMock.getMaxTries()).andReturn(3).once(); - eventsDb.storeEvent(mockEvent); - expectLastCall().andThrow(new SQLException(TERM_CONN_MSG)).times(3); - expect(localEventsDb.getAll()).andStubReturn(results); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + when(cfgMock.getMaxTries()).thenReturn(3); + Throwable[] exceptions = new Throwable[3]; + Arrays.fill(exceptions, new SQLException(TERM_CONN_MSG)); + setUpClientMock(); + doThrow(exceptions).doNothing().when(eventsDb).storeEvent(mockEvent); + doThrow(exceptions).doNothing().when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(eventsDb, times(3)).storeEvent(mockEvent); + verify(localEventsDb).storeEvent(mockEvent); } @Test public void noRetryOnMessage() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(false); - expect(cfgMock.getMaxTries()).andReturn(3).once(); - eventsDb.storeEvent(mockEvent); - expectLastCall().andThrow(new SQLException(MSG)).once(); - expect(localEventsDb.getAll()).andReturn(results); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + when(cfgMock.getMaxTries()).thenReturn(3); + setUpClientMock(); + doThrow(new SQLException(MSG)).when(eventsDb).storeEvent(mockEvent); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(eventsDb, times(1)).storeEvent(mockEvent); } @Test public void noRetryOnZeroMaxTries() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(false); - expect(cfgMock.getMaxTries()).andReturn(0).once(); - eventsDb.storeEvent(mockEvent); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - expect(localEventsDb.getAll()).andStubReturn(results); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + when(cfgMock.getMaxTries()).thenReturn(0); + Throwable[] exceptions = new Throwable[3]; + Arrays.fill(exceptions, new SQLException(new ConnectException())); + setUpClientMock(); + doThrow(exceptions).doNothing().when(eventsDb).storeEvent(mockEvent); + doThrow(exceptions).doNothing().when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(eventsDb, times(1)).storeEvent(mockEvent); } - @Test (expected = ServiceUnavailableException.class) + @Test(expected = ServiceUnavailableException.class) public void throwSQLExceptionIfNotOnline() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(true); - eventsDb.createDBIfNotCreated(); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - eventsDb.queryOne(); - expectLastCall().andThrow(new SQLException()); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + setUpClientMock(); + doThrow(new SQLException(new ConnectException())).when(eventsDb) + .createDBIfNotCreated(); + doThrow(new SQLException()).when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); store.storeEvent(mockEvent); store.queryChangeEvents(GENERIC_QUERY); - easyMock.verifyAll(); } @Test @@ -298,26 +272,22 @@ MockEvent mockEvent2 = new MockEvent("proj"); MockEvent mockEvent3 = new MockEvent("unfound"); - ProjectControl pc = easyMock.createNiceMock(ProjectControl.class); - NoSuchProjectException e = - easyMock.createNiceMock(NoSuchProjectException.class); - expect( - pcFactoryMock.controlFor(EasyMock.eq(mockEvent.getProjectNameKey()), - EasyMock.anyObject(CurrentUser.class))).andReturn(pc).once(); - expect( - pcFactoryMock.controlFor(EasyMock.eq(mockEvent2.getProjectNameKey()), - EasyMock.anyObject(CurrentUser.class))).andReturn(pc).once(); - expect(pc.isVisible()).andReturn(true).times(2); - expect( - pcFactoryMock.controlFor(EasyMock.eq(mockEvent3.getProjectNameKey()), - EasyMock.anyObject(CurrentUser.class))).andThrow(e); - easyMock.replayAll(); + ProjectControl pc = mock(ProjectControl.class); + NoSuchProjectException e = mock(NoSuchProjectException.class); + CurrentUser userMock = mock(CurrentUser.class); + when(userProviderMock.get()).thenReturn(userMock); + when(pcFactoryMock.controlFor((mockEvent.getProjectNameKey()), userMock)) + .thenReturn(pc); + when(pcFactoryMock.controlFor((mockEvent2.getProjectNameKey()), userMock)) + .thenReturn(pc); + when(pc.isVisible()).thenReturn(true); + doThrow(e).when(pcFactoryMock).controlFor((mockEvent3.getProjectNameKey()), + userMock); eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS); localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); localEventsDb.createDBIfNotCreated(); localEventsDb.storeEvent(mockEvent); @@ -329,61 +299,48 @@ String json = gson.toJson(mockEvent); String json2 = gson.toJson(mockEvent2); assertThat(events).containsExactly(json, json2); - easyMock.verifyAll(); tearDown(); } @Test public void offlineUponStart() throws Exception { - setUpClientMock(true); - eventsDb.createDBIfNotCreated(); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - eventsDb.queryOne(); - expectLastCall().andThrow(new SQLException()); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + setUpClientMock(); + doThrow(new SQLException(new ConnectException())).when(eventsDb) + .createDBIfNotCreated(); + doThrow(new SQLException()).when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - easyMock.verifyAll(); + verify(localEventsDb).createDBIfNotCreated(); } @Test public void storeLocalOffline() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(true); - eventsDb.createDBIfNotCreated(); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - localEventsDb.storeEvent(mockEvent); - expectLastCall().once(); - eventsDb.queryOne(); - expectLastCall().andThrow(new SQLException()); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + setUpClientMock(); + doThrow(new SQLException(new ConnectException())).when(eventsDb) + .createDBIfNotCreated(); + doThrow(new SQLException()).when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(localEventsDb).storeEvent(mockEvent); } @Test public void storeLocalOfflineAfterNoRetry() throws Exception { MockEvent mockEvent = new MockEvent(); - setUpClientMock(false); - expect(cfgMock.getMaxTries()).andReturn(0).once(); - eventsDb.storeEvent(mockEvent); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - expect(localEventsDb.getAll()).andStubReturn(results); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + setUpClientMock(); + when(cfgMock.getMaxTries()).thenReturn(0); + doThrow(new SQLException(new ConnectException())).when(eventsDb) + .createDBIfNotCreated(); + doThrow(new SQLException()).when(eventsDb).queryOne(); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); - store.storeEvent(mockEvent); - easyMock.verifyAll(); + verify(localEventsDb).storeEvent(mockEvent); } /** @@ -395,17 +352,16 @@ @Test public void testConnectionTask() throws Exception { eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS); - localEventsDb = easyMock.createMock(SQLClient.class); - expect(localEventsDb.dbExists()).andReturn(true).once(); - expect(localEventsDb.getAll()).andReturn(new ArrayList<SQLEntry>()); - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); - eventsDb.createDBIfNotCreated(); + localEventsDb = mock(SQLClient.class); + when(localEventsDb.dbExists()).thenReturn(true); + when(localEventsDb.getAll()) + .thenReturn(ImmutableList.of(mock(SQLEntry.class))); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); + store.start(); poolMock.scheduleWithFixedDelay(store.new CheckConnectionTask(), 0, 0, TimeUnit.MILLISECONDS); - easyMock.verifyAll(); + verify(localEventsDb, times(2)).removeOldEvents(0); } @Test @@ -420,37 +376,28 @@ private void checkConnectionAndRestore(boolean copy) throws Exception { MockEvent mockEvent = new MockEvent(); - eventsDb = easyMock.createNiceMock(SQLClient.class); + eventsDb = mock(SQLClient.class); localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS); localEventsDb.createDBIfNotCreated(); localEventsDb.storeEvent(mockEvent); - eventsDb.createDBIfNotCreated(); - expectLastCall().andThrow(new SQLException(new ConnectException())).once(); - eventsDb.queryOne(); - expectLastCall().once(); - eventsDb.storeEvent(EasyMock.anyString(), - EasyMock.anyObject(Timestamp.class), EasyMock.anyString()); - expectLastCall().once(); + doThrow(new SQLException(new ConnectException())).doNothing().when(eventsDb) + .createDBIfNotCreated(); if (copy) { - testCopyLocal(); + when(cfgMock.getCopyLocal()).thenReturn(true); } - easyMock.replayAll(); - store = - new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, - localEventsDb, poolMock); + store = new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb, + localEventsDb, poolMock); store.start(); + verify(eventsDb).queryOne(); + verify(eventsDb).storeEvent(any(String.class), any(Timestamp.class), + any(String.class)); List<SQLEntry> entries = localEventsDb.getAll(); assertThat(entries).isEmpty(); - easyMock.verifyAll(); } - private void testCopyLocal() { - expect(cfgMock.getCopyLocal()).andReturn(true).once(); - } - - public class MockEvent extends ChangeEvent { + public class MockEvent extends ProjectEvent { public String project = "mock project"; MockEvent() { @@ -466,21 +413,11 @@ public Project.NameKey getProjectNameKey() { return new Project.NameKey(project); } - - @Override - public Key getChangeKey() { - return null; - } - - @Override - public String getRefName() { - return null; - } } class PoolMock extends ScheduledThreadPoolExecutor { - PoolMock(int corePoolSize) { - super(corePoolSize); + PoolMock() { + super(1); } @Override