Use new project creation API

Change-Id: I1508490fa3144515055c1eda2f567160cc3969b9
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 68b0699..a4eda1b 100644
--- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -552,25 +552,50 @@
     return resourcePrefix + name;
   }
 
-  protected Project.NameKey createProject(String nameSuffix) throws RestApiException {
-    return createProject(nameSuffix, null);
+  protected Project.NameKey createProject(String nameSuffix) throws Exception {
+    return projectOperations.newProject().withEmptyCommit().create();
   }
 
   protected Project.NameKey createProject(String nameSuffix, Project.NameKey parent)
-      throws RestApiException {
+      throws Exception {
     // Default for createEmptyCommit should match TestProjectConfig.
-    return createProject(nameSuffix, parent, true, null);
+    return projectOperations.newProject().withEmptyCommit().parent(parent).create();
   }
 
   protected Project.NameKey createProject(
-      String nameSuffix, Project.NameKey parent, boolean createEmptyCommit)
-      throws RestApiException {
+      String nameSuffix, Project.NameKey parent, boolean createEmptyCommit) throws Exception {
     // Default for createEmptyCommit should match TestProjectConfig.
-    return createProject(nameSuffix, parent, createEmptyCommit, null);
+    if (parent == null) {
+      return projectOperations.newProject().createEmptyCommit(createEmptyCommit).create();
+    }
+    return projectOperations
+        .newProject()
+        .parent(parent)
+        .createEmptyCommit(createEmptyCommit)
+        .create();
   }
 
   protected Project.NameKey createProject(
       String nameSuffix, Project.NameKey parent, boolean createEmptyCommit, SubmitType submitType)
+      throws Exception {
+    if (parent == null) {
+      return projectOperations
+          .newProject()
+          .createEmptyCommit(createEmptyCommit)
+          .submitType(submitType)
+          .create();
+    }
+    return projectOperations
+        .newProject()
+        .submitType(submitType)
+        .parent(parent)
+        .createEmptyCommit(createEmptyCommit)
+        .parent(parent)
+        .create();
+  }
+
+  protected Project.NameKey createProjectOverAPI(
+      String nameSuffix, Project.NameKey parent, boolean createEmptyCommit, SubmitType submitType)
       throws RestApiException {
     ProjectInput in = new ProjectInput();
     in.name = name(nameSuffix);
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 744d1e9..fc0805e 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -69,6 +69,7 @@
 import com.google.gerrit.acceptance.TestProjectInput;
 import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
 import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.FooterConstants;
 import com.google.gerrit.common.data.LabelFunction;
 import com.google.gerrit.common.data.LabelType;
@@ -196,6 +197,7 @@
   @Inject private IndexConfig indexConfig;
 
   @Inject protected GroupOperations groupOperations;
+  @Inject private ProjectOperations projectOperations;
 
   private ChangeIndexedCounter changeIndexedCounter;
   private RegistrationHandle changeIndexedCounterHandle;
@@ -1613,7 +1615,7 @@
   @Test
   public void pushCommitWithFooterOfOtherUserThatCannotSeeChange() throws Exception {
     // create hidden project that is only visible to administrators
-    Project.NameKey p = createProject("p");
+    Project.NameKey p = projectOperations.newProject().create();
     try (ProjectConfigUpdate u = updateProject(p)) {
       Util.allow(u.getConfig(), Permission.READ, adminGroupUuid(), "refs/*");
       Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
@@ -1657,7 +1659,7 @@
   @Test
   public void addReviewerThatCannotSeeChange() throws Exception {
     // create hidden project that is only visible to administrators
-    Project.NameKey p = createProject("p");
+    Project.NameKey p = projectOperations.newProject().create();
     try (ProjectConfigUpdate u = updateProject(p)) {
       Util.allow(u.getConfig(), Permission.READ, adminGroupUuid(), "refs/*");
       Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
index e4194a3..f0296fc 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.acceptance.TestAccount;
 import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.config.AccessCheckInfo;
 import com.google.gerrit.extensions.api.config.AccessCheckInput;
@@ -40,7 +41,7 @@
 import org.junit.Test;
 
 public class CheckAccessIT extends AbstractDaemonTest {
-
+  @Inject private ProjectOperations projectOperations;
   @Inject private GroupOperations groupOperations;
 
   private Project.NameKey normalProject;
@@ -50,9 +51,9 @@
 
   @Before
   public void setUp() throws Exception {
-    normalProject = createProject("normal");
-    secretProject = createProject("secret");
-    secretRefProject = createProject("secretRef");
+    normalProject = projectOperations.newProject().create();
+    secretProject = projectOperations.newProject().create();
+    secretRefProject = projectOperations.newProject().create();
     AccountGroup.UUID privilegedGroupUuid =
         groupOperations.newGroup().name(name("privilegedGroup")).create();
 
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java b/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
index 9e2efd8..28a45c3 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
@@ -19,6 +19,7 @@
 
 import com.google.common.collect.Iterables;
 import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.common.data.SubscribeSection;
@@ -29,6 +30,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.StreamSupport;
+import javax.inject.Inject;
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.dircache.DirCacheBuilder;
 import org.eclipse.jgit.dircache.DirCacheEditor;
@@ -57,6 +59,12 @@
 
 public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
 
+  protected TestRepository<?> superRepo;
+  protected Project.NameKey superKey;
+  protected TestRepository<?> subRepo;
+  protected Project.NameKey subKey;
+  @Inject protected ProjectOperations projectOperations;
+
   protected SubmitType getSubmitType() {
     return cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
   }
@@ -109,10 +117,6 @@
   }
 
   private static AtomicInteger contentCounter = new AtomicInteger(0);
-  protected TestRepository<?> superRepo;
-  protected Project.NameKey superKey;
-  protected TestRepository<?> subRepo;
-  protected Project.NameKey subKey;
 
   @Before
   public void setUp() throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
index 94e3c0a..8317ab1 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
@@ -468,9 +468,9 @@
 
   @Test
   @GerritConfig(name = "submodule.verboseSuperprojectUpdate", value = "SUBJECT_ONLY")
-  // The value 195 must tuned to the test environment, and is sensitive to the
+  // The value 110 must tuned to the test environment, and is sensitive to the
   // length of the uniquified repository name.
-  @GerritConfig(name = "submodule.maxCombinedCommitMessageSize", value = "200")
+  @GerritConfig(name = "submodule.maxCombinedCommitMessageSize", value = "110")
   public void submoduleSubjectCommitMessageSizeLimit() throws Exception {
     assume().that(isSubmitWholeTopicEnabled()).isFalse();
     testSubmoduleSubjectCommitMessageAndExpectTruncation();
@@ -481,7 +481,6 @@
     // Make sure that the commit is created at an earlier timestamp than the submit timestamp.
     TestTimeUtil.resetWithClockStep(1, SECONDS);
     try {
-
       allowMatchingSubmoduleSubscription(
           subKey, "refs/heads/master", superKey, "refs/heads/master");
       createSubmoduleSubscription(superRepo, "master", subKey, "master");
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
index bc84593..dd0575d 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
@@ -18,21 +18,25 @@
 
 import com.google.common.collect.Lists;
 import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.extensions.client.ProjectWatchInfo;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
+import com.google.inject.Inject;
 import java.util.ArrayList;
 import java.util.List;
 import org.junit.Test;
 
 public class WatchedProjectsIT extends AbstractDaemonTest {
+  @Inject private ProjectOperations projectOperations;
 
   private static final String NEW_PROJECT_NAME = "newProjectAccess";
 
   @Test
   public void setAndGetWatchedProjects() throws Exception {
-    String projectName1 = createProject(NEW_PROJECT_NAME).get();
-    String projectName2 = createProject(NEW_PROJECT_NAME + "2").get();
+    String projectName1 = projectOperations.newProject().name(NEW_PROJECT_NAME).create().get();
+    String projectName2 =
+        projectOperations.newProject().name(NEW_PROJECT_NAME + "2").create().get();
 
     List<ProjectWatchInfo> projectsToWatch = new ArrayList<>(2);
 
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index 08a76e4..f717d27 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -37,6 +37,8 @@
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.acceptance.TestAccount;
 import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectCreation;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.changes.ChangeApi;
@@ -65,6 +67,7 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.Project.NameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.IdentifiedUser;
@@ -120,6 +123,7 @@
   @Inject private Submit submitHandler;
 
   @Inject private IdentifiedUser.GenericFactory userFactory;
+  @Inject private ProjectOperations projectOperations;
 
   @Inject private DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
   private RegistrationHandle onSubmitValidatorHandle;
@@ -315,7 +319,7 @@
   @Test
   public void submitNoPermission() throws Exception {
     // create project where submit is blocked
-    Project.NameKey p = createProject("p");
+    Project.NameKey p = projectOperations.newProject().create();
     block(p, "refs/*", Permission.SUBMIT, REGISTERED_USERS);
 
     TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@@ -329,7 +333,7 @@
   @Test
   public void noSelfSubmit() throws Exception {
     // create project where submit is blocked for the change owner
-    Project.NameKey p = createProject("p");
+    Project.NameKey p = projectOperations.newProject().create();
     try (ProjectConfigUpdate u = updateProject(p)) {
       Util.block(u.getConfig(), Permission.SUBMIT, CHANGE_OWNER, "refs/*");
       Util.allow(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, "refs/heads/*");
@@ -355,7 +359,7 @@
   @Test
   public void onlySelfSubmit() throws Exception {
     // create project where only the change owner can submit
-    Project.NameKey p = createProject("p");
+    Project.NameKey p = projectOperations.newProject().create();
     try (ProjectConfigUpdate u = updateProject(p)) {
       Util.block(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, "refs/*");
       Util.allow(u.getConfig(), Permission.SUBMIT, CHANGE_OWNER, "refs/*");
@@ -385,8 +389,10 @@
     String topic = "test-topic";
 
     // Create test projects
-    TestRepository<?> repoA = createProjectWithPush("project-a", null, getSubmitType());
-    TestRepository<?> repoB = createProjectWithPush("project-b", null, getSubmitType());
+    Project.NameKey keyA = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoA = cloneProject(keyA);
+    Project.NameKey keyB = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoB = cloneProject(keyB);
 
     // Create changes on project-a
     PushOneCommit.Result change1 =
@@ -419,15 +425,15 @@
     String topic = "test-topic";
 
     // Create test project
-    String projectName = "project-a";
-    TestRepository<?> repoA = createProjectWithPush(projectName, null, getSubmitType());
+    Project.NameKey keyA = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoA = cloneProject(keyA);
 
-    RevCommit initialHead = getRemoteHead(new Project.NameKey(name(projectName)), "master");
+    RevCommit initialHead = getRemoteHead(keyA, "master");
 
     // Create the dev branch on the test project
     BranchInput in = new BranchInput();
     in.revision = initialHead.name();
-    gApi.projects().name(name(projectName)).branch("dev").create(in);
+    gApi.projects().name(keyA.get()).branch("dev").create(in);
 
     // Create changes on master
     PushOneCommit.Result change1 =
@@ -769,8 +775,10 @@
     String topic = "test-topic";
 
     // Create test projects
-    TestRepository<?> repoA = createProjectWithPush("project-a", null, getSubmitType());
-    TestRepository<?> repoB = createProjectWithPush("project-b", null, getSubmitType());
+    Project.NameKey keyA = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoA = cloneProject(keyA);
+    Project.NameKey keyB = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoB = cloneProject(keyB);
 
     // Create changes on project-a
     PushOneCommit.Result change1 =
@@ -815,15 +823,13 @@
           }
         });
     submitWithConflict(change4.getChangeId(), "time to fail");
-    assertThat(projectsCalled).containsExactly(name("project-a"), name("project-b"));
+    assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get());
     for (PushOneCommit.Result change : changes) {
       change.assertChange(Change.Status.NEW, name(topic), admin);
     }
 
     submit(change4.getChangeId());
-    assertThat(projectsCalled)
-        .containsExactly(
-            name("project-a"), name("project-b"), name("project-a"), name("project-b"));
+    assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get(), keyA.get(), keyB.get());
     for (PushOneCommit.Result change : changes) {
       change.assertChange(Change.Status.MERGED, name(topic), admin);
     }
@@ -934,8 +940,10 @@
 
     String topic = "test-topic";
 
-    TestRepository<?> repoA = createProjectWithPush("project-a", null, getSubmitType());
-    TestRepository<?> repoB = createProjectWithPush("project-b", null, getSubmitType());
+    Project.NameKey keyA = createProjectForPush(null, getSubmitType());
+    Project.NameKey keyB = createProjectForPush(null, getSubmitType());
+    TestRepository<?> repoA = cloneProject(keyA);
+    TestRepository<?> repoB = cloneProject(keyB);
 
     PushOneCommit.Result change1 =
         createChange(repoA, "master", "Change 1", "a.txt", "content", topic);
@@ -962,13 +970,13 @@
 
     repoA.git().fetch().call();
     RevWalk rwA = repoA.getRevWalk();
-    RevCommit masterA = rwA.parseCommit(getRemoteHead(name("project-a"), "master"));
+    RevCommit masterA = rwA.parseCommit(getRemoteHead(keyA, "master"));
     RevCommit change1Ps = parseCurrentRevision(rwA, change1.getChangeId());
     assertThat(rwA.isMergedInto(change1Ps, masterA)).isTrue();
 
     repoB.git().fetch().call();
     RevWalk rwB = repoB.getRevWalk();
-    RevCommit masterB = rwB.parseCommit(getRemoteHead(name("project-b"), "master"));
+    RevCommit masterB = rwB.parseCommit(getRemoteHead(keyB, "master"));
     RevCommit change2Ps = parseCurrentRevision(rwB, change2.getChangeId());
     assertThat(rwB.isMergedInto(change2Ps, masterB)).isTrue();
 
@@ -1353,12 +1361,18 @@
     }
   }
 
-  private TestRepository<?> createProjectWithPush(
-      String name, @Nullable Project.NameKey parent, SubmitType submitType) throws Exception {
-    Project.NameKey project = createProject(name, parent, true, submitType);
+  // TODO(hanwen): the submodule tests have a similar method; maybe we could share code?
+  protected Project.NameKey createProjectForPush(@Nullable NameKey parent, SubmitType submitType)
+      throws Exception {
+    TestProjectCreation.Builder b =
+        projectOperations.newProject().withEmptyCommit().submitType(submitType);
+    if (parent != null) {
+      b.parent(parent);
+    }
+    Project.NameKey project = b.create();
     grant(project, "refs/heads/*", Permission.PUSH);
     grant(project, "refs/for/refs/heads/*", Permission.SUBMIT);
-    return cloneProject(project);
+    return project;
   }
 
   protected PushOneCommit.Result createChange(
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
index baf56de..22c19ac 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.acceptance.GitUtil;
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.projects.ProjectInput;
@@ -31,6 +32,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.inject.Inject;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Config;
@@ -43,6 +45,8 @@
 import org.junit.Test;
 
 public class ConfigChangeIT extends AbstractDaemonTest {
+  @Inject private ProjectOperations projectOperations;
+
   @Before
   public void setUp() throws Exception {
     try (ProjectConfigUpdate u = updateProject(project)) {
@@ -144,8 +148,8 @@
   public void rejectDoubleInheritance() throws Exception {
     setApiUser(admin);
     // Create separate projects to test the config
-    Project.NameKey parent = createProject("projectToInheritFrom");
-    Project.NameKey child = createProject("projectWithMalformedConfig");
+    Project.NameKey parent = createProjectOverAPI("projectToInheritFrom", null, true, null);
+    Project.NameKey child = createProjectOverAPI("projectWithMalformedConfig", null, true, null);
 
     String config =
         gApi.projects()
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
index 229122b..062cb69 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
@@ -789,6 +789,6 @@
         untarredFiles.add(entry.getName());
       }
     }
-    assertThat(untarredFiles).containsExactly(name("project-name") + ".git");
+    assertThat(untarredFiles).containsExactly(p1.get() + ".git");
   }
 }
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
index 34d87d0..e2fc14f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
@@ -18,12 +18,14 @@
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.extensions.api.projects.ConfigInput;
 import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
 import com.google.gerrit.extensions.client.InheritableBoolean;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.common.ChangeInput;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.inject.Inject;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
 import org.eclipse.jgit.junit.TestRepository;
 import org.junit.After;
@@ -33,11 +35,12 @@
 public class WorkInProgressByDefaultIT extends AbstractDaemonTest {
   private Project.NameKey project1;
   private Project.NameKey project2;
+  @Inject private ProjectOperations projectOperations;
 
   @Before
   public void setUp() throws Exception {
-    project1 = createProject("project-1");
-    project2 = createProject("project-2", project1);
+    project1 = projectOperations.newProject().create();
+    project2 = projectOperations.newProject().parent(project1).create();
   }
 
   @After
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
index dd92a7a..d6ae794 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
@@ -43,9 +43,9 @@
     Project.NameKey child1_1 = createProject("p1.1", child1);
     Project.NameKey child1_2 = createProject("p1.2", child1);
 
+    assertThatNameList(gApi.projects().name(child1.get()).children()).isOrdered();
     assertThatNameList(gApi.projects().name(child1.get()).children())
-        .containsExactly(child1_1, child1_2)
-        .inOrder();
+        .containsExactly(child1_1, child1_2);
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
index cd88a56..d5fd74e 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
@@ -23,6 +23,7 @@
 import com.google.gerrit.acceptance.NoHttpd;
 import com.google.gerrit.acceptance.Sandboxed;
 import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.projects.ConfigInfo;
 import com.google.gerrit.extensions.api.projects.ConfigInput;
@@ -33,6 +34,7 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.inject.Inject;
 import java.util.List;
 import java.util.Map;
 import org.junit.Test;
@@ -40,13 +42,14 @@
 @NoHttpd
 @Sandboxed
 public class ListProjectsIT extends AbstractDaemonTest {
+  @Inject private ProjectOperations projectOperations;
 
   @Test
   public void listProjects() throws Exception {
     Project.NameKey someProject = createProject("some-project");
-    assertThatNameList(filter(gApi.projects().list().get()))
-        .containsExactly(allProjects, allUsers, project, someProject)
-        .inOrder();
+    assertThatNameList(gApi.projects().list().get())
+        .containsExactly(allProjects, allUsers, project, someProject);
+    assertThatNameList(gApi.projects().list().get()).isOrdered();
   }
 
   @Test
@@ -59,7 +62,7 @@
       u.save();
     }
 
-    assertThatNameList(filter(gApi.projects().list().get())).doesNotContain(project);
+    assertThatNameList(gApi.projects().list().get()).doesNotContain(project);
   }
 
   @Test
@@ -87,91 +90,97 @@
 
   @Test
   public void listProjectsWithLimit() throws Exception {
-    for (int i = 0; i < 5; i++) {
-      createProject("someProject" + i);
+    String pre = "lpwl-someProject";
+    int n = 6;
+    for (int i = 0; i < n; i++) {
+      projectOperations.newProject().name(pre + i).create();
     }
 
-    String p = name("");
-    // 5, plus p which was automatically created.
-    int n = 6;
     for (int i = 1; i <= n + 2; i++) {
-      assertThatNameList(gApi.projects().list().withPrefix(p).withLimit(i).get())
+      assertThatNameList(gApi.projects().list().withPrefix(pre).withLimit(i).get())
           .hasSize(Math.min(i, n));
     }
   }
 
   @Test
   public void listProjectsWithPrefix() throws Exception {
-    Project.NameKey someProject = createProject("some-project");
-    Project.NameKey someOtherProject = createProject("some-other-project");
-    createProject("project-awesome");
+    // Default for createEmptyCommit should match TestProjectConfig.
+    Project.NameKey someProject = projectOperations.newProject().name("listtest-p1").create();
+    Project.NameKey someOtherProject = projectOperations.newProject().name("listtest-p2").create();
+    projectOperations.newProject().name("other-prefix-project").create();
 
-    String p = name("some");
+    String p = "listtest";
     assertBadRequest(gApi.projects().list().withPrefix(p).withRegex(".*"));
     assertBadRequest(gApi.projects().list().withPrefix(p).withSubstring(p));
-    assertThatNameList(filter(gApi.projects().list().withPrefix(p).get()))
-        .containsExactly(someOtherProject, someProject)
-        .inOrder();
-    p = name("SOME");
-    assertThatNameList(filter(gApi.projects().list().withPrefix(p).get())).isEmpty();
+    assertThatNameList(gApi.projects().list().withPrefix(p).get())
+        .containsExactly(someOtherProject, someProject);
+    p = "notlisttest";
+    assertThatNameList(gApi.projects().list().withPrefix(p).get()).isEmpty();
   }
 
   @Test
   public void listProjectsWithRegex() throws Exception {
-    Project.NameKey someProject = createProject("some-project");
-    Project.NameKey someOtherProject = createProject("some-other-project");
-    Project.NameKey projectAwesome = createProject("project-awesome");
+    Project.NameKey someProject = projectOperations.newProject().name("lpwr-some-project").create();
+    Project.NameKey someOtherProject =
+        projectOperations.newProject().name("lpwr-some-other-project").create();
+    Project.NameKey projectAwesome =
+        projectOperations.newProject().name("lpwr-project-awesome").create();
 
     assertBadRequest(gApi.projects().list().withRegex("[.*"));
     assertBadRequest(gApi.projects().list().withRegex(".*").withPrefix("p"));
     assertBadRequest(gApi.projects().list().withRegex(".*").withSubstring("p"));
 
-    assertThatNameList(filter(gApi.projects().list().withRegex(".*some").get()))
+    assertThatNameList(gApi.projects().list().withRegex(".*some").get())
         .containsExactly(projectAwesome);
-    String r = name("some-project$").replace(".", "\\.");
-    assertThatNameList(filter(gApi.projects().list().withRegex(r).get()))
-        .containsExactly(someProject);
-    assertThatNameList(filter(gApi.projects().list().withRegex(".*").get()))
+    String r = ("lpwr-some-project$").replace(".", "\\.");
+    assertThatNameList(gApi.projects().list().withRegex(r).get()).containsExactly(someProject);
+    assertThatNameList(gApi.projects().list().withRegex(".*").get())
         .containsExactly(
-            allProjects, allUsers, project, projectAwesome, someOtherProject, someProject)
-        .inOrder();
+            allProjects, allUsers, project, projectAwesome, someOtherProject, someProject);
   }
 
   @Test
   public void listProjectsWithStart() throws Exception {
+    String pre = "lpws-";
     for (int i = 0; i < 5; i++) {
-      createProject(new Project.NameKey("someProject" + i).get());
+      projectOperations.newProject().name(pre + i).create();
     }
 
-    String p = name("");
-    List<ProjectInfo> all = gApi.projects().list().withPrefix(p).get();
-    // 5, plus p which was automatically created.
-    int n = 6;
+    List<ProjectInfo> all = gApi.projects().list().withPrefix(pre).get();
+    int n = 5;
     assertThat(all).hasSize(n);
-    assertThatNameList(gApi.projects().list().withPrefix(p).withStart(n - 1).get())
+    assertThatNameList(gApi.projects().list().withPrefix(pre).withStart(n - 1).get())
         .containsExactly(new Project.NameKey(Iterables.getLast(all).name));
   }
 
   @Test
   public void listProjectsWithSubstring() throws Exception {
-    Project.NameKey someProject = createProject("some-project");
-    Project.NameKey someOtherProject = createProject("some-other-project");
-    Project.NameKey projectAwesome = createProject("project-awesome");
+    Project.NameKey someProject = projectOperations.newProject().name("some-project").create();
+    Project.NameKey someOtherProject =
+        projectOperations.newProject().name("some-other-project").create();
+    Project.NameKey projectAwesome =
+        projectOperations.newProject().name("project-awesome").create();
 
     assertBadRequest(gApi.projects().list().withSubstring("some").withRegex(".*"));
     assertBadRequest(gApi.projects().list().withSubstring("some").withPrefix("some"));
-    assertThatNameList(filter(gApi.projects().list().withSubstring("some").get()))
-        .containsExactly(projectAwesome, someOtherProject, someProject)
-        .inOrder();
-    assertThatNameList(filter(gApi.projects().list().withSubstring("SOME").get()))
-        .containsExactly(projectAwesome, someOtherProject, someProject)
-        .inOrder();
+    assertThatNameList(gApi.projects().list().withSubstring("some").get())
+        .containsExactly(projectAwesome, someOtherProject, someProject);
+    assertThatNameList(gApi.projects().list().withSubstring("SOME").get())
+        .containsExactly(projectAwesome, someOtherProject, someProject);
   }
 
   @Test
   public void listProjectsWithTree() throws Exception {
-    Project.NameKey someParentProject = createProject("some-parent-project");
-    Project.NameKey someChildProject = createProject("some-child-project", someParentProject);
+    // Default for createEmptyCommit should match TestProjectConfig.
+    Project.NameKey someParentProject =
+        projectOperations.newProject().name("some-parent-project").create();
+    // Default for createEmptyCommit should match TestProjectConfig.
+    Project.NameKey someChildProject =
+        projectOperations
+            .newProject()
+            .name("some-child-project")
+            .parent(someParentProject)
+            .create();
 
     Map<String, ProjectInfo> result = gApi.projects().list().withTree(true).getAsMap();
     assertThat(result).containsKey(someChildProject.get());
@@ -184,9 +193,8 @@
         gApi.projects().list().withType(FilterType.PERMISSIONS).getAsMap();
     assertThat(result.keySet()).containsExactly(allProjects.get(), allUsers.get());
 
-    assertThatNameList(filter(gApi.projects().list().withType(FilterType.ALL).get()))
-        .containsExactly(allProjects, allUsers, project)
-        .inOrder();
+    assertThatNameList(gApi.projects().list().withType(FilterType.ALL).get())
+        .containsExactly(allProjects, allUsers, project);
   }
 
   @Test
@@ -203,8 +211,7 @@
     // The hidden project is included because it was not hidden yet.
     // The read-only project is included.
     assertThatNameList(gApi.projects().list().get())
-        .containsExactly(allProjects, allUsers, project, hidden, readonly)
-        .inOrder();
+        .containsExactly(allProjects, allUsers, project, hidden, readonly);
 
     // Hide the project
     input.state = ProjectState.HIDDEN;
@@ -216,18 +223,15 @@
 
     // Hidden project is not included in the list
     assertThatNameList(gApi.projects().list().get())
-        .containsExactly(allProjects, allUsers, project, readonly)
-        .inOrder();
+        .containsExactly(allProjects, allUsers, project, readonly);
 
     // ALL filter applies to type, and doesn't include hidden state
     assertThatNameList(gApi.projects().list().withType(FilterType.ALL).get())
-        .containsExactly(allProjects, allUsers, project, readonly)
-        .inOrder();
+        .containsExactly(allProjects, allUsers, project, readonly);
 
     // "All" boolean option causes hidden projects to be included
     assertThatNameList(gApi.projects().list().withAll(true).get())
-        .containsExactly(allProjects, allUsers, project, hidden, readonly)
-        .inOrder();
+        .containsExactly(allProjects, allUsers, project, hidden, readonly);
 
     // "State" option causes only the projects in that state to be included
     assertThatNameList(gApi.projects().list().withState(ProjectState.HIDDEN).get())
@@ -235,8 +239,7 @@
     assertThatNameList(gApi.projects().list().withState(ProjectState.READ_ONLY).get())
         .containsExactly(readonly);
     assertThatNameList(gApi.projects().list().withState(ProjectState.ACTIVE).get())
-        .containsExactly(allProjects, allUsers, project)
-        .inOrder();
+        .containsExactly(allProjects, allUsers, project);
 
     // Cannot use "all" and "state" together
     assertBadRequest(gApi.projects().list().withAll(true).withState(ProjectState.ACTIVE));
@@ -250,16 +253,4 @@
       // Expected.
     }
   }
-
-  private Iterable<ProjectInfo> filter(Iterable<ProjectInfo> infos) {
-    String prefix = name("");
-    return Iterables.filter(
-        infos,
-        p -> {
-          return p.name != null
-              && (p.name.equals(allProjects.get())
-                  || p.name.equals(allUsers.get())
-                  || p.name.startsWith(prefix));
-        });
-  }
 }
diff --git a/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java b/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
index 720eeed..c8574de 100644
--- a/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertNotEquals;
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.extensions.conditions.BooleanCondition;
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Project;
@@ -34,6 +35,7 @@
 public class PermissionBackendConditionIT extends AbstractDaemonTest {
 
   @Inject PermissionBackend pb;
+  @Inject ProjectOperations projectOperations;
 
   @Test
   public void globalPermissions_sameUserAndPermissionEquals() throws Exception {
@@ -110,7 +112,7 @@
 
   @Test
   public void projectPermissions_differentResourceSameUserDoesNotEqual() throws Exception {
-    Project.NameKey project2 = createProject("p2");
+    Project.NameKey project2 = projectOperations.newProject().create();
     BooleanCondition cond1 = pb.user(user()).project(project).testCond(ProjectPermission.READ);
     BooleanCondition cond2 = pb.user(user()).project(project2).testCond(ProjectPermission.READ);
 
diff --git a/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java b/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
index cfdd781..f9493fa 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.acceptance.NoHttpd;
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.changes.StarsInput;
@@ -32,6 +33,7 @@
 import com.google.gerrit.server.account.ProjectWatches.NotifyType;
 import com.google.gerrit.server.git.NotifyConfig;
 import com.google.gerrit.testing.FakeEmailSender.Message;
+import com.google.inject.Inject;
 import java.util.EnumSet;
 import java.util.List;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@@ -40,6 +42,8 @@
 
 @NoHttpd
 public class ProjectWatchIT extends AbstractDaemonTest {
+  @Inject private ProjectOperations projectOperations;
+
   @Test
   public void newPatchSetsNotifyConfig() throws Exception {
     Address addr = new Address("Watcher", "watcher@example.com");
@@ -210,7 +214,7 @@
   @Test
   public void watchProject() throws Exception {
     // watch project
-    String watchedProject = createProject("watchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
     setApiUser(user);
     watch(watchedProject);
 
@@ -226,7 +230,7 @@
 
     // push a change to non-watched project -> should not trigger email
     // notification
-    String notWatchedProject = createProject("otherProject").get();
+    String notWatchedProject = projectOperations.newProject().create().get();
     TestRepository<InMemoryRepository> notWatchedRepo =
         cloneProject(new Project.NameKey(notWatchedProject), admin);
     r =
@@ -246,8 +250,8 @@
 
   @Test
   public void watchFile() throws Exception {
-    String watchedProject = createProject("watchedProject").get();
-    String otherWatchedProject = createProject("otherWatchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
+    String otherWatchedProject = projectOperations.newProject().create().get();
     setApiUser(user);
 
     // watch file in project as user
@@ -300,7 +304,7 @@
 
   @Test
   public void watchKeyword() throws Exception {
-    String watchedProject = createProject("watchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
     setApiUser(user);
 
     // watch keyword in project as user
@@ -339,7 +343,7 @@
 
   @Test
   public void watchAllProjects() throws Exception {
-    String anyProject = createProject("anyProject").get();
+    String anyProject = projectOperations.newProject().create().get();
     setApiUser(user);
 
     // watch the All-Projects project to watch all projects
@@ -366,7 +370,7 @@
 
   @Test
   public void watchFileAllProjects() throws Exception {
-    String anyProject = createProject("anyProject").get();
+    String anyProject = projectOperations.newProject().create().get();
     setApiUser(user);
 
     // watch file in All-Projects project as user to watch the file in all
@@ -417,7 +421,7 @@
 
   @Test
   public void watchKeywordAllProjects() throws Exception {
-    String anyProject = createProject("anyProject").get();
+    String anyProject = projectOperations.newProject().create().get();
     setApiUser(user);
 
     // watch keyword in project as user
@@ -458,7 +462,7 @@
   @Test
   public void watchProjectNoNotificationForIgnoredChange() throws Exception {
     // watch project
-    String watchedProject = createProject("watchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
     setApiUser(user);
     watch(watchedProject);
 
@@ -491,7 +495,7 @@
   @Test
   public void watchProjectNoNotificationForPrivateChange() throws Exception {
     // watch project
-    String watchedProject = createProject("watchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
     setApiUser(user);
     watch(watchedProject);
 
@@ -511,7 +515,7 @@
 
   @Test
   public void watchProjectNotifyOnPrivateChange() throws Exception {
-    String watchedProject = createProject("watchedProject").get();
+    String watchedProject = projectOperations.newProject().create().get();
 
     // create group that can view all private changes
     GroupInfo groupThatCanViewPrivateChanges =