/** * Licensed 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 org.apache.aurora.scheduler.updater; import java.util.Set; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import org.apache.aurora.common.testing.easymock.EasyMockTest; import org.apache.aurora.gen.AssignedTask; import org.apache.aurora.gen.ExecutorConfig; import org.apache.aurora.gen.Identity; import org.apache.aurora.gen.Range; import org.apache.aurora.gen.ScheduledTask; import org.apache.aurora.gen.TaskConfig; import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.base.Query; import org.apache.aurora.scheduler.storage.TaskStore; import org.apache.aurora.scheduler.storage.entities.IAssignedTask; import org.apache.aurora.scheduler.storage.entities.IJobKey; import org.apache.aurora.scheduler.storage.entities.IRange; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.ITaskConfig; import org.easymock.IExpectationSetters; import org.junit.Before; import org.junit.Test; import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; public class JobDiffTest extends EasyMockTest { private static final IJobKey JOB = JobKeys.from("role", "env", "job"); private static final Set<IRange> NO_SCOPE = ImmutableSet.of(); private static final Set<IRange> CANARY_SCOPE = ImmutableSet.of(IRange.build(new Range(0, 0))); private TaskStore store; @Before public void setUp() { store = createMock(TaskStore.class); } @Test public void testNoDiff() { ITaskConfig task = makeTask("job", "echo"); expectFetch(instance(task, 0), instance(task, 1)).times(2); control.replay(); assertEquals( new JobDiff(ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of(0, task, 1, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 2), NO_SCOPE)); assertEquals( new JobDiff(ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of(0, task, 1, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 2), CANARY_SCOPE)); } @Test public void testInstancesAdded() { ITaskConfig task = makeTask("job", "echo"); expectFetch(instance(task, 0), instance(task, 1)).times(2); control.replay(); assertEquals( new JobDiff(ImmutableMap.of(), ImmutableSet.of(2, 3, 4), ImmutableMap.of(0, task, 1, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 5), NO_SCOPE)); assertEquals( new JobDiff(ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of(0, task, 1, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 5), CANARY_SCOPE)); } @Test public void testInstancesRemoved() { ITaskConfig task = makeTask("job", "echo"); expectFetch(instance(task, 0), instance(task, 1), instance(task, 2)).times(2); control.replay(); assertEquals( new JobDiff(ImmutableMap.of(1, task, 2, task), ImmutableSet.of(), ImmutableMap.of(0, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 1), NO_SCOPE)); assertEquals( new JobDiff( ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of(0, task, 1, task, 2, task)), JobDiff.compute(store, JOB, JobDiff.asMap(task, 1), CANARY_SCOPE)); } @Test public void testFullUpdate() { ITaskConfig oldTask = makeTask("job", "echo"); ITaskConfig newTask = makeTask("job", "echo2"); expectFetch(instance(oldTask, 0), instance(oldTask, 1), instance(oldTask, 2)).times(2); control.replay(); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask, 1, oldTask, 2, oldTask), ImmutableSet.of(0, 1, 2), ImmutableMap.of()), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 3), NO_SCOPE)); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask), ImmutableSet.of(0), ImmutableMap.of(1, oldTask, 2, oldTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 3), CANARY_SCOPE)); } @Test public void testMultipleConfigsAndHoles() { ITaskConfig oldTask = makeTask("job", "echo"); ITaskConfig oldTask2 = makeTask("job", "echo1"); ITaskConfig newTask = makeTask("job", "echo2"); expectFetch( instance(oldTask, 0), instance(newTask, 1), instance(oldTask2, 3), instance(oldTask, 4)) .times(2); control.replay(); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask, 3, oldTask2, 4, oldTask), ImmutableSet.of(0, 2, 3, 4), ImmutableMap.of(1, newTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 5), NO_SCOPE)); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask), ImmutableSet.of(0), ImmutableMap.of(1, newTask, 3, oldTask2, 4, oldTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 5), CANARY_SCOPE)); } @Test public void testUnchangedInstances() { ITaskConfig oldTask = makeTask("job", "echo"); ITaskConfig newTask = makeTask("job", "echo2"); expectFetch(instance(oldTask, 0), instance(newTask, 1), instance(oldTask, 2)).times(3); control.replay(); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask, 2, oldTask), ImmutableSet.of(0, 2), ImmutableMap.of(1, newTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 3), NO_SCOPE)); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask), ImmutableSet.of(0), ImmutableMap.of(1, newTask, 2, oldTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 3), CANARY_SCOPE)); assertEquals( new JobDiff( ImmutableMap.of(0, oldTask), ImmutableSet.of(0), ImmutableMap.of(1, newTask, 2, oldTask)), JobDiff.compute(store, JOB, JobDiff.asMap(newTask, 4), CANARY_SCOPE)); } @Test public void testObjectOverrides() { control.replay(); JobDiff a = new JobDiff( ImmutableMap.of(0, makeTask("job", "echo")), ImmutableSet.of(0), ImmutableMap.of()); JobDiff b = new JobDiff( ImmutableMap.of(0, makeTask("job", "echo")), ImmutableSet.of(0), ImmutableMap.of()); JobDiff c = new JobDiff( ImmutableMap.of(0, makeTask("job", "echo1")), ImmutableSet.of(0), ImmutableMap.of()); JobDiff d = new JobDiff( ImmutableMap.of(0, makeTask("job", "echo")), ImmutableSet.of(1), ImmutableMap.of()); assertEquals(a, b); assertEquals(ImmutableSet.of(a), ImmutableSet.of(a, b)); assertNotEquals(a, c); assertNotEquals(a, "a string"); assertNotEquals(a, d); assertEquals(a.toString(), b.toString()); } private IExpectationSetters<?> expectFetch(IAssignedTask... results) { ImmutableSet.Builder<IScheduledTask> tasks = ImmutableSet.builder(); for (IAssignedTask result : results) { tasks.add(IScheduledTask.build(new ScheduledTask().setAssignedTask(result.newBuilder()))); } return expect(store.fetchTasks(Query.jobScoped(JOB).active())) .andReturn(tasks.build()); } private static IAssignedTask instance(ITaskConfig config, int instance) { return IAssignedTask.build( new AssignedTask().setTask(config.newBuilder()).setInstanceId(instance)); } private static ITaskConfig makeTask(String job, String config) { return ITaskConfig.build(new TaskConfig() .setJob(JobKeys.from("role", "test", job).newBuilder()) .setOwner(new Identity().setUser("owner")) .setExecutorConfig(new ExecutorConfig().setData(config))); } }