[test/e2e] Enhancement TopoMatcher (#3990)
* Enhancement TopoMatcher * optimize parse * Update test/e2e/e2e-base/src/main/java/org/apache/skywalking/e2e/assertor/VariableExpressParser.java Co-Authored-By: kezhenxu94 <kezhenxu94@163.com>
This commit is contained in:
parent
52de0c6dfa
commit
e67d7b85ef
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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 org.apache.skywalking.e2e.assertor;
|
||||||
|
|
||||||
|
import org.apache.skywalking.e2e.assertor.exception.VariableNotFoundException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhangwei
|
||||||
|
*/
|
||||||
|
public class VariableExpressParser {
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> T parse(String express, List<T> actual, Function<T, String> getFiled) {
|
||||||
|
express = express.trim();
|
||||||
|
if (!(express.startsWith("${") && express.endsWith("}"))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
express = express.substring(2, express.length() - 1);
|
||||||
|
|
||||||
|
int startIndexOfIndex = express.lastIndexOf("[");
|
||||||
|
String regex = express.substring(0, startIndexOfIndex);
|
||||||
|
int endIndexOfIndex = express.indexOf("]", startIndexOfIndex);
|
||||||
|
int expectedIndex = Integer.parseInt(express.substring(startIndexOfIndex + 1, endIndexOfIndex));
|
||||||
|
int mappingIndex = 0;
|
||||||
|
|
||||||
|
T mapping = null;
|
||||||
|
for (T t : actual) {
|
||||||
|
if (Pattern.matches(regex, getFiled.apply(t))) {
|
||||||
|
if (mappingIndex++ == expectedIndex) {
|
||||||
|
mapping = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNull(mapping)) {
|
||||||
|
throw new VariableNotFoundException(express);
|
||||||
|
}
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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 org.apache.skywalking.e2e.assertor.exception;
|
||||||
|
|
||||||
|
import org.apache.skywalking.e2e.exception.AssertFailedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhangwei
|
||||||
|
*/
|
||||||
|
public class VariableNotFoundException extends AssertFailedException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1337142072507388456L;
|
||||||
|
|
||||||
|
private final String express;
|
||||||
|
|
||||||
|
public VariableNotFoundException(String express) {
|
||||||
|
this.express = express;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCauseMessage() {
|
||||||
|
return String.format("VariableNotFoundException\nexpected: %s\nactual: %s\n", express, "NOT FOUND");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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 org.apache.skywalking.e2e.exception;
|
||||||
|
/**
|
||||||
|
* Created by xin on 2017/7/15.
|
||||||
|
*/
|
||||||
|
public abstract class AssertFailedException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8870675340514007954L;
|
||||||
|
|
||||||
|
protected AssertFailedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AssertFailedException(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getCauseMessage();
|
||||||
|
}
|
||||||
|
|
@ -18,11 +18,12 @@
|
||||||
|
|
||||||
package org.apache.skywalking.e2e.topo;
|
package org.apache.skywalking.e2e.topo;
|
||||||
|
|
||||||
|
import org.apache.skywalking.e2e.assertor.VariableExpressParser;
|
||||||
import org.apache.skywalking.e2e.verification.AbstractMatcher;
|
import org.apache.skywalking.e2e.verification.AbstractMatcher;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,11 +38,12 @@ public class TopoMatcher extends AbstractMatcher<TopoData> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verify(final TopoData topoData) {
|
public void verify(final TopoData topoData) {
|
||||||
if (Objects.nonNull(getNodes())) {
|
if (nonNull(getNodes())) {
|
||||||
verifyNodes(topoData);
|
verifyNodes(topoData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Objects.nonNull(getCalls())) {
|
if (nonNull(getCalls())) {
|
||||||
|
convertNodeId(getCalls(), topoData.getNodes());
|
||||||
verifyCalls(topoData);
|
verifyCalls(topoData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,4 +103,26 @@ public class TopoMatcher extends AbstractMatcher<TopoData> {
|
||||||
", calls=" + calls +
|
", calls=" + calls +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void convertNodeId(List<CallMatcher> callMatchers, List<Node> nodes) {
|
||||||
|
for (CallMatcher callMatcher : callMatchers) {
|
||||||
|
Node sourceNode = VariableExpressParser.parse(callMatcher.getSource(), nodes, Node::getName);
|
||||||
|
Node targetNode = VariableExpressParser.parse(callMatcher.getTarget(), nodes, Node::getName);
|
||||||
|
|
||||||
|
boolean convert = false;
|
||||||
|
if (nonNull(sourceNode)) {
|
||||||
|
callMatcher.setSource(sourceNode.getId());
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
if (nonNull(targetNode)) {
|
||||||
|
callMatcher.setTarget(targetNode.getId());
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (convert) {
|
||||||
|
callMatcher.setId(String.join("_", callMatcher.getSource(), callMatcher.getTarget()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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 org.apache.skywalking.e2e;
|
||||||
|
|
||||||
|
import org.apache.skywalking.e2e.assertor.exception.VariableNotFoundException;
|
||||||
|
import org.apache.skywalking.e2e.topo.Call;
|
||||||
|
import org.apache.skywalking.e2e.topo.Node;
|
||||||
|
import org.apache.skywalking.e2e.topo.TopoData;
|
||||||
|
import org.apache.skywalking.e2e.topo.TopoMatcher;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhangwei
|
||||||
|
*/
|
||||||
|
public class TestTopoMatcher {
|
||||||
|
|
||||||
|
private TopoMatcher topoMatcher;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
try (InputStream expectedInputStream = new ClassPathResource("topo.yml").getInputStream()) {
|
||||||
|
topoMatcher = new Yaml().loadAs(expectedInputStream, TopoMatcher.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSuccess() {
|
||||||
|
final List<Node> nodes = new ArrayList<>();
|
||||||
|
nodes.add(new Node().setId("1").setName("User").setType("USER").setIsReal("false"));
|
||||||
|
nodes.add(new Node().setId("2").setName("projectB-pid:27960@skywalking-server-0001").setType("Tomcat").setIsReal("true"));
|
||||||
|
nodes.add(new Node().setId("3").setName("projectB-pid:27961@skywalking-server-0001").setType("Tomcat").setIsReal("true"));
|
||||||
|
|
||||||
|
|
||||||
|
final List<Call> calls = new ArrayList<>();
|
||||||
|
calls.add(new Call().setId("1_2").setSource("1").setTarget("2"));
|
||||||
|
calls.add(new Call().setId("1_3").setSource("1").setTarget("3"));
|
||||||
|
|
||||||
|
final TopoData topoData = new TopoData().setNodes(nodes).setCalls(calls);
|
||||||
|
|
||||||
|
topoMatcher.verify(topoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = VariableNotFoundException.class)
|
||||||
|
public void shouldVariableNotFound() {
|
||||||
|
final List<Node> nodes = new ArrayList<>();
|
||||||
|
nodes.add(new Node().setId("1").setName("User").setType("USER").setIsReal("false"));
|
||||||
|
nodes.add(new Node().setId("2").setName("projectA-pid:27960@skywalking-server-0001").setType("Tomcat").setIsReal("true"));
|
||||||
|
nodes.add(new Node().setId("3").setName("projectB-pid:27961@skywalking-server-0001").setType("Tomcat").setIsReal("true"));
|
||||||
|
|
||||||
|
|
||||||
|
final List<Call> calls = new ArrayList<>();
|
||||||
|
calls.add(new Call().setId("1_2").setSource("1").setTarget("2"));
|
||||||
|
calls.add(new Call().setId("1_3").setSource("1").setTarget("3"));
|
||||||
|
|
||||||
|
final TopoData topoData = new TopoData().setNodes(nodes).setCalls(calls);
|
||||||
|
|
||||||
|
topoMatcher.verify(topoData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# 1 health-check by docker-maven-plugin
|
||||||
|
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||||
|
# 1 drop sequence
|
||||||
|
# 1 create sequence
|
||||||
|
# 1 create table statement
|
||||||
|
|
||||||
|
nodes:
|
||||||
|
- id: not null
|
||||||
|
name: User
|
||||||
|
type: USER
|
||||||
|
- id: not null
|
||||||
|
name: not null
|
||||||
|
type: Tomcat
|
||||||
|
- id: not null
|
||||||
|
name: not null
|
||||||
|
type: Tomcat
|
||||||
|
calls:
|
||||||
|
- id: not null
|
||||||
|
source: ${User[0]}
|
||||||
|
target: ${projectB-pid:(.*)@skywalking-server-0001[0]}
|
||||||
|
- id: not null
|
||||||
|
source: ${User[0]}
|
||||||
|
target: ${projectB-pid:(.*)@skywalking-server-0001[1]}
|
||||||
|
|
@ -32,14 +32,14 @@ nodes:
|
||||||
type: Unknown
|
type: Unknown
|
||||||
calls:
|
calls:
|
||||||
- id: not null
|
- id: not null
|
||||||
source: not null
|
source: ${User[0]}
|
||||||
target: not null
|
target: ${consumer[0]}
|
||||||
- id: not null
|
- id: not null
|
||||||
source: not null
|
source: ${127.0.0.1:9099[0]}
|
||||||
target: not null
|
target: ${provider[0]}
|
||||||
- id: not null
|
- id: not null
|
||||||
source: not null
|
source: ${consumer[0]}
|
||||||
target: not null
|
target: ${127.0.0.1:9099[0]}
|
||||||
- id: not null
|
- id: not null
|
||||||
source: not null
|
source: ${provider[0]}
|
||||||
target: not null
|
target: ${localhost:-1[0]}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue