@Test public void shouldNotDeadlockWhenAllPossibleWaysOfUpdatingTheConfigAreBeingUsedAtTheSameTime() throws Exception { final ArrayList<Thread> configSaveThreads = new ArrayList<>(); final int pipelineCreatedThroughApiCount = 100; final int pipelineCreatedThroughUICount = 100; for (int i = 0; i < pipelineCreatedThroughUICount; i++) { Thread thread = configSaveThread(i); configSaveThreads.add(thread); } for (int i = 0; i < pipelineCreatedThroughApiCount; i++) { Thread thread = pipelineSaveThread(i); configSaveThreads.add(thread); } for (Thread configSaveThread : configSaveThreads) { Thread timerThread = null; try { timerThread = createThread( new Runnable() { @Override public void run() { try { File configFile = new File(goConfigDao.fileLocation()); String currentConfig = FileUtil.readContentFromFile(configFile); String updatedConfig = currentConfig.replaceFirst( "artifactsdir=\".*\"", "artifactsdir=\"" + UUID.randomUUID().toString() + "\""); FileUtil.writeContentToFile(updatedConfig, configFile); } catch (IOException e) { fail("Failed with error: " + e.getMessage()); } cachedFileGoConfig.forceReload(); } }, "timer-thread"); } catch (InterruptedException e) { fail(e.getMessage()); } try { configSaveThread.start(); timerThread.start(); configSaveThread.join(); timerThread.join(); } catch (InterruptedException e) { fail(e.getMessage()); } } assertThat( goConfigService.getAllPipelineConfigs().size(), is(pipelineCreatedThroughApiCount + pipelineCreatedThroughUICount)); }
private void run( Runnable runnable, int numberOfRequests, final ConcurrentHashMap<String, Boolean> results) throws InterruptedException { Boolean finalResult = true; LOGGER.info("Tests start now!"); final ArrayList<Thread> threads = new ArrayList<>(); for (int i = 0; i < numberOfRequests; i++) { Thread t = new Thread(runnable, "pipeline" + i); threads.add(t); } for (Thread t : threads) { Thread.sleep(1000 * (new Random().nextInt(3) + 1)); t.setUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { LOGGER.error("Exception " + e + " from thread " + t); results.put(t.getName(), false); } }); t.start(); } for (Thread t : threads) { int i = threads.indexOf(t); if (i == (numberOfRequests - 1)) { // takeHeapDump(dumpDir, i); } t.join(); } for (String threadId : results.keySet()) { finalResult = results.get(threadId) && finalResult; } assertThat(finalResult, is(true)); }
@Test public void shouldNotReloadScheduledJobPlansWhenAgentWorkAssignmentIsInProgress() throws Exception { fixture.createPipelineWithFirstStageScheduled(); Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName); JobInstance job = pipeline.getFirstStage().getJobInstances().first(); final JobInstanceService mockJobInstanceService = mock(JobInstanceService.class); final Pipeline pipeline1 = pipeline; final Semaphore sem = new Semaphore(1); sem.acquire(); when(mockJobInstanceService.orderedScheduledBuilds()) .thenReturn(jobInstanceService.orderedScheduledBuilds()); when(mockJobInstanceService.buildByIdWithTransitions(job.getId())) .thenReturn(jobInstanceService.buildByIdWithTransitions(job.getId())); ScheduledPipelineLoader scheduledPipelineLoader = new ScheduledPipelineLoader(null, null, null, null, null, null, null, null) { @Override public Pipeline pipelineWithPasswordAwareBuildCauseByBuildId(long buildId) { sem.release(); sleepQuietly(1000); verify(mockJobInstanceService, times(1)).orderedScheduledBuilds(); return pipeline1; } }; final BuildAssignmentService buildAssignmentServiceUnderTest = new BuildAssignmentService( goConfigService, mockJobInstanceService, scheduleService, agentService, environmentConfigService, timeProvider, transactionTemplate, scheduledPipelineLoader, pipelineService, builderFactory, agentRemoteHandler); final Throwable[] fromThread = new Throwable[1]; buildAssignmentServiceUnderTest.onTimer(); Thread assigner = new Thread( new Runnable() { public void run() { try { final AgentConfig agentConfig = AgentMother.localAgentWithResources("some-other-resource"); buildAssignmentServiceUnderTest.assignWorkToAgent(agent(agentConfig)); } catch (Throwable e) { e.printStackTrace(); fromThread[0] = e; } finally { } } }, "assignmentThread"); assigner.start(); sem.acquire(); buildAssignmentServiceUnderTest.onTimer(); assigner.join(); assertThat(fromThread[0], is(nullValue())); }