提交 e67d7b85 编写于 作者: Z zhang-wei 提交者: wu-sheng

[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: Nkezhenxu94 <kezhenxu94@163.com>
上级 52de0c6d
/*
* 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;
}
}
/*
* 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");
}
}
/*
* 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;
import org.apache.skywalking.e2e.assertor.VariableExpressParser;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.nonNull;
import static org.assertj.core.api.Assertions.fail;
/**
......@@ -37,11 +38,12 @@ public class TopoMatcher extends AbstractMatcher<TopoData> {
@Override
public void verify(final TopoData topoData) {
if (Objects.nonNull(getNodes())) {
if (nonNull(getNodes())) {
verifyNodes(topoData);
}
if (Objects.nonNull(getCalls())) {
if (nonNull(getCalls())) {
convertNodeId(getCalls(), topoData.getNodes());
verifyCalls(topoData);
}
}
......@@ -101,4 +103,26 @@ public class TopoMatcher extends AbstractMatcher<TopoData> {
", 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()));
}
}
}
}
/*
* 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);
}
}
# 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]}
\ No newline at end of file
......@@ -32,14 +32,14 @@ nodes:
type: Unknown
calls:
- id: not null
source: not null
target: not null
source: ${User[0]}
target: ${consumer[0]}
- id: not null
source: not null
target: not null
source: ${127.0.0.1:9099[0]}
target: ${provider[0]}
- id: not null
source: not null
target: not null
source: ${consumer[0]}
target: ${127.0.0.1:9099[0]}
- id: not null
source: not null
target: not null
source: ${provider[0]}
target: ${localhost:-1[0]}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册