/* * 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.marshalling.impl.databinding.kpi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.*; import java.io.InputStream; import java.io.OutputStream; import com.betfair.cougar.marshalling.api.databinding.FaultMarshaller; import com.betfair.cougar.marshalling.api.databinding.Marshaller; import com.betfair.cougar.marshalling.api.databinding.UnMarshaller; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; import com.betfair.cougar.core.api.fault.CougarFault; import com.betfair.tornjak.kpi.KPIMonitor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** * Unit tests {@link KPITimingMarshaller}, {@link KPITimingFaultMarshaller} and * {@link KPITimingUnMarshaller}. These tests re-use a lot of functionality, no point in separate * classes. */ public class KPITimersTest { private static final String TEST_KPI_NAME = "test.kpi.name"; private static final String TEST_ERROR_MSG = "test error message"; private static final Object RESULT = new Object(); private static final String ENCODING = "TESTENCODING"; private OutputStream os; private CougarFault fault; private InputStream inputStream; private KPIMonitor monitor; private Marshaller baseMarshaller; private FaultMarshaller baseFaultMarshaller; private UnMarshaller baseUnmarshaller; @Before public void setUp() { fault = mock(CougarFault.class); inputStream = mock(InputStream.class); os = mock(OutputStream.class); monitor = mock(KPIMonitor.class); baseMarshaller = mock(Marshaller.class); baseFaultMarshaller = mock(FaultMarshaller.class); baseUnmarshaller = mock(UnMarshaller.class); } @Test public void testMarshallerSuccess() { doAnswer(doStuff(false)).when(baseMarshaller).marshall(os, RESULT, ENCODING, false); KPITimingMarshaller marshaller = new KPITimingMarshaller(monitor, TEST_KPI_NAME, baseMarshaller); marshaller.marshall(os, RESULT, ENCODING, false); expectKPIUpdate(TEST_KPI_NAME, true); } @Test public void testMarshallerFailure() { doAnswer(doStuff(true)).when(baseMarshaller).marshall(os, RESULT, ENCODING, false); KPITimingMarshaller marshaller = new KPITimingMarshaller(monitor, TEST_KPI_NAME, baseMarshaller); try { marshaller.marshall(os, RESULT, ENCODING, false); fail("Should have thrown an exception"); } catch (RuntimeException e) { assertEquals(TEST_ERROR_MSG, e.getMessage()); } expectKPIUpdate(TEST_KPI_NAME, false); } @Test public void testFaultMarshallerSuccess() { doAnswer(doStuff(false)).when(baseFaultMarshaller).marshallFault(os, fault, ENCODING); KPITimingFaultMarshaller marshaller = new KPITimingFaultMarshaller(monitor, TEST_KPI_NAME, baseFaultMarshaller); marshaller.marshallFault(os, fault, ENCODING); expectKPIUpdate(TEST_KPI_NAME, true); } @Test public void testFaultMarshallerFailure() { doAnswer(doStuff(true)).when(baseFaultMarshaller).marshallFault(os, fault, ENCODING); KPITimingFaultMarshaller marshaller = new KPITimingFaultMarshaller(monitor, TEST_KPI_NAME, baseFaultMarshaller); try { marshaller.marshallFault(os, fault, ENCODING); fail("Should have thrown an exception"); } catch (RuntimeException e) { assertEquals(TEST_ERROR_MSG, e.getMessage()); } expectKPIUpdate(TEST_KPI_NAME, false); } @Test public void testUnmarshallerSuccess() { doAnswer(doStuff(false)).when(baseUnmarshaller).unmarshall(inputStream,String.class,"test", true); KPITimingUnMarshaller marshaller = new KPITimingUnMarshaller(monitor, TEST_KPI_NAME, baseUnmarshaller); marshaller.unmarshall(inputStream,String.class,"test", true); expectKPIUpdate(TEST_KPI_NAME, true); } @Test public void testUnmarshallerFailure() { doAnswer(doStuff(true)).when(baseUnmarshaller).unmarshall(inputStream,String.class,"test", true); KPITimingUnMarshaller marshaller = new KPITimingUnMarshaller(monitor, TEST_KPI_NAME, baseUnmarshaller); try { marshaller.unmarshall(inputStream,String.class,"test", true); fail("Should have thrown an exception"); } catch (RuntimeException e) { assertEquals(TEST_ERROR_MSG, e.getMessage()); } expectKPIUpdate(TEST_KPI_NAME, false); } protected <T> Answer<T> doStuff(final boolean throwException) { return new Answer<T>() { @Override public T answer(InvocationOnMock invocation) throws Throwable { Thread.sleep(20); if (throwException) { throw new RuntimeException(TEST_ERROR_MSG); } return null; } }; } private void expectKPIUpdate(final String msgSuffix, final boolean success) { verify(monitor, times(1)).addEvent(argThat(validKpiName(msgSuffix)), doubleThat(nonZero()), eq(success)); } private Matcher<String> validKpiName(final String msgSuffix) { return new BaseMatcher<String>() { @Override public boolean matches(Object o) { return msgSuffix.equals(o); } @Override public void describeTo(Description arg0) { arg0.appendText("Update with KPI name ending with " + msgSuffix); } }; } private Matcher<Double> nonZero() { return new BaseMatcher<Double>() { @Override public boolean matches(Object arg0) { assertTrue("Timed value must be non-zero", ((Double)arg0).doubleValue() > 0); return true; } @Override public void describeTo(Description arg0) { arg0.appendText("Non-zero duration"); } }; } }