Ignore immutable and draft-comments Refs

Some Refs can be ignored when persisting or validating
the Refs in the shared Ref database.
This change ignores all the immutable Refs in refs/changes
as well draft-comments.

Change-Id: I365dae30bd3a345d43fb0763da7682466bdf7df9
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java
index c886751..b475a72 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java
@@ -116,4 +116,17 @@
    * @throws java.io.IOException the reference could not be removed due to a system error.
    */
   boolean compareAndRemove(String project, Ref oldRef) throws IOException;
+
+  /**
+   * Some references should not be stored in the SharedRefDatabase.
+   *
+   * @param ref
+   * @return true if it's to be ignore; false otherwise
+   */
+  default boolean ignoreRefInSharedDb(Ref ref) {
+    String refName = ref.getName();
+    return refName == null
+        || refName.startsWith("refs/draft-comments")
+        || (refName.startsWith("refs/changes") && !refName.endsWith("/meta"));
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java
index e290b3d..b02db38 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java
@@ -48,11 +48,15 @@
 
   @Override
   public boolean compareAndRemove(String project, Ref oldRef) throws IOException {
-    return compareAndPut(project, oldRef, NULL_REF);
+    return ignoreRefInSharedDb(oldRef) || compareAndPut(project, oldRef, NULL_REF);
   }
 
   @Override
   public boolean compareAndPut(String projectName, Ref oldRef, Ref newRef) throws IOException {
+    if (newRef != NULL_REF && ignoreRefInSharedDb(newRef)) {
+      return true;
+    }
+
     final DistributedAtomicValue distributedRefValue =
         new DistributedAtomicValue(client, pathFor(projectName, oldRef, newRef), retryPolicy);
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java
index f092c7e..6e64850 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java
@@ -45,6 +45,7 @@
   static final ObjectId AN_OBJECT_ID_2 = new ObjectId(1, 2, 3, 4, 6);
   static final ObjectId AN_OBJECT_ID_3 = new ObjectId(1, 2, 3, 4, 7);
   static final String A_TEST_REF_NAME = "refs/heads/master";
+  static final String A_REF_NAME_OF_A_PATCHSET = "refs/changes/01/1/1";
 
   default String aBranchRef() {
     return RefNames.REFS_HEADS + testBranch();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java
index a94f6c4..bcdf475 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java
@@ -29,6 +29,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import org.apache.curator.retry.RetryNTimes;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Ref;
@@ -139,6 +140,55 @@
     return zkSharedRefDatabase.newRef(aBranchRef(), objectId);
   }
 
+  @Test
+  public void immutableChangeShouldReturnTrue() throws Exception {
+    Ref changeRef = zkSharedRefDatabase.newRef("refs/changes/01/1/1", AN_OBJECT_ID_1);
+
+    boolean shouldReturnTrue =
+        zkSharedRefDatabase.compareAndPut(
+            A_TEST_PROJECT_NAME, SharedRefDatabase.NULL_REF, changeRef);
+
+    assertThat(shouldReturnTrue).isTrue();
+  }
+
+  @Test(expected = Exception.class)
+  public void immutableChangeShouldNotBeStored() throws Exception {
+    Ref changeRef = zkSharedRefDatabase.newRef(A_REF_NAME_OF_A_PATCHSET, AN_OBJECT_ID_1);
+    zkSharedRefDatabase.compareAndPut(A_TEST_PROJECT_NAME, SharedRefDatabase.NULL_REF, changeRef);
+    zookeeperContainer.readRefValueFromZk(A_TEST_PROJECT_NAME, changeRef);
+  }
+
+  @Test
+  public void anImmutableChangeShouldBeIgnored() {
+    Ref immutableChangeRef = zkSharedRefDatabase.newRef(A_REF_NAME_OF_A_PATCHSET, AN_OBJECT_ID_1);
+    assertThat(zkSharedRefDatabase.ignoreRefInSharedDb(immutableChangeRef)).isTrue();
+  }
+
+  @Test
+  public void aChangeMetaShouldNotBeIgnored() {
+    Ref immutableChangeRef = zkSharedRefDatabase.newRef("refs/changes/01/1/meta", AN_OBJECT_ID_1);
+    assertThat(zkSharedRefDatabase.ignoreRefInSharedDb(immutableChangeRef)).isFalse();
+  }
+
+  @Test
+  public void aDraftCommentsShouldBeIgnored() {
+    Ref immutableChangeRef =
+        zkSharedRefDatabase.newRef("refs/draft-comments/01/1/1000000", AN_OBJECT_ID_1);
+    assertThat(zkSharedRefDatabase.ignoreRefInSharedDb(immutableChangeRef)).isTrue();
+  }
+
+  @Test
+  public void regularRefHeadsMasterShouldNotBeIgnored() {
+    Ref immutableChangeRef = zkSharedRefDatabase.newRef("refs/heads/master", AN_OBJECT_ID_1);
+    assertThat(zkSharedRefDatabase.ignoreRefInSharedDb(immutableChangeRef)).isFalse();
+  }
+
+  @Test
+  public void regularCommitShouldNotBeIgnored() {
+    Ref immutableChangeRef = zkSharedRefDatabase.newRef("refs/heads/stable-2.16", AN_OBJECT_ID_1);
+    assertThat(zkSharedRefDatabase.ignoreRefInSharedDb(immutableChangeRef)).isFalse();
+  }
+
   @Override
   public String testBranch() {
     return "branch_" + nameRule.getMethodName();