### Question:
SolverExecutor extends RunnableBase { public void start(final TaskAssigningSolution solution) { checkNotNull("solution", solution); if (!status.compareAndSet(STOPPED, STARTING)) { throw new SolverExecutorException("SolverExecutor start method can only be invoked when the status is STOPPED"); } this.solution = solution; try { this.solver = buildSolver(solverDef, registry); } catch (Exception e) { status.set(STOPPED); throw new SolverExecutorException(e.getMessage(), e); } solver.addEventListener(event -> { if (isAlive() && isStarted()) { eventListener.bestSolutionChanged(event); } }); startPermit.release(); } SolverExecutor(final SolverDef solverDef,
                          final KieServerRegistry registry,
                          final SolverEventListener<TaskAssigningSolution> eventListener); void start(final TaskAssigningSolution solution); boolean isStarted(); boolean isStopped(); void stop(); @Override void destroy(); void addProblemFactChanges(final List<ProblemFactChange<TaskAssigningSolution>> changes); @Override void run();  }### Answer:
@Test(timeout = TEST_TIMEOUT) public void start() throws Exception { CompletableFuture future = startRunnableBase(); runnableBase.start(solution); startFinished.await(); assertTrue(runnableBase.isStarted()); verify(solver).addEventListener(eventListenerCaptor.capture()); eventListenerCaptor.getValue().bestSolutionChanged(event); verify(eventListener).bestSolutionChanged(event); runnableBase.destroy(); future.get(); assertTrue(runnableBase.isDestroyed()); }
@Test public void startWithFailure() { runnableBase.start(solution); Assertions.assertThatThrownBy(() -> runnableBase.start(solution)) .hasMessage("SolverExecutor start method can only be invoked when the status is STOPPED"); }