Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wrap functionality to the Observation #3433

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -116,6 +116,27 @@ void runnableShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedRunnableShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Runnable runnable = () -> assertThat(registry.getCurrentObservation()).isSameAs(observation);
observation.wrap(runnable).run();
assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler, times(0)).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void runnableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
Expand All @@ -142,6 +163,32 @@ void runnableThrowingErrorShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedRunnableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Runnable runnable = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
throw new RuntimeException("simulated");
};
assertThatThrownBy(() -> observation.wrap(runnable).run()).isInstanceOf(RuntimeException.class)
.hasMessage("simulated").hasNoCause();

assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void checkedRunnableShouldBeObserved() throws Throwable {
@SuppressWarnings("unchecked")
Expand All @@ -164,6 +211,28 @@ void checkedRunnableShouldBeObserved() throws Throwable {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedCheckedRunnableShouldBeObserved() throws Throwable {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Observation.CheckedRunnable<Throwable> checkedRunnable = () -> assertThat(registry.getCurrentObservation())
.isSameAs(observation);
observation.wrapChecked(checkedRunnable).run();
assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler, times(0)).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void checkedRunnableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
Expand All @@ -190,6 +259,32 @@ void checkedRunnableThrowingErrorShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedCheckedRunnableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Observation.CheckedRunnable<IOException> checkedRunnable = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
throw new IOException("simulated");
};
assertThatThrownBy(() -> observation.wrapChecked(checkedRunnable).run()).isInstanceOf(IOException.class)
.hasMessage("simulated").hasNoCause();

assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void supplierShouldBeObserved() {
@SuppressWarnings("unchecked")
Expand All @@ -215,6 +310,31 @@ void supplierShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedSupplierShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Supplier<String> supplier = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
return "test";
};
String result = observation.wrap(supplier).get();
assertThat(result).isEqualTo("test");
assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler, times(0)).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void supplierThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
Expand All @@ -241,6 +361,32 @@ void supplierThrowingErrorShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedSupplierThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Supplier<String> supplier = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
throw new RuntimeException("simulated");
};
assertThatThrownBy(() -> observation.wrap(supplier).get()).isInstanceOf(RuntimeException.class)
.hasMessage("simulated").hasNoCause();

assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void callableShouldBeObserved() throws Throwable {
@SuppressWarnings("unchecked")
Expand All @@ -266,6 +412,31 @@ void callableShouldBeObserved() throws Throwable {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedCallableShouldBeObserved() throws Throwable {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Observation.CheckedCallable<String, Throwable> callable = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
return "test";
};
String result = observation.wrapChecked(callable).call();
assertThat(result).isEqualTo("test");
assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler, times(0)).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void callableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
Expand All @@ -292,6 +463,32 @@ void callableThrowingErrorShouldBeObserved() {
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void wrappedCallableThrowingErrorShouldBeObserved() {
@SuppressWarnings("unchecked")
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
when(handler.supportsContext(isA(Observation.Context.class))).thenReturn(true);
registry.observationConfig().observationHandler(handler);
Observation observation = Observation.createNotStarted("myObservation", registry);

Observation.CheckedCallable<String, IOException> callable = () -> {
assertThat(registry.getCurrentObservation()).isSameAs(observation);
throw new IOException("simulated");
};
assertThatThrownBy(() -> observation.wrapChecked(callable).call()).isInstanceOf(IOException.class)
.hasMessage("simulated").hasNoCause();

assertThat(registry.getCurrentObservation()).isNull();

InOrder inOrder = inOrder(handler);
inOrder.verify(handler).supportsContext(isA(Observation.Context.class));
inOrder.verify(handler).onStart(isA(Observation.Context.class));
inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class));
inOrder.verify(handler).onScopeClosed(isA(Observation.Context.class));
inOrder.verify(handler).onError(isA(Observation.Context.class));
inOrder.verify(handler).onStop(isA(Observation.Context.class));
}

@Test
void runnableShouldBeScoped() {
ObservationHandler<Observation.Context> handler = mock(ObservationHandler.class);
Expand Down
Expand Up @@ -411,6 +411,10 @@ default void observe(Runnable runnable) {
}
}

default Runnable wrap(Runnable runnable) {
return () -> observe(runnable);
}

/**
* Observes the passed {@link CheckedRunnable}, this means the followings:
*
Expand Down Expand Up @@ -440,6 +444,10 @@ default <E extends Throwable> void observeChecked(CheckedRunnable<E> checkedRunn
}
}

default <E extends Throwable> CheckedRunnable<E> wrapChecked(CheckedRunnable<E> checkedRunnable) throws E {
return () -> observeChecked(checkedRunnable);
}

/**
* Observes the passed {@link Supplier}, this means the followings:
*
Expand Down Expand Up @@ -470,6 +478,10 @@ default <T> T observe(Supplier<T> supplier) {
}
}

default <T> Supplier<T> wrap(Supplier<T> supplier) {
return () -> observe(supplier);
}

/**
* Observes the passed {@link CheckedCallable}, this means the followings:
*
Expand Down Expand Up @@ -501,6 +513,10 @@ default <T, E extends Throwable> T observeChecked(CheckedCallable<T, E> checkedC
}
}

default <T, E extends Throwable> CheckedCallable<T, E> wrapChecked(CheckedCallable<T, E> checkedCallable) throws E {
return () -> observeChecked(checkedCallable);
}

/**
* Wraps the given action in a scope and signals an error.
* @param runnable the {@link Runnable} to run
Expand Down