/* * Copyright (C) 2014-2017 the original authors or authors. * * Licensed 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 io.sarl.util.tests.util; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import io.sarl.lang.util.SynchronizedCollection; import io.sarl.lang.util.SynchronizedSet; import io.sarl.tests.api.AbstractSarlTest; import io.sarl.util.Collections3; /** * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ @RunWith(Suite.class) @SuiteClasses({ Collections3Test.SynchronizedCollectionTest.class, Collections3Test.SynchronizedSetTest.class }) @SuppressWarnings("all") public class Collections3Test { @RunWith(Suite.class) @SuiteClasses({ Collections3Test.SynchronizedCollectionTest.CollectionTest.class, Collections3Test.SynchronizedCollectionTest.SyncTest.class }) public static class SynchronizedCollectionTest { public static class CollectionTest extends AbstractSarlTest { private Object mutex; private List<String> original; private SynchronizedCollection<String> collection; @Before public void setUp() { this.mutex = new Object(); this.original = new ArrayList<>(); for(int i=0; i<50; ++i) { this.original.add("0x"+Double.toHexString(Math.random())); //$NON-NLS-1$ } this.collection = Collections3.synchronizedCollection(this.original, this.mutex); } @Test public void size() { assertEquals(this.original.size(), this.collection.size()); } @Test public void isEmpty() { assertFalse(this.collection.isEmpty()); } @Test public void contains() { for(String s : this.original) { assertTrue(this.collection.contains(s)); } for(int i=0; i<50; ++i) { assertFalse(this.collection.contains(Integer.toString(i))); } } @Test public void toArray() { Object[] t = this.collection.toArray(); assertEquals(this.original.size(), t.length); for(int i=0; i<t.length; ++i) { assertSame(this.original.get(i), t[i]); } } @Test public void toArray_ObjectArray() { String[] t = new String[this.original.size()/2]; String[] t2 = this.collection.toArray(t); assertNotSame(t, t2); assertEquals(this.original.size(), t2.length); for(int i=0; i<t2.length; ++i) { assertSame(this.original.get(i), t2[i]); } } @Test public void add() { this.collection.add(Integer.toString(5)); assertTrue(this.collection.contains(Integer.toString(5))); assertTrue(this.original.contains(Integer.toString(5))); } @Test public void remove() { assertFalse(this.collection.remove(Integer.toString(5))); Random r = new Random(); while (!this.original.isEmpty()) { String s = this.original.get(r.nextInt(this.original.size())); assertTrue(this.collection.remove(s)); assertFalse(this.collection.contains(s)); assertFalse(this.original.contains(s)); } assertTrue(this.collection.isEmpty()); assertFalse(this.collection.remove(Integer.toString(5))); } @Test public void clear() { this.collection.clear(); assertTrue(this.collection.isEmpty()); assertTrue(this.original.isEmpty()); } @Test public void testEquals() { assertTrue(this.collection.equals(this.collection)); assertTrue(this.collection.equals(this.original)); Collection<String> c = new ArrayList<>(this.original); assertTrue(this.collection.equals(c)); assertFalse(this.collection.equals(Collections.singleton(5))); } @Test public void testHashCode() { assertEquals(this.collection.hashCode(), this.collection.hashCode()); assertEquals(this.original.hashCode(), this.collection.hashCode()); Collection<String> c = new ArrayList<>(this.original); assertEquals(c.hashCode(), this.collection.hashCode()); assertNotEquals(Collections.singleton(5), this.collection.hashCode()); } @Test public void iterator() { Iterator<String> it = this.collection.iterator(); int i=0; while (it.hasNext() && i<this.original.size()) { String e = it.next(); assertSame(this.original.get(i), e); ++i; } assertFalse(it.hasNext()); assertEquals(this.original.size(), i); } @Test public void mutex() { assertSame(this.mutex, this.collection.mutex()); } } public static class SyncTest extends AbstractSarlTest { private ExecutorService executors; private Object mutex; private List<String> original; private Collection<String> collection; @Before public void setUp() { this.executors = Executors.newFixedThreadPool(5); this.mutex = new Object(); this.original = new ArrayList<>(); for(int i=0; i<50; ++i) { this.original.add("0x"+Double.toHexString(Math.random())); //$NON-NLS-1$ } this.collection = Collections3.synchronizedCollection(this.original, this.mutex); } @After public void tearDown() throws Exception { this.executors.shutdownNow(); this.executors.awaitTermination(30, TimeUnit.SECONDS); } @Test public void iteratorHasMutex() throws Exception { synchronized(this.mutex) { this.executors.submit(new Runnable() { @Override public void run() { for(int i=0; i<10; ++i) { SyncTest.this.collection.add(Integer.toString(i)); } } }); Iterator<String> it = this.collection.iterator(); int i = 0; while(it.hasNext()) { String s = it.next(); assertSame(this.original.get(i), s); ++i; } } this.executors.shutdown(); this.executors.awaitTermination(30, TimeUnit.SECONDS); for(int i=0; i<10; ++i) { assertTrue(this.collection.contains(Integer.toString(i))); } } } } @RunWith(Suite.class) @SuiteClasses({ Collections3Test.SynchronizedSetTest.CollectionTest.class, Collections3Test.SynchronizedSetTest.SyncTest.class }) public static class SynchronizedSetTest { public static class CollectionTest extends AbstractSarlTest { private Object mutex; private TreeSet<String> original; private SynchronizedSet<String> collection; @Before public void setUp() { this.mutex = new Object(); this.original = new TreeSet<>(); for(int i=0; i<50; ++i) { this.original.add("0x"+Double.toHexString(Math.random())); //$NON-NLS-1$ } this.collection = Collections3.synchronizedSet(this.original, this.mutex); } @Test public void size() { assertEquals(this.original.size(), this.collection.size()); } @Test public void isEmpty() { assertFalse(this.collection.isEmpty()); } @Test public void contains() { for(String s : this.original) { assertTrue(this.collection.contains(s)); } for(int i=0; i<50; ++i) { assertFalse(this.collection.contains(Integer.toString(i))); } } @Test public void toArray() { Object[] t = this.collection.toArray(); assertEquals(this.original.size(), t.length); Iterator<String> it = this.original.iterator(); for(int i=0; i<t.length; ++i) { assertSame(it.next(), t[i]); } } @Test public void toArray_ObjectArray() { String[] t = new String[this.original.size()/2]; String[] t2 = this.collection.toArray(t); assertNotSame(t, t2); assertEquals(this.original.size(), t2.length); Iterator<String> it = this.original.iterator(); for(int i=0; i<t2.length; ++i) { assertSame(it.next(), t2[i]); } } @Test public void add() { this.collection.add(Integer.toString(5)); assertTrue(this.collection.contains(Integer.toString(5))); assertTrue(this.original.contains(Integer.toString(5))); } private <S> S get(Set<S> c, int index) { Iterator<S> it = c.iterator(); for(int i=0; i<index; ++i) { it.next(); } return it.next(); } @Test public void remove() { assertFalse(this.collection.remove(Integer.toString(5))); Random r = new Random(); while (!this.original.isEmpty()) { String s = get(this.original, r.nextInt(this.original.size())); assertTrue(this.collection.remove(s)); assertFalse(this.collection.contains(s)); assertFalse(this.original.contains(s)); } assertTrue(this.collection.isEmpty()); assertFalse(this.collection.remove(Integer.toString(5))); } @Test public void clear() { this.collection.clear(); assertTrue(this.collection.isEmpty()); assertTrue(this.original.isEmpty()); } @Test public void testEquals() { assertTrue(this.collection.equals(this.collection)); assertTrue(this.collection.equals(this.original)); Collection<String> c = new ArrayList<>(this.original); assertFalse(this.collection.equals(c)); c = new TreeSet<>(this.original); assertTrue(this.collection.equals(c)); assertFalse(this.collection.equals(Collections.singleton(5))); } @Test public void testHashCode() { assertEquals(this.collection.hashCode(), this.collection.hashCode()); assertEquals(this.original.hashCode(), this.collection.hashCode()); Collection<String> c = new ArrayList<>(this.original); assertNotEquals(c.hashCode(), this.collection.hashCode()); c = new TreeSet<>(this.original); assertEquals(c.hashCode(), this.collection.hashCode()); assertNotEquals(Collections.singleton(5), this.collection.hashCode()); } @Test public void iterator() { Iterator<String> it = this.collection.iterator(); Iterator<String> oit = this.original.iterator(); while (it.hasNext() && oit.hasNext()) { String e = it.next(); assertSame(oit.next(), e); } assertFalse(it.hasNext()); assertFalse(oit.hasNext()); } @Test public void mutex() { assertSame(this.mutex, this.collection.mutex()); } } public static class SyncTest extends AbstractSarlTest { private <S> S get(Set<S> c, int index) { Iterator<S> it = c.iterator(); for(int i=0; i<index; ++i) { it.next(); } return it.next(); } private ExecutorService executors; private Object mutex; private TreeSet<String> original; private Set<String> collection; @Before public void setUp() { this.executors = Executors.newFixedThreadPool(5); this.mutex = new Object(); this.original = new TreeSet<>(); for(int i=0; i<50; ++i) { this.original.add("0x"+Double.toHexString(Math.random())); //$NON-NLS-1$ } this.collection = Collections3.synchronizedSet(this.original, this.mutex); } @After public void tearDown() throws Exception { this.executors.shutdownNow(); this.executors.awaitTermination(30, TimeUnit.SECONDS); } @Test public void iteratorHasMutex() throws Exception { synchronized(this.mutex) { this.executors.submit(new Runnable() { @Override public void run() { for(int i=0; i<10; ++i) { SyncTest.this.collection.add(Integer.toString(i)); } } }); Iterator<String> it = this.collection.iterator(); int i = 0; while(it.hasNext()) { String s = it.next(); assertSame(get(this.original, i), s); ++i; } } this.executors.shutdown(); this.executors.awaitTermination(30, TimeUnit.SECONDS); for(int i=0; i<10; ++i) { assertTrue(this.collection.contains(Integer.toString(i))); } } } } }