/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate licenses this file * to you 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.jobs; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import io.crate.test.integration.CrateUnitTest; import org.apache.logging.log4j.Logger; import org.elasticsearch.common.logging.Loggers; import org.junit.Before; import org.junit.Test; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.greaterThan; public class AbstractExecutionSubContextTest extends CrateUnitTest { private TestingExecutionSubContext ctx; private Runnable killRunnable = new Runnable() { @Override public void run() { ctx.kill(null); } }; private Runnable closeRunnable = new Runnable() { @Override public void run() { ctx.close(); } }; @Override @Before public void setUp() throws Exception { super.setUp(); ctx = new TestingExecutionSubContext(); } private void runAsync(Runnable task, int calls) { List<Thread> threads = new ArrayList<Thread>(calls); for (int i = 0; i < calls; i++) { Thread t = new Thread(task); t.start(); threads.add(t); } for (Thread thread : threads) { try { thread.join(500); } catch (InterruptedException e) { Throwables.propagate(e); } } } public static class TestingExecutionSubContext extends AbstractExecutionSubContext { private static final Logger LOGGER = Loggers.getLogger(TestingExecutionSubContext.class); final AtomicInteger numPrepare = new AtomicInteger(); final AtomicInteger numStart = new AtomicInteger(); final AtomicInteger numClose = new AtomicInteger(); final AtomicInteger numKill = new AtomicInteger(); public TestingExecutionSubContext(int id) { super(id, LOGGER); } public TestingExecutionSubContext() { this(0); } @Override public String name() { return getClass().getCanonicalName(); } @Override protected void innerClose(@Nullable Throwable t) { numClose.incrementAndGet(); } @Override protected void innerKill(@Nonnull Throwable t) { numKill.incrementAndGet(); } @Override public void innerPrepare() { numPrepare.incrementAndGet(); } @Override protected void innerStart() { numStart.incrementAndGet(); } public List<Integer> stats() { return ImmutableList.of( numPrepare.get(), numStart.get(), numClose.get(), numKill.get() ); } } @Test public void testNormalSequence() throws Exception { TestingExecutionSubContext ctx = new TestingExecutionSubContext(); ctx.prepare(); ctx.start(); ctx.close(); assertThat(ctx.stats(), contains(1, 1, 1, 0)); } @Test public void testCloseAfterPrepare() throws Exception { TestingExecutionSubContext ctx = new TestingExecutionSubContext(); ctx.prepare(); ctx.close(); ctx.start(); ctx.close(); assertThat(ctx.stats(), contains(1, 0, 1, 0)); } @Test public void testParallelClose() throws Exception { ctx.prepare(); ctx.start(); runAsync(closeRunnable, 3); assertThat(ctx.stats(), contains(1, 1, 1, 0)); } @Test public void testParallelKill() throws Exception { ctx.prepare(); ctx.start(); runAsync(killRunnable, 3); assertThat(ctx.stats(), contains(1, 1, 0, 1)); assertThat(ctx.numKill.get(), greaterThan(0)); } }