Commit eed73d6f authored by Martti Käärik's avatar Martti Käärik
Browse files

Helper class for executing parallel test component behaviours + rendering of...

Helper class for executing parallel test component behaviours + rendering of the test class that uses it.
parent 7d983ec0
Loading
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
package org.etsi.mts.tdl.execution.java.rt.core;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ComponentExecutor {
	private Set<TestComponentTest> tests = new HashSet<ComponentExecutor.TestComponentTest>();

	public void addTest(TestControl control, Runnable test) {
		synchronized (this.tests) {
			this.tests.add(new TestComponentTest(control, test));
		}
	}

	public void execute() {

		int count = tests.size();

		ExecutorService pool = Executors.newFixedThreadPool(count);
		CountDownLatch latch = new CountDownLatch(count);

		Set<RuntimeException> errors = new HashSet<>();
		synchronized (tests) {
			for (TestComponentTest test : tests) {
				pool.submit(() -> {
					try {
						test.thread = Thread.currentThread();
						test.test.run();
						
					} catch (Throwable t) {
						System.err.println(t);
						errors.add(new RuntimeException(t));
						
						synchronized (tests) {
							for (TestComponentTest otherTest : tests) {
								if (otherTest == test)
									continue;
								if (otherTest.thread != null)
									otherTest.thread.interrupt();
							}
						}
						
					} finally {
						latch.countDown();
					}
				});
			}
		}

		try {
			latch.await();
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		pool.shutdown();

		if (!errors.isEmpty())
			throw errors.iterator().next();
	}

	class TestComponentTest {
		TestControl control;
		Runnable test;
		Thread thread;

		public TestComponentTest(TestControl control, Runnable test) {
			this.control = control;
			this.test = test;
		}
	}
}