You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CeTasksMBeanImplTest.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.ce.monitoring;
  21. import com.google.common.collect.ImmutableSet;
  22. import java.lang.management.ManagementFactory;
  23. import java.util.List;
  24. import java.util.Optional;
  25. import java.util.Random;
  26. import java.util.Set;
  27. import java.util.stream.Collectors;
  28. import java.util.stream.IntStream;
  29. import java.util.stream.Stream;
  30. import javax.annotation.CheckForNull;
  31. import javax.management.InstanceNotFoundException;
  32. import javax.management.ObjectInstance;
  33. import javax.management.ObjectName;
  34. import org.apache.commons.lang.RandomStringUtils;
  35. import org.junit.Test;
  36. import org.sonar.ce.configuration.CeConfiguration;
  37. import org.sonar.ce.taskprocessor.CeWorker;
  38. import org.sonar.ce.taskprocessor.CeWorkerController;
  39. import org.sonar.ce.taskprocessor.CeWorkerFactory;
  40. import org.sonar.core.util.stream.MoreCollectors;
  41. import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
  42. import static org.assertj.core.api.Assertions.assertThat;
  43. import static org.mockito.Mockito.mock;
  44. import static org.mockito.Mockito.when;
  45. public class CeTasksMBeanImplTest {
  46. private static final long PENDING_COUNT = 2;
  47. private static final Optional<Long> PENDING_TIME = Optional.of(10_000L);
  48. private static final long IN_PROGRESS_COUNT = 5;
  49. private static final long ERROR_COUNT = 10;
  50. private static final long SUCCESS_COUNT = 13;
  51. private static final long PROCESSING_TIME = 987;
  52. private static final int WORKER_MAX_COUNT = 666;
  53. private static final int WORKER_COUNT = 56;
  54. private static final Set<CeWorker> WORKERS = IntStream.range(0, 2 + new Random().nextInt(10))
  55. .mapToObj(i -> RandomStringUtils.randomAlphabetic(15))
  56. .map(uuid -> {
  57. CeWorker res = mock(CeWorker.class);
  58. when(res.getUUID()).thenReturn(uuid);
  59. return res;
  60. })
  61. .collect(MoreCollectors.toSet());
  62. private CeWorkerController ceWorkerController = mock(CeWorkerController.class);
  63. private CeTasksMBeanImpl underTest = new CeTasksMBeanImpl(new DumbCEQueueStatus(), new DumbCeConfiguration(), new DumbCeWorkerFactory(), ceWorkerController);
  64. @Test
  65. public void register_and_unregister() throws Exception {
  66. assertThat(getMBean()).isNull();
  67. underTest.start();
  68. assertThat(getMBean()).isNotNull();
  69. underTest.stop();
  70. assertThat(getMBean()).isNull();
  71. }
  72. /**
  73. * Dumb implementation of CEQueueStatus which returns constant values for get methods and throws UnsupportedOperationException
  74. * for other methods.
  75. */
  76. @CheckForNull
  77. private ObjectInstance getMBean() throws Exception {
  78. try {
  79. return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(CeTasksMBean.OBJECT_NAME));
  80. } catch (InstanceNotFoundException e) {
  81. return null;
  82. }
  83. }
  84. @Test
  85. public void get_methods_delegate_to_the_CEQueueStatus_instance() {
  86. assertThat(underTest.getPendingCount()).isEqualTo(PENDING_COUNT);
  87. assertThat(underTest.getLongestTimePending()).isEqualTo(PENDING_TIME);
  88. assertThat(underTest.getInProgressCount()).isEqualTo(IN_PROGRESS_COUNT);
  89. assertThat(underTest.getErrorCount()).isEqualTo(ERROR_COUNT);
  90. assertThat(underTest.getSuccessCount()).isEqualTo(SUCCESS_COUNT);
  91. assertThat(underTest.getProcessingTime()).isEqualTo(PROCESSING_TIME);
  92. }
  93. @Test
  94. public void getWorkerCount_delegates_to_the_CEConfiguration_instance() {
  95. assertThat(underTest.getWorkerCount()).isEqualTo(WORKER_COUNT);
  96. }
  97. @Test
  98. public void getWorkerMaxCount_delegates_to_the_CEConfiguration_instance() {
  99. assertThat(underTest.getWorkerMaxCount()).isEqualTo(WORKER_MAX_COUNT);
  100. }
  101. @Test
  102. public void getWorkerUuids_returns_ordered_list_of_uuids_of_worker_from_CeWorkerFactory_instance() {
  103. List<String> workerUuids = underTest.getWorkerUuids();
  104. assertThat(workerUuids).isEqualTo(WORKERS.stream().map(CeWorker::getUUID).sorted().collect(Collectors.toList()));
  105. // ImmutableSet can not be serialized
  106. assertThat(workerUuids).isNotInstanceOf(ImmutableSet.class);
  107. }
  108. @Test
  109. public void getEnabledWorkerUuids_returns_ordered_list_of_uuids_of_worker_from_CeWorkerFactory_instance_filtered_on_enabled_ones() {
  110. int enabledWorkerCount = new Random().nextInt(WORKERS.size());
  111. int i = 0;
  112. CeWorker[] enabledWorkers = new CeWorker[enabledWorkerCount];
  113. for (CeWorker worker : WORKERS) {
  114. if (i < enabledWorkerCount) {
  115. enabledWorkers[i] = worker;
  116. when(ceWorkerController.isEnabled(worker)).thenReturn(true);
  117. } else {
  118. when(ceWorkerController.isEnabled(worker)).thenReturn(false);
  119. }
  120. i++;
  121. }
  122. List<String> enabledWorkerUuids = underTest.getEnabledWorkerUuids();
  123. assertThat(enabledWorkerUuids).isEqualTo(Stream.of(enabledWorkers).map(CeWorker::getUUID).sorted().collect(Collectors.toList()));
  124. // ImmutableSet can not be serialized
  125. assertThat(enabledWorkerUuids).isNotInstanceOf(ImmutableSet.class);
  126. }
  127. @Test
  128. public void export_system_info() {
  129. ProtobufSystemInfo.Section section = underTest.toProtobuf();
  130. assertThat(section.getName()).isEqualTo("Compute Engine Tasks");
  131. assertThat(section.getAttributesCount()).isEqualTo(9);
  132. }
  133. private static class DumbCEQueueStatus implements CEQueueStatus {
  134. @Override
  135. public long getPendingCount() {
  136. return PENDING_COUNT;
  137. }
  138. @Override
  139. public Optional<Long> getLongestTimePending() {
  140. return PENDING_TIME;
  141. }
  142. @Override
  143. public long addInProgress() {
  144. return methodNotImplemented();
  145. }
  146. @Override
  147. public long getInProgressCount() {
  148. return IN_PROGRESS_COUNT;
  149. }
  150. @Override
  151. public long addError(long processingTime) {
  152. return methodNotImplemented();
  153. }
  154. @Override
  155. public long getErrorCount() {
  156. return ERROR_COUNT;
  157. }
  158. @Override
  159. public long addSuccess(long processingTime) {
  160. return methodNotImplemented();
  161. }
  162. @Override
  163. public long getSuccessCount() {
  164. return SUCCESS_COUNT;
  165. }
  166. @Override
  167. public long getProcessingTime() {
  168. return PROCESSING_TIME;
  169. }
  170. @Override
  171. public boolean areWorkersPaused() {
  172. return false;
  173. }
  174. private long methodNotImplemented() {
  175. throw new UnsupportedOperationException("Not Implemented");
  176. }
  177. }
  178. private static class DumbCeConfiguration implements CeConfiguration {
  179. @Override
  180. public int getWorkerMaxCount() {
  181. return WORKER_MAX_COUNT;
  182. }
  183. @Override
  184. public int getWorkerCount() {
  185. return WORKER_COUNT;
  186. }
  187. @Override
  188. public long getQueuePollingDelay() {
  189. throw new UnsupportedOperationException("getQueuePollingDelay is not implemented");
  190. }
  191. @Override
  192. public long getCleanCeTasksInitialDelay() {
  193. throw new UnsupportedOperationException("getCleanCeTasksInitialDelay is not implemented");
  194. }
  195. @Override
  196. public long getCleanCeTasksDelay() {
  197. throw new UnsupportedOperationException("getCleanCeTasksDelay is not implemented");
  198. }
  199. @Override
  200. public int getGracefulStopTimeoutInMs() {
  201. return 40_000;
  202. }
  203. }
  204. private static class DumbCeWorkerFactory implements CeWorkerFactory {
  205. @Override
  206. public CeWorker create(int ordinal) {
  207. throw new UnsupportedOperationException("create should not be called");
  208. }
  209. @Override
  210. public Set<CeWorker> getWorkers() {
  211. return WORKERS;
  212. }
  213. }
  214. }