Skip to content

Commit 5cdd197

Browse files
author
pmarupaka
committed
Add EndpointServiceExceptionAssert
1 parent aad80d0 commit 5cdd197

File tree

7 files changed

+366
-89
lines changed

7 files changed

+366
-89
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.palantir.conjure.java.api.testing;
18+
19+
import com.palantir.conjure.java.api.errors.ErrorType;
20+
import com.palantir.logsafe.Arg;
21+
import java.util.Arrays;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
import org.assertj.core.api.AbstractThrowableAssert;
27+
import org.assertj.core.util.Throwables;
28+
29+
abstract class AbstractServiceExceptionAssert<T extends AbstractThrowableAssert<T, U>, U extends Throwable>
30+
extends AbstractThrowableAssert<T, U> {
31+
32+
protected AbstractServiceExceptionAssert(U throwable, Class<T> selfType) {
33+
super(throwable, selfType);
34+
}
35+
36+
void hasCode(ErrorType.Code code, ErrorType.Code actualCode) {
37+
isNotNull();
38+
failIfNotEqual("Expected ErrorType.Code to be %s, but found %s", code, actualCode);
39+
}
40+
41+
void hasType(ErrorType type, ErrorType actualType) {
42+
isNotNull();
43+
failIfNotEqual("Expected ErrorType to be %s, but found %s", type, actualType);
44+
}
45+
46+
final void hasArgs(List<Arg<?>> actualArguments, Arg<?>... expectedArguments) {
47+
isNotNull();
48+
49+
AssertableArgs actualArgs = AssertableArgs.fromArgs(actualArguments);
50+
AssertableArgs expectedArgs = AssertableArgs.fromArgs(Arrays.asList(expectedArguments));
51+
52+
failIfNotEqual("Expected safe args to be %s, but found %s", expectedArgs.safeArgs(), actualArgs.safeArgs());
53+
failIfNotEqual(
54+
"Expected unsafe args to be %s, but found %s", expectedArgs.unsafeArgs(), actualArgs.unsafeArgs());
55+
}
56+
57+
final void hasNoArgs(List<Arg<?>> actualArguments) {
58+
isNotNull();
59+
AssertableArgs actualArgs = AssertableArgs.fromArgs(actualArguments);
60+
if (!actualArgs.safeArgs().isEmpty() || !actualArgs.unsafeArgs().isEmpty()) {
61+
Map<String, Object> allArgs = new HashMap<>();
62+
allArgs.putAll(actualArgs.safeArgs());
63+
allArgs.putAll(actualArgs.unsafeArgs());
64+
failWithMessage(
65+
"Expected no args, but found %s; service exception: %s", allArgs, Throwables.getStackTrace(actual));
66+
}
67+
}
68+
69+
final void containsArgs(List<Arg<?>> actualArguments, Arg<?>... expectedArguments) {
70+
isNotNull();
71+
72+
AssertableArgs actualArgs = AssertableArgs.fromArgs(actualArguments);
73+
AssertableArgs expectedArgs = AssertableArgs.fromArgs(Arrays.asList(expectedArguments));
74+
75+
failIfDoesNotContain(
76+
"Expected safe args to contain %s, but found %s", expectedArgs.safeArgs(), actualArgs.safeArgs());
77+
failIfDoesNotContain(
78+
"Expected unsafe args to contain %s, but found %s", expectedArgs.unsafeArgs(), actualArgs.unsafeArgs());
79+
}
80+
81+
void failIfDoesNotContain(String message, Map<String, Object> expectedArgs, Map<String, Object> actualArgs) {
82+
if (!actualArgs.entrySet().containsAll(expectedArgs.entrySet())) {
83+
failWithMessage(
84+
message + "; service exception: %s", expectedArgs, actualArgs, Throwables.getStackTrace(actual));
85+
}
86+
}
87+
88+
<V> void failIfNotEqual(String message, V expectedValue, V actualValue) {
89+
if (!Objects.equals(expectedValue, actualValue)) {
90+
failWithMessage(
91+
message + "; service exception: ", expectedValue, actualValue, Throwables.getStackTrace(actual));
92+
}
93+
}
94+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.palantir.conjure.java.api.testing;
18+
19+
import com.palantir.logsafe.Arg;
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
record AssertableArgs(Map<String, Object> safeArgs, Map<String, Object> unsafeArgs) {
25+
static AssertableArgs fromArgs(List<Arg<?>> args) {
26+
Map<String, Object> safeArgs = new HashMap<>();
27+
Map<String, Object> unsafeArgs = new HashMap<>();
28+
args.forEach(arg -> {
29+
if (arg.isSafeForLogging()) {
30+
assertPutSafe(safeArgs, arg);
31+
} else {
32+
assertPutUnsafe(unsafeArgs, arg);
33+
}
34+
});
35+
return new AssertableArgs(safeArgs, unsafeArgs);
36+
}
37+
38+
private static void assertPutSafe(Map<String, Object> args, Arg<?> arg) {
39+
assertPut(args, arg.getName(), arg.getValue(), "safe");
40+
}
41+
42+
private static void assertPutUnsafe(Map<String, Object> args, Arg<?> arg) {
43+
assertPut(args, arg.getName(), arg.getValue(), "unsafe");
44+
}
45+
46+
private static void assertPut(Map<String, Object> map, String key, Object value, String name) {
47+
Object previous = map.put(key, value);
48+
if (previous != null) {
49+
throw new AssertionError(String.format(
50+
"Duplicate %s arg name '%s', first value: %s, second value: %s", name, key, previous, value));
51+
}
52+
}
53+
}

test-utils/src/main/java/com/palantir/conjure/java/api/testing/Assertions.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.palantir.conjure.java.api.testing;
1818

19+
import com.palantir.conjure.java.api.errors.EndpointServiceException;
1920
import com.palantir.conjure.java.api.errors.QosException;
2021
import com.palantir.conjure.java.api.errors.RemoteException;
2122
import com.palantir.conjure.java.api.errors.ServiceException;
@@ -33,6 +34,10 @@ public static ServiceExceptionAssert assertThat(ServiceException actual) {
3334
return new ServiceExceptionAssert(actual);
3435
}
3536

37+
public static EndpointServiceExceptionAssert assertThat(EndpointServiceException actual) {
38+
return new EndpointServiceExceptionAssert(actual);
39+
}
40+
3641
public static RemoteExceptionAssert assertThat(RemoteException actual) {
3742
return new RemoteExceptionAssert(actual);
3843
}
@@ -47,6 +52,12 @@ public static ServiceExceptionAssert assertThatServiceExceptionThrownBy(Throwing
4752
return assertThatThrownBy(shouldRaiseThrowable).asInstanceOf(ServiceExceptionAssert.instanceOfAssertFactory());
4853
}
4954

55+
public static EndpointServiceExceptionAssert assertThatEndpointServiceExceptionThrownBy(
56+
ThrowingCallable shouldRaiseThrowable) {
57+
return assertThatThrownBy(shouldRaiseThrowable)
58+
.asInstanceOf(EndpointServiceExceptionAssert.instanceOfAssertFactory());
59+
}
60+
5061
@SuppressWarnings("for-rollout:deprecation")
5162
@CanIgnoreReturnValue
5263
public static RemoteExceptionAssert assertThatRemoteExceptionThrownBy(ThrowingCallable shouldRaiseThrowable) {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.palantir.conjure.java.api.testing;
18+
19+
import com.palantir.conjure.java.api.errors.EndpointServiceException;
20+
import com.palantir.conjure.java.api.errors.ErrorType;
21+
import com.palantir.logsafe.Arg;
22+
import org.assertj.core.api.InstanceOfAssertFactory;
23+
24+
public class EndpointServiceExceptionAssert
25+
extends AbstractServiceExceptionAssert<EndpointServiceExceptionAssert, EndpointServiceException> {
26+
27+
private static final InstanceOfAssertFactory<EndpointServiceException, EndpointServiceExceptionAssert>
28+
INSTANCE_OF_ASSERT_FACTORY =
29+
new InstanceOfAssertFactory<>(EndpointServiceException.class, EndpointServiceExceptionAssert::new);
30+
31+
EndpointServiceExceptionAssert(EndpointServiceException actual) {
32+
super(actual, EndpointServiceExceptionAssert.class);
33+
}
34+
35+
public static InstanceOfAssertFactory<EndpointServiceException, EndpointServiceExceptionAssert>
36+
instanceOfAssertFactory() {
37+
return INSTANCE_OF_ASSERT_FACTORY;
38+
}
39+
40+
public final EndpointServiceExceptionAssert hasCode(ErrorType.Code code) {
41+
hasCode(code, actual.getErrorType().code());
42+
return this;
43+
}
44+
45+
public final EndpointServiceExceptionAssert hasType(ErrorType type) {
46+
hasType(type, actual.getErrorType());
47+
return this;
48+
}
49+
50+
public final EndpointServiceExceptionAssert hasArgs(Arg<?>... args) {
51+
hasArgs(actual.getArgs(), args);
52+
return this;
53+
}
54+
55+
public final EndpointServiceExceptionAssert hasNoArgs() {
56+
hasNoArgs(actual.getArgs());
57+
return this;
58+
}
59+
60+
public final EndpointServiceExceptionAssert containsArgs(Arg<?>... args) {
61+
containsArgs(actual.getArgs(), args);
62+
return this;
63+
}
64+
}

test-utils/src/main/java/com/palantir/conjure/java/api/testing/ServiceExceptionAssert.java

Lines changed: 6 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,9 @@
1919
import com.palantir.conjure.java.api.errors.ErrorType;
2020
import com.palantir.conjure.java.api.errors.ServiceException;
2121
import com.palantir.logsafe.Arg;
22-
import java.util.Arrays;
23-
import java.util.HashMap;
24-
import java.util.List;
25-
import java.util.Map;
26-
import java.util.Objects;
27-
import org.assertj.core.api.AbstractThrowableAssert;
2822
import org.assertj.core.api.InstanceOfAssertFactory;
29-
import org.assertj.core.util.Throwables;
3023

31-
public class ServiceExceptionAssert extends AbstractThrowableAssert<ServiceExceptionAssert, ServiceException> {
24+
public class ServiceExceptionAssert extends AbstractServiceExceptionAssert<ServiceExceptionAssert, ServiceException> {
3225

3326
private static final InstanceOfAssertFactory<ServiceException, ServiceExceptionAssert> INSTANCE_OF_ASSERT_FACTORY =
3427
new InstanceOfAssertFactory<>(ServiceException.class, ServiceExceptionAssert::new);
@@ -42,103 +35,27 @@ public static InstanceOfAssertFactory<ServiceException, ServiceExceptionAssert>
4235
}
4336

4437
public final ServiceExceptionAssert hasCode(ErrorType.Code code) {
45-
isNotNull();
46-
failIfNotEqual(
47-
"Expected ErrorType.Code to be %s, but found %s",
48-
code, actual.getErrorType().code());
38+
hasCode(code, actual.getErrorType().code());
4939
return this;
5040
}
5141

5242
public final ServiceExceptionAssert hasType(ErrorType type) {
53-
isNotNull();
54-
failIfNotEqual("Expected ErrorType to be %s, but found %s", type, actual.getErrorType());
43+
hasType(type, actual.getErrorType());
5544
return this;
5645
}
5746

5847
public final ServiceExceptionAssert hasArgs(Arg<?>... args) {
59-
isNotNull();
60-
61-
AssertableArgs actualArgs = new AssertableArgs(actual.getArgs());
62-
AssertableArgs expectedArgs = new AssertableArgs(Arrays.asList(args));
63-
64-
failIfNotEqual("Expected safe args to be %s, but found %s", expectedArgs.safeArgs, actualArgs.safeArgs);
65-
failIfNotEqual("Expected unsafe args to be %s, but found %s", expectedArgs.unsafeArgs, actualArgs.unsafeArgs);
66-
48+
hasArgs(actual.getArgs(), args);
6749
return this;
6850
}
6951

7052
public final ServiceExceptionAssert hasNoArgs() {
71-
isNotNull();
72-
73-
AssertableArgs actualArgs = new AssertableArgs(actual.getArgs());
74-
if (!actualArgs.safeArgs.isEmpty() || !actualArgs.unsafeArgs.isEmpty()) {
75-
Map<String, Object> allArgs = new HashMap<>();
76-
allArgs.putAll(actualArgs.safeArgs);
77-
allArgs.putAll(actualArgs.unsafeArgs);
78-
failWithMessage(
79-
"Expected no args, but found %s; service exception: %s", allArgs, Throwables.getStackTrace(actual));
80-
}
81-
53+
hasNoArgs(actual.getArgs());
8254
return this;
8355
}
8456

85-
private <T> void failIfNotEqual(String message, T expectedValue, T actualValue) {
86-
if (!Objects.equals(expectedValue, actualValue)) {
87-
failWithMessage(
88-
message + "; service exception: ", expectedValue, actualValue, Throwables.getStackTrace(actual));
89-
}
90-
}
91-
9257
public final ServiceExceptionAssert containsArgs(Arg<?>... args) {
93-
isNotNull();
94-
95-
AssertableArgs actualArgs = new AssertableArgs(actual.getArgs());
96-
AssertableArgs expectedArgs = new AssertableArgs(Arrays.asList(args));
97-
98-
failIfDoesNotContain(
99-
"Expected safe args to contain %s, but found %s", expectedArgs.safeArgs, actualArgs.safeArgs);
100-
failIfDoesNotContain(
101-
"Expected unsafe args to contain %s, but found %s", expectedArgs.unsafeArgs, actualArgs.unsafeArgs);
102-
58+
containsArgs(actual.getArgs(), args);
10359
return this;
10460
}
105-
106-
private void failIfDoesNotContain(
107-
String message, Map<String, Object> expectedArgs, Map<String, Object> actualArgs) {
108-
if (!actualArgs.entrySet().containsAll(expectedArgs.entrySet())) {
109-
failWithMessage(
110-
message + "; service exception: %s", expectedArgs, actualArgs, Throwables.getStackTrace(actual));
111-
}
112-
}
113-
114-
private static final class AssertableArgs {
115-
private final Map<String, Object> safeArgs = new HashMap<>();
116-
private final Map<String, Object> unsafeArgs = new HashMap<>();
117-
118-
private AssertableArgs(List<Arg<?>> args) {
119-
args.forEach(arg -> {
120-
if (arg.isSafeForLogging()) {
121-
assertPutSafe(arg);
122-
} else {
123-
assertPutUnsafe(arg);
124-
}
125-
});
126-
}
127-
128-
private void assertPutSafe(Arg<?> arg) {
129-
assertPut(safeArgs, arg.getName(), arg.getValue(), "safe");
130-
}
131-
132-
private void assertPutUnsafe(Arg<?> arg) {
133-
assertPut(unsafeArgs, arg.getName(), arg.getValue(), "unsafe");
134-
}
135-
136-
private static void assertPut(Map<String, Object> map, String key, Object value, String name) {
137-
Object previous = map.put(key, value);
138-
if (previous != null) {
139-
throw new AssertionError(String.format(
140-
"Duplicate %s arg name '%s', first value: %s, second value: %s", name, key, previous, value));
141-
}
142-
}
143-
}
14461
}

0 commit comments

Comments
 (0)