Do not load or save contributor agreements for regular projects

The contributor agreements are set on the All-Projects level; however,
the code was still loading and saving them on a project-level basis,
which is incorrect.

Block the loading and storage of the incorrect section and ignore its
content altogether.

NOTE: The contributor agreements in a regular project are just treated
as any other configuration that is not recognised and therefore is
simply ignored rather than rejected at commit time.

Release-Notes: Ignore project-level contributor agreements during load/save as they do not make sense outside the All-Projects
Change-Id: I2fa68c3efa1b69b12cc3c2e26f79dc2e3997283b
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index a981c3c..b8bfe01 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -376,6 +376,7 @@
     this.projectName = projectName;
     this.baseConfig = baseConfig;
     this.allProjectsName = allProjectsName;
+    this.contributorAgreements = new HashMap<>();
   }
 
   public void load(Repository repo) throws IOException, ConfigInvalidException {
@@ -695,7 +696,9 @@
     this.project = p.build();
 
     loadAccountsSection(rc);
-    loadContributorAgreements(rc);
+    if (projectName.equals(allProjectsName)) {
+      loadContributorAgreements(rc);
+    }
     loadAccessSections(rc);
     loadBranchOrderSection(rc);
     loadNotifySections(rc);
@@ -734,7 +737,7 @@
   }
 
   private void loadContributorAgreements(Config rc) {
-    contributorAgreements = new HashMap<>();
+    contributorAgreements.clear();
     for (String name : rc.getSubsections(CONTRIBUTOR_AGREEMENT)) {
       ContributorAgreement.Builder ca = ContributorAgreement.builder(name);
       ca.setDescription(rc.getString(CONTRIBUTOR_AGREEMENT, name, KEY_DESCRIPTION));
@@ -1352,7 +1355,9 @@
 
     Set<AccountGroup.UUID> keepGroups = new HashSet<>();
     saveAccountsSection(rc, keepGroups);
-    saveContributorAgreements(rc, keepGroups);
+    if (projectName.equals(allProjectsName)) {
+      saveContributorAgreements(rc, keepGroups);
+    }
     saveAccessSections(rc, keepGroups);
     saveNotifySections(rc, keepGroups);
     savePluginSections(rc, keepGroups);
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index 2917c13..0003f59 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -132,7 +132,7 @@
                     + "  agreementUrl = http://www.example.com/agree\n")
             .create();
 
-    ProjectConfig cfg = read(rev);
+    ProjectConfig cfg = read(ALL_PROJECTS, rev);
     assertThat(cfg.getAccountsSection().getSameGroupVisibility()).hasSize(2);
     ContributorAgreement ca = cfg.getContributorAgreement("Individual");
     assertThat(ca.getName()).isEqualTo("Individual");
@@ -439,7 +439,7 @@
             .create();
     update(rev);
 
-    ProjectConfig cfg = read(rev);
+    ProjectConfig cfg = read(ALL_PROJECTS, rev);
     cfg.upsertAccessSection(
         "refs/heads/*",
         section -> {
@@ -877,7 +877,7 @@
             .create();
     update(rev);
 
-    ProjectConfig cfg = read(rev);
+    ProjectConfig cfg = read(ALL_PROJECTS, rev);
     ContributorAgreement.Builder section = cfg.getContributorAgreement("Individual").toBuilder();
     section.setAccepted(ImmutableList.of());
     cfg.upsertContributorAgreement(section.build());
@@ -890,6 +890,20 @@
   }
 
   @Test
+  public void contributorSectionIsIgnoredIfSetOnRegularProject() throws Exception {
+    RevCommit rev =
+        tr.commit()
+            .add(
+                "project.config",
+                "[contributor-agreement \"Individual\"]\n" + "  accepted = group Developers\n")
+            .create();
+    update(rev);
+
+    ProjectConfig cfg = read(rev);
+    assertThat(cfg.getContributorAgreement("Individual")).isNull();
+  }
+
+  @Test
   public void notifySectionIsUnsetIfNoNotificationsAreSet() throws Exception {
     RevCommit rev =
         tr.commit()
@@ -1020,7 +1034,12 @@
   }
 
   private ProjectConfig read(RevCommit rev) throws IOException, ConfigInvalidException {
-    ProjectConfig cfg = factory.create(Project.nameKey("test"));
+    return read(Project.nameKey("test"), rev);
+  }
+
+  private ProjectConfig read(Project.NameKey projectNameKey, RevCommit rev)
+      throws IOException, ConfigInvalidException {
+    ProjectConfig cfg = factory.create(projectNameKey);
     cfg.load(db, rev);
     return cfg;
   }