| // Copyright (C) 2018 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.rest; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.apache.http.HttpStatus.SC_CREATED; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| import com.google.gerrit.acceptance.AbstractDaemonTest; |
| import com.google.gerrit.acceptance.PushOneCommit; |
| import com.google.gerrit.acceptance.RestResponse; |
| import com.google.gerrit.extensions.registration.DynamicSet; |
| import com.google.gerrit.extensions.registration.RegistrationHandle; |
| import com.google.gerrit.httpd.restapi.ParameterParser; |
| import com.google.gerrit.httpd.restapi.RestApiServlet; |
| import com.google.gerrit.server.events.CommitReceivedEvent; |
| import com.google.gerrit.server.git.validators.CommitValidationException; |
| import com.google.gerrit.server.git.validators.CommitValidationListener; |
| import com.google.gerrit.server.git.validators.CommitValidationMessage; |
| import com.google.gerrit.server.logging.LoggingContext; |
| import com.google.gerrit.server.project.CreateProjectArgs; |
| import com.google.gerrit.server.validators.ProjectCreationValidationListener; |
| import com.google.gerrit.server.validators.ValidationException; |
| import com.google.inject.Inject; |
| import java.util.List; |
| import org.apache.http.message.BasicHeader; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class TraceIT extends AbstractDaemonTest { |
| @Inject private DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners; |
| @Inject private DynamicSet<CommitValidationListener> commitValidationListeners; |
| |
| private TraceValidatingProjectCreationValidationListener projectCreationListener; |
| private RegistrationHandle projectCreationListenerRegistrationHandle; |
| private TraceValidatingCommitValidationListener commitValidationListener; |
| private RegistrationHandle commitValidationRegistrationHandle; |
| |
| @Before |
| public void setup() { |
| projectCreationListener = new TraceValidatingProjectCreationValidationListener(); |
| projectCreationListenerRegistrationHandle = |
| projectCreationValidationListeners.add("gerrit", projectCreationListener); |
| commitValidationListener = new TraceValidatingCommitValidationListener(); |
| commitValidationRegistrationHandle = |
| commitValidationListeners.add("gerrit", commitValidationListener); |
| } |
| |
| @After |
| public void cleanup() { |
| projectCreationListenerRegistrationHandle.remove(); |
| commitValidationRegistrationHandle.remove(); |
| } |
| |
| @Test |
| public void restCallWithoutTrace() throws Exception { |
| RestResponse response = adminRestSession.put("/projects/new1"); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull(); |
| assertThat(projectCreationListener.traceId).isNull(); |
| assertThat(projectCreationListener.isLoggingForced).isFalse(); |
| } |
| |
| @Test |
| public void restCallWithTraceRequestParam() throws Exception { |
| RestResponse response = |
| adminRestSession.put("/projects/new2?" + ParameterParser.TRACE_PARAMETER); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNotNull(); |
| assertThat(projectCreationListener.traceId).isNotNull(); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void restCallWithTraceRequestParamAndProvidedTraceId() throws Exception { |
| RestResponse response = |
| adminRestSession.put("/projects/new3?" + ParameterParser.TRACE_PARAMETER + "=issue/123"); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.traceId).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void restCallWithTraceHeader() throws Exception { |
| RestResponse response = |
| adminRestSession.putWithHeader( |
| "/projects/new4", new BasicHeader(RestApiServlet.X_GERRIT_TRACE, null)); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNotNull(); |
| assertThat(projectCreationListener.traceId).isNotNull(); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void restCallWithTraceHeaderAndProvidedTraceId() throws Exception { |
| RestResponse response = |
| adminRestSession.putWithHeader( |
| "/projects/new5", new BasicHeader(RestApiServlet.X_GERRIT_TRACE, "issue/123")); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.traceId).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void restCallWithTraceRequestParamAndTraceHeader() throws Exception { |
| // trace ID only specified by trace header |
| RestResponse response = |
| adminRestSession.putWithHeader( |
| "/projects/new6?trace", new BasicHeader(RestApiServlet.X_GERRIT_TRACE, "issue/123")); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.traceId).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| |
| // trace ID only specified by trace request parameter |
| response = |
| adminRestSession.putWithHeader( |
| "/projects/new7?trace=issue/123", new BasicHeader(RestApiServlet.X_GERRIT_TRACE, null)); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.traceId).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| |
| // same trace ID specified by trace header and trace request parameter |
| response = |
| adminRestSession.putWithHeader( |
| "/projects/new8?trace=issue/123", |
| new BasicHeader(RestApiServlet.X_GERRIT_TRACE, "issue/123")); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.traceId).isEqualTo("issue/123"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| |
| // different trace IDs specified by trace header and trace request parameter |
| response = |
| adminRestSession.putWithHeader( |
| "/projects/new9?trace=issue/123", |
| new BasicHeader(RestApiServlet.X_GERRIT_TRACE, "issue/456")); |
| assertThat(response.getStatusCode()).isEqualTo(SC_CREATED); |
| assertThat(response.getHeaders(RestApiServlet.X_GERRIT_TRACE)) |
| .containsExactly("issue/123", "issue/456"); |
| assertThat(projectCreationListener.traceIds).containsExactly("issue/123", "issue/456"); |
| assertThat(projectCreationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void pushWithoutTrace() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| PushOneCommit.Result r = push.to("refs/heads/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isNull(); |
| assertThat(commitValidationListener.isLoggingForced).isFalse(); |
| } |
| |
| @Test |
| public void pushWithTrace() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| push.setPushOptions(ImmutableList.of("trace")); |
| PushOneCommit.Result r = push.to("refs/heads/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isNotNull(); |
| assertThat(commitValidationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void pushWithTraceAndProvidedTraceId() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| push.setPushOptions(ImmutableList.of("trace=issue/123")); |
| PushOneCommit.Result r = push.to("refs/heads/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isEqualTo("issue/123"); |
| assertThat(commitValidationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void pushForReviewWithoutTrace() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| PushOneCommit.Result r = push.to("refs/for/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isNull(); |
| assertThat(commitValidationListener.isLoggingForced).isFalse(); |
| } |
| |
| @Test |
| public void pushForReviewWithTrace() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| push.setPushOptions(ImmutableList.of("trace")); |
| PushOneCommit.Result r = push.to("refs/for/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isNotNull(); |
| assertThat(commitValidationListener.isLoggingForced).isTrue(); |
| } |
| |
| @Test |
| public void pushForReviewWithTraceAndProvidedTraceId() throws Exception { |
| PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); |
| push.setPushOptions(ImmutableList.of("trace=issue/123")); |
| PushOneCommit.Result r = push.to("refs/for/master"); |
| r.assertOkStatus(); |
| assertThat(commitValidationListener.traceId).isEqualTo("issue/123"); |
| assertThat(commitValidationListener.isLoggingForced).isTrue(); |
| } |
| |
| private static class TraceValidatingProjectCreationValidationListener |
| implements ProjectCreationValidationListener { |
| String traceId; |
| ImmutableSet<String> traceIds; |
| Boolean isLoggingForced; |
| |
| @Override |
| public void validateNewProject(CreateProjectArgs args) throws ValidationException { |
| this.traceId = |
| Iterables.getFirst(LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"), null); |
| this.traceIds = LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"); |
| this.isLoggingForced = LoggingContext.getInstance().shouldForceLogging(null, null, false); |
| } |
| } |
| |
| private static class TraceValidatingCommitValidationListener implements CommitValidationListener { |
| String traceId; |
| Boolean isLoggingForced; |
| |
| @Override |
| public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent) |
| throws CommitValidationException { |
| this.traceId = |
| Iterables.getFirst(LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"), null); |
| this.isLoggingForced = LoggingContext.getInstance().shouldForceLogging(null, null, false); |
| return ImmutableList.of(); |
| } |
| } |
| } |