blob: f6421a5065e2e9e163bb7e9b7592cc56b7f195cc [file] [log] [blame]
// Copyright (C) 2019 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.google.gerrit.acceptance.testsuite.request;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
import com.google.gerrit.acceptance.UseSsh;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.account.TestAccount;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.CurrentUser.PropertyKey;
import com.google.gerrit.server.notedb.Sequences;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
@UseSsh
public class RequestScopeOperationsImplTest extends AbstractDaemonTest {
private static final AtomicInteger changeCounter = new AtomicInteger();
@Inject private AccountOperations accountOperations;
@Inject private Provider<CurrentUser> userProvider;
@Inject private RequestScopeOperationsImpl requestScopeOperations;
@Inject private Sequences sequences;
@Test
public void setApiUserToExistingUserById() throws Exception {
fastCheckCurrentUser(admin.id());
AcceptanceTestRequestScope.Context oldCtx = requestScopeOperations.setApiUser(user.id());
assertThat(oldCtx.getUser().getAccountId()).isEqualTo(admin.id());
checkCurrentUser(user.id());
}
@Test
public void setApiUserToExistingUserByTestAccount() throws Exception {
fastCheckCurrentUser(admin.id());
TestAccount testAccount =
accountOperations.account(accountOperations.newAccount().username("tester").create()).get();
AcceptanceTestRequestScope.Context oldCtx = requestScopeOperations.setApiUser(testAccount);
assertThat(oldCtx.getUser().getAccountId()).isEqualTo(admin.id());
checkCurrentUser(testAccount.accountId());
}
@Test
public void setApiUserToNonExistingUser() throws Exception {
fastCheckCurrentUser(admin.id());
assertThrows(
RuntimeException.class,
() -> requestScopeOperations.setApiUser(Account.id(sequences.nextAccountId())));
checkCurrentUser(admin.id());
}
@Test
public void resetCurrentApiUserClearsCachedState() throws Exception {
requestScopeOperations.setApiUser(user.id());
PropertyKey<String> key = PropertyKey.create();
atrScope.get().getUser().put(key, "foo");
assertThat(atrScope.get().getUser().get(key)).hasValue("foo");
AcceptanceTestRequestScope.Context oldCtx = requestScopeOperations.resetCurrentApiUser();
checkCurrentUser(user.id());
assertThat(atrScope.get().getUser().get(key)).isEmpty();
assertThat(oldCtx.getUser().get(key)).hasValue("foo");
}
@Test
public void setApiUserAnonymousSetsAnonymousUser() throws Exception {
fastCheckCurrentUser(admin.id());
requestScopeOperations.setApiUserAnonymous();
assertThat(userProvider.get()).isInstanceOf(AnonymousUser.class);
}
private void fastCheckCurrentUser(Account.Id expected) {
// Check current user quickly, since the full check requires creating changes and is quite slow.
assertWithMessage("user from provider is an IdentifiedUser")
.that(userProvider.get().isIdentifiedUser())
.isTrue();
assertWithMessage("user from provider")
.that(userProvider.get().getAccountId())
.isEqualTo(expected);
}
private void checkCurrentUser(Account.Id expected) throws Exception {
// Test all supported ways that an acceptance test might query the active user.
fastCheckCurrentUser(expected);
assertWithMessage("user from GerritApi")
.that(gApi.accounts().self().get()._accountId)
.isEqualTo(expected.get());
AcceptanceTestRequestScope.Context ctx = atrScope.get();
assertWithMessage("user from AcceptanceTestRequestScope.Context is an IdentifiedUser")
.that(ctx.getUser().isIdentifiedUser())
.isTrue();
assertWithMessage("user from AcceptanceTestRequestScope.Context")
.that(ctx.getUser().getAccountId())
.isEqualTo(expected);
checkSshUser(expected);
}
private void checkSshUser(Account.Id expected) throws Exception {
// No "gerrit whoami" command, so the simplest way to check who the user is over SSH is to query
// for owner:self.
ChangeInput cin = new ChangeInput();
cin.project = project.get();
cin.branch = "master";
cin.subject = "Test change " + changeCounter.incrementAndGet();
String changeId = gApi.changes().create(cin).get().changeId;
assertThat(gApi.changes().id(changeId).get().owner._accountId).isEqualTo(expected.get());
String queryResults =
atrScope.get().getSession().exec("gerrit query owner:self change:" + changeId);
assertWithMessage("Change-Ids in query results:\n%s", queryResults)
.that(findDistinct(queryResults, "I[0-9a-f]{40}"))
.containsExactly(changeId);
}
private static ImmutableSet<String> findDistinct(String input, String pattern) {
Matcher m = Pattern.compile(pattern).matcher(input);
ImmutableSet.Builder<String> b = ImmutableSet.builder();
while (m.find()) {
b.add(m.group(0));
}
return b.build();
}
}