Add handling of multi-base local disk repositories

Multi-site plugin always used LocalDiskRepositoryManager as its backbone
for repository access. However it should depend on the site configuration
(resulting in MultiBaseLocalDiskRepositoryManager being used when
configured).

Change-Id: Idb07d32e651d409eb40d9a806b6f36fa10f6ee11
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
index 4f7205d..e79e7dd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
@@ -14,22 +14,30 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
+import com.google.gerrit.server.ModuleImpl;
+import com.google.gerrit.server.config.RepositoryConfig;
+import com.google.gerrit.server.git.GitRepositoryManagerModule;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.validation.ValidationModule;
 
+@ModuleImpl(name = GitRepositoryManagerModule.MANAGER_MODULE)
 public class GitModule extends AbstractModule {
   private final Configuration config;
+  private final RepositoryConfig repoConfig;
 
   @Inject
-  public GitModule(Configuration config) {
+  public GitModule(Configuration config, RepositoryConfig repoConfig) {
     this.config = config;
+    this.repoConfig = repoConfig;
   }
 
   @Override
   protected void configure() {
     if (config.getSharedRefDb().isEnabled()) {
-      install(new ValidationModule(config));
+      install(new ValidationModule(config, repoConfig));
+    } else {
+      install(new GitRepositoryManagerModule(repoConfig));
     }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RepositoryManagerModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RepositoryManagerModule.java
new file mode 100644
index 0000000..9b4d1a5
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RepositoryManagerModule.java
@@ -0,0 +1,40 @@
+// Copyright (C) 2022 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.googlesource.gerrit.plugins.multisite.validation;
+
+import com.google.gerrit.lifecycle.LifecycleModule;
+import com.google.gerrit.server.config.RepositoryConfig;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
+import com.google.gerrit.server.git.MultiBaseLocalDiskRepositoryManager;
+
+class RepositoryManagerModule extends LifecycleModule {
+  private final RepositoryConfig cfg;
+
+  RepositoryManagerModule(RepositoryConfig cfg) {
+    this.cfg = cfg;
+  }
+
+  @Override
+  protected void configure() {
+    bind(GitRepositoryManager.class).to(MultiSiteGitRepositoryManager.class);
+
+    // part responsible for physical repositories handling
+    listener().to(LocalDiskRepositoryManager.Lifecycle.class);
+    if (!cfg.getAllBasePaths().isEmpty()) {
+      bind(LocalDiskRepositoryManager.class).to(MultiBaseLocalDiskRepositoryManager.class);
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
index 4a34b7a..dc29fb0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
@@ -16,7 +16,7 @@
 
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.config.RepositoryConfig;
 import com.google.inject.Scopes;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.LockWrapper;
@@ -33,9 +33,11 @@
 
 public class ValidationModule extends FactoryModule {
   private final Configuration cfg;
+  private final RepositoryConfig repoConfig;
 
-  public ValidationModule(Configuration cfg) {
+  public ValidationModule(Configuration cfg, RepositoryConfig repoConfig) {
     this.cfg = cfg;
+    this.repoConfig = repoConfig;
   }
 
   @Override
@@ -54,7 +56,8 @@
     factory(RefUpdateValidator.Factory.class);
     factory(BatchRefUpdateValidator.Factory.class);
 
-    bind(GitRepositoryManager.class).to(MultiSiteGitRepositoryManager.class);
+    install(new RepositoryManagerModule(repoConfig));
+
     DynamicItem.bind(binder(), ReplicationPushFilter.class)
         .to(MultisiteReplicationPushFilter.class);
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/GitModuleTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/GitModuleTest.java
new file mode 100644
index 0000000..eb50991
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/GitModuleTest.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2022 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.googlesource.gerrit.plugins.multisite;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.config.GerritConfig;
+import com.google.gerrit.acceptance.config.GlobalPluginConfig;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
+import com.google.gerrit.server.git.MultiBaseLocalDiskRepositoryManager;
+import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.validation.MultiSiteGitRepositoryManager;
+import org.junit.Test;
+
+@UseLocalDisk
+@NoHttpd
+public class GitModuleTest extends AbstractDaemonTest {
+  @Inject private GitRepositoryManager gitRepoManager;
+  @Inject private LocalDiskRepositoryManager wrapped;
+
+  @Test
+  @GerritConfig(
+      name = "gerrit.installDbModule",
+      value = "com.googlesource.gerrit.plugins.multisite.GitModule")
+  public void shouldUseLocalDiskRepositoryManagerByDefault() {
+    assertThat(gitRepoManager).isInstanceOf(MultiSiteGitRepositoryManager.class);
+    assertThat(wrapped).isNotInstanceOf(MultiBaseLocalDiskRepositoryManager.class);
+  }
+
+  @Test
+  @GerritConfig(
+      name = "gerrit.installDbModule",
+      value = "com.googlesource.gerrit.plugins.multisite.GitModule")
+  @GerritConfig(name = "repository.r1.basePath", value = "/tmp/git1")
+  public void shouldUseMultiBaseLocalDiskRepositoryManagerWhenItIsConfigured() {
+    assertThat(gitRepoManager).isInstanceOf(MultiSiteGitRepositoryManager.class);
+    assertThat(wrapped).isInstanceOf(MultiBaseLocalDiskRepositoryManager.class);
+  }
+
+  @Test
+  @GerritConfig(
+      name = "gerrit.installDbModule",
+      value = "com.googlesource.gerrit.plugins.multisite.GitModule")
+  @GlobalPluginConfig(
+      pluginName = Configuration.PLUGIN_NAME,
+      name = "ref-database.enabled",
+      value = "false")
+  public void shouldInstallDefaultGerritGitManagerWhenRefDbIsDisabled() {
+    assertThat(gitRepoManager).isInstanceOf(LocalDiskRepositoryManager.class);
+  }
+}