Merge "Preserve refs order in the GitBatchRefUpdateEvent event" into stable-3.6
diff --git a/java/com/google/gerrit/server/extensions/events/GitReferenceUpdated.java b/java/com/google/gerrit/server/extensions/events/GitReferenceUpdated.java
index 814390b..107e987 100644
--- a/java/com/google/gerrit/server/extensions/events/GitReferenceUpdated.java
+++ b/java/com/google/gerrit/server/extensions/events/GitReferenceUpdated.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.server.plugincontext.PluginSetContext;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.eclipse.jgit.lib.BatchRefUpdate;
@@ -128,7 +128,7 @@
     if (batchRefUpdateListeners.isEmpty() && refUpdatedListeners.isEmpty()) {
       return;
     }
-    Set<GitBatchRefUpdateListener.UpdatedRef> updates = new HashSet<>();
+    Set<GitBatchRefUpdateListener.UpdatedRef> updates = new LinkedHashSet<>();
     for (ReceiveCommand cmd : batchRefUpdate.getCommands()) {
       if (cmd.getResult() == ReceiveCommand.Result.OK) {
         updates.add(
@@ -254,7 +254,7 @@
     public Set<String> getRefNames() {
       return updatedRefs.stream()
           .map(GitBatchRefUpdateListener.UpdatedRef::getRefName)
-          .collect(Collectors.toSet());
+          .collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
     @Override
diff --git a/javatests/com/google/gerrit/server/extensions/events/GitReferenceUpdatedTest.java b/javatests/com/google/gerrit/server/extensions/events/GitReferenceUpdatedTest.java
index 96919be..9143dd5f 100644
--- a/javatests/com/google/gerrit/server/extensions/events/GitReferenceUpdatedTest.java
+++ b/javatests/com/google/gerrit/server/extensions/events/GitReferenceUpdatedTest.java
@@ -14,11 +14,14 @@
 
 package com.google.gerrit.server.extensions.events;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.events.GitBatchRefUpdateListener;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.extensions.events.GitReferenceUpdated.GitBatchRefUpdateEvent;
 import com.google.gerrit.server.plugincontext.PluginContext.PluginMetrics;
 import com.google.gerrit.server.plugincontext.PluginSetContext;
 import java.io.IOException;
@@ -32,6 +35,8 @@
 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.Mockito;
 import org.mockito.junit.MockitoJUnitRunner;
@@ -45,6 +50,7 @@
   @Mock GitBatchRefUpdateListener batchRefUpdateListener;
   @Mock EventUtil util;
   @Mock AccountState updater;
+  @Captor ArgumentCaptor<GitBatchRefUpdateEvent> eventCaptor;
 
   @Before
   public void setup() {
@@ -83,6 +89,36 @@
   }
 
   @Test
+  public void shouldPreserveRefsOrderInTheBatchRefsUpdatedEvent() {
+    BatchRefUpdate update = newBatchRefUpdate();
+    ReceiveCommand cmd1 =
+        new ReceiveCommand(
+            ObjectId.zeroId(),
+            ObjectId.fromString("0000000000000000000000000000000000000001"),
+            "refs/changes/01/1/1");
+    ReceiveCommand cmd2 =
+        new ReceiveCommand(
+            ObjectId.zeroId(),
+            ObjectId.fromString("0000000000000000000000000000000000000001"),
+            "refs/changes/01/1/meta");
+    cmd1.setResult(ReceiveCommand.Result.OK);
+    cmd2.setResult(ReceiveCommand.Result.OK);
+    update.addCommand(cmd1);
+    update.addCommand(cmd2);
+
+    GitReferenceUpdated event =
+        new GitReferenceUpdated(
+            new PluginSetContext<>(batchRefUpdateListeners, PluginMetrics.DISABLED_INSTANCE),
+            new PluginSetContext<>(refUpdatedListeners, PluginMetrics.DISABLED_INSTANCE),
+            util);
+    event.fire(Project.NameKey.parse("project"), update, updater);
+    Mockito.verify(batchRefUpdateListener, Mockito.times(1))
+        .onGitBatchRefUpdate(eventCaptor.capture());
+    GitBatchRefUpdateEvent batchEvent = eventCaptor.getValue();
+    assertThat(batchEvent.getRefNames()).isInOrder();
+  }
+
+  @Test
   public void RefUpdateEventAndRefsUpdateEventAreFired_RefUpdate() throws Exception {
     String ref = "refs/heads/master";
     RefUpdate update = newRefUpdate(ref);