Repository: aurora Updated Branches: refs/heads/master 6fc7f58ed -> 5506bfa27
Add a test utility to check that all fields are set on a storage entity. Reviewed at https://reviews.apache.org/r/32909/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/5506bfa2 Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/5506bfa2 Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/5506bfa2 Branch: refs/heads/master Commit: 5506bfa27cb69aea1cd08e768aa803d7b4d5a72b Parents: 6fc7f58 Author: Bill Farner <[email protected]> Authored: Mon Apr 6 17:38:55 2015 -0700 Committer: Bill Farner <[email protected]> Committed: Mon Apr 6 17:38:55 2015 -0700 ---------------------------------------------------------------------- .../storage/db/DBJobUpdateStoreTest.java | 24 ++++- .../scheduler/storage/db/DbLockStoreTest.java | 3 +- .../scheduler/storage/db/DbQuotaStoreTest.java | 3 +- .../scheduler/storage/mem/MemTaskStoreTest.java | 34 +++++- .../storage/testing/StorageEntityUtil.java | 108 +++++++++++++++++++ 5 files changed, 168 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/5506bfa2/src/test/java/org/apache/aurora/scheduler/storage/db/DBJobUpdateStoreTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/storage/db/DBJobUpdateStoreTest.java b/src/test/java/org/apache/aurora/scheduler/storage/db/DBJobUpdateStoreTest.java index 9810750..1f50515 100644 --- a/src/test/java/org/apache/aurora/scheduler/storage/db/DBJobUpdateStoreTest.java +++ b/src/test/java/org/apache/aurora/scheduler/storage/db/DBJobUpdateStoreTest.java @@ -19,12 +19,16 @@ import java.util.Set; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import org.apache.aurora.gen.Constraint; +import org.apache.aurora.gen.ExecutorConfig; import org.apache.aurora.gen.Identity; import org.apache.aurora.gen.InstanceTaskConfig; import org.apache.aurora.gen.JobInstanceUpdateEvent; +import org.apache.aurora.gen.JobKey; import org.apache.aurora.gen.JobUpdate; import org.apache.aurora.gen.JobUpdateAction; import org.apache.aurora.gen.JobUpdateDetails; @@ -38,8 +42,11 @@ import org.apache.aurora.gen.JobUpdateStatus; import org.apache.aurora.gen.JobUpdateSummary; import org.apache.aurora.gen.Lock; import org.apache.aurora.gen.LockKey; +import org.apache.aurora.gen.Metadata; import org.apache.aurora.gen.Range; import org.apache.aurora.gen.TaskConfig; +import org.apache.aurora.gen.TaskConstraint; +import org.apache.aurora.gen.ValueConstraint; import org.apache.aurora.gen.storage.StoredJobUpdateDetails; import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.storage.Storage; @@ -57,6 +64,7 @@ import org.apache.aurora.scheduler.storage.entities.IJobUpdateKey; import org.apache.aurora.scheduler.storage.entities.IJobUpdateQuery; import org.apache.aurora.scheduler.storage.entities.IJobUpdateSummary; import org.apache.aurora.scheduler.storage.entities.ILock; +import org.apache.aurora.scheduler.storage.testing.StorageEntityUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -111,6 +119,10 @@ public class DBJobUpdateStoreTest { assertEquals(Optional.<IJobUpdate>absent(), getUpdate(updateId1)); assertEquals(Optional.<IJobUpdate>absent(), getUpdate(updateId2)); + StorageEntityUtil.assertFullyPopulated( + update1, + StorageEntityUtil.getField(JobUpdateSummary.class, "state"), + StorageEntityUtil.getField(IJobUpdateSummary.class, "state")); saveUpdate(update1, Optional.of("lock1")); assertUpdate(update1); @@ -1049,6 +1061,16 @@ public class DBJobUpdateStoreTest { .setJobName(JOB.getName()) .setEnvironment(JOB.getEnvironment()) .setOwner(new Identity(JOB.getRole(), "user")) - .setIsService(true); + .setJob(new JobKey("role", "env", "job")) + .setIsService(true) + .setConstraints(ImmutableSet.of( + new Constraint( + "name", + TaskConstraint.value(new ValueConstraint(true, ImmutableSet.of("x86")))))) + .setRequestedPorts(ImmutableSet.of("http")) + .setTaskLinks(ImmutableMap.of("key", "url")) + .setContactEmail("[email protected]") + .setExecutorConfig(new ExecutorConfig("name", "data")) + .setMetadata(ImmutableSet.of(new Metadata("name", "value"))); } } http://git-wip-us.apache.org/repos/asf/aurora/blob/5506bfa2/src/test/java/org/apache/aurora/scheduler/storage/db/DbLockStoreTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/storage/db/DbLockStoreTest.java b/src/test/java/org/apache/aurora/scheduler/storage/db/DbLockStoreTest.java index d6140f5..ecbe1dd 100644 --- a/src/test/java/org/apache/aurora/scheduler/storage/db/DbLockStoreTest.java +++ b/src/test/java/org/apache/aurora/scheduler/storage/db/DbLockStoreTest.java @@ -31,6 +31,7 @@ import org.apache.aurora.scheduler.storage.Storage.StoreProvider; import org.apache.aurora.scheduler.storage.Storage.Work.Quiet; import org.apache.aurora.scheduler.storage.entities.ILock; import org.apache.aurora.scheduler.storage.entities.ILockKey; +import org.apache.aurora.scheduler.storage.testing.StorageEntityUtil; import org.junit.Before; import org.junit.Test; @@ -169,7 +170,7 @@ public class DbLockStoreTest { assertEquals(Optional.<ILock>absent(), getLock(lock1.getKey())); assertEquals(Optional.<ILock>absent(), getLock(lock2.getKey())); - saveLocks(lock1); + saveLocks(StorageEntityUtil.assertFullyPopulated(lock1)); assertEquals(Optional.of(lock1), getLock(lock1.getKey())); assertEquals(Optional.<ILock>absent(), getLock(lock2.getKey())); saveLocks(lock2); http://git-wip-us.apache.org/repos/asf/aurora/blob/5506bfa2/src/test/java/org/apache/aurora/scheduler/storage/db/DbQuotaStoreTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/storage/db/DbQuotaStoreTest.java b/src/test/java/org/apache/aurora/scheduler/storage/db/DbQuotaStoreTest.java index dc27c3e..a0bd6e1 100644 --- a/src/test/java/org/apache/aurora/scheduler/storage/db/DbQuotaStoreTest.java +++ b/src/test/java/org/apache/aurora/scheduler/storage/db/DbQuotaStoreTest.java @@ -26,6 +26,7 @@ import org.apache.aurora.scheduler.storage.Storage.MutateWork; import org.apache.aurora.scheduler.storage.Storage.StoreProvider; import org.apache.aurora.scheduler.storage.Storage.Work; import org.apache.aurora.scheduler.storage.entities.IResourceAggregate; +import org.apache.aurora.scheduler.storage.testing.StorageEntityUtil; import org.junit.Before; import org.junit.Test; @@ -52,7 +53,7 @@ public class DbQuotaStoreTest { assertEquals(Optional.<IResourceAggregate>absent(), select(ROLE_A)); assertQuotas(ImmutableMap.<String, IResourceAggregate>of()); - save(ROLE_A, QUOTA_A); + save(ROLE_A, StorageEntityUtil.assertFullyPopulated(QUOTA_A)); save(ROLE_B, QUOTA_B); assertEquals(Optional.of(QUOTA_A), select(ROLE_A)); http://git-wip-us.apache.org/repos/asf/aurora/blob/5506bfa2/src/test/java/org/apache/aurora/scheduler/storage/mem/MemTaskStoreTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/storage/mem/MemTaskStoreTest.java b/src/test/java/org/apache/aurora/scheduler/storage/mem/MemTaskStoreTest.java index c1217e2..83b238f 100644 --- a/src/test/java/org/apache/aurora/scheduler/storage/mem/MemTaskStoreTest.java +++ b/src/test/java/org/apache/aurora/scheduler/storage/mem/MemTaskStoreTest.java @@ -22,6 +22,7 @@ import java.util.concurrent.Executors; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -32,19 +33,25 @@ import com.twitter.common.quantity.Time; import com.twitter.common.util.concurrent.ExecutorServiceShutdown; import org.apache.aurora.gen.AssignedTask; +import org.apache.aurora.gen.Constraint; import org.apache.aurora.gen.ExecutorConfig; import org.apache.aurora.gen.Identity; import org.apache.aurora.gen.JobKey; +import org.apache.aurora.gen.Metadata; import org.apache.aurora.gen.ScheduleStatus; import org.apache.aurora.gen.ScheduledTask; import org.apache.aurora.gen.TaskConfig; +import org.apache.aurora.gen.TaskConstraint; +import org.apache.aurora.gen.TaskEvent; import org.apache.aurora.gen.TaskQuery; +import org.apache.aurora.gen.ValueConstraint; import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.base.Query; import org.apache.aurora.scheduler.base.Tasks; import org.apache.aurora.scheduler.storage.TaskStore.Mutable.TaskMutation; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.ITaskConfig; +import org.apache.aurora.scheduler.storage.testing.StorageEntityUtil; import org.junit.Before; import org.junit.Test; @@ -70,6 +77,7 @@ public class MemTaskStoreTest { @Test public void testSave() { + StorageEntityUtil.assertFullyPopulated(TASK_A.newBuilder()); store.saveTasks(ImmutableSet.of(TASK_A, TASK_B)); assertStoreContents(TASK_A, TASK_B); @@ -453,15 +461,39 @@ public class MemTaskStoreTest { private static IScheduledTask makeTask(String id, String role, String env, String jobName) { return IScheduledTask.build(new ScheduledTask() .setStatus(ScheduleStatus.PENDING) + .setTaskEvents(ImmutableList.of( + new TaskEvent(100L, ScheduleStatus.ASSIGNED) + .setMessage("message") + .setScheduler("scheduler"))) + .setAncestorId("ancestor") .setAssignedTask(new AssignedTask() .setInstanceId(0) .setTaskId(id) + .setSlaveId("slave") + .setSlaveHost("slavehost") + .setAssignedPorts(ImmutableMap.of("http", 1000)) .setTask(new TaskConfig() .setJob(new JobKey(role, env, jobName)) .setJobName(jobName) .setEnvironment(env) .setOwner(new Identity(role, role)) - .setExecutorConfig(new ExecutorConfig().setData("executor config"))))); + .setIsService(true) + .setNumCpus(1.0) + .setRamMb(1024) + .setDiskMb(1024) + .setPriority(1) + .setMaxTaskFailures(-1) + .setProduction(true) + .setConstraints(ImmutableSet.of( + new Constraint( + "name", + TaskConstraint.value( + new ValueConstraint(false, ImmutableSet.of("value")))))) + .setRequestedPorts(ImmutableSet.of("http")) + .setTaskLinks(ImmutableMap.of("http", "link")) + .setContactEmail("[email protected]") + .setMetadata(ImmutableSet.of(new Metadata("key", "value"))) + .setExecutorConfig(new ExecutorConfig("name", "config"))))); } private static IScheduledTask makeTask(String id) { http://git-wip-us.apache.org/repos/asf/aurora/blob/5506bfa2/src/test/java/org/apache/aurora/scheduler/storage/testing/StorageEntityUtil.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/storage/testing/StorageEntityUtil.java b/src/test/java/org/apache/aurora/scheduler/storage/testing/StorageEntityUtil.java new file mode 100644 index 0000000..b26ddd3 --- /dev/null +++ b/src/test/java/org/apache/aurora/scheduler/storage/testing/StorageEntityUtil.java @@ -0,0 +1,108 @@ +/** + * 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.storage.testing; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableSet; +import com.google.gson.internal.Primitives; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +/** + * Utility for validating objects used in storage testing. + */ +public final class StorageEntityUtil { + + private StorageEntityUtil() { + // Utility class. + } + + private static void assertFullyPopulated(String name, Object object, Set<Field> ignoredFields) { + if (object instanceof Collection) { + Object[] values = ((Collection<?>) object).toArray(); + assertFalse("Collection is empty: " + name, values.length == 0); + for (int i = 0; i < values.length; i++) { + assertFullyPopulated(name + "[" + i + "]", values[i], ignoredFields); + } + } else if (object instanceof Map) { + Map<?, ?> map = (Map<?, ?>) object; + assertFalse("Map is empty: " + name, map.isEmpty()); + for (Map.Entry<?, ?> entry : map.entrySet()) { + assertFullyPopulated(name + " key", entry.getKey(), ignoredFields); + assertFullyPopulated(name + "[" + entry.getKey() + "]", entry.getValue(), ignoredFields); + } + } else if (!Primitives.isPrimitive(object.getClass()) + && !Primitives.isWrapperType(object.getClass())) { + + for (Field field : object.getClass().getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers())) { + try { + field.setAccessible(true); + String fullName = name + "." + field.getName(); + Object value = field.get(object); + if (!ignoredFields.contains(field)) { + assertNotNull(fullName + " is null", value); + } + if (value != null) { + assertFullyPopulated(fullName, value, ignoredFields); + } + } catch (IllegalAccessException e) { + throw Throwables.propagate(e); + } + } + } + } + } + + /** + * Ensures that an object tree is fully-populated. This is useful when testing store + * implementations to validate that all fields are mapped during a round-trip into and out of + * a store implementation. + * + * @param object Object to ensure is fully populated. + * @param <T> Object type. + * @return The original {@code object}. + */ + public static <T> T assertFullyPopulated(T object, Field... ignoredFields) { + assertFullyPopulated( + object.getClass().getSimpleName(), + object, + ImmutableSet.copyOf(ignoredFields)); + return object; + } + + /** + * Convenience method to get a field by name from a class, to pass as an ignored field to + * {@link #assertFullyPopulated(Object, Field...)}. + * + * @param clazz Class to get a field from. + * @param field Field name. + * @return Field with the given {@code name}. + */ + public static Field getField(Class<?> clazz, String field) { + for (Field f : clazz.getDeclaredFields()) { + if (f.getName().equals(field)) { + return f; + } + } + throw new IllegalArgumentException("Field not found: " + field); + } +}
