Package ma.glasnost.orika.test.perf

Source Code of ma.glasnost.orika.test.perf.MultiThreadedTestCase$PersonVO

/*
* Orika - simpler, better and faster Java bean mapping
*
* Copyright (C) 2011 Orika 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 ma.glasnost.orika.test.perf;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.ref.SoftReference;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import junit.framework.Assert;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
import ma.glasnost.orika.test.ConcurrentRule;
import ma.glasnost.orika.test.ConcurrentRule.Concurrent;
import ma.glasnost.orika.test.DynamicSuite;
import ma.glasnost.orika.test.MappingUtil;
import ma.glasnost.orika.test.common.types.TestCaseClasses.AuthorImpl;
import ma.glasnost.orika.test.common.types.TestCaseClasses.Book;
import ma.glasnost.orika.test.common.types.TestCaseClasses.BookImpl;
import ma.glasnost.orika.test.common.types.TestCaseClasses.Library;
import ma.glasnost.orika.test.common.types.TestCaseClasses.LibraryDTO;
import ma.glasnost.orika.test.common.types.TestCaseClasses.LibraryImpl;

import org.apache.commons.lang.time.DateUtils;
import org.junit.Rule;
import org.junit.Test;

/**
* @author matt.deboer@gmail.com
*
*/
public class MultiThreadedTestCase {

 
  /**
   * Allows us to run methods concurrently by marking with <code>@Concurrent</code>;
   * note that in the current implementation, such methods will have the
   * <code>@Before</code> and <code>@After</code> methods also invoked concurrently.
   */
  @Rule
  public ConcurrentRule concurrentRule = new ConcurrentRule();
 
  private volatile Set<Class<?>> classes = getNonAnonymousClasses();
 
 
  private final MapperFacade mapper = MappingUtil.getMapperFactory().getMapperFacade();
 
  private static Set<Class<?>> getNonAnonymousClasses() {
    Set<Class<?>> classes = new HashSet<Class<?>>();
    File classFolder;
    try {
      classFolder = new File(URLDecoder.decode(MultiThreadedTestCase.class.getResource("/")
          .getFile(), "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
    List<Class<?>> allClasses = DynamicSuite.findTestCases(classFolder, ".*");
    for (Class<?> aClass: allClasses) {
      if (!aClass.isAnonymousClass()) {
        classes.add(aClass);
      }
    }
    return classes;
  }
 
  private final AtomicInteger threadIndex = new AtomicInteger(0);
  private Type<?>[] typeResults = new Type<?>[15];
  private CountDownLatch finishLine = new CountDownLatch(15);
 
  @Test
  @Concurrent(15)
  public void testDefineSingleTypeSimultaneously() throws InterruptedException {
   
    int myIndex = threadIndex.getAndAdd(1);
    typeResults[myIndex] = TypeFactory.valueOf(Integer.class);
   
    finishLine.countDown();

    finishLine.await();
   
    Type<?> firstType = typeResults[0];
    for (Type<?> type: typeResults) {
      Assert.assertEquals(firstType, type);
    }
  }
 
 
  AtomicInteger myIndex = new AtomicInteger();
 
  /**
   * Verifies that multiple threads requesting the type for the same set of classes receive
   * the same set of values over a large number of classes.
   */
  @Test
  @Concurrent(100)
  public void testDefineTypesSimultaneously() {
   
    int i = myIndex.getAndIncrement();
    int c = 0;
    Map<Type<?>,Class<?>> types = new HashMap<Type<?>,Class<?>>();
    for (Class<?> aClass: classes) {
     
      /*
       * In this section, we force each of the threads to trigger a GC
       * at some point in mid process; this should help shake out any
       * issues with weak references getting cleared (that we didn't expect to
       * be cleared).
       */
      ++c;
      Type<?> aType;
      try {
        aType = TypeFactory.valueOf(aClass);
      } catch (StackOverflowError e) {
        throw new RuntimeException("while trying to evaluate valueOf(" + aClass.getCanonicalName() + ")", e);
      }
      if (aType == null) {
        throw new IllegalStateException("TypeFactory.valueOf() returned null for " + aClass);
      } else if (types.containsKey(aType)) {
        throw new IllegalStateException("mapping already exists for " + aClass + ": " + aType + " = " + types.get(aType));
      } else {
        if (aClass.isAssignableFrom(aType.getRawType())) {
          types.put(aType, aClass);
        } else {
          throw new IllegalStateException(aType + " is not an instance of " + aClass);
        }
      }
      if (c == i) {
                forceClearSoftAndWeakReferences();
            }
    }
   
    Assert.assertEquals(classes.size(), types.size());
  }
 
  @Test
  @Concurrent(20)
  public void testGenerateMappers() {
    BookImpl book = new BookImpl("The Book Title", new AuthorImpl("The Author Name"));
    Library lib = new LibraryImpl("The Library", Arrays.<Book>asList(book));
   
    LibraryDTO mappedLib = mapper.map(lib, LibraryDTO.class);
   
    // Just to be sure things mapped as expected
    Assert.assertEquals(lib.getTitle(),mappedLib.getTitle());
    Assert.assertEquals(book.getTitle(),mappedLib.getBooks().get(0).getTitle());
    Assert.assertEquals(book.getAuthor().getName(),mappedLib.getBooks().get(0).getAuthor().getName());
 
  }
 
 
  @Test
  @Concurrent(20)
  public void testGenerateObjectFactories() {
       
        Person person = new Person();
        person.setFirstName("Abdelkrim");
        person.setLastName("EL KHETTABI");
        Calendar cal = Calendar.getInstance();
        cal = DateUtils.truncate(cal, Calendar.DAY_OF_MONTH);
        cal.add(Calendar.YEAR, -31);
        person.setDateOfBirth(cal.getTime());
        person.setAge(31L);
       
        PersonVO vo = mapper.map(person, PersonVO.class);
       
        Assert.assertEquals(person.getFirstName(), vo.getFirstName());
        Assert.assertEquals(person.getLastName(), vo.getLastName());
        Assert.assertTrue(person.getAge() == vo.getAge());
        Assert.assertEquals(cal.getTime(), vo.getDateOfBirth());
  }
 
  public static class Person {
        private String firstName;
        private String lastName;
       
        private Long age;
        private Date date;
       
        public String getFirstName() {
            return firstName;
        }
       
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
       
        public String getLastName() {
            return lastName;
        }
       
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
       
        public Long getAge() {
            return age;
        }
       
        public void setAge(Long age) {
            this.age = age;
        }
       
        public Date getDateOfBirth() {
            return date;
        }
       
        public void setDateOfBirth(Date date) {
            this.date = date;
        }
       
    }
   
    public static class PersonVO {
        private final String firstName;
        private final String lastName;
       
        private final long age;
        private final Date dateOfBirth;
       
        public PersonVO(String firstName, String lastName, long age, Date dateOfBirth) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
            this.dateOfBirth = dateOfBirth;
        }
       
        public String getFirstName() {
            return firstName;
        }
       
        public String getLastName() {
            return lastName;
        }
       
        public long getAge() {
            return age;
        }
       
        public Date getDateOfBirth() {
            return dateOfBirth;
        }
    }
   
    /**
   * Since the contract for SoftReference states that all soft references
   * will be cleared by the garbage collector before OOME is thrown, we
   * allocate dummy bytes until we reach OOME.
   */
  private void forceClearSoftAndWeakReferences() {
   
    SoftReference<Object> checkReference = new SoftReference<Object>(new Object());
    Assert.assertNotNull(checkReference.get());
    try {
      List<byte[]> byteBucket = new ArrayList<byte[]>();
      for (int i=0; i < Integer.MAX_VALUE; ++i) {
        int available = (int)Math.min((long)Integer.MAX_VALUE,Runtime.getRuntime().maxMemory());
          byteBucket.add(new byte[available]);
      }
    } catch (Throwable e) {
        // Ignore OME; soft references should now have been cleared
      Assert.assertNull(checkReference.get());
    }
   
  }
 
 
}
TOP

Related Classes of ma.glasnost.orika.test.perf.MultiThreadedTestCase$PersonVO

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.