use k8s-like model for omni demos

This commit is contained in:
金戟 2021-03-20 17:30:10 +08:00
parent a0dae0dfe1
commit 7b9a0964bc
18 changed files with 870 additions and 165 deletions

View File

@ -1,43 +0,0 @@
package com.alibaba.demo.basic.model.omni;
public class Child {
/**
* An inner class
*/
public class SubChild {
private GrandChild gc;
public GrandChild getGrandChild() {
return gc;
}
public void setGrandChild(GrandChild grandChild) {
this.gc = grandChild;
}
}
// ---------- Member fields ----------
private GrandChild gc;
private EnumChild ec;
// ---------- Getters and Setters ----------
public GrandChild getGrandChild() {
return gc;
}
public void setGrandChild(GrandChild grandChild) {
this.gc = grandChild;
}
public EnumChild getEnumChild() {
return ec;
}
public void setEnumChild(EnumChild enumChild) {
this.ec = enumChild;
}
}

View File

@ -0,0 +1,158 @@
package com.alibaba.demo.basic.model.omni;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Container {
// ---------- Member fields ----------
private List<String> args = new ArrayList();
private String command;
private Map<String, String> env = new HashMap<>();
private String image;
private String imagePullPolicy;
private Probe livenessProbe;
private String name;
private List<ContainerPort> ports = new ArrayList();
private Probe readinessProbe;
private Probe startupProbe;
private Boolean stdin;
private Boolean stdinOnce;
private String terminationMessagePath;
private String terminationMessagePolicy;
private Boolean tty;
private String workingDir;
// ---------- Getters and Setters ----------
public List<String> getArgs() {
return args;
}
public void setArgs(List<String> args) {
this.args = args;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public Map<String, String> getEnv() {
return env;
}
public void setEnv(Map<String, String> env) {
this.env = env;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getImagePullPolicy() {
return imagePullPolicy;
}
public void setImagePullPolicy(String imagePullPolicy) {
this.imagePullPolicy = imagePullPolicy;
}
public Probe getLivenessProbe() {
return livenessProbe;
}
public void setLivenessProbe(Probe livenessProbe) {
this.livenessProbe = livenessProbe;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ContainerPort> getPorts() {
return ports;
}
public void setPorts(List<ContainerPort> ports) {
this.ports = ports;
}
public Probe getReadinessProbe() {
return readinessProbe;
}
public void setReadinessProbe(Probe readinessProbe) {
this.readinessProbe = readinessProbe;
}
public Probe getStartupProbe() {
return startupProbe;
}
public void setStartupProbe(Probe startupProbe) {
this.startupProbe = startupProbe;
}
public Boolean getStdin() {
return stdin;
}
public void setStdin(Boolean stdin) {
this.stdin = stdin;
}
public Boolean getStdinOnce() {
return stdinOnce;
}
public void setStdinOnce(Boolean stdinOnce) {
this.stdinOnce = stdinOnce;
}
public String getTerminationMessagePath() {
return terminationMessagePath;
}
public void setTerminationMessagePath(String terminationMessagePath) {
this.terminationMessagePath = terminationMessagePath;
}
public String getTerminationMessagePolicy() {
return terminationMessagePolicy;
}
public void setTerminationMessagePolicy(String terminationMessagePolicy) {
this.terminationMessagePolicy = terminationMessagePolicy;
}
public Boolean getTty() {
return tty;
}
public void setTty(Boolean tty) {
this.tty = tty;
}
public String getWorkingDir() {
return workingDir;
}
public void setWorkingDir(String workingDir) {
this.workingDir = workingDir;
}
}

View File

@ -0,0 +1,54 @@
package com.alibaba.demo.basic.model.omni;
public class ContainerPort {
// ---------- Member fields ----------
private Integer containerPort;
private String hostIP;
private Integer hostPort;
private String name;
private String protocol;
// ---------- Getters and Setters ----------
public Integer getContainerPort() {
return containerPort;
}
public void setContainerPort(Integer containerPort) {
this.containerPort = containerPort;
}
public String getHostIP() {
return hostIP;
}
public void setHostIP(String hostIP) {
this.hostIP = hostIP;
}
public Integer getHostPort() {
return hostPort;
}
public void setHostPort(Integer hostPort) {
this.hostPort = hostPort;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
}

View File

@ -1,15 +0,0 @@
package com.alibaba.demo.basic.model.omni;
public enum EnumChild {
/**
* demo value - 1
*/
VAL1,
/**
* demo value - 2
*/
VAL2
}

View File

@ -0,0 +1,18 @@
package com.alibaba.demo.basic.model.omni;
public class ExecAction {
// ---------- Member fields ----------
private String command;
// ---------- Getters and Setters ----------
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}

View File

@ -1,22 +0,0 @@
package com.alibaba.demo.basic.model.omni;
public class GrandChild {
// ---------- Member fields ----------
private int value;
// ---------- Constructor, Getters and Setters ----------
public GrandChild(int v) {
this.value = v;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,139 @@
package com.alibaba.demo.basic.model.omni;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ObjectMeta {
// ---------- Member fields ----------
private Map<String, String> annotations;
private String clusterName;
private String creationTimestamp;
private Long deletionGracePeriodSeconds;
private String deletionTimestamp;
private List<String> finalizers = new ArrayList();
private String generateName;
private Long generation;
private Map<String, String> labels;
private String name;
private String namespace;
private String resourceVersion;
private String selfLink;
private String uid;
// ---------- Getters and Setters ----------
public Map<String, String> getAnnotations() {
return annotations;
}
public void setAnnotations(Map<String, String> annotations) {
this.annotations = annotations;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getCreationTimestamp() {
return creationTimestamp;
}
public void setCreationTimestamp(String creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
public Long getDeletionGracePeriodSeconds() {
return deletionGracePeriodSeconds;
}
public void setDeletionGracePeriodSeconds(Long deletionGracePeriodSeconds) {
this.deletionGracePeriodSeconds = deletionGracePeriodSeconds;
}
public String getDeletionTimestamp() {
return deletionTimestamp;
}
public void setDeletionTimestamp(String deletionTimestamp) {
this.deletionTimestamp = deletionTimestamp;
}
public List<String> getFinalizers() {
return finalizers;
}
public void setFinalizers(List<String> finalizers) {
this.finalizers = finalizers;
}
public String getGenerateName() {
return generateName;
}
public void setGenerateName(String generateName) {
this.generateName = generateName;
}
public Long getGeneration() {
return generation;
}
public void setGeneration(Long generation) {
this.generation = generation;
}
public Map<String, String> getLabels() {
return labels;
}
public void setLabels(Map<String, String> labels) {
this.labels = labels;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getResourceVersion() {
return resourceVersion;
}
public void setResourceVersion(String resourceVersion) {
this.resourceVersion = resourceVersion;
}
public String getSelfLink() {
return selfLink;
}
public void setSelfLink(String selfLink) {
this.selfLink = selfLink;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
}

View File

@ -1,39 +0,0 @@
package com.alibaba.demo.basic.model.omni;
public class Parent {
// ---------- Member fields ----------
private Child c;
private Child[] cs;
private Child.SubChild sc;
// ---------- Getters and Setters ----------
public Child getChild() {
return c;
}
public void setChild(Child child) {
this.c = child;
}
public Child[] getChildren() {
return cs;
}
public void setChildren(Child[] children) {
this.cs = children;
}
public Child.SubChild getSubChild() {
return sc;
}
public void setSubChild(Child.SubChild subChild) {
this.sc = subChild;
}
}

View File

@ -0,0 +1,58 @@
package com.alibaba.demo.basic.model.omni;
/**
* 这是一个简化了的Kubernetes Pod模型
* This is a simplified kubernetes pod model
*/
public class Pod {
// ---------- Member fields ----------
private String apiVersion = "v1";
private String kind = "Pod";
private ObjectMeta metadata;
private PodSpec spec;
private PodStatus status;
// ---------- Getters and Setters ----------
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public ObjectMeta getMetadata() {
return metadata;
}
public void setMetadata(ObjectMeta metadata) {
this.metadata = metadata;
}
public PodSpec getSpec() {
return spec;
}
public void setSpec(PodSpec spec) {
this.spec = spec;
}
public PodStatus getStatus() {
return status;
}
public void setStatus(PodStatus status) {
this.status = status;
}
}

View File

@ -0,0 +1,227 @@
package com.alibaba.demo.basic.model.omni;
import java.util.Map;
public class PodSpec {
// ---------- Member fields ----------
private Long activeDeadlineSeconds;
private Boolean automountServiceAccountToken;
private Container[] containers;
private String dnsPolicy;
private Boolean enableServiceLinks;
private Boolean hostIPC;
private Boolean hostNetwork;
private Boolean hostPID;
private String hostname;
private Container[] initContainers;
private String nodeName;
private Map<String, String> nodeSelector;
private String preemptionPolicy;
private Integer priority;
private String priorityClassName;
private String restartPolicy;
private String runtimeClassName;
private String schedulerName;
private String serviceAccount;
private String serviceAccountName;
private Boolean setHostnameAsFQDN;
private Boolean shareProcessNamespace;
private String subdomain;
private Long terminationGracePeriodSeconds;
// ---------- Getters and Setters ----------
public Long getActiveDeadlineSeconds() {
return activeDeadlineSeconds;
}
public void setActiveDeadlineSeconds(Long activeDeadlineSeconds) {
this.activeDeadlineSeconds = activeDeadlineSeconds;
}
public Boolean getAutomountServiceAccountToken() {
return automountServiceAccountToken;
}
public void setAutomountServiceAccountToken(Boolean automountServiceAccountToken) {
this.automountServiceAccountToken = automountServiceAccountToken;
}
public Container[] getContainers() {
return containers;
}
public void setContainers(Container[] containers) {
this.containers = containers;
}
public String getDnsPolicy() {
return dnsPolicy;
}
public void setDnsPolicy(String dnsPolicy) {
this.dnsPolicy = dnsPolicy;
}
public Boolean getEnableServiceLinks() {
return enableServiceLinks;
}
public void setEnableServiceLinks(Boolean enableServiceLinks) {
this.enableServiceLinks = enableServiceLinks;
}
public Boolean getHostIPC() {
return hostIPC;
}
public void setHostIPC(Boolean hostIPC) {
this.hostIPC = hostIPC;
}
public Boolean getHostNetwork() {
return hostNetwork;
}
public void setHostNetwork(Boolean hostNetwork) {
this.hostNetwork = hostNetwork;
}
public Boolean getHostPID() {
return hostPID;
}
public void setHostPID(Boolean hostPID) {
this.hostPID = hostPID;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public Container[] getInitContainers() {
return initContainers;
}
public void setInitContainers(Container[] initContainers) {
this.initContainers = initContainers;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public Map<String, String> getNodeSelector() {
return nodeSelector;
}
public void setNodeSelector(Map<String, String> nodeSelector) {
this.nodeSelector = nodeSelector;
}
public String getPreemptionPolicy() {
return preemptionPolicy;
}
public void setPreemptionPolicy(String preemptionPolicy) {
this.preemptionPolicy = preemptionPolicy;
}
public Integer getPriority() {
return priority;
}
public void setPriority(Integer priority) {
this.priority = priority;
}
public String getPriorityClassName() {
return priorityClassName;
}
public void setPriorityClassName(String priorityClassName) {
this.priorityClassName = priorityClassName;
}
public String getRestartPolicy() {
return restartPolicy;
}
public void setRestartPolicy(String restartPolicy) {
this.restartPolicy = restartPolicy;
}
public String getRuntimeClassName() {
return runtimeClassName;
}
public void setRuntimeClassName(String runtimeClassName) {
this.runtimeClassName = runtimeClassName;
}
public String getSchedulerName() {
return schedulerName;
}
public void setSchedulerName(String schedulerName) {
this.schedulerName = schedulerName;
}
public String getServiceAccount() {
return serviceAccount;
}
public void setServiceAccount(String serviceAccount) {
this.serviceAccount = serviceAccount;
}
public String getServiceAccountName() {
return serviceAccountName;
}
public void setServiceAccountName(String serviceAccountName) {
this.serviceAccountName = serviceAccountName;
}
public Boolean getSetHostnameAsFQDN() {
return setHostnameAsFQDN;
}
public void setSetHostnameAsFQDN(Boolean setHostnameAsFQDN) {
this.setHostnameAsFQDN = setHostnameAsFQDN;
}
public Boolean getShareProcessNamespace() {
return shareProcessNamespace;
}
public void setShareProcessNamespace(Boolean shareProcessNamespace) {
this.shareProcessNamespace = shareProcessNamespace;
}
public String getSubdomain() {
return subdomain;
}
public void setSubdomain(String subdomain) {
this.subdomain = subdomain;
}
public Long getTerminationGracePeriodSeconds() {
return terminationGracePeriodSeconds;
}
public void setTerminationGracePeriodSeconds(Long terminationGracePeriodSeconds) {
this.terminationGracePeriodSeconds = terminationGracePeriodSeconds;
}
}

View File

@ -0,0 +1,22 @@
package com.alibaba.demo.basic.model.omni;
public enum PodStatus {
/**
* waiting
*/
WAITING("waiting"),
/**
* running
*/
RUNNING("running"),
/**
* terminated
*/
TERMINATED("terminated");
PodStatus(String status) {}
}

View File

@ -0,0 +1,63 @@
package com.alibaba.demo.basic.model.omni;
public class Probe {
// ---------- Member fields ----------
private ExecAction exec;
private Integer failureThreshold;
private Integer initialDelaySeconds;
private Integer periodSeconds;
private Integer successThreshold;
private Integer timeoutSeconds;
// ---------- Getters and Setters ----------
public ExecAction getExec() {
return exec;
}
public void setExec(ExecAction exec) {
this.exec = exec;
}
public Integer getFailureThreshold() {
return failureThreshold;
}
public void setFailureThreshold(Integer failureThreshold) {
this.failureThreshold = failureThreshold;
}
public Integer getInitialDelaySeconds() {
return initialDelaySeconds;
}
public void setInitialDelaySeconds(Integer initialDelaySeconds) {
this.initialDelaySeconds = initialDelaySeconds;
}
public Integer getPeriodSeconds() {
return periodSeconds;
}
public void setPeriodSeconds(Integer periodSeconds) {
this.periodSeconds = periodSeconds;
}
public Integer getSuccessThreshold() {
return successThreshold;
}
public void setSuccessThreshold(Integer successThreshold) {
this.successThreshold = successThreshold;
}
public Integer getTimeoutSeconds() {
return timeoutSeconds;
}
public void setTimeoutSeconds(Integer timeoutSeconds) {
this.timeoutSeconds = timeoutSeconds;
}
}

View File

@ -1,13 +1,12 @@
package com.alibaba.demo.basic;
import com.alibaba.demo.basic.model.omni.Child;
import com.alibaba.demo.basic.model.omni.EnumChild;
import com.alibaba.demo.basic.model.omni.GrandChild;
import com.alibaba.demo.basic.model.omni.Parent;
import com.alibaba.demo.basic.model.omni.*;
import com.alibaba.testable.core.tool.OmniAccessor;
import com.alibaba.testable.core.tool.OmniConstructor;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
@ -18,32 +17,52 @@ class DemoOmniMethodsTest {
@Test
void should_construct_any_class() {
Pod pod = OmniConstructor.newInstance(Pod.class);
Container container = OmniConstructor.newInstance(Container.class);
// 所有基础类型初始化为默认数值
GrandChild aGrandChild = OmniConstructor.newInstance(GrandChild.class);
assertEquals(0, aGrandChild.getValue());
assertEquals(0L, pod.getSpec().getActiveDeadlineSeconds());
// 所有枚举类型初始化为第一个可选值
Child aChild = OmniConstructor.newInstance(Child.class);
assertEquals(EnumChild.VAL1, aChild.getEnumChild());
assertEquals(PodStatus.WAITING, pod.getStatus());
// 所有数组类型初始化为空数组
// 所有子孙成员对象都会逐级初始化
Parent aParent = OmniConstructor.newInstance(Parent.class);
assertEquals(0, aParent.getChildren().length);
assertEquals(0, aParent.getSubChild().getGrandChild().getValue());
assertEquals(0, pod.getSpec().getContainers().length);
// 任意深度的子孙成员对象都会被初始化
assertEquals("", container.getReadinessProbe().getExec().getCommand());
}
@Test
void should_get_any_member() {
Parent demo = OmniConstructor.newInstance(Parent.class);
Pod pod = preparePod();
demo.getChild().setEnumChild(EnumChild.VAL2);
assertEquals(EnumChild.VAL2, OmniAccessor.getFirst(demo, "ec"));
assertEquals(EnumChild.VAL2, OmniAccessor.getFirst(demo, "{EnumChild}"));
assertEquals(EnumChild.VAL2, OmniAccessor.getFirst(demo, "c/ec"));
// 使用成员名快速读取成员变量
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));
demo.setChildren(new Child[]{ OmniConstructor.newInstance(Child.class) });
assertEquals(EnumChild.VAL1, OmniAccessor.getFirst(demo, "cs[0]/ec"));
// 使用成员类型快速读取成员变量
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());
// 使用模糊路径快速读取成员变量
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));
// 使用带下标的模糊路径读取成员变量
List<String> firstStartupCommands = OmniAccessor.get(pod, "containers[0]/livenessProbe/*/command");
assertEquals(1, firstStartupCommands.size());
assertEquals("liveness-cmd-1", firstStartupCommands.get(0));
}
@Test
@ -51,4 +70,17 @@ class DemoOmniMethodsTest {
}
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;
}
}

View File

@ -107,7 +107,7 @@ public class OmniAccessor {
}
private static List<String> generateMemberIndex(String basePath, Class<?> clazz) {
if (clazz.isEnum()) {
if (isAtomicType(clazz)) {
return Collections.emptyList();
}
List<String> paths = new ArrayList<String>();
@ -121,6 +121,13 @@ public class OmniAccessor {
return paths;
}
private static boolean isAtomicType(Class<?> clazz) {
return clazz.isEnum() || clazz.equals(Integer.class) || clazz.equals(Short.class) || clazz.equals(Long.class)
|| clazz.equals(Byte.class) || clazz.equals(Character.class) || clazz.equals(Float.class)
|| clazz.equals(Double.class) || clazz.equals(Boolean.class) || clazz.equals(Class.class)
|| clazz.equals(String.class);
}
private static String toPath(Field field) {
return field.getName() + BRACE_START + field.getType().getSimpleName() + BRACE_END;
}

View File

@ -47,7 +47,9 @@ public class OmniConstructor {
Object ins = newInstance(constructor);
for (Field f : TypeUtil.getAllFields(clazz)) {
f.setAccessible(true);
f.set(ins, newInstance(f.getType()));
if (f.get(ins) == null) {
f.set(ins, newInstance(f.getType()));
}
}
return (T)ins;
}

View File

@ -2,11 +2,13 @@ package com.alibaba.testable.core.tool;
public class DemoGrandChild {
private int i;
private int i = 1;
public DemoGrandChild(int i) {
this.i = i;
}
private final long l = 1L;
private static Integer si = 2;
private static final Long sl = 2L;
public int get() {
return i;
@ -16,4 +18,12 @@ public class DemoGrandChild {
this.i = i;
}
public Integer getStatic() {
return si;
}
public void setStatic(Integer i) {
this.si = si;
}
}

View File

@ -12,23 +12,41 @@ class OmniAccessorTest {
@Test
void should_generate_member_index() {
List<String> index = PrivateAccessor.invokeStatic(OmniAccessor.class, "generateMemberIndex", DemoParent.class);
assertEquals(16, index.size());
assertEquals(34, index.size());
assertEquals("/c{DemoChild}", index.get(0));
assertEquals("/c{DemoChild}/gc{DemoGrandChild}", index.get(1));
assertEquals("/c{DemoChild}/gc{DemoGrandChild}/i{int}", index.get(2));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}", index.get(3));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}/i{int}", index.get(4));
assertEquals("/cs{DemoChild[]}", index.get(5));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}", index.get(6));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}/i{int}", index.get(7));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}", index.get(8));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}/i{int}", index.get(9));
assertEquals("/sc{SubChild}", index.get(10));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}", index.get(11));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}/i{int}", index.get(12));
assertEquals("/ssc{StaticSubChild}", index.get(13));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}", index.get(14));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}/i{int}", index.get(15));
assertEquals("/c{DemoChild}/gc{DemoGrandChild}/l{long}", index.get(3));
assertEquals("/c{DemoChild}/gc{DemoGrandChild}/si{Integer}", index.get(4));
assertEquals("/c{DemoChild}/gc{DemoGrandChild}/sl{Long}", index.get(5));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}", index.get(6));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}/i{int}", index.get(7));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}/l{long}", index.get(8));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}/si{Integer}", index.get(9));
assertEquals("/c{DemoChild}/gcs{DemoGrandChild[]}/sl{Long}", index.get(10));
assertEquals("/cs{DemoChild[]}", index.get(11));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}", index.get(12));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}/i{int}", index.get(13));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}/l{long}", index.get(14));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}/si{Integer}", index.get(15));
assertEquals("/cs{DemoChild[]}/gc{DemoGrandChild}/sl{Long}", index.get(16));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}", index.get(17));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}/i{int}", index.get(18));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}/l{long}", index.get(19));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}/si{Integer}", index.get(20));
assertEquals("/cs{DemoChild[]}/gcs{DemoGrandChild[]}/sl{Long}", index.get(21));
assertEquals("/sc{SubChild}", index.get(22));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}", index.get(23));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}/i{int}", index.get(24));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}/l{long}", index.get(25));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}/si{Integer}", index.get(26));
assertEquals("/sc{SubChild}/gc{DemoGrandChild}/sl{Long}", index.get(27));
assertEquals("/ssc{StaticSubChild}", index.get(28));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}", index.get(29));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}/i{int}", index.get(30));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}/l{long}", index.get(31));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}/si{Integer}", index.get(32));
assertEquals("/ssc{StaticSubChild}/gc{DemoGrandChild}/sl{Long}", index.get(33));
}
@Test
@ -88,25 +106,25 @@ class OmniAccessorTest {
DemoParent parent = prepareParentObject();
List<Object> obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gc{DemoGrandChild}", "c/gc");
assertTrue(obj.get(0) instanceof DemoGrandChild);
assertEquals(0, ((DemoGrandChild)obj.get(0)).get());
PrivateAccessor.set(parent.c, "gcs", new DemoGrandChild[] { new DemoGrandChild(4), new DemoGrandChild(6) });
assertEquals(1, ((DemoGrandChild)obj.get(0)).get());
PrivateAccessor.set(parent.c, "gcs", new DemoGrandChild[] { new DemoGrandChild(), new DemoGrandChild() });
obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs");
assertTrue(obj.get(0) instanceof DemoGrandChild[]);
assertEquals(2, ((DemoGrandChild[])obj.get(0)).length);
obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs[1]");
assertTrue(obj.get(0) instanceof DemoGrandChild);
assertEquals(6, ((DemoGrandChild)obj.get(0)).get());
assertEquals(1, ((DemoGrandChild)obj.get(0)).get());
parent.cs = new DemoChild[] { null, prepareChildObject() };
obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/cs{DemoChild[]}/gcs{DemoGrandChild[]}/i{int}", "c[1]/gcs[1]/i");
assertEquals(3, obj.get(0));
assertEquals(1, obj.get(0));
}
@Test
void should_set_by_path_segment() {
DemoParent parent = prepareParentObject();
DemoChild child = prepareChildObject();
PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "setByPathSegment", parent.c, "gc{DemoGrandChild}", "gc", new DemoGrandChild(2));
assertEquals(2, parent.c.gc.get());
PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "setByPathSegment", parent.c, "gc{DemoGrandChild}", "gc", new DemoGrandChild());
assertEquals(1, parent.c.gc.get());
PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "setByPathSegment", parent, "cs{DemoChild[]}", "cs[2]", child);
assertNull(parent.cs[0]);
assertNull(parent.cs[1]);
@ -125,7 +143,7 @@ class OmniAccessorTest {
private DemoChild prepareChildObject() {
DemoChild child = OmniConstructor.newInstance(DemoChild.class);
PrivateAccessor.set(child, "gcs", new DemoGrandChild[] { null, new DemoGrandChild(3) });
PrivateAccessor.set(child, "gcs", new DemoGrandChild[] { null, new DemoGrandChild() });
child.gc.set(5);
return child;
}

View File

@ -0,0 +1,16 @@
package com.alibaba.testable.core.tool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class OmniConstructorTest {
@Test
public void should_keep_origin_value() {
DemoParent demoParent = OmniConstructor.newInstance(DemoParent.class);
assertEquals(2, demoParent.c.gc.getStatic());
assertEquals(1, demoParent.c.gc.get());
}
}