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