001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.monitoring.jta;
018
019 import org.apache.commons.monitoring.gauges.Gauge;
020 import org.apache.commons.monitoring.repositories.Repository;
021 import org.junit.AfterClass;
022 import org.junit.BeforeClass;
023 import org.junit.Test;
024
025 import javax.ejb.EJB;
026 import javax.ejb.Lock;
027 import javax.ejb.LockType;
028 import javax.ejb.Singleton;
029 import javax.ejb.embeddable.EJBContainer;
030 import java.util.Collection;
031 import java.util.concurrent.CountDownLatch;
032 import java.util.concurrent.ExecutorService;
033 import java.util.concurrent.Executors;
034
035 import static org.junit.Assert.assertEquals;
036
037 public class GaugesTest {
038 private static final int ITERATIONS = 500;
039
040 private static Gauge.LoaderHelper gaugeLoader;
041
042 @BeforeClass
043 public static void init() {
044 Repository.INSTANCE.clear();
045 gaugeLoader = new Gauge.LoaderHelper(false);
046 }
047
048 @AfterClass
049 public static void reset() {
050 Repository.INSTANCE.clear();
051 gaugeLoader.destroy();
052 }
053
054 @EJB
055 private EjbWithJTASupport jtaSupport;
056
057 @Test
058 public void test() throws Exception {
059 final EJBContainer container = EJBContainer.createEJBContainer();
060 container.getContext().bind("inject", this);
061
062 final long start = System.currentTimeMillis();
063
064 final CountDownLatch latch = new CountDownLatch(ITERATIONS);
065 try {
066 final ExecutorService es = Executors.newFixedThreadPool(50);
067 for (int i = 0; i < ITERATIONS; i++) {
068 es.submit(new Runnable() {
069 @Override
070 public void run() {
071 jtaSupport.commit();
072 try {
073 jtaSupport.rollback();
074 } finally {
075 latch.countDown();
076 }
077 }
078 });
079 }
080 es.shutdown();
081 latch.await();
082
083 Thread.sleep(500); // wait last measure
084
085 final long end = System.currentTimeMillis();
086
087 assertEquals(ITERATIONS, sum(Repository.INSTANCE.getGaugeValues(start, end, JTAGauges.JTA_COMMITED).values()), 0);
088 assertEquals(ITERATIONS, sum(Repository.INSTANCE.getGaugeValues(start, end, JTAGauges.JTA_ROLLBACKED).values()), 0);
089
090 // due to the sleep we use in commit() we only see half of the tx when checking actives
091 assertEquals(ITERATIONS / 2, sum(Repository.INSTANCE.getGaugeValues(start, end, JTAGauges.JTA_ACTIVE).values()), ITERATIONS * .1);
092 } finally {
093 container.close();
094 }
095 }
096
097 private double sum(final Collection<Double> values) {
098 double sum = 0;
099 for (final Double d : values) {
100 sum += d;
101 }
102 return sum;
103 }
104
105 @Singleton
106 @Lock(LockType.READ)
107 @JTAMonitored
108 public static class EjbWithJTASupport {
109 public void commit() {
110 try {
111 Thread.sleep(50);
112 } catch (final InterruptedException e) {
113 // no-op
114 }
115 }
116
117 public void rollback() {
118 throw new NullPointerException();
119 }
120 }
121 }