This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch 2.13.x in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/2.13.x by this push: new b075dc776c Snnmp: reworked tests to avoid flaky failures b075dc776c is described below commit b075dc776cb605566e2eb209f9163a04c4299e9e Author: JiriOndrusek <ondrusek.j...@gmail.com> AuthorDate: Tue May 2 08:51:47 2023 +0200 Snnmp: reworked tests to avoid flaky failures --- .../quarkus/component/snmp/it/SnmpResource.java | 21 ++-- .../camel/quarkus/component/snmp/it/SnmpRoute.java | 48 +++++++-- .../camel/quarkus/component/snmp/it/SnmpTest.java | 81 ++++++++++++--- .../component/snmp/it/SnmpTestResource.java | 112 ++++++++++++++++----- 4 files changed, 199 insertions(+), 63 deletions(-) diff --git a/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpResource.java b/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpResource.java index 3253d8e22c..a98ebbb2c3 100644 --- a/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpResource.java +++ b/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpResource.java @@ -24,7 +24,6 @@ import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; -import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -65,14 +64,13 @@ public class SnmpResource { ProducerTemplate producerTemplate; @Path("/producePDU/{version}") - @GET + @POST @Produces(MediaType.TEXT_PLAIN) - public Response producePDU(@PathParam("version") int version) { + public Response producePDU(@PathParam("version") int version, String payload) { String url = String.format("snmp://%s?retries=1&snmpVersion=%d", snmpListenAddress, version); SnmpMessage pdu = producerTemplate.requestBody(url, version, SnmpMessage.class); String response = pdu.getSnmpMessage().getVariableBindings().stream() - .filter(vb -> vb.getOid().equals(SnmpConstants.sysDescr)) .map(vb -> vb.getVariable().toString()) .collect(Collectors.joining()); @@ -84,12 +82,11 @@ public class SnmpResource { @Produces(MediaType.TEXT_PLAIN) public Response getNext(String payload, @PathParam("version") int version) { String url = String.format("snmp://%s?type=GET_NEXT&retries=1&protocol=udp&oids=%s&snmpVersion=%d", snmpListenAddress, - SnmpConstants.sysDescr, version); + payload, version); List<SnmpMessage> pdu = producerTemplate.requestBody(url, "", List.class); String response = pdu.stream() .flatMap(m -> m.getSnmpMessage().getVariableBindings().stream()) - .filter(vb -> vb.getOid().equals(SnmpConstants.sysDescr)) .map(vb -> vb.getVariable().toString()) .collect(Collectors.joining(",")); @@ -109,12 +106,11 @@ public class SnmpResource { return Response.ok().build(); } - @Path("/results") + @Path("/results/{from}") @POST @Produces(MediaType.TEXT_PLAIN) - public Response results(String from) throws Exception { - OID oid = from.startsWith("trap") ? new OID("1.2.3.4.5") : SnmpConstants.sysDescr; - String result = snmpResults.get(from).stream().map(m -> m.getSnmpMessage().getVariable(oid).toString()) + public Response results(@PathParam("from") String from, String oid) throws Exception { + String result = snmpResults.get(from).stream().map(m -> m.getSnmpMessage().getVariable(new OID(oid)).toString()) .collect(Collectors.joining(",")); return Response.ok(result).build(); @@ -129,18 +125,17 @@ public class SnmpResource { trap0.setGenericTrap(PDUv1.ENTERPRISE_SPECIFIC); trap0.setSpecificTrap(1); - trap0.add(new VariableBinding(SnmpConstants.snmpTrapOID, oid)); + trap0.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OctetString(payload))); trap0.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(5000))); // put your uptime here trap0.add(new VariableBinding(SnmpConstants.sysDescr, new OctetString("System Description"))); trap0.setEnterprise(oid); - //Add Payload trap0.add(new VariableBinding(oid, var)); return trap0; case 1: PDU trap1 = new PDU(); - trap1.add(new VariableBinding(SnmpConstants.snmpTrapOID, oid)); + trap1.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OctetString(payload))); trap1.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(5000))); // put your uptime here trap1.add(new VariableBinding(SnmpConstants.sysDescr, new OctetString("System Description"))); diff --git a/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpRoute.java b/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpRoute.java index ed2dbb8bcb..3f906ab477 100644 --- a/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpRoute.java +++ b/integration-tests-jvm/snmp/src/main/java/org/apache/camel/quarkus/component/snmp/it/SnmpRoute.java @@ -22,14 +22,15 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import javax.ws.rs.Produces; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.snmp.SnmpMessage; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.snmp4j.mp.SnmpConstants; @ApplicationScoped public class SnmpRoute extends RouteBuilder { @@ -54,18 +55,38 @@ public class SnmpRoute extends RouteBuilder { public void configure() { //TRAP consumer snmpVersion=0 from("snmp:0.0.0.0:" + trap0Port + "?protocol=udp&type=TRAP&snmpVersion=0") - .process(e -> snmpResults.get("trap0").add(e.getIn().getBody(SnmpMessage.class))); + .process(e -> snmpResults.get("v0_trap").add(e.getIn().getBody(SnmpMessage.class))); //TRAP consumer snmpVersion=1 from("snmp:0.0.0.0:" + trap1Port + "?protocol=udp&type=TRAP&snmpVersion=1") - .process(e -> snmpResults.get("trap1").add(e.getIn().getBody(SnmpMessage.class))); + .process(e -> snmpResults.get("v1_trap").add(e.getIn().getBody(SnmpMessage.class))); + + //POLL consumer 2 oids, snmpVersion=0 + from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids=" + + SnmpConstants.sysLocation + "," + SnmpConstants.sysContact) + .process(e -> snmpResults.get("v0_poll2oids").add(e.getIn().getBody(SnmpMessage.class))); + //POLL consumer 2 oids, snmpVersion=1 + from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&type=POLL&oids=" + + SnmpConstants.sysLocation + "," + SnmpConstants.sysContact) + .process(e -> snmpResults.get("v1_poll2oids").add(e.getIn().getBody(SnmpMessage.class))); + + // POLL consumer starting with dot snmpVersion=0 + from("snmp://" + snmpListenAddress + + "?protocol=udp&snmpVersion=0&type=POLL&oids=.1.3.6.1.4.1.6527.3.1.2.21.2.1.50") + .process(e -> snmpResults.get("v0_pollStartingDot").add(e.getIn().getBody(SnmpMessage.class))); + //POLL consumer startingWith dot snmpVersion=1 + from("snmp://" + snmpListenAddress + + "?protocol=udp&snmpVersion=1&type=POLL&oids=.1.3.6.1.4.1.6527.3.1.2.21.2.1.50") + .process(e -> snmpResults.get("v1_pollStartingDot").add(e.getIn().getBody(SnmpMessage.class))); //POLL consumer snmpVersion=0 - from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&securityName=aaa&type=POLL&oids=1.3.6.1.2.1.1.5.0") - .process(e -> snmpResults.get("poll0").add(e.getIn().getBody(SnmpMessage.class))); + from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids=" + + SnmpConstants.sysDescr) + .process(e -> snmpResults.get("v0_poll").add(e.getIn().getBody(SnmpMessage.class))); //POLL consumer snmpVersion=1 - from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&securityName=aaa&type=POLL&oids=1.3.6.1.2.1.1.5.0") - .process(e -> snmpResults.get("poll1").add(e.getIn().getBody(SnmpMessage.class))); + from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&type=POLL&oids=" + + SnmpConstants.sysDescr) + .process(e -> snmpResults.get("v1_poll").add(e.getIn().getBody(SnmpMessage.class))); } static class Producers { @@ -74,10 +95,15 @@ public class SnmpRoute extends RouteBuilder { @Named("snmpTrapResults") Map<String, Deque<SnmpMessage>> snmpResults() { Map<String, Deque<SnmpMessage>> map = new ConcurrentHashMap<>(); - map.put("trap0", new ConcurrentLinkedDeque()); - map.put("trap1", new ConcurrentLinkedDeque()); - map.put("poll0", new ConcurrentLinkedDeque()); - map.put("poll1", new ConcurrentLinkedDeque()); + map.put("v0_trap", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v1_trap", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v0_poll", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v1_poll", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v3_poll", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v0_pollStartingDot", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v1_pollStartingDot", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v0_poll2oids", new ConcurrentLinkedDeque<SnmpMessage>()); + map.put("v1_poll2oids", new ConcurrentLinkedDeque<SnmpMessage>()); return map; } } diff --git a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTest.java b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTest.java index 200fe0e948..5155a7c85c 100644 --- a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTest.java +++ b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTest.java @@ -25,6 +25,8 @@ import io.restassured.RestAssured; import org.hamcrest.Matchers; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.smi.OID; import static org.awaitility.Awaitility.await; @@ -39,6 +41,13 @@ import static org.awaitility.Awaitility.await; @QuarkusTestResource(SnmpTestResource.class) class SnmpTest { + public static final OID GET_NEXT_OID = new OID(new int[] { 1, 3, 6, 1, 2, 1, 25, 3, 2, 1, 5, 1 }); + public static final OID POLL_OID = SnmpConstants.sysDescr; + public static final OID PRODUCE_PDU_OID = SnmpConstants.sysName; + public static final OID TWO_OIDS_A = SnmpConstants.sysLocation; + public static final OID TWO_OIDS_B = SnmpConstants.sysContact; + public static final OID DOT_OID = new OID(new int[] { 1, 3, 6, 1, 4, 1, 6527, 3, 1, 2, 21, 2, 1, 50 }); + static Stream<Integer> supportedVersions() { return Stream.of(0, 1/*, 3 not supported because of https://issues.apache.org/jira/browse/CAMEL-19298 */); } @@ -46,6 +55,7 @@ class SnmpTest { @ParameterizedTest @MethodSource("supportedVersions") public void testSendReceiveTrap(int version) throws Exception { + String resultsName = "v" + version + "_trap"; RestAssured.given() .body("TEXT") @@ -55,8 +65,8 @@ class SnmpTest { await().atMost(10L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { String result = RestAssured.given() - .body("trap" + version) - .post("/snmp/results") + .body(SnmpConstants.snmpTrapOID.toString()) + .post("/snmp/results/" + resultsName) .then() .statusCode(200) .extract().body().asString(); @@ -68,27 +78,47 @@ class SnmpTest { @ParameterizedTest @MethodSource("supportedVersions") public void testPoll(int version) throws Exception { - await().atMost(10L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { + String resultsName = "v" + version + "_poll"; + + await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { String result = RestAssured.given() - .body("poll" + version) - .post("/snmp/results") + .body(SnmpConstants.sysDescr.toString()) + .post("/snmp/results/" + resultsName) .then() .statusCode(200) .extract().body().asString(); - return result.startsWith("Response from the test #1,Response from the test #2,Response from the test #3"); + return result + .startsWith("My POLL Printer - response #1,My POLL Printer - response #2,My POLL Printer - response #3"); }); } @ParameterizedTest @MethodSource("supportedVersions") - public void testProducePDU(int version) { + public void testPollStartingDot(int version) throws Exception { + String resultsName = "v" + version + "_pollStartingDot"; + + await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { + String result = RestAssured.given() + .body(DOT_OID.toString()) + .post("/snmp/results/" + resultsName) + .then() + .statusCode(200) + .extract().body().asString(); + + return result.startsWith("My DOT Printer - response #1,My DOT Printer - response #2,My DOT Printer - response #3"); + }); + } - RestAssured - .get("/snmp/producePDU/" + version) + @ParameterizedTest + @MethodSource("supportedVersions") + public void testProducePDU(int version) { + RestAssured.given() + .body(PRODUCE_PDU_OID.toString()) + .post("/snmp/producePDU/" + version) .then() .statusCode(200) - .body(Matchers.equalTo("Response from the test #1")); + .body(Matchers.startsWith("My PRODUCE_PDU Printer - response #")); } @ParameterizedTest @@ -96,10 +126,37 @@ class SnmpTest { public void testGetNext(int version) { RestAssured.given() - .body("TEXT") + .body(GET_NEXT_OID.toString()) .post("/snmp/getNext/" + version) .then() .statusCode(200) - .body(Matchers.equalTo("Response from the test #1,Response from the test #2")); + .body(Matchers.equalTo("1,2,My GET_NEXT Printer - response #3")); + } + + @ParameterizedTest + @MethodSource("supportedVersions") + public void testPollWith2OIDs(int version) throws Exception { + String resultsName = "v" + version + "_poll2oids"; + + await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { + String resultOid1 = RestAssured.given() + .body(TWO_OIDS_A.toString()) + .post("/snmp/results/" + resultsName) + .then() + .statusCode(200) + .extract().body().asString(); + String resultOid2 = RestAssured.given() + .body(TWO_OIDS_B.toString()) + .post("/snmp/results/" + resultsName) + .then() + .statusCode(200) + .extract().body().asString(); + + return resultOid1.startsWith( + "My 2 OIDs A Printer - response #1,My 2 OIDs A Printer - response #2,My 2 OIDs A Printer - response #3") && + resultOid2.startsWith( + "My 2 OIDs B Printer - response #1,My 2 OIDs B Printer - response #2,My 2 OIDs B Printer - response #3"); + }); + } } diff --git a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java index 9653a3dfb4..9f0f1db6e3 100644 --- a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java +++ b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java @@ -19,7 +19,6 @@ package org.apache.camel.quarkus.component.snmp.it; import java.io.IOException; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -33,6 +32,7 @@ import org.snmp4j.CommandResponderEvent; import org.snmp4j.MessageException; import org.snmp4j.PDU; import org.snmp4j.PDUv1; +import org.snmp4j.ScopedPDU; import org.snmp4j.Snmp; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.mp.StatusInformation; @@ -96,54 +96,112 @@ public class SnmpTestResource implements QuarkusTestResourceLifecycleManager { @Override public synchronized void processPdu(CommandResponderEvent event) { PDU pdu = event.getPDU(); - Vector<? extends VariableBinding> vbs = Optional.ofNullable(pdu.getVariableBindings()).orElse(new Vector<>(0)); + Vector<? extends VariableBinding> vbs; + if (pdu.getVariableBindings() != null) { + vbs = (Vector<? extends VariableBinding>) new Vector(pdu.getVariableBindings()); + } else { + vbs = new Vector<>(0); + } String key = vbs.stream().sequential().map(vb -> vb.getOid().toString()).collect(Collectors.joining(",")); //differ snmp versions if (pdu instanceof PDUv1) { - key = "v1" + key; + key = "v1_" + key; + } else if (pdu instanceof ScopedPDU) { + key = "v3_" + key; + } else { + key = "v2_" + key; } int numberOfSent = counts.getOrDefault(key, 0); - //if 3 responses were already sent for the OID, do not respond anymore - if (numberOfSent > 3) { - return; - } - //first 2 responses are quick, the third response takes 3000ms (so there is a timeout with default 1500ms) -> - // getNext producer will receive only 2 messages - // poll consumer should receive all of them - if (numberOfSent % 3 == 2) { - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - //nothing - } - } - - PDU response = makeResponse(++numberOfSent, SnmpConstants.version1); - if (response != null) { - try { + try { + PDU response = makeResponse(++numberOfSent, SnmpConstants.version1, vbs); + if (response != null) { response.setRequestID(pdu.getRequestID()); commandResponder.getMessageDispatcher().returnResponsePdu( event.getMessageProcessingModel(), event.getSecurityModel(), event.getSecurityName(), event.getSecurityLevel(), response, event.getMaxSizeResponsePDU(), event.getStateReference(), new StatusInformation()); - } catch (MessageException e) { - Assertions.assertNull(e); } - counts.put(key, numberOfSent); + } catch (MessageException e) { + Assertions.assertNull(e); } + counts.put(key, numberOfSent); } - private PDU makeResponse(int counter, int version) { + private PDU makeResponse(int counter, int version, Vector<? extends VariableBinding> vbs) { PDU responsePDU = new PDU(); responsePDU.setType(PDU.RESPONSE); responsePDU.setErrorStatus(PDU.noError); responsePDU.setErrorIndex(0); - responsePDU.add(new VariableBinding(new OID(SnmpConstants.sysDescr), - new OctetString("Response from the test #" + counter))); + if (vbs.isEmpty()) { + VariableBinding vb = generateResponseBinding(counter, SnmpTest.PRODUCE_PDU_OID); + if (vb != null) { + responsePDU.add(vb); + } + } else { + vbs.stream().forEach(vb -> responsePDU.add(generateResponseBinding(counter, vb.getOid()))); + } + if (responsePDU.getVariableBindings().isEmpty()) { + return null; + } return responsePDU; } + + private VariableBinding generateResponseBinding(int counter, OID oid) { + //get next test + if (SnmpTest.GET_NEXT_OID.equals(oid)) { + //if counter < 2 return the same oid + if (counter < 3) { + return new VariableBinding(SnmpTest.GET_NEXT_OID, new OctetString("" + counter)); + } + if (counter == 3) { + //else return sysDescr + return new VariableBinding(SnmpTest.GET_NEXT_OID, + new OctetString("My GET_NEXT Printer - response #" + counter)); + } + //else do not send response + return null; + } + + if (SnmpTest.POLL_OID.equals(oid)) { + if (counter < 4) { + return new VariableBinding(SnmpTest.POLL_OID, + new OctetString("My POLL Printer - response #" + counter)); + } + + } + + if (SnmpTest.PRODUCE_PDU_OID.equals(oid)) { + if (counter < 4) { + return new VariableBinding(SnmpTest.PRODUCE_PDU_OID, + new OctetString("My PRODUCE_PDU Printer - response #" + counter)); + } + } + + if (SnmpTest.TWO_OIDS_A.equals(oid)) { + if (counter < 4) { + return new VariableBinding(SnmpTest.TWO_OIDS_A, + new OctetString("My 2 OIDs A Printer - response #" + counter)); + } + } + + if (SnmpTest.TWO_OIDS_B.equals(oid)) { + if (counter < 4) { + return new VariableBinding(SnmpTest.TWO_OIDS_B, + new OctetString("My 2 OIDs B Printer - response #" + counter)); + } + } + + if (SnmpTest.DOT_OID.equals(oid)) { + if (counter < 4) { + return new VariableBinding(SnmpTest.DOT_OID, + new OctetString("My DOT Printer - response #" + counter)); + } + } + + return null; + } } }