/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/
package gobblin.runtime.instance;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.util.concurrent.Service.State;
import com.typesafe.config.ConfigFactory;
import gobblin.metrics.MetricContext;
import gobblin.broker.SharedResourcesBrokerFactory;
import gobblin.broker.gobblin_scopes.GobblinScopeTypes;
import gobblin.runtime.api.Configurable;
import gobblin.runtime.api.GobblinInstancePluginFactory;
import gobblin.runtime.api.JobExecutionLauncher;
import gobblin.runtime.api.JobSpec;
import gobblin.runtime.api.JobSpecScheduler;
import gobblin.runtime.job_catalog.InMemoryJobCatalog;
import gobblin.runtime.std.DefaultConfigurableImpl;
import gobblin.runtime.std.DefaultJobSpecScheduleImpl;
import gobblin.testing.AssertWithBackoff;
/**
* Unit tests for {@link DefaultGobblinInstanceDriverImpl}
*/
public class TestDefaultGobblinInstanceDriverImpl {
@Test
public void testScheduling() throws Exception {
final Logger log = LoggerFactory.getLogger(getClass().getName() + ".testScheduling");
final Optional<Logger> loggerOpt = Optional.of(log);
InMemoryJobCatalog jobCatalog = new InMemoryJobCatalog(loggerOpt);
JobSpecScheduler scheduler = Mockito.mock(JobSpecScheduler.class);
JobExecutionLauncher jobLauncher = Mockito.mock(JobExecutionLauncher.class);
Configurable sysConfig = DefaultConfigurableImpl.createFromConfig(ConfigFactory.empty());
final DefaultGobblinInstanceDriverImpl driver =
new StandardGobblinInstanceDriver("testScheduling", sysConfig, jobCatalog, scheduler,
jobLauncher,
Optional.<MetricContext>absent(),
loggerOpt,
Collections.<GobblinInstancePluginFactory>emptyList(), SharedResourcesBrokerFactory.createDefaultTopLevelBroker(ConfigFactory.empty(),
GobblinScopeTypes.GLOBAL.defaultScopeInstance()));
JobSpec js1_1 = JobSpec.builder("test.job1").withVersion("1").build();
JobSpec js1_2 = JobSpec.builder("test.job1").withVersion("2").build();
JobSpec js2 = JobSpec.builder("test.job2").withVersion("1").build();
driver.startAsync().awaitRunning(1000, TimeUnit.MILLISECONDS);
long startTimeMs = System.currentTimeMillis();
Assert.assertTrue(driver.isRunning());
Assert.assertTrue(driver.isInstrumentationEnabled());
Assert.assertNotNull(driver.getMetricContext());
jobCatalog.put(js1_1);
AssertWithBackoff awb = AssertWithBackoff.create().backoffFactor(1.5).maxSleepMs(100)
.timeoutMs(1000).logger(log);
awb.assertTrue(new Predicate<Void>() {
@Override public boolean apply(Void input) {
log.debug("upFlag=" + driver.getMetrics().getUpFlag().getValue().intValue());
return driver.getMetrics().getUpFlag().getValue().intValue() == 1;
}
}, "upFlag==1");
jobCatalog.put(js2);
jobCatalog.put(js1_2);
jobCatalog.remove(js2.getUri());
Mockito.when(
scheduler.scheduleJob(Mockito.eq(js1_1),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class)))
.thenReturn(DefaultJobSpecScheduleImpl.createNoSchedule(js1_1, null));
Mockito.when(
scheduler.scheduleJob(Mockito.eq(js2),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class)))
.thenReturn(DefaultJobSpecScheduleImpl.createNoSchedule(js2, null));
Mockito.when(
scheduler.scheduleJob(Mockito.eq(js1_2),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class)))
.thenReturn(DefaultJobSpecScheduleImpl.createNoSchedule(js1_2, null));
Mockito.verify(scheduler).scheduleJob(Mockito.eq(js1_1),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class));
Mockito.verify(scheduler).scheduleJob(Mockito.eq(js2),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class));
Mockito.verify(scheduler).scheduleJob(Mockito.eq(js1_2),
Mockito.any(DefaultGobblinInstanceDriverImpl.JobSpecRunnable.class));
Mockito.verify(scheduler).unscheduleJob(Mockito.eq(js2.getUri()));
final long elapsedMs = System.currentTimeMillis() - startTimeMs;
awb.assertTrue(new Predicate<Void>() {
@Override public boolean apply(Void input) {
long uptimeMs = driver.getMetrics().getUptimeMs().getValue().longValue();
return uptimeMs >= elapsedMs;
}
}, "uptime > elapsedMs");
long uptimeMs = driver.getMetrics().getUptimeMs().getValue().longValue();
Assert.assertTrue(uptimeMs <= 2 * elapsedMs, "uptime=" + uptimeMs + " elapsedMs=" + elapsedMs);
driver.stopAsync();
driver.awaitTerminated(100, TimeUnit.MILLISECONDS);
Assert.assertEquals(driver.state(), State.TERMINATED);
Assert.assertEquals(driver.getMetrics().getUpFlag().getValue().intValue(), 0);
// Need an assert with retries because Guava service container notifications are async
awb.assertTrue(new Predicate<Void>() {
@Override public boolean apply(Void input) {
log.debug("upTimeMs=" + driver.getMetrics().getUptimeMs().getValue().longValue());
return driver.getMetrics().getUptimeMs().getValue().longValue() == 0;
}
}, "upTimeMs==0");
}
}