private void runVerification(int numberOfRequests, int jobsPerRequest) { // verify control info CountInfo countInfo = new CountInfo(numberOfRequests, jobsPerRequest); ConcurrentHashMap<Long, ConcurrentLinkedDeque<TraceContext.Info>> testInfoMap = TraceContext.getTestInfoMap(); // LOGGER.info("Thread {}: {}", key, testInfoMap.get(key).toString().replace(",", "\n")); for (ConcurrentLinkedDeque<TraceContext.Info> queue : testInfoMap.values()) { mixedInvariants(queue, countInfo); } countInfo.verify(); // verify trace info for (long rqId = 0; rqId < numberOfRequests; rqId++) { ConcurrentLinkedDeque<Trace> traceQueue = TraceContext.getAllTraceInfoMap().get(rqId); assertEquals(traceQueue.size(), jobsPerRequest + 1); Set<Integer> jobIdSet = new HashSet<Integer>(); for (Trace trace : traceQueue) { // one trace is used for request handler, it has no info recorded if (trace.getValue().size() > 0) { Object obj = trace.getValue().get(0); // we have recorded one entry per job in tests String[] tmp = ((String) obj).split(SEP); long reqId = Long.parseLong(tmp[0].trim()); assertEquals(rqId, reqId); int jobId = Integer.parseInt(tmp[1].trim()); jobIdSet.add(jobId); } } assertEquals(jobIdSet.size(), jobsPerRequest); // show trace LOGGER.info("Trace Tree: {}", TraceContext.getTraceInfoOfRequestId(rqId)); } }
private void singleRequestCall( ExecutorService jobService, final InstanceRequest request, int jobsPerRequest) throws Exception { TraceContext.register(request); Future[] tasks = new Future[jobsPerRequest]; // fan out multiple threads for this request for (int i = 0; i < jobsPerRequest; i++) { final int taskId = i; tasks[i] = jobService.submit( new TraceRunnable() { @Override public void runJob() { String tid = Thread.currentThread().getId() + ""; TraceContext.log(tid, request.getRequestId() + SEP + taskId); } }); } // wait for all threads to finish the job for (int i = 0; i < jobsPerRequest; i++) { // block waiting tasks[i].get(); } TraceContext.unregister(request); }
@Test public void testSingleRequest() throws Exception { TraceContext.reset(); ExecutorService jobService = Executors.newFixedThreadPool(NUMBER_OF_THREADS, new NamedThreadFactory("jobService")); InstanceRequest request = new InstanceRequest(0L, null); request.setEnableTrace(true); singleRequestCall(jobService, request, JOBS_PER_REQUEST); runVerification(1, JOBS_PER_REQUEST); }
/** * If using the shared {@link ExecutorService} created by {@link * Executors#newFixedThreadPool(int)} for handling requests and jobs, avoiding potential deadlock * by making sure NUMBER_OF_REQUESTS < nThreads. (Using non-shared {@link ExecutorService} is * no issue.) * * @throws Exception */ @Test public void testMultipleRequests() throws Exception { TraceContext.reset(); // shared Service ExecutorService sharedService = Executors.newFixedThreadPool(NUMBER_OF_THREADS, new NamedThreadFactory("sharedService")); runVariousConditionTests(sharedService, sharedService); // non-shared Service ExecutorService requestService = Executors.newFixedThreadPool(NUMBER_OF_THREADS, new NamedThreadFactory("requestService")); ExecutorService jobService = Executors.newFixedThreadPool(NUMBER_OF_THREADS, new NamedThreadFactory("jobService")); runVariousConditionTests(requestService, jobService); }
private void runVariousConditionTests(ExecutorService requestService, ExecutorService jobService) throws Exception { int reqStep = NUMBER_OF_REQUESTS / 5; int jobStep = JOBS_PER_REQUEST / 5; boolean shared = false; if (requestService == jobService) { shared = true; } for (int numberOfRequests = reqStep; numberOfRequests <= NUMBER_OF_REQUESTS; numberOfRequests += reqStep) { for (int jobsPerRequest = jobStep; jobsPerRequest < JOBS_PER_REQUEST; jobsPerRequest += jobStep) { if (shared) { LOGGER.info( "Shared exec service for #request: " + numberOfRequests + " #jobsPerRequest: " + jobsPerRequest); } else { LOGGER.info( "Non-shared exec service for #request: " + numberOfRequests + " #jobsPerRequest: " + jobsPerRequest); } if (shared && (numberOfRequests >= NUMBER_OF_THREADS)) { LOGGER.info( "Ignore tests for #request: " + numberOfRequests + ", since it will deadlock."); } else { TraceContext.reset(); multipleRequestsCall(requestService, jobService, numberOfRequests, jobsPerRequest); runVerification(numberOfRequests, jobsPerRequest); } } } }