/* * Copyright 2016 NAVER Corp. * * 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.navercorp.pinpoint.web.vo; import com.navercorp.pinpoint.bootstrap.util.jdk.ThreadLocalRandom; import com.navercorp.pinpoint.common.util.PinpointThreadFactory; import com.navercorp.pinpoint.profiler.util.ThreadDumpUtils; import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadDump; import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadLightDump; import com.navercorp.pinpoint.thrift.dto.command.TThreadLightDump; import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; import java.util.List; /** * @author Taejin Koo */ public class AgentActiveThreadDumpListTest { private static final int CREATE_DUMP_SIZE = 10; private final PinpointThreadFactory pinpointThreadFactory = new PinpointThreadFactory(this.getClass().getSimpleName()); @Test public void basicFunctionTest1() throws Exception { List<WaitingJob> waitingJobList = createWaitingJobList(CREATE_DUMP_SIZE); try { Thread[] threads = createThread(waitingJobList); AgentActiveThreadDumpList activeThreadDumpList = createThreadDumpList(threads); Assert.assertEquals(CREATE_DUMP_SIZE, activeThreadDumpList.getAgentActiveThreadDumpRepository().size()); } finally { clearResource(waitingJobList); } } @Test public void basicFunctionTest2() throws Exception { List<WaitingJob> waitingJobList = createWaitingJobList(CREATE_DUMP_SIZE); try { Thread[] threads = createThread(waitingJobList); AgentActiveThreadDumpList activeThreadDumpList = createThreadLightDumpList(threads); List<AgentActiveThreadDump> sortOldestAgentActiveThreadDumpRepository = activeThreadDumpList.getSortOldestAgentActiveThreadDumpRepository(); long before = 0; for (AgentActiveThreadDump dump : sortOldestAgentActiveThreadDumpRepository) { long startTime = dump.getStartTime(); if (before > startTime) { Assert.fail(); } before = startTime; } } finally { clearResource(waitingJobList); } } @Test(expected = UnsupportedOperationException.class) public void checkUnmodifiableList() throws Exception { List<WaitingJob> waitingJobList = createWaitingJobList(CREATE_DUMP_SIZE); try { Thread[] threads = createThread(waitingJobList); AgentActiveThreadDumpList activeThreadDumpList = createThreadDumpList(threads); List<AgentActiveThreadDump> agentActiveThreadDumpRepository = activeThreadDumpList.getAgentActiveThreadDumpRepository(); agentActiveThreadDumpRepository.remove(0); } finally { clearResource(waitingJobList); } } private List<WaitingJob> createWaitingJobList(int createActiveTraceRepositorySize) { List<WaitingJob> waitingJobList = new ArrayList<WaitingJob>(); for (int i = 0; i < createActiveTraceRepositorySize; i++) { waitingJobList.add(new WaitingJob(100)); } return waitingJobList; } private Thread[] createThread(List<WaitingJob> runnableList) { Thread[] threads = new Thread[runnableList.size()]; for (int i = 0; i < runnableList.size(); i++) { Thread thread = createThread(runnableList.get(i)); threads[i] = thread; } return threads; } private Thread createThread(Runnable runnable) { Thread thread = pinpointThreadFactory.newThread(runnable); thread.start(); return thread; } private AgentActiveThreadDumpList createThreadDumpList(Thread[] threads) { List<TActiveThreadDump> activeThreadDumpList = new ArrayList<>(); for (Thread thread : threads) { TActiveThreadDump tActiveThreadDump = new TActiveThreadDump(); tActiveThreadDump.setStartTime(System.currentTimeMillis() - ThreadLocalRandom.current().nextLong(100000)); tActiveThreadDump.setThreadDump(ThreadDumpUtils.createTThreadDump(thread)); activeThreadDumpList.add(tActiveThreadDump); } AgentActiveThreadDumpFactory factory = new AgentActiveThreadDumpFactory(); return factory.create1(activeThreadDumpList); } private AgentActiveThreadDumpList createThreadLightDumpList(Thread[] threads) { List<TActiveThreadLightDump> activeThreadLightDumpList = new ArrayList<>(); for (Thread thread : threads) { TActiveThreadLightDump tActiveThreadDump = new TActiveThreadLightDump(); tActiveThreadDump.setStartTime(System.currentTimeMillis() - ThreadLocalRandom.current().nextLong(100000)); tActiveThreadDump.setThreadDump(createTThreadLightDump(thread)); activeThreadLightDumpList.add(tActiveThreadDump); } AgentActiveThreadDumpFactory factory = new AgentActiveThreadDumpFactory(); return factory.create2(activeThreadLightDumpList); } private TThreadLightDump createTThreadLightDump(Thread thread) { TThreadLightDump threadDump = new TThreadLightDump(); threadDump.setThreadName(thread.getName()); threadDump.setThreadId(thread.getId()); threadDump.setThreadState(ThreadDumpUtils.toTThreadState(thread.getState())); return threadDump; } private void clearResource(List<WaitingJob> waitingJobList) { if (waitingJobList == null) { return; } for (WaitingJob waitingJob : waitingJobList) { waitingJob.close(); } } private static class WaitingJob implements Runnable { private final long timeIntervalMillis; private boolean close = false; public WaitingJob(long timeIntervalMillis) { this.timeIntervalMillis = timeIntervalMillis; } @Override public void run() { while (!close) { try { Thread.sleep(timeIntervalMillis); } catch (InterruptedException e) { close = true; } } } public void close() { this.close = true; } } }