/* * Copyright 2014, The Sporting Exchange Limited * * 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 com.betfair.cougar.util; import com.betfair.cougar.api.RequestUUID; import com.betfair.cougar.api.UUIDGenerator; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.junit.Assert.*; public class UUIDGeneratorImplTest { @BeforeClass public static void setup() { RequestUUIDImpl.setGenerator(new UUIDGeneratorImpl()); } @Test public void testRequestIdsShouldNotBeEqual() throws Exception { final String uuid1 = new UUIDGeneratorImpl().getNextUUID(); final String uuid2 = new UUIDGeneratorImpl().getNextUUID(); assertFalse("Uuids should not be equal", uuid1.equals(uuid2)); } @Test public void testRequestIdShouldContainFirstPartOfHostname() throws Exception { final String uuid = new UUIDGeneratorImpl().getNextUUID(); String host; try { host = InetAddress.getLocalHost().getHostName(); Pattern HOST_FINDER = Pattern.compile("([\\w\\d\\-]{1,30}+).*", Pattern.CASE_INSENSITIVE); Matcher m = HOST_FINDER.matcher(host); if (m.matches()) { host = m.group(1); } else { host = UUIDGeneratorImpl.DEFAULT_HOSTNAME; } } catch (UnknownHostException e) { host = UUIDGeneratorImpl.DEFAULT_HOSTNAME; } assertTrue("Request id should contain first part of hostname "+host, uuid.contains(host)); } @Test public void testRequestIdShouldContainTimestamp() throws Exception { final String uuid = new UUIDGeneratorImpl().getNextUUID(); final Pattern pattern = Pattern.compile("-\\d{8}-"); assertTrue("Request id should contain timestamp",pattern.matcher(uuid).find()); } @Test public void testRequestIdShouldContainCounter() throws Exception { final String uuid = new UUIDGeneratorImpl().getNextUUID(); final Pattern pattern = Pattern.compile("-(\\d|[a-f]){10}"); assertTrue("Request id should contain counter",pattern.matcher(uuid).find()); } @Test public void testRequestIdShouldHaveCorrectFormat() throws Exception { final String uuid = new UUIDGeneratorImpl().getNextUUID(); final Pattern pattern = Pattern.compile("\\S*-\\d{8}-(\\d|[a-f]){10}"); assertTrue("Request id should have correct format",pattern.matcher(uuid).matches()); } @Test public void testLengthAlwaysEqual() throws Exception { Field f = UUIDGeneratorImpl.class.getDeclaredField("count"); f.setAccessible(true); AtomicLong c = (AtomicLong)f.get(null); c.set(0); int referenceLength = new UUIDGeneratorImpl().getNextUUID().length(); int numUUIDsCreated = 0; long lastVal = -1; while (true) { UUIDGenerator uuid = new UUIDGeneratorImpl(); ++numUUIDsCreated; assertTrue("Bad uuid: "+ uuid , uuid.getNextUUID().length() == referenceLength); c.set(c.get() * 2); long thisVal = Long.parseLong(uuid.getNextUUID().substring(uuid.getNextUUID().lastIndexOf("-")+1), 16); if (thisVal < lastVal) { if (c.get() < 0xFFFFFFFFFFL) { Assert.fail("Cycled after "+numUUIDsCreated+" uuids. lastVal was "+lastVal+", thisVal is "+thisVal); } else { break; } } else { lastVal = thisVal; } } System.out.println("Length tested OK after "+ numUUIDsCreated+ "iterations"); } @Test public void testPerformance() throws Exception { UUIDThread[] threads = new UUIDThread[5]; for (int i=0; i < threads.length; ++i) { threads[i] = new UUIDThread() ; } for (int i=0; i < threads.length; ++i) { threads[i].start(); } for (int i=0; i < threads.length; ++i) { threads[i].join(); } long totalTime = 0; for (int i=0; i < threads.length; ++i) { if (threads[i].failString != null) { Assert.fail("Thread " + i + " failed - UUID found was " + threads[i].failString); } totalTime += threads[i].timeTaken; } System.out.println("Time taken for 5,000,000 requests was "+totalTime+" ms"); } @Test public void tripleComponent() { UUIDGeneratorImpl impl = new UUIDGeneratorImpl(); String[] component = impl.validateUuid("abcd001-abcdef-00001:defg002-ghijkl-00001:hijk003-mnopqr-00001"); assertEquals(3, component.length); assertEquals("abcd001-abcdef-00001",component[0]); assertEquals("defg002-ghijkl-00001",component[1]); assertEquals("hijk003-mnopqr-00001",component[2]); } @Test public void singleComponent() { UUIDGeneratorImpl impl = new UUIDGeneratorImpl(); String[] component = impl.validateUuid("abcd001-abcdef-00001"); assertEquals(3, component.length); assertNull(component[0]); assertNull(component[1]); assertEquals("abcd001-abcdef-00001",component[2]); } @Test(expected = IllegalArgumentException.class) public void tripleComponentWrongSep() { UUIDGeneratorImpl impl = new UUIDGeneratorImpl(); impl.validateUuid("abcd001-abcdef-00001;defg002-ghijkl-00001;hijk003-mnopqr-00001"); } @Test(expected = IllegalArgumentException.class) public void twoComponents() { UUIDGeneratorImpl impl = new UUIDGeneratorImpl(); impl.validateUuid("abcd001-abcdef-00001:defg002-ghijkl-00001"); } private static class UUIDThread extends Thread { private long timeTaken; private String failString; @Override public void run() { timeTaken = System.currentTimeMillis(); for (int i = 0; i < 1000000; ++i) { UUIDGenerator foo = new UUIDGeneratorImpl(); String uuid = foo.getNextUUID(); if (uuid.length() - uuid.lastIndexOf("-", uuid.lastIndexOf("-") - 1) != 20) { failString = uuid; } } timeTaken = System.currentTimeMillis() - timeTaken; } } }