gemmellr commented on code in PR #5079: URL: https://github.com/apache/activemq-artemis/pull/5079#discussion_r1679244445
########## artemis-server/src/test/java/org/apache/activemq/artemis/core/config/DivertConfigurationEncodingTest.java: ########## @@ -0,0 +1,47 @@ +/* + * 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.activemq.artemis.core.config; + +import org.apache.activemq.artemis.api.core.ActiveMQBuffer; +import org.apache.activemq.artemis.api.core.ActiveMQBuffers; +import org.apache.activemq.artemis.core.server.ComponentConfigurationRoutingType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DivertConfigurationEncodingTest { + + @Test + public void testStoreDivertConfigurationWithTransformerNoProperties() { + DivertConfiguration configuration = new DivertConfiguration(); + configuration.setName("myDivertName"); + configuration.setAddress("myDivertAddress"); + configuration.setForwardingAddress("myDivertForwardingAddress"); + configuration.setFilterString("foo='foo'"); + configuration.setRoutingName("myDivertRoutingName"); + configuration.setExclusive(false); + configuration.setRoutingType(ComponentConfigurationRoutingType.ANYCAST); + TransformerConfiguration myDivertTransformer = new TransformerConfiguration("myDivertTransformer"); + myDivertTransformer.getProperties().put("foo", "foo"); + configuration.setTransformerConfiguration(myDivertTransformer); + + int encodeSize = configuration.getEncodeSize(); + ActiveMQBuffer data = ActiveMQBuffers.fixedBuffer(encodeSize); + configuration.encode(data); + assertEquals(encodeSize, data.writerIndex()); Review Comment: > > The bug here was apparently that the value of getEncodeSize() was wrong. > > That was _most_ of the bug, but not all. There was also a bug in the actual encoding (which used `writeString` instead of `writeNullableString`). > > > For a comprehensive encoder test I'd expect an assertion on the exact actual value for given inputs to check it is as expected, but there still isnt such an assertion. > > The test does, in fact, make an assertion on the actual value in question (i.e. the data in the buffer) to ensure it matches the calculated encoded size. > It asserts it is the same as some other length value _it also doesnt really know is correct_. Checking the two values are equal does not validate that either value was actually correct. This PR is even fixing bugs on both sides of the comparison. > Are you suggesting the test essentially re-implement `o.a.a.a.c.c.DivertConfiguration#getEncodeSize` and compare that with the value that the "real" implementation returns? > I am saying that for a given input we should know the exact encoded size and output expected and assert it in a test, but none of these tests really do that. Dont need to implement anything to do that (but could), just verify it. The new additional tests at least check round-tripping gets back to the expected values, which is much improved, but still doesnt check the encoder and decoder are actually doing the correct thing, just that they 'both agree'. I could unwittingly change them in future in a way that 'breaks' them (/the output) but the tests wont detect because they dont really verify the output itself. I think it should be the first test that notices something changed unexpectedly. > > All the tests do is verify the number of bytes written equals that value returned, which it always should, but that doesnt actually check the value was correct to expectations. > > I'm not following. If the code just tested something which "always should" be the case then it would never fail. However, the test does fail if you remove the fix(es). To be clear, the test is comparing the _calculated_ encoding size with the _actual_ encoded size of the data to ensure they are the same. > I meant it 'always should' in the sense that _if the size calculation and encoding code is all correct_, those values clearly should match. The code wasnt all correct (both sides being broken in some way), so unwinding the fix would be expected to _potentially_ make it fail. A mismatch between those two proves at least one side is incorrect, which is the minimal value in the assertion, but them being the same size does not prove either is correct. That needs verified separately. > > Similarly with the actual encoded bytes, they are not directly asserted, only indirectly verified by using the decoder. > > I'm not clear on how to "directly" assert the values of the bytes without essentially re-implementing the decoder or using static values which themselves are generated from existing code. Do you have any specific suggestions on how to do this? > In this case I meant literally compare the bytes with what they should be, as we can tell what they should be. One case would as you said be taking the output from the encoder, verify manually they are correct as-is, and then codifying the expected output into the test via assertion(s). Then in future if it the output changes unexpectedly, it would fail, and indicate exactly where and how the output changed. Another route would be essentially 'reimplementing' as you say. We effectively do both for proton and qpid-jms. There are tests that verify known bytes for encoders and decoders testing using fixed output assertions or input bytes. There are also simpler alternative protocol implementations forming the test peers that can be run against the full client / engine output to exercise them and/or validate the bytes on the wire as changes are being made to the 'production' implementations. In this case, verifying 'known expected bytes' seems the more suitable and simple approach. > FWIW, my goal for this PR was not to provide an exhaustive set of tests for divert encoding/decoding. I simply wanted to fix and verify the specific use-case from [ARTEMIS-4910](https://issues.apache.org/jira/browse/ARTEMIS-4910). A simple encoder that spits out expected bytes from a given input is some of the most easily comprehensively testable code we ever come across. Not adding appropriate testing when creating the code, or later fixing the code and clearly seeing it is missing such testing, is pretty much exactly how to repeatedly end up with situations like this one. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: gitbox-unsubscr...@activemq.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: gitbox-unsubscr...@activemq.apache.org For additional commands, e-mail: gitbox-h...@activemq.apache.org For further information, visit: https://activemq.apache.org/contact