This is an automated email from the ASF dual-hosted git repository. robertlazarski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git
commit e4923cde53ee6978adb56d8df3a6a79872568aca Author: Robert Lazarski <[email protected]> AuthorDate: Mon Apr 13 08:09:05 2026 -1000 AXIS2-5788 Unit tests for getServiceGroupContext touch semantics Covers all branches of the two overloads: - null id returns null from both overloads (no NPE, no mutation) - unknown id returns null from both overloads - legacy single-arg lookup touches lastTouchedTime (back-compat) - two-arg lookup with touch=true matches the legacy behaviour - two-arg lookup with touch=false LEAVES lastTouchedTime alone -- the actual AXIS2-5788 fix - the no-touch contract holds for both SOAP-session-scoped contexts (serviceGroupContextMap) and application-session-scoped contexts (applicationSessionServiceGroupContexts) - repeated no-touch lookups stay read-only (guard against a future refactor that re-introduces the observer effect for only the first call) The mutation check is done by forcing lastTouchedTime to 0L before the lookup and asserting it is either still 0L (no touch) or > 0L (touched) after -- avoids flakiness from the millisecond resolution of System.currentTimeMillis() that a "before vs after" comparison would have. --- ...ConfigurationContextServiceGroupLookupTest.java | 162 +++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/modules/kernel/test/org/apache/axis2/context/ConfigurationContextServiceGroupLookupTest.java b/modules/kernel/test/org/apache/axis2/context/ConfigurationContextServiceGroupLookupTest.java new file mode 100644 index 0000000000..b8a3a5dbea --- /dev/null +++ b/modules/kernel/test/org/apache/axis2/context/ConfigurationContextServiceGroupLookupTest.java @@ -0,0 +1,162 @@ +/* + * 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.axis2.context; + +import junit.framework.TestCase; + +import org.apache.axis2.description.AxisService; +import org.apache.axis2.description.AxisServiceGroup; +import org.apache.axis2.engine.AxisConfiguration; + +/** + * Covers the AXIS2-5788 fix: ConfigurationContext.getServiceGroupContext must + * no longer unconditionally touch the returned context -- callers must be + * able to opt out of the touch via the new + * {@code getServiceGroupContext(String, boolean)} overload. + */ +public class ConfigurationContextServiceGroupLookupTest extends TestCase { + + private static final String SOAP_SESSION_ID = "soap-session-sgc"; + private static final String APP_SESSION_SG_NAME = "app-session-sg"; + + private ConfigurationContext configurationContext; + private ServiceGroupContext soapSessionContext; + private ServiceGroupContext appSessionContext; + + @Override + protected void setUp() throws Exception { + AxisConfiguration axisConfiguration = new AxisConfiguration(); + + // A SOAP-session-scoped group (ends up in serviceGroupContextMap). + AxisServiceGroup soapSessionGroup = new AxisServiceGroup(axisConfiguration); + soapSessionGroup.setServiceGroupName("soap-session-group"); + soapSessionGroup.addService(new AxisService("soap-svc")); + axisConfiguration.addServiceGroup(soapSessionGroup); + + // An application-session-scoped group (ends up in + // applicationSessionServiceGroupContexts). + AxisServiceGroup appSessionGroup = new AxisServiceGroup(axisConfiguration); + appSessionGroup.setServiceGroupName(APP_SESSION_SG_NAME); + appSessionGroup.addService(new AxisService("app-svc")); + axisConfiguration.addServiceGroup(appSessionGroup); + + configurationContext = new ConfigurationContext(axisConfiguration); + + soapSessionContext = new ServiceGroupContext(configurationContext, soapSessionGroup); + soapSessionContext.setId(SOAP_SESSION_ID); + configurationContext.addServiceGroupContextIntoSoapSessionTable(soapSessionContext); + + appSessionContext = new ServiceGroupContext(configurationContext, appSessionGroup); + configurationContext.addServiceGroupContextIntoApplicationScopeTable(appSessionContext); + } + + /** Null id must short-circuit to null without mutation or NPE. */ + public void testNullIdReturnsNull() { + assertNull(configurationContext.getServiceGroupContext(null)); + assertNull(configurationContext.getServiceGroupContext(null, true)); + assertNull(configurationContext.getServiceGroupContext(null, false)); + } + + /** Unknown id returns null from both overloads. */ + public void testUnknownIdReturnsNull() { + assertNull(configurationContext.getServiceGroupContext("no-such-id")); + assertNull(configurationContext.getServiceGroupContext("no-such-id", true)); + assertNull(configurationContext.getServiceGroupContext("no-such-id", false)); + } + + /** Legacy single-arg lookup must still touch (back-compat). */ + public void testSingleArgLookupTouchesSoapSessionContext() { + soapSessionContext.setLastTouchedTime(0L); + + ServiceGroupContext found = configurationContext.getServiceGroupContext(SOAP_SESSION_ID); + + assertSame(soapSessionContext, found); + assertTrue("single-arg lookup must update lastTouchedTime", + found.getLastTouchedTime() > 0L); + } + + /** Two-arg lookup with touch=true matches the legacy behaviour. */ + public void testTwoArgLookupWithTouchTrueTouchesSoapSessionContext() { + soapSessionContext.setLastTouchedTime(0L); + + ServiceGroupContext found = + configurationContext.getServiceGroupContext(SOAP_SESSION_ID, true); + + assertSame(soapSessionContext, found); + assertTrue("touch=true must update lastTouchedTime", + found.getLastTouchedTime() > 0L); + } + + /** + * The AXIS2-5788 fix proper: touch=false must NOT mutate lastTouchedTime + * on the returned context. + */ + public void testTwoArgLookupWithTouchFalseDoesNotTouchSoapSessionContext() { + soapSessionContext.setLastTouchedTime(0L); + + ServiceGroupContext found = + configurationContext.getServiceGroupContext(SOAP_SESSION_ID, false); + + assertSame(soapSessionContext, found); + assertEquals("touch=false must leave lastTouchedTime unchanged", + 0L, found.getLastTouchedTime()); + } + + /** The same no-touch contract must hold for application-session contexts. */ + public void testTwoArgLookupWithTouchFalseDoesNotTouchAppSessionContext() { + appSessionContext.setLastTouchedTime(0L); + + ServiceGroupContext found = + configurationContext.getServiceGroupContext(APP_SESSION_SG_NAME, false); + + assertSame(appSessionContext, found); + assertEquals("touch=false must leave lastTouchedTime unchanged", + 0L, found.getLastTouchedTime()); + } + + /** And the legacy-touching contract must also hold for app-session contexts. */ + public void testSingleArgLookupTouchesAppSessionContext() { + appSessionContext.setLastTouchedTime(0L); + + ServiceGroupContext found = + configurationContext.getServiceGroupContext(APP_SESSION_SG_NAME); + + assertSame(appSessionContext, found); + assertTrue("single-arg lookup must update lastTouchedTime for app-session SGC", + found.getLastTouchedTime() > 0L); + } + + /** + * Calling the no-touch variant repeatedly must continue to leave + * lastTouchedTime alone -- guards against a future refactor that + * re-introduces the observer effect for only the first call. + */ + public void testRepeatedNoTouchLookupsNeverMutate() { + soapSessionContext.setLastTouchedTime(0L); + + for (int i = 0; i < 5; i++) { + ServiceGroupContext found = + configurationContext.getServiceGroupContext(SOAP_SESSION_ID, false); + assertSame(soapSessionContext, found); + assertEquals("iteration " + i + ": touch=false must stay read-only", + 0L, found.getLastTouchedTime()); + } + } +}
