From 29598063d7c512423e212382425ec529f06b886e Mon Sep 17 00:00:00 2001 From: JiriOndrusek Date: Tue, 2 May 2023 08:51:47 +0200 Subject: [PATCH] Snnmp: reworked tests to avoid flaky failures --- .../component/snmp/it/SnmpResource.java | 12 +- .../quarkus/component/snmp/it/SnmpRoute.java | 32 ++--- .../quarkus/component/snmp/it/SnmpTest.java | 38 ++++-- .../component/snmp/it/SnmpTestResource.java | 111 +++++++++++++----- 4 files changed, 128 insertions(+), 65 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 eee1ae9cd2c7..f76f9c1d13de 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 jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.inject.Named; -import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; @@ -47,8 +46,6 @@ @ApplicationScoped public class SnmpResource { - public static OID TRAP_OID = new OID("1.2.3.4.5"); - @ConfigProperty(name = SnmpRoute.TRAP_V0_PORT) int trap0Port; @@ -66,14 +63,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()); @@ -85,12 +81,12 @@ public Response producePDU(@PathParam("version") int version) { @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); + @SuppressWarnings("unchecked") List 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(",")); 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 ea4db233a5c5..d6fb2f64f991 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 @@ -59,16 +59,16 @@ public void configure() { from("snmp:0.0.0.0:" + trap1Port + "?protocol=udp&type=TRAP&snmpVersion=1") .process(e -> snmpResults.get("v1_trap").add(e.getIn().getBody(SnmpMessage.class))); - //POLL consumer 2 oidps, snmpVersion=0 + //POLL consumer 2 oids, snmpVersion=0 from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids=" + - SnmpConstants.sysName + "," + SnmpConstants.sysContact) + SnmpConstants.sysLocation + "," + SnmpConstants.sysContact) .process(e -> snmpResults.get("v0_poll2oids").add(e.getIn().getBody(SnmpMessage.class))); - //POLL consumer 2 oidps, snmpVersion=1 + //POLL consumer 2 oids, snmpVersion=1 from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=1&type=POLL&oids=" + - SnmpConstants.sysName + "," + SnmpConstants.sysContact) + SnmpConstants.sysLocation + "," + SnmpConstants.sysContact) .process(e -> snmpResults.get("v1_poll2oids").add(e.getIn().getBody(SnmpMessage.class))); - //POLL consumer starting with dot snmpVersion=0 + // 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))); @@ -79,11 +79,11 @@ public void configure() { //POLL consumer snmpVersion=0 from("snmp://" + snmpListenAddress + "?protocol=udp&snmpVersion=0&type=POLL&oids=" - + SnmpConstants.sysName) + + 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&type=POLL&oids=" - + SnmpConstants.sysName) + + SnmpConstants.sysDescr) .process(e -> snmpResults.get("v1_poll").add(e.getIn().getBody(SnmpMessage.class))); } @@ -93,15 +93,15 @@ static class Producers { @Named("snmpTrapResults") Map> snmpResults() { Map> map = new ConcurrentHashMap<>(); - map.put("v0_trap", new ConcurrentLinkedDeque()); - map.put("v1_trap", new ConcurrentLinkedDeque()); - map.put("v0_poll", new ConcurrentLinkedDeque()); - map.put("v1_poll", new ConcurrentLinkedDeque()); - map.put("v3_poll", new ConcurrentLinkedDeque()); - map.put("v0_pollStartingDot", new ConcurrentLinkedDeque()); - map.put("v1_pollStartingDot", new ConcurrentLinkedDeque()); - map.put("v0_poll2oids", new ConcurrentLinkedDeque()); - map.put("v1_poll2oids", new ConcurrentLinkedDeque()); + map.put("v0_trap", new ConcurrentLinkedDeque<>()); + map.put("v1_trap", new ConcurrentLinkedDeque<>()); + map.put("v0_poll", new ConcurrentLinkedDeque<>()); + map.put("v1_poll", new ConcurrentLinkedDeque<>()); + map.put("v3_poll", new ConcurrentLinkedDeque<>()); + map.put("v0_pollStartingDot", new ConcurrentLinkedDeque<>()); + map.put("v1_pollStartingDot", new ConcurrentLinkedDeque<>()); + map.put("v0_poll2oids", new ConcurrentLinkedDeque<>()); + map.put("v1_poll2oids", new ConcurrentLinkedDeque<>()); 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 47b19ecca16c..5155a7c85c8a 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 @@ -26,6 +26,7 @@ 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; @@ -40,6 +41,13 @@ @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 supportedVersions() { return Stream.of(0, 1/*, 3 not supported because of https://issues.apache.org/jira/browse/CAMEL-19298 */); } @@ -74,13 +82,14 @@ public void testPoll(int version) throws Exception { await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { String result = RestAssured.given() - .body(SnmpConstants.sysName.toString()) + .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"); }); } @@ -91,24 +100,25 @@ public void testPollStartingDot(int version) throws Exception { await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { String result = RestAssured.given() - .body("1.3.6.1.4.1.6527.3.1.2.21.2.1.50") + .body(DOT_OID.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 DOT Printer - response #1,My DOT Printer - response #2,My DOT Printer - response #3"); }); } @ParameterizedTest @MethodSource("supportedVersions") public void testProducePDU(int version) { - RestAssured - .get("/snmp/producePDU/" + 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 @@ -116,11 +126,11 @@ public void testProducePDU(int version) { 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 @@ -130,20 +140,22 @@ public void testPollWith2OIDs(int version) throws Exception { await().atMost(20L, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> { String resultOid1 = RestAssured.given() - .body(SnmpConstants.sysName.toString()) + .body(TWO_OIDS_A.toString()) .post("/snmp/results/" + resultsName) .then() .statusCode(200) .extract().body().asString(); String resultOid2 = RestAssured.given() - .body(SnmpConstants.sysContact.toString()) + .body(TWO_OIDS_B.toString()) .post("/snmp/results/" + resultsName) .then() .statusCode(200) .extract().body().asString(); - return resultOid1.startsWith("Response from the test #1,Response from the test #2,Response from the test #3") && - resultOid2.startsWith("Response from the test #1,Response from the test #2,Response from the test #3"); + 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 59e87e38a5f7..769c7824b6d2 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 @@ 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.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,38 +96,34 @@ public TestCommandResponder(Snmp commandResponder) { @Override public synchronized void processPdu(CommandResponderEvent event) { PDU pdu = event.getPDU(); - Vector vbs = Optional.ofNullable(pdu.getVariableBindings()).orElse(new Vector<>(0)); + Vector vbs; + if (pdu.getVariableBindings() != null) { + vbs = 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 - } - } - try { PDU response = makeResponse(++numberOfSent, SnmpConstants.version1, vbs); - response.setRequestID(pdu.getRequestID()); - commandResponder.getMessageDispatcher().returnResponsePdu( - event.getMessageProcessingModel(), event.getSecurityModel(), - event.getSecurityName(), event.getSecurityLevel(), - response, event.getMaxSizeResponsePDU(), - event.getStateReference(), new StatusInformation()); + 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); } @@ -140,13 +136,72 @@ private PDU makeResponse(int counter, int version, Vector responsePDU.add(new VariableBinding(vb.getOid(), - new OctetString("Response from the test #" + counter)))); + 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; + } } }