Bug 449599 - Return value of DefaultSessionData.set(key, null, null) disobeys API doc
Fixed set(key, null, null) to return true if current mapping is null/non-existing Project: http://git-wip-us.apache.org/repos/asf/maven-resolver/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-resolver/commit/d171401c Tree: http://git-wip-us.apache.org/repos/asf/maven-resolver/tree/d171401c Diff: http://git-wip-us.apache.org/repos/asf/maven-resolver/diff/d171401c Branch: refs/heads/master Commit: d171401cf3e24a715006f566774cd48e7932e91c Parents: 7a07539 Author: Benjamin Bentmann <bentm...@sonatype.com> Authored: Tue Nov 11 15:08:39 2014 +0100 Committer: Benjamin Bentmann <bentm...@sonatype.com> Committed: Tue Nov 11 15:08:39 2014 +0100 ---------------------------------------------------------------------- .../org/eclipse/aether/DefaultSessionData.java | 6 +- .../eclipse/aether/DefaultSessionDataTest.java | 128 +++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/d171401c/aether-api/src/main/java/org/eclipse/aether/DefaultSessionData.java ---------------------------------------------------------------------- diff --git a/aether-api/src/main/java/org/eclipse/aether/DefaultSessionData.java b/aether-api/src/main/java/org/eclipse/aether/DefaultSessionData.java index 90f1127..738cebc 100644 --- a/aether-api/src/main/java/org/eclipse/aether/DefaultSessionData.java +++ b/aether-api/src/main/java/org/eclipse/aether/DefaultSessionData.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2012 Sonatype, Inc. + * Copyright (c) 2010, 2014 Sonatype, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -61,6 +61,10 @@ public final class DefaultSessionData } else { + if ( oldValue == null ) + { + return !data.containsKey( key ); + } return data.remove( key, oldValue ); } } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/d171401c/aether-api/src/test/java/org/eclipse/aether/DefaultSessionDataTest.java ---------------------------------------------------------------------- diff --git a/aether-api/src/test/java/org/eclipse/aether/DefaultSessionDataTest.java b/aether-api/src/test/java/org/eclipse/aether/DefaultSessionDataTest.java new file mode 100644 index 0000000..2c239a4 --- /dev/null +++ b/aether-api/src/test/java/org/eclipse/aether/DefaultSessionDataTest.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether; + +import static org.junit.Assert.*; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.Test; + +public class DefaultSessionDataTest +{ + + private DefaultSessionData data = new DefaultSessionData(); + + private Object get( Object key ) + { + return data.get( key ); + } + + private void set( Object key, Object value ) + { + data.set( key, value ); + } + + private boolean set( Object key, Object oldValue, Object newValue ) + { + return data.set( key, oldValue, newValue ); + } + + @Test( expected = RuntimeException.class ) + public void testGet_NullKey() + { + get( null ); + } + + @Test( expected = RuntimeException.class ) + public void testSet_NullKey() + { + set( null, "data" ); + } + + @Test + public void testGetSet() + { + Object key = "key"; + assertNull( get( key ) ); + set( key, "value" ); + assertEquals( "value", get( key ) ); + set( key, "changed" ); + assertEquals( "changed", get( key ) ); + set( key, null ); + assertNull( get( key ) ); + } + + @Test + public void testGetSafeSet() + { + Object key = "key"; + assertNull( get( key ) ); + assertFalse( set( key, "wrong", "value" ) ); + assertNull( get( key ) ); + assertTrue( set( key, null, "value" ) ); + assertEquals( "value", get( key ) ); + assertTrue( set( key, "value", "value" ) ); + assertEquals( "value", get( key ) ); + assertFalse( set( key, "wrong", "changed" ) ); + assertEquals( "value", get( key ) ); + assertTrue( set( key, "value", "changed" ) ); + assertEquals( "changed", get( key ) ); + assertFalse( set( key, "wrong", null ) ); + assertEquals( "changed", get( key ) ); + assertTrue( set( key, "changed", null ) ); + assertNull( get( key ) ); + assertTrue( set( key, null, null ) ); + assertNull( get( key ) ); + } + + @Test( timeout = 10000 ) + public void testConcurrency() + throws Exception + { + final AtomicReference<Throwable> error = new AtomicReference<Throwable>(); + Thread threads[] = new Thread[20]; + for ( int i = 0; i < threads.length; i++ ) + { + threads[i] = new Thread() + { + @Override + public void run() + { + for ( int i = 0; i < 100; i++ ) + { + String key = UUID.randomUUID().toString(); + try + { + set( key, Boolean.TRUE ); + assertEquals( Boolean.TRUE, get( key ) ); + } + catch ( Throwable t ) + { + error.compareAndSet( null, t ); + t.printStackTrace(); + } + } + } + }; + } + for ( Thread thread : threads ) + { + thread.start(); + } + for ( Thread thread : threads ) + { + thread.join(); + } + assertNull( String.valueOf( error.get() ), error.get() ); + } +}