Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.acceptance; 16 : 17 : import static com.google.common.truth.Truth.assertThat; 18 : 19 : import com.google.common.annotations.VisibleForTesting; 20 : import com.google.common.collect.FluentIterable; 21 : import com.google.common.collect.ImmutableList; 22 : import com.google.common.collect.LinkedListMultimap; 23 : import com.google.common.collect.ListMultimap; 24 : import com.google.gerrit.extensions.registration.DynamicSet; 25 : import com.google.gerrit.extensions.registration.RegistrationHandle; 26 : import com.google.gerrit.server.CurrentUser; 27 : import com.google.gerrit.server.IdentifiedUser; 28 : import com.google.gerrit.server.data.RefUpdateAttribute; 29 : import com.google.gerrit.server.events.ChangeDeletedEvent; 30 : import com.google.gerrit.server.events.ChangeMergedEvent; 31 : import com.google.gerrit.server.events.Event; 32 : import com.google.gerrit.server.events.RefEvent; 33 : import com.google.gerrit.server.events.RefUpdatedEvent; 34 : import com.google.gerrit.server.events.ReviewerDeletedEvent; 35 : import com.google.gerrit.server.events.UserScopedEventListener; 36 : import com.google.inject.Inject; 37 : import com.google.inject.Singleton; 38 : import org.eclipse.jgit.lib.ObjectId; 39 : import org.eclipse.jgit.revwalk.RevCommit; 40 : 41 : public class EventRecorder { 42 : private final RegistrationHandle eventListenerRegistration; 43 : private final ListMultimap<String, Event> recordedEvents; 44 : 45 : @Singleton 46 : public static class Factory { 47 : private final DynamicSet<UserScopedEventListener> eventListeners; 48 : private final IdentifiedUser.GenericFactory userFactory; 49 : 50 : @Inject 51 : Factory( 52 : DynamicSet<UserScopedEventListener> eventListeners, 53 132 : IdentifiedUser.GenericFactory userFactory) { 54 132 : this.eventListeners = eventListeners; 55 132 : this.userFactory = userFactory; 56 132 : } 57 : 58 : public EventRecorder create(TestAccount user) { 59 132 : return new EventRecorder(eventListeners, userFactory.create(user.id())); 60 : } 61 : } 62 : 63 132 : public EventRecorder(DynamicSet<UserScopedEventListener> eventListeners, IdentifiedUser user) { 64 132 : recordedEvents = LinkedListMultimap.create(); 65 : 66 132 : eventListenerRegistration = 67 132 : eventListeners.add( 68 : "gerrit", 69 132 : new UserScopedEventListener() { 70 : @Override 71 : public void onEvent(Event e) { 72 116 : if (e instanceof ReviewerDeletedEvent) { 73 11 : recordedEvents.put(ReviewerDeletedEvent.TYPE, e); 74 116 : } else if (e instanceof ChangeDeletedEvent) { 75 7 : recordedEvents.put(ChangeDeletedEvent.TYPE, e); 76 116 : } else if (e instanceof RefEvent) { 77 115 : RefEvent event = (RefEvent) e; 78 115 : String key = 79 115 : refEventKey( 80 115 : event.getType(), event.getProjectNameKey().get(), event.getRefName()); 81 115 : recordedEvents.put(key, event); 82 115 : } else { 83 42 : recordedEvents.put(e.type, e); 84 : } 85 116 : } 86 : 87 : @Override 88 : public CurrentUser getUser() { 89 120 : return user; 90 : } 91 : }); 92 132 : } 93 : 94 : private static String refEventKey(String type, String project, String ref) { 95 115 : return String.format("%s-%s-%s", type, project, ref); 96 : } 97 : 98 : private ImmutableList<RefUpdatedEvent> getRefUpdatedEvents( 99 : String project, String refName, int expectedSize) { 100 13 : String key = refEventKey(RefUpdatedEvent.TYPE, project, refName); 101 13 : if (expectedSize == 0) { 102 7 : assertThat(recordedEvents).doesNotContainKey(key); 103 7 : return ImmutableList.of(); 104 : } 105 : 106 13 : assertThat(recordedEvents).containsKey(key); 107 13 : ImmutableList<RefUpdatedEvent> events = 108 13 : FluentIterable.from(recordedEvents.get(key)) 109 13 : .transform(RefUpdatedEvent.class::cast) 110 13 : .toList(); 111 13 : assertThat(events).hasSize(expectedSize); 112 13 : return events; 113 : } 114 : 115 : @VisibleForTesting 116 : public ImmutableList<ChangeMergedEvent> getChangeMergedEvents( 117 : String project, String branch, int expectedSize) { 118 8 : String key = refEventKey(ChangeMergedEvent.TYPE, project, branch); 119 8 : if (expectedSize == 0) { 120 6 : assertThat(recordedEvents).doesNotContainKey(key); 121 6 : return ImmutableList.of(); 122 : } 123 : 124 8 : assertThat(recordedEvents).containsKey(key); 125 8 : ImmutableList<ChangeMergedEvent> events = 126 8 : FluentIterable.from(recordedEvents.get(key)) 127 8 : .transform(ChangeMergedEvent.class::cast) 128 8 : .toList(); 129 8 : assertThat(events).hasSize(expectedSize); 130 8 : return events; 131 : } 132 : 133 : private ImmutableList<ReviewerDeletedEvent> getReviewerDeletedEvents(int expectedSize) { 134 1 : String key = ReviewerDeletedEvent.TYPE; 135 1 : if (expectedSize == 0) { 136 0 : assertThat(recordedEvents).doesNotContainKey(key); 137 0 : return ImmutableList.of(); 138 : } 139 1 : assertThat(recordedEvents).containsKey(key); 140 1 : ImmutableList<ReviewerDeletedEvent> events = 141 1 : FluentIterable.from(recordedEvents.get(key)) 142 1 : .transform(ReviewerDeletedEvent.class::cast) 143 1 : .toList(); 144 1 : assertThat(events).hasSize(expectedSize); 145 1 : return events; 146 : } 147 : 148 : private ImmutableList<ChangeDeletedEvent> getChangeDeletedEvents(int expectedSize) { 149 1 : String key = ChangeDeletedEvent.TYPE; 150 1 : if (expectedSize == 0) { 151 0 : assertThat(recordedEvents).doesNotContainKey(key); 152 0 : return ImmutableList.of(); 153 : } 154 1 : assertThat(recordedEvents).containsKey(key); 155 1 : ImmutableList<ChangeDeletedEvent> events = 156 1 : FluentIterable.from(recordedEvents.get(key)) 157 1 : .transform(ChangeDeletedEvent.class::cast) 158 1 : .toList(); 159 1 : assertThat(events).hasSize(expectedSize); 160 1 : return events; 161 : } 162 : 163 : public ImmutableList<Event> getGenericEvents(String type, int expectedSize) { 164 1 : if (expectedSize == 0) { 165 0 : assertThat(recordedEvents).doesNotContainKey(type); 166 0 : return ImmutableList.of(); 167 : } 168 1 : assertThat(recordedEvents).containsKey(type); 169 1 : ImmutableList<Event> events = FluentIterable.from(recordedEvents.get(type)).toList(); 170 1 : assertThat(events).hasSize(expectedSize); 171 1 : return events; 172 : } 173 : 174 : public void assertNoRefUpdatedEvents(String project, String branch) throws Exception { 175 0 : getRefUpdatedEvents(project, branch, 0); 176 0 : } 177 : 178 : public void assertRefUpdatedEvents(String project, String branch, String... expected) 179 : throws Exception { 180 5 : ImmutableList<RefUpdatedEvent> events = 181 5 : getRefUpdatedEvents(project, branch, expected.length / 2); 182 5 : int i = 0; 183 5 : for (RefUpdatedEvent event : events) { 184 4 : RefUpdateAttribute actual = event.refUpdate.get(); 185 4 : String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i]; 186 4 : String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1]; 187 4 : assertThat(actual.oldRev).isEqualTo(oldRev); 188 4 : assertThat(actual.newRev).isEqualTo(newRev); 189 4 : i += 2; 190 4 : } 191 5 : } 192 : 193 : public void assertRefUpdatedEvents(String project, String branch, RevCommit... expected) 194 : throws Exception { 195 9 : ImmutableList<RefUpdatedEvent> events = 196 9 : getRefUpdatedEvents(project, branch, expected.length / 2); 197 9 : int i = 0; 198 9 : for (RefUpdatedEvent event : events) { 199 9 : RefUpdateAttribute actual = event.refUpdate.get(); 200 9 : String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i].name(); 201 9 : String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1].name(); 202 9 : assertThat(actual.oldRev).isEqualTo(oldRev); 203 9 : assertThat(actual.newRev).isEqualTo(newRev); 204 9 : i += 2; 205 9 : } 206 9 : } 207 : 208 : public void assertChangeMergedEvents(String project, String branch, String... expected) 209 : throws Exception { 210 6 : ImmutableList<ChangeMergedEvent> events = 211 6 : getChangeMergedEvents(project, branch, expected.length / 2); 212 6 : int i = 0; 213 6 : for (ChangeMergedEvent event : events) { 214 6 : String id = event.change.get().id; 215 6 : assertThat(id).isEqualTo(expected[i]); 216 6 : assertThat(event.newRev).isEqualTo(expected[i + 1]); 217 6 : i += 2; 218 6 : } 219 6 : } 220 : 221 : public void assertReviewerDeletedEvents(String... expected) { 222 1 : ImmutableList<ReviewerDeletedEvent> events = getReviewerDeletedEvents(expected.length / 2); 223 1 : int i = 0; 224 1 : for (ReviewerDeletedEvent event : events) { 225 1 : String id = event.change.get().id; 226 1 : assertThat(id).isEqualTo(expected[i]); 227 1 : String reviewer = event.reviewer.get().email; 228 1 : assertThat(reviewer).isEqualTo(expected[i + 1]); 229 1 : i += 2; 230 1 : } 231 1 : } 232 : 233 : public void assertChangeDeletedEvents(String... expected) { 234 1 : ImmutableList<ChangeDeletedEvent> events = getChangeDeletedEvents(expected.length / 2); 235 1 : int i = 0; 236 1 : for (ChangeDeletedEvent event : events) { 237 1 : String id = event.change.get().id; 238 1 : assertThat(id).isEqualTo(expected[i]); 239 1 : String reviewer = event.deleter.get().email; 240 1 : assertThat(reviewer).isEqualTo(expected[i + 1]); 241 1 : i += 2; 242 1 : } 243 1 : } 244 : 245 : public void close() { 246 132 : eventListenerRegistration.remove(); 247 132 : } 248 : }