support quick create array instance

This commit is contained in:
金戟 2021-03-20 20:23:23 +08:00
parent bbc41f2987
commit a54bb33c09
4 changed files with 76 additions and 40 deletions

View File

@ -35,52 +35,65 @@ class DemoOmniMethodsTest {
@Test
void should_get_any_member() {
Pod pod = preparePod();
Pod pod = OmniConstructor.newInstance(Pod.class);
pod.getSpec().setContainers( OmniConstructor.newArray(Container.class, 3) );
pod.getSpec().getContainers()[0].setCommand("container-cmd-1st");
pod.getSpec().getContainers()[0].getLivenessProbe().getExec().setCommand("liveness-cmd-1st");
pod.getSpec().getContainers()[0].getReadinessProbe().getExec().setCommand("readness-cmd-1st");
pod.getSpec().getContainers()[0].getStartupProbe().getExec().setCommand("startup-cmd-1st");
pod.getSpec().getContainers()[1].setCommand("container-cmd-2nd");
pod.getSpec().getContainers()[1].getLivenessProbe().getExec().setCommand("liveness-cmd-2nd");
pod.getSpec().getContainers()[1].getReadinessProbe().getExec().setCommand("readness-cmd-2nd");
pod.getSpec().getContainers()[1].getStartupProbe().getExec().setCommand("startup-cmd-2nd");
pod.getSpec().getContainers()[2].setCommand("container-cmd-3rd");
pod.getSpec().getContainers()[2].getLivenessProbe().getExec().setCommand("liveness-cmd-3rd");
pod.getSpec().getContainers()[2].getReadinessProbe().getExec().setCommand("readness-cmd-3rd");
pod.getSpec().getContainers()[2].getStartupProbe().getExec().setCommand("startup-cmd-3rd");
// 使用成员名快速读取成员变量
List<String> commands = OmniAccessor.get(pod, "command");
assertEquals(12, commands.size());
assertEquals("container-cmd-1", commands.get(0));
assertEquals("liveness-cmd-1", commands.get(3));
assertEquals("readness-cmd-1", commands.get(6));
assertEquals("startup-cmd-1", commands.get(9));
assertEquals("container-cmd-1st", commands.get(0));
assertEquals("liveness-cmd-1st", commands.get(3));
assertEquals("readness-cmd-1st", commands.get(6));
assertEquals("startup-cmd-1st", commands.get(9));
// 使用成员类型快速读取成员变量
List<Probe> probes = OmniAccessor.get(pod, "{Probe}");
assertEquals(9, probes.size());
assertEquals("liveness-cmd-1", probes.get(0).getExec().getCommand());
assertEquals("readness-cmd-1", probes.get(3).getExec().getCommand());
assertEquals("startup-cmd-1", probes.get(6).getExec().getCommand());
assertEquals("liveness-cmd-1st", probes.get(0).getExec().getCommand());
assertEquals("readness-cmd-1st", probes.get(3).getExec().getCommand());
assertEquals("startup-cmd-1st", probes.get(6).getExec().getCommand());
// 使用模糊路径快速读取成员变量
List<String> startupCommands = OmniAccessor.get(pod, "startupProbe/*/command");
assertEquals(3, startupCommands.size());
assertEquals("startup-cmd-1", startupCommands.get(0));
assertEquals("startup-cmd-2", startupCommands.get(1));
assertEquals("startup-cmd-3", startupCommands.get(2));
assertEquals("startup-cmd-1st", startupCommands.get(0));
assertEquals("startup-cmd-2nd", startupCommands.get(1));
assertEquals("startup-cmd-3rd", startupCommands.get(2));
// 使用带下标的模糊路径读取成员变量
List<String> firstStartupCommands = OmniAccessor.get(pod, "containers[0]/livenessProbe/*/command");
// 使用带下标的路径读取成员变量
List<Probe> firstStartupCommands = OmniAccessor.get(pod, "containers[0]/livenessProbe");
assertEquals(1, firstStartupCommands.size());
assertEquals("liveness-cmd-1", firstStartupCommands.get(0));
assertEquals("liveness-cmd-1st", firstStartupCommands.get(0).getExec().getCommand());
}
@Test
void should_set_any_member() {
}
private Pod preparePod() {
Pod pod = OmniConstructor.newInstance(Pod.class);
pod.getSpec().setContainers( new Container[]{ OmniConstructor.newInstance(Container.class),
OmniConstructor.newInstance(Container.class), OmniConstructor.newInstance(Container.class) } );
for (int i = 0; i < 3; i++) {
pod.getSpec().getContainers()[i].setCommand("container-cmd-" + (i + 1));
pod.getSpec().getContainers()[i].getLivenessProbe().getExec().setCommand("liveness-cmd-" + (i + 1));
pod.getSpec().getContainers()[i].getReadinessProbe().getExec().setCommand("readness-cmd-" + (i + 1));
pod.getSpec().getContainers()[i].getStartupProbe().getExec().setCommand("startup-cmd-" + (i + 1));
}
return pod;
pod.getSpec().setContainers( OmniConstructor.newArray(Container.class, 3) );
// 使用模糊路径批量给成员变量赋值
OmniAccessor.set(pod, "containers/command", "container-cmd");
OmniAccessor.set(pod, "{Probe}/*/command", "probe-cmd");
assertEquals("container-cmd", pod.getSpec().getContainers()[0].getCommand());
assertEquals("probe-cmd", pod.getSpec().getContainers()[1].getReadinessProbe().getExec().getCommand());
assertEquals("probe-cmd", pod.getSpec().getContainers()[2].getLivenessProbe().getExec().getCommand());
// 使用带下标的路径给成员变量赋值
OmniAccessor.set(pod, "containers[1]/*/*/command", "probe-cmd-2nd");
assertEquals("probe-cmd", pod.getSpec().getContainers()[0].getLivenessProbe().getExec().getCommand());
assertEquals("probe-cmd-2nd", pod.getSpec().getContainers()[1].getLivenessProbe().getExec().getCommand());
}
}

View File

@ -248,6 +248,16 @@ public class OmniAccessor {
throws IllegalAccessException {
String name = extraNameFromMemberRecord(memberSegment);
int nth = extraIndexFromQuery(querySegment);
if (target.getClass().isArray()) {
for (int i = 0; i < Array.getLength(target); i++) {
setFieldByName(Array.get(target, i), name, nth, value);
}
} else {
setFieldByName(target, name, nth, value);
}
}
private static void setFieldByName(Object target, String name, int nth, Object value) throws IllegalAccessException {
Field field = TypeUtil.getFieldByName(target.getClass(), name);
field.setAccessible(true);
if (field.getType().isArray()) {

View File

@ -13,12 +13,18 @@ public class OmniConstructor {
private OmniConstructor() {}
/**
* 快速创建任意指定类型的测试对象
*
* @param clazz 目标类型
* @return 返回新建的对象
*/
public static <T> T newInstance(Class<T> clazz) {
try {
if (clazz.isPrimitive()) {
return newPrimitive(clazz);
} else if (clazz.isArray()) {
return newArray(clazz);
return (T)newArray(clazz.getComponentType(), 0);
} else if (clazz.isEnum()) {
return newEnum(clazz);
} else if (clazz.isInterface()) {
@ -40,11 +46,26 @@ public class OmniConstructor {
}
}
/**
* 快速创建任意指定类型的对象数组
*
* @param clazz 目标类型
* @param size 数组大小
* @return 返回新建的数组
*/
public static <T> T[] newArray(Class<T> clazz, int size) {
T[] array = (T[])Array.newInstance(clazz, size);
for (int i = 0; i < size; i++) {
Array.set(array, i, newInstance(clazz));
}
return array;
}
private static <T> T newObject(Class<T> clazz)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor<?> constructor = getBestConstructor(clazz);
constructor.setAccessible(true);
Object ins = newInstance(constructor);
Object ins = createInstance(constructor);
for (Field f : TypeUtil.getAllFields(clazz)) {
f.setAccessible(true);
if (f.get(ins) == null) {
@ -68,10 +89,6 @@ public class OmniConstructor {
return constants.length > 0 ? constants[0] : null;
}
private static <T> T newArray(Class<T> clazz) {
return (T)Array.newInstance(clazz.getComponentType(), 0);
}
private static <T> T newPrimitive(Class<T> clazz) {
if (clazz.equals(int.class)) {
return (T)Integer.valueOf(0);
@ -93,7 +110,7 @@ public class OmniConstructor {
return null;
}
private static Object newInstance(Constructor<?> constructor)
private static Object createInstance(Constructor<?> constructor)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
Class<?>[] types = constructor.getParameterTypes();
if (types.length == 1 && types[0].equals(Null.class)) {

View File

@ -1,10 +1,6 @@
package com.alibaba.testable.core.util;
import com.sun.tools.javac.util.ListBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.*;
/**
* @author flin
@ -18,7 +14,7 @@ public class FixSizeMap<K, V> {
public FixSizeMap(int size) {
this.capacity = size;
this.content = new HashMap<K, V>(size);
this.order = new ListBuffer<K>();
this.order = new ArrayDeque<K>(size);
}
public V get(K key) {