Mercurial > stress-tester
changeset 554:b54118ccc0e0
HttpSequenceFilter - in progress
author | Devel 1 |
---|---|
date | Tue, 19 Sep 2017 11:25:18 +0200 |
parents | 80af3ca1b618 |
children | 7b10dfafe23a |
files | stress-tester/src/main/java/com/passus/st/client/http/filter/HttpHostRewriterFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpLogoutFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpSequenceFilter.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java |
diffstat | 4 files changed, 188 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpHostRewriterFilter.java Mon Sep 18 12:27:16 2017 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpHostRewriterFilter.java Tue Sep 19 11:25:18 2017 +0200 @@ -164,7 +164,7 @@ @Override public NodeDefinition create() { return mapDef( - tupleDef("hostMap", new MappingNodeDefinition()) + tupleDef("hostMap", new MappingNodeDefinition().setMinNumberOfValues(1)) ); } }
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpLogoutFilter.java Mon Sep 18 12:27:16 2017 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpLogoutFilter.java Tue Sep 19 11:25:18 2017 +0200 @@ -11,14 +11,9 @@ import com.passus.net.http.HttpRequest; import com.passus.net.http.HttpResponse; import com.passus.st.ParametersBag; -import com.passus.st.client.credentials.CredentialsProvider; -import com.passus.st.client.http.HttpConsts; import static com.passus.st.client.http.HttpConsts.PARAM_USERNAME; import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID; import com.passus.st.client.http.HttpFlowContext; -import com.passus.st.client.http.filter.HttpFilter; -import com.passus.st.client.http.filter.HttpFilterMessagePredicateNodeDefinition; -import com.passus.st.client.http.filter.HttpMessagePredicate; import com.passus.st.plugin.PluginConstants; /**
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpSequenceFilter.java Mon Sep 18 12:27:16 2017 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpSequenceFilter.java Tue Sep 19 11:25:18 2017 +0200 @@ -1,11 +1,30 @@ package com.passus.st.client.http.filter; import com.passus.commons.annotations.Plugin; +import com.passus.config.CMapNode; +import com.passus.config.CNode; +import com.passus.config.CTupleNode; +import com.passus.config.CValueNode; +import com.passus.config.Configuration; +import com.passus.config.annotations.NodeDefinitionCreate; +import static com.passus.config.schema.ConfigurationSchemaBuilder.mapDef; +import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef; +import static com.passus.config.schema.ConfigurationSchemaBuilder.valueDef; +import com.passus.config.schema.ListNodeDefinition; +import com.passus.config.schema.MapNodeDefinition; +import com.passus.config.schema.MappingNodeDefinition; +import com.passus.config.schema.NodeDefinition; +import com.passus.config.schema.NodeDefinitionCreator; +import com.passus.config.schema.NodeTransformer; +import com.passus.config.validation.Errors; import com.passus.filter.ValueExtractor; +import com.passus.filter.ValueExtractorParser; +import com.passus.filter.config.PredicateNodeTransformer; import com.passus.net.http.HttpRequest; import com.passus.net.http.HttpResponse; import com.passus.st.client.http.HttpFlowContext; import com.passus.st.plugin.PluginConstants; +import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -18,6 +37,7 @@ * * @author mikolaj.podbielski */ +@NodeDefinitionCreate(HttpSequenceFilter.NodeDefCreator.class) @Plugin(name = HttpSequenceFilter.TYPE, category = PluginConstants.CATEGORY_HTTP_FILTER) public class HttpSequenceFilter extends HttpFilter { @@ -26,15 +46,23 @@ private final Predicate predicate; private boolean mustOccur = true; private long time = 10_000; - private final int num; + private int num; private String alias; private String[] aliases; public SequenceItem(Predicate predicate, int num) { + this(predicate); + this.num = num; + } + + public SequenceItem(Predicate predicate) { if (predicate == null) { throw new NullPointerException(); } this.predicate = predicate; + } + + public void setNum(int num) { this.num = num; } @@ -213,14 +241,26 @@ private SequenceItem[] seqItems; private Map<String, ValueExtractor> values = Collections.EMPTY_MAP; + public HttpSequenceListener getListener() { + return listener; + } + public void setListener(HttpSequenceListener listener) { this.listener = listener; } + public SequenceItem[] getSeqItems() { + return seqItems; + } + public void setSeqItems(SequenceItem[] seqItems) { this.seqItems = seqItems; } + public Map<String, ValueExtractor> getValues() { + return values; + } + public void setValues(Map<String, ValueExtractor> values) { this.values = values; } @@ -313,4 +353,124 @@ return filter; } + @Override + public void configure(Configuration config) { + List<SequenceItem> itemsList = (List<SequenceItem>) config.get("sequence"); + seqItems = itemsList.toArray(new SequenceItem[itemsList.size()]); + for (int i = 0; i < seqItems.length; ++i) { + //TODO: refactor + seqItems[i].setNum(i); + } + + this.values = (Map<String, ValueExtractor>) config.get("values", Collections.EMPTY_MAP); + } + + public static class NodeDefCreator implements NodeDefinitionCreator { + + @Override + public NodeDefinition create() { + MapNodeDefinition elementDef = mapDef( + tupleDef("match", new HttpFilterMessagePredicateNodeDefinition()), + tupleDef("mustOccur", valueDef(Boolean.class)).setRequired(false), + tupleDef("time", valueDef(Long.class)).setRequired(false), + tupleDef("alias", valueDef()).setRequired(false) + ); + elementDef.setTransformer(new SequencesNodeTransformer()); + // TODO: mustOccur and time required in all steps but first + + return mapDef( + tupleDef("sequence", new ListNodeDefinition(elementDef).setMinNumberOfValues(2)), + tupleDef("values", new MappingNodeDefinition().setTransformer(new ValuesNodeTransformer())).setRequired(false) + ); + } + + } + + private static class SequencesNodeTransformer implements NodeTransformer<CNode> { + + private static final PredicateNodeTransformer TRANSFORMER = new PredicateNodeTransformer(); + + @Override + public CNode transform(CNode node, Errors errors) { + try { + CMapNode mapNode = (CMapNode) node; + List<CTupleNode> tupleNodes = mapNode.getChildren(); + + Predicate predicate = null; + boolean mustOccur = true; + long time = 0; + String alias = null; + for (CTupleNode tupleNode : tupleNodes) { + String name = tupleNode.getName(); + CNode valueNode = tupleNode.getNode(); + switch (name) { + case "match": + predicate = TRANSFORMER.transform(valueNode); + break; + case "mustOccur": + mustOccur = (Boolean) getValue(valueNode); + break; + case "time": + time = (Long) getValue(valueNode); + break; + case "alias": + alias = (String) getValue(valueNode); + break; + } + } + SequenceItem item = new SequenceItem(predicate); + if (time > 0) { + item.setTime(time); + } + item.setMustOccur(mustOccur); + item.setAlias(alias); + return new CValueNode(item); + } catch (Exception ex) { + return node; + } + } + + @Override + public CNode reverseTransform(CNode node, Errors errors) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + private static class ValuesNodeTransformer implements NodeTransformer<CNode> { + + @Override + public CNode transform(CNode node, Errors errors) { + Map<String, ValueExtractor> result = new HashMap<>(); + + CMapNode mapNode = (CMapNode) node; + List<CTupleNode> tupleNodes = mapNode.getChildren(); + for (CTupleNode tupleNode : tupleNodes) { + String name = tupleNode.getName(); + CValueNode valueNode = (CValueNode) tupleNode.getNode(); + String value = (String) valueNode.getValue(); + try { + errors.pushNestedPath(name); + ValueExtractor extractor = ValueExtractorParser.DEFAULT.parse(value); + result.put(name, extractor); + } catch (ParseException ex) { + errors.reject(tupleNode, "Invalid expression: \"%s\"", value); + } finally { + errors.popNestedPath(); + } + } + return new CValueNode(result); + } + + @Override + public CNode reverseTransform(CNode node, Errors errors) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + private static Object getValue(CNode node) { + CValueNode valueNode = (CValueNode) node; + return valueNode.getValue(); + } }
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java Mon Sep 18 12:27:16 2017 +0200 +++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java Tue Sep 19 11:25:18 2017 +0200 @@ -1,5 +1,7 @@ package com.passus.st.client.http.filter; +import com.passus.commons.utils.ResourceUtils; +import com.passus.config.validation.Errors; import com.passus.filter.ValueExtractor; import com.passus.filter.ValueExtractorParser; import com.passus.filter.config.PredicateNodeTransformer; @@ -9,9 +11,13 @@ import com.passus.net.http.HttpResponseBuilder; import com.passus.st.AppUtils; import com.passus.st.client.http.filter.HttpSequenceFilter.SequenceItem; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Predicate; import static org.testng.AssertJUnit.*; @@ -83,6 +89,26 @@ return ValueExtractorParser.DEFAULT.parse(s); } + @Test + public void testConfigure() throws Exception { + File file = ResourceUtils.getFile("com/passus/st/client/http/filter/sequence.yml"); + String filterConfig = new String(Files.readAllBytes(Paths.get(file.toURI()))); + + Errors errors = new Errors(); + List<HttpFilter> filters = HttpFiltersConfigurator.getFilters(filterConfig, errors); + HttpFilterTestUtils.printErrors(errors); + + assertEquals(0, errors.getErrorCount()); + assertEquals(1, filters.size()); + assertTrue(filters.get(0) instanceof HttpSequenceFilter); + + HttpSequenceFilter filter = (HttpSequenceFilter) filters.get(0); + filter.getSeqItems(); + filter.getValues(); + + System.out.println(""); + } + public static class TestHttpSequenceListener implements HttpSequenceListener { ArrayList<HttpSequenceEvent> events = new ArrayList<>();