blob: 3570d5bdc80f83a5e237078bf53953ea5af34e9a [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you 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 org.apache.juneau.mstat;
import static org.junit.runners.MethodSorters.*;
import static org.apache.juneau.assertions.Assertions.*;
import java.util.*;
import org.apache.juneau.cp.*;
import org.junit.*;
@SuppressWarnings("serial")
@FixMethodOrder(NAME_ASCENDING)
public class ThrownStore_Test {
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
@Test
public void a01_testBasic() {
Throwable t1 = new Throwable();
t1.fillInStackTrace();
Throwable t2 = new Throwable();
t2.fillInStackTrace();
ThrownStore db = new ThrownStore();
assertInteger(db.add(t1).getCount()).is(1);
assertInteger(db.add(t1).getCount()).is(2);
assertInteger(db.add(t2).getCount()).is(1);
assertLong(db.getStats(t1).get().getHash()).isEqual(db.getStats(t1).get().getHash());
assertLong(db.getStats(t1).get().getHash()).doesNotEqual(db.getStats(t2).get().getHash());
}
@Test
public void a02_getStats() {
Throwable t1 = new Throwable();
t1.fillInStackTrace();
Throwable t2 = new Throwable();
t2.fillInStackTrace();
ThrownStore db = new ThrownStore();
db.add(t1);
db.add(t1);
db.add(t2);
List<ThrownStats> l = db.getStats(); // Should be a snapshot.
db.add(t1);
assertList(l).isSize(2);
assertInteger(l.get(0).getCount()).is(2);
assertInteger(l.get(1).getCount()).is(1);
}
@Test
public void a03_reset() {
Throwable t1 = new Throwable();
t1.fillInStackTrace();
ThrownStore db = new ThrownStore();
db.add(t1);
db.reset();
assertObject(db.getStats(t1)).isNull();
}
@Test
public void a04_sameStackTraces() {
ThrownStore db = new ThrownStore();
Throwable t1 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop", "baz", "Stop.class", 3),
new StackTraceElement("Object", "baz", "Object.class", 6)
};
}
};
Throwable t2 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop", "baz", "Stop.class", 3),
new StackTraceElement("Object", "baz", "Object.class", 6)
};
}
};
db.add(t1);
db.add(t2);
assertInteger(db.getStats(t1).get().getCount()).is(2);
assertInteger(db.getStats(t2).get().getCount()).is(2);
}
@Test
public void a05_slightlyDifferentStackTraces() {
ThrownStore db = new ThrownStore();
Throwable t1 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop", "baz", "Stop.class", 3),
new StackTraceElement("Object", "baz", "Object.class", 6)
};
}
};
Throwable t2 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop", "baz", "Stop.class", 3),
new StackTraceElement("Object", "baz", "Object.class", 7)
};
}
};
db.add(t1);
db.add(t2);
assertInteger(db.getStats(t1).get().getCount()).is(1);
assertInteger(db.getStats(t2).get().getCount()).is(1);
}
@Test
public void a06_proxyElements() {
ThrownStore db = new ThrownStore();
Throwable t1 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop$1", "baz", "Stop.class", 6),
new StackTraceElement("Object", "baz", "Object.class", 6)
};
}
};
Throwable t2 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement("Stop$2", "baz", "Stop.class", 6),
new StackTraceElement("Object", "baz", "Object.class", 6)
};
}
};
db.add(t1);
db.add(t2);
assertInteger(db.getStats(t1).get().getCount()).is(2);
assertInteger(db.getStats(t2).get().getCount()).is(2);
}
//------------------------------------------------------------------------------------------------------------------
// Builder tests.
//------------------------------------------------------------------------------------------------------------------
@Test
public void b01_builder_default() {
assertObject(ThrownStore.create().build()).isType(ThrownStore.class);
}
public static class B1 extends ThrownStore{}
@Test
public void b02_builder_implClass() {
assertObject(ThrownStore.create().implClass(B1.class).build()).isType(B1.class);
}
@Test
public void b03_builder_defaultImplClass() {
ThrownStoreBuilder b = new ThrownStoreBuilder() {
@Override
protected Class<? extends ThrownStore> getDefaultImplClass() {
return B1.class;
}
};
assertObject(b.build()).isType(B1.class);
}
public static class B4 extends ThrownStore {
public B4(ThrownStoreBuilder b) throws Exception {
throw new RuntimeException("foobar");
}
}
@Test
public void b04_builder_implClass_bad() {
assertThrown(()->ThrownStore.create().implClass(B4.class).build()).contains("foobar");
}
public static class B5a {}
public static class B5b extends ThrownStore {
public B5b(ThrownStoreBuilder b, B5a x) throws Exception {
if (x == null)
throw new RuntimeException("Bad");
}
}
public static class B5c extends ThrownStore {
public B5c(ThrownStoreBuilder b, Optional<B5a> x) throws Exception {
if (x == null)
throw new RuntimeException("Bad");
}
}
@Test
public void b05_builder_beanFactory() throws Exception {
BeanStore bs = BeanStore.create().build();
assertThrown(()->ThrownStore.create().beanStore(bs).implClass(B5b.class).build()).contains("Public constructor found but could not find prerequisites: B5a");
assertObject(ThrownStore.create().beanStore(bs).implClass(B5c.class).build()).isType(B5c.class);
bs.addBean(B5a.class, new B5a());
assertObject(ThrownStore.create().beanStore(bs).implClass(B5b.class).build()).isType(B5b.class);
assertObject(ThrownStore.create().beanStore(bs).implClass(B5c.class).build()).isType(B5c.class);
}
public static class B6a {}
public static class B6b extends ThrownStats {
public B6b(ThrownStatsBuilder b, B6a x) throws Exception {
super(b);
if (x == null)
throw new RuntimeException("Bad");
}
}
public static class B6c extends ThrownStats {
public B6c(ThrownStatsBuilder b, Optional<B6a> x) throws Exception {
super(b);
if (x == null)
throw new RuntimeException("Bad");
}
}
@Test
public void b06_statsImplClass() throws Exception {
BeanStore bs = BeanStore.create().build();
Throwable t1 = new Throwable();
t1.fillInStackTrace();
assertThrown(()->ThrownStore.create().beanStore(bs).statsImplClass(B6b.class).build().add(t1)).contains("Public constructor found but could not find prerequisites: B6a");
assertObject(ThrownStore.create().beanStore(bs).statsImplClass(B6c.class).build().add(t1)).isType(B6c.class);
bs.addBean(B6a.class, new B6a());
assertObject(ThrownStore.create().statsImplClass(B6b.class).beanStore(bs).build().add(t1)).isType(B6b.class);
assertObject(ThrownStore.create().statsImplClass(B6c.class).beanStore(bs).build().add(t1)).isType(B6c.class);
}
//------------------------------------------------------------------------------------------------------------------
// ThrownStats tests.
//------------------------------------------------------------------------------------------------------------------
@Test
public void c01_thrownStats_basic() throws Exception {
Throwable t1 = new Throwable("foo");
t1.fillInStackTrace();
Throwable t2 = new Throwable("bar", t1);
t2.fillInStackTrace();
ThrownStore store = ThrownStore.create().build();
ThrownStats stats = store.add(t2);
assertObject(stats.getThrownClass()).is(Throwable.class);
assertLong(stats.getHash()).isNot(0);
assertLong(stats.getGuid()).isNot(0);
assertLong(stats.getFirstOccurrence()).isNot(0);
assertLong(stats.getLastOccurrence()).isNot(0);
assertString(stats.getFirstMessage()).is("bar");
assertObject(stats.getStackTrace()).asJson().contains("org.apache.juneau");
assertObject(stats).asString().contains("bar");
stats = stats.clone();
assertObject(stats.getThrownClass()).is(Throwable.class);
assertLong(stats.getHash()).isNot(0);
assertLong(stats.getGuid()).isNot(0);
assertLong(stats.getFirstOccurrence()).isNot(0);
assertLong(stats.getLastOccurrence()).isNot(0);
assertString(stats.getFirstMessage()).is("bar");
assertObject(stats.getStackTrace()).asJson().contains("org.apache.juneau");
assertObject(stats).asString().contains("bar");
stats = stats.getCausedBy().get();
assertObject(stats.getThrownClass()).is(Throwable.class);
assertLong(stats.getHash()).isNot(0);
assertLong(stats.getGuid()).isNot(0);
assertLong(stats.getFirstOccurrence()).isNot(0);
assertLong(stats.getLastOccurrence()).isNot(0);
assertString(stats.getFirstMessage()).is("foo");
assertObject(stats.getStackTrace()).asJson().contains("org.apache.juneau");
assertObject(stats).asString().contains("foo");
}
//------------------------------------------------------------------------------------------------------------------
// ThrownStore tests.
//------------------------------------------------------------------------------------------------------------------
public static class D1 {}
public static class D2 {}
@Test
public void d01_ignoreClasses() {
ThrownStore db = ThrownStore.create().ignoreClasses(D1.class,D2.class,ThrownStore_Test.class).build();
Throwable t1 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement(D1.class.getName(), "baz", "D1.class", 3),
new StackTraceElement(D1.class.getName()+"$X", "baz", "D1.X.class", 4),
new StackTraceElement("Object", "baz", "Object.class", 5)
};
}
};
Throwable t2 = new Throwable() {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[] {
new StackTraceElement("Foo", "bar", "Foo.class", 1),
new StackTraceElement("Foo", "baz", "Foo.class", 2),
new StackTraceElement(D2.class.getName(), "baz", "D2.class", 3),
new StackTraceElement(D2.class.getName()+"$X", "baz", "D2.X.class", 4),
new StackTraceElement("Object", "baz", "Object.class", 5)
};
}
};
db.add(t1);
db.add(t2);
assertObject(db.getStats(t1).get().getStackTrace()).asJson().is("['Foo.bar(Foo.class:1)','Foo.baz(Foo.class:2)','<ignored>','<ignored>','Object.baz(Object.class:5)']");
assertObject(db.getStats(t2).get().getStackTrace()).asJson().is("['Foo.bar(Foo.class:1)','Foo.baz(Foo.class:2)','<ignored>','<ignored>','Object.baz(Object.class:5)']");
assertInteger(db.getStats(t1).get().getCount()).is(2);
assertInteger(db.getStats(t2).get().getCount()).is(2);
ThrownStore db2 = ThrownStore.create().parent(db).build();
db2.add(t1);
db2.add(t2);
assertObject(db2.getStats(t1).get().getStackTrace()).asJson().is("['Foo.bar(Foo.class:1)','Foo.baz(Foo.class:2)','<ignored>','<ignored>','Object.baz(Object.class:5)']");
assertObject(db2.getStats(t2).get().getStackTrace()).asJson().is("['Foo.bar(Foo.class:1)','Foo.baz(Foo.class:2)','<ignored>','<ignored>','Object.baz(Object.class:5)']");
assertInteger(db2.getStats(t1).get().getCount()).is(2);
assertInteger(db2.getStats(t2).get().getCount()).is(2);
assertInteger(db.getStats(t1).get().getCount()).is(4);
assertInteger(db.getStats(t2).get().getCount()).is(4);
}
}