From dcb999b593c355de00ab644412fd9f76d46df9ba Mon Sep 17 00:00:00 2001 From: seoyoung-park Date: Thu, 21 Nov 2024 18:04:12 +0900 Subject: [PATCH] [#noissue] Refactor DefaultExceptionRecorderTest --- .../exception/DefaultExceptionRecorder.java | 4 +- .../DefaultExceptionRecorderTest.java | 188 +++++++++++++ .../DefaultExceptionRecorderTest.java | 262 ------------------ 3 files changed, 190 insertions(+), 264 deletions(-) create mode 100644 agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorderTest.java delete mode 100644 agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/DefaultExceptionRecorderTest.java diff --git a/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorder.java b/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorder.java index f3b6451c25d0..92ef0156a4be 100644 --- a/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorder.java +++ b/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorder.java @@ -45,7 +45,7 @@ public DefaultExceptionRecorder(ExceptionChainSampler exceptionChainSampler, this.exceptionContext = Objects.requireNonNull(exceptionContext, "exceptionContext"); } - public void recordException(Throwable current, long startTime) { + public void recordThrowable(Throwable current, long startTime) { final ExceptionContext context = this.exceptionContext; ExceptionRecordingState state = context.stateOf(current); ExceptionChainSampler.SamplingState samplingState = getSamplingState(state, context); @@ -75,7 +75,7 @@ public void recordException( SpanEvent spanEvent, Throwable throwable ) { - this.recordException( + this.recordThrowable( throwable, spanEvent.getStartTime() ); diff --git a/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorderTest.java b/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorderTest.java new file mode 100644 index 000000000000..d5290a74ae91 --- /dev/null +++ b/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/exception/DefaultExceptionRecorderTest.java @@ -0,0 +1,188 @@ +/* + * Copyright 2023 NAVER Corp. + * + * 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.navercorp.pinpoint.profiler.context.exception; + +import com.navercorp.pinpoint.common.util.CollectionUtils; +import com.navercorp.pinpoint.profiler.context.exception.model.DefaultExceptionContext; +import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionContext; +import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionContextValue; +import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionWrapper; +import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionWrapperFactory; +import com.navercorp.pinpoint.profiler.context.exception.sampler.ExceptionChainSampler; +import com.navercorp.pinpoint.profiler.context.exception.storage.ExceptionStorage; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +/** + * @author intr3p1d + */ +public class DefaultExceptionRecorderTest { + + private final static Logger logger = LogManager.getLogger(DefaultExceptionRecorderTest.class); + private final static long START_TIME = 1; + + private ExceptionWrapperFactory exceptionWrapperFactory; + private TestExceptionStorage exceptionStorage; + private ExceptionContext context; + private DefaultExceptionRecorder exceptionRecorder; + + @BeforeEach + void setUp() { + ExceptionChainSampler exceptionChainSampler = new ExceptionChainSampler(100000); + exceptionWrapperFactory = new ExceptionWrapperFactory(10, 1048); + exceptionStorage = new TestExceptionStorage(); + context = new DefaultExceptionContext(exceptionStorage); + exceptionRecorder = new DefaultExceptionRecorder( + exceptionChainSampler, exceptionWrapperFactory, context + ); + } + + + static class TestExceptionStorage implements ExceptionStorage { + + List wrappers; + public List outputStream; + + public TestExceptionStorage() { + this.wrappers = new ArrayList<>(); + this.outputStream = new ArrayList<>(); + } + + @Override + public void store(List wrappers) { + logger.info(wrappers); + this.wrappers.addAll(wrappers); + } + + @Override + public void flush() { + final List copy = new ArrayList<>(wrappers); + if (CollectionUtils.hasLength(copy)) { + outputStream.addAll(copy); + } + wrappers.clear(); + } + + @Override + public void close() { + this.outputStream.clear(); + } + + public List getWrappers() { + return this.wrappers; + } + + public List getOutputStream() { + return outputStream; + } + } + + + @Test + void testRecordNothing() { + Throwable firstOne = null; + List expected = Collections.emptyList(); + + exceptionRecorder.recordThrowable(null, START_TIME); + + exceptionStorage.flush(); + List actual = exceptionStorage.getOutputStream(); + + Assertions.assertTrue(actual.isEmpty()); + Assertions.assertEquals(expected, actual); + } + + @Test + void testRecordException() { + Throwable firstOne = new RuntimeException("level 1 Error"); + Throwable secondOne = new RuntimeException("level 2 Error", firstOne); + Throwable thirdOne = new RuntimeException("level 3 Error", secondOne); + + exceptionRecorder.recordThrowable(firstOne, START_TIME); + exceptionRecorder.recordThrowable(thirdOne, START_TIME + 1); + List expected = exceptionWrapperFactory.newExceptionWrappers(context); + + exceptionRecorder.close(); + + List actual = exceptionStorage.getOutputStream(); + Assertions.assertFalse(actual.isEmpty()); + Assertions.assertEquals(3, actual.size()); + Assertions.assertEquals(expected, actual); + } + + + @Test + void testRecordNotChainedException() { + Throwable firstOne = new RuntimeException("level 1 Error"); + Throwable secondOne = new RuntimeException("level 2 Error", firstOne); + Throwable thirdOne = new RuntimeException("level 3 Error", secondOne); + Throwable notChained = new RuntimeException("This is not chained with level 3 Error"); + + exceptionRecorder.recordThrowable(firstOne, START_TIME); + exceptionRecorder.recordThrowable(thirdOne, START_TIME + 1); + List expected = exceptionWrapperFactory.newExceptionWrappers(context); + + exceptionRecorder.recordThrowable(notChained, START_TIME + 2); + List added = exceptionWrapperFactory.newExceptionWrappers(context); + + List actual1 = exceptionStorage.getWrappers(); + Assertions.assertFalse(actual1.isEmpty()); + Assertions.assertEquals(3, actual1.size()); + Assertions.assertEquals(expected, actual1); + + exceptionRecorder.close(); + + expected.addAll(added); + List actual2 = exceptionStorage.getOutputStream(); + Assertions.assertFalse(actual2.isEmpty()); + Assertions.assertEquals(4, actual2.size()); + Assertions.assertEquals(expected, actual2); + } + + @Test + void testRecordRethrownException() { + + Throwable firstOne = new RuntimeException("level 1 Error"); + Throwable secondOne = new RuntimeException("level 2 Error", firstOne); + Throwable thirdOne = new RuntimeException("level 3 Error", secondOne); + Throwable rethrown = thirdOne; // Rethrown Exception + + exceptionRecorder.recordThrowable(firstOne, START_TIME); + exceptionRecorder.recordThrowable(thirdOne, START_TIME + 1); + List expected = exceptionWrapperFactory.newExceptionWrappers(context); + + exceptionRecorder.recordThrowable(rethrown, START_TIME + 2); + + List actual1 = exceptionStorage.getWrappers(); + Assertions.assertTrue(actual1.isEmpty()); + + exceptionRecorder.close(); + + List actual2 = exceptionStorage.getOutputStream(); + Assertions.assertFalse(actual2.isEmpty()); + Assertions.assertEquals(3, actual2.size()); + Assertions.assertEquals(expected, actual2); + } + +} diff --git a/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/DefaultExceptionRecorderTest.java b/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/DefaultExceptionRecorderTest.java deleted file mode 100644 index c02fe6e77284..000000000000 --- a/agent-module/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/DefaultExceptionRecorderTest.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2023 NAVER Corp. - * - * 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.navercorp.pinpoint.profiler.metadata; - -import com.navercorp.pinpoint.common.util.CollectionUtils; -import com.navercorp.pinpoint.profiler.context.exception.DefaultExceptionRecorder; -import com.navercorp.pinpoint.profiler.context.exception.ExceptionRecorder; -import com.navercorp.pinpoint.profiler.context.exception.model.DefaultExceptionContext; -import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionContext; -import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionWrapper; -import com.navercorp.pinpoint.profiler.context.exception.model.ExceptionWrapperFactory; -import com.navercorp.pinpoint.profiler.context.exception.sampler.ExceptionChainSampler; -import com.navercorp.pinpoint.profiler.context.exception.storage.ExceptionStorage; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -/** - * @author intr3p1d - */ -public class DefaultExceptionRecorderTest { - - private final static Logger logger = LogManager.getLogger(DefaultExceptionRecorderTest.class); - private final static long START_TIME = 1; - - ExceptionChainSampler exceptionChainSampler = new ExceptionChainSampler(1000); - ExceptionWrapperFactory exceptionWrapperFactory = new ExceptionWrapperFactory(10, 1048); - - - static class TestExceptionStorage implements ExceptionStorage { - - List wrappers; - public List outputStream; - - public TestExceptionStorage() { - this.wrappers = new ArrayList<>(); - this.outputStream = new ArrayList<>(); - } - - @Override - public void store(List wrappers) { - logger.info(wrappers); - this.wrappers.addAll(wrappers); - } - - @Override - public void flush() { - final List copy = new ArrayList<>(wrappers); - if (CollectionUtils.hasLength(copy)) { - outputStream.addAll(copy); - } - wrappers.clear(); - } - - @Override - public void close() { - } - - public List getWrappers() { - return this.wrappers; - } - - public List getOutputStream() { - return outputStream; - } - } - - private static Function getThrowableFunction( - DefaultExceptionRecorder recorder, - List throwable - ) { - return (Throwable th) -> { - recorder.recordException(th, START_TIME); - throwable.add(th); - logger.info(th); - return th; - }; - } - - - private List newExceptionWrappers(Throwable throwable, long startTime, long exceptionId) { - List wrappers = new ArrayList<>(); - exceptionWrapperFactory.addAllExceptionWrappers(wrappers, throwable, null, startTime, exceptionId, 0); - return wrappers; - } - - @Test - public void testRecordNothing() { - List exceptions = new ArrayList<>(); - TestExceptionStorage exceptionStorage = new TestExceptionStorage(); - ExceptionContext context = new DefaultExceptionContext(exceptionStorage); - DefaultExceptionRecorder exceptionRecorder = new DefaultExceptionRecorder( - exceptionChainSampler, exceptionWrapperFactory, context - ); - Function recordThrowable = getThrowableFunction( - exceptionRecorder, exceptions - ); - - recordThrowable.apply(null); - exceptionRecorder.close(); - - List expected = new ArrayList<>(); - List actual = exceptionStorage.getOutputStream(); - - Assertions.assertEquals(expected, actual); - } - - @Test - public void testRecordException() { - List exceptions = new ArrayList<>(); - TestExceptionStorage exceptionStorage = new TestExceptionStorage(); - ExceptionContext context = new DefaultExceptionContext(exceptionStorage); - DefaultExceptionRecorder exceptionRecorder = new DefaultExceptionRecorder( - exceptionChainSampler, exceptionWrapperFactory, context - ); - Function recordThrowable = getThrowableFunction( - exceptionRecorder, exceptions - ); - - List expected = null; - List actual = null; - - try { - level3Error(recordThrowable); - } catch (Throwable e) { - expected = newExceptionWrappers(e, START_TIME, 1); - recordThrowable.apply(e); - actual = exceptionStorage.getWrappers(); - Assertions.assertTrue(actual.isEmpty()); - } - exceptionRecorder.close(); - actual = exceptionStorage.getOutputStream(); - Assertions.assertEquals(expected, actual); - } - - @Test - public void testRecordNotChainedException() { - List exceptions = new ArrayList<>(); - TestExceptionStorage exceptionStorage = new TestExceptionStorage(); - ExceptionContext context = new DefaultExceptionContext(exceptionStorage); - DefaultExceptionRecorder exceptionRecorder = new DefaultExceptionRecorder( - exceptionChainSampler, exceptionWrapperFactory, context - ); - Function recordThrowable = getThrowableFunction( - exceptionRecorder, exceptions - ); - - List expected1 = null; - List expected2 = null; - List actual1 = null; - List actual2 = null; - - Throwable throwable = null; - - try { - notChainedException(recordThrowable); - } catch (Throwable e) { - expected1 = newExceptionWrappers(exceptions.get(exceptions.size() - 2), START_TIME, 1); - logger.warn(exceptionStorage.getWrappers()); - actual1 = new ArrayList<>(exceptionStorage.getWrappers()); - throwable = e; - logger.warn(actual1); - logger.warn(actual2); - Assertions.assertFalse(actual1.isEmpty()); - Assertions.assertEquals(expected1, actual1); - } - - - exceptionStorage.flush(); - exceptionStorage.getOutputStream().clear(); - expected2 = newExceptionWrappers(throwable, START_TIME, 2); - exceptionRecorder.close(); - actual2 = exceptionStorage.getOutputStream(); - Assertions.assertEquals(expected2, actual2); - } - - @Test - public void testRecordRethrowGivenException() { - - List exceptions = new ArrayList<>(); - TestExceptionStorage exceptionStorage = new TestExceptionStorage(); - ExceptionContext context = new DefaultExceptionContext(exceptionStorage); - DefaultExceptionRecorder exceptionRecorder = new DefaultExceptionRecorder( - exceptionChainSampler, exceptionWrapperFactory, context - ); - Function recordThrowable = getThrowableFunction( - exceptionRecorder, exceptions - ); - - List expected = null; - List actual = null; - - try { - rethrowGivenException(recordThrowable); - } catch (Throwable e) { - expected = newExceptionWrappers(e, START_TIME, 1); - actual = exceptionStorage.getWrappers(); - Assertions.assertTrue(actual.isEmpty()); - } - - exceptionRecorder.close(); - actual = exceptionStorage.getOutputStream(); - Assertions.assertEquals(expected, actual); - } - - - public void notChainedException(Function interceptor) throws Throwable { - try { - level3Error(interceptor); - } catch (Throwable e) { - throw interceptor.apply(new RuntimeException("Not Chained, Another New Exception")); - } - } - - public void rethrowGivenException(Function interceptor) throws Throwable { - try { - level3Error(interceptor); - } catch (Exception e) { - throw interceptor.apply(e); - } - } - - public void level3Error(Function interceptor) throws Throwable { - try { - level2Error(interceptor); - } catch (Throwable e) { - throw interceptor.apply(new RuntimeException("Level 3 Error", e)); - } - } - - public void level2Error(Function interceptor) throws Throwable { - try { - level1Error(interceptor); - } catch (Throwable e) { - throw interceptor.apply(new RuntimeException("Level 2 Error", e)); - } - } - - public void level1Error(Function interceptor) throws Throwable { - throw interceptor.apply(new RuntimeException("Level 1 Error")); - } - -}