Code review comment: Could we actually instantiate a `RpcCheckpointResponder` instead of calling directly on the gateway. I think this is also part of the code which should be tested.

Code under review:
public void testDeclineCheckpointInvocationWithUserException() throws Exception {
		RpcService rpcService1 = null;
		RpcService rpcService2 = null;
		try {
			final ActorSystem actorSystem1 = AkkaUtils.createDefaultActorSystem();
			final ActorSystem actorSystem2 = AkkaUtils.createDefaultActorSystem();

			rpcService1 = new AkkaRpcService(actorSystem1, testingTimeout);
			rpcService2 = new AkkaRpcService(actorSystem2, testingTimeout);

			final CompletableFuture<Throwable> declineCheckpointMessageFuture = new CompletableFuture<>();

			final JobManagerSharedServices jobManagerSharedServices = new TestingJobManagerSharedServicesBuilder().build();
			final JobMasterConfiguration jobMasterConfiguration = JobMasterConfiguration.fromConfiguration(configuration);
			final JobMaster jobMaster = new JobMaster(
				rpcService1,
				jobMasterConfiguration,
				jmResourceId,
				jobGraph,
				haServices,
				DefaultSlotPoolFactory.fromConfiguration(configuration, rpcService1),
				jobManagerSharedServices,
				heartbeatServices,
				blobServer,
				UnregisteredJobManagerJobMetricGroupFactory.INSTANCE,
				new NoOpOnCompletionActions(),
				testingFatalErrorHandler,
				JobMasterTest.class.getClassLoader()) {
				@Override
				public void declineCheckpoint(DeclineCheckpoint declineCheckpoint) {
					declineCheckpointMessageFuture.complete(declineCheckpoint.getReason());
				}
			};

			jobMaster.start(jobMasterId, testingTimeout).get();

			final String className = "UserException";
			final URLClassLoader userClassLoader = ClassLoaderUtils.compileAndLoadJava(
				temporaryFolder.newFolder(),
				className + ".java",
				String.format("public class %s extends RuntimeException { public %s() {super(\"UserMessage\");} }",
					className,
					className));

			Throwable userException = (Throwable) Class.forName(className, false, userClassLoader).newInstance();

			CompletableFuture<JobMasterGateway> jobMasterGateway =
				rpcService2.connect(jobMaster.getAddress(), jobMaster.getFencingToken(), JobMasterGateway.class);

			jobMasterGateway.thenAccept(gateway -> {
				gateway.declineCheckpoint(new DeclineCheckpoint(
						jobGraph.getJobID(),
						new ExecutionAttemptID(1, 1),
						1,
						userException
					)
				);
			});

			Throwable throwable = declineCheckpointMessageFuture.get(testingTimeout.toMilliseconds(),
				TimeUnit.MILLISECONDS);
			assertThat(throwable, instanceOf(SerializedThrowable.class));
			assertThat(throwable.getMessage(), equalTo(userException.getMessage()));
		} finally {
			RpcUtils.terminateRpcServices(testingTimeout, rpcService1, rpcService2);
		}
	}

Line commented on: gateway.declineCheckpoint(new DeclineCheckpoint(

Revised code:
public void testDeclineCheckpointInvocationWithUserException() throws Exception {
		RpcService rpcService1 = null;
		RpcService rpcService2 = null;
		try {
			final ActorSystem actorSystem1 = AkkaUtils.createDefaultActorSystem();
			final ActorSystem actorSystem2 = AkkaUtils.createDefaultActorSystem();

			rpcService1 = new AkkaRpcService(actorSystem1, testingTimeout);
			rpcService2 = new AkkaRpcService(actorSystem2, testingTimeout);

			final CompletableFuture<Throwable> declineCheckpointMessageFuture = new CompletableFuture<>();

			final JobManagerSharedServices jobManagerSharedServices = new TestingJobManagerSharedServicesBuilder().build();
			final JobMasterConfiguration jobMasterConfiguration = JobMasterConfiguration.fromConfiguration(configuration);
			final JobMaster jobMaster = new JobMaster(
				rpcService1,
				jobMasterConfiguration,
				jmResourceId,
				jobGraph,
				haServices,
				DefaultSlotPoolFactory.fromConfiguration(configuration, rpcService1),
				jobManagerSharedServices,
				heartbeatServices,
				blobServer,
				UnregisteredJobManagerJobMetricGroupFactory.INSTANCE,
				new NoOpOnCompletionActions(),
				testingFatalErrorHandler,
				JobMasterTest.class.getClassLoader()) {
				@Override
				public void declineCheckpoint(DeclineCheckpoint declineCheckpoint) {
					declineCheckpointMessageFuture.complete(declineCheckpoint.getReason());
				}
			};

			jobMaster.start(jobMasterId, testingTimeout).get();

			final String className = "UserException";
			final URLClassLoader userClassLoader = ClassLoaderUtils.compileAndLoadJava(
				temporaryFolder.newFolder(),
				className + ".java",
				String.format("public class %s extends RuntimeException { public %s() {super(\"UserMessage\");} }",
					className,
					className));

			Throwable userException = (Throwable) Class.forName(className, false, userClassLoader).newInstance();

			CompletableFuture<JobMasterGateway> jobMasterGateway =
				rpcService2.connect(jobMaster.getAddress(), jobMaster.getFencingToken(), JobMasterGateway.class);

			jobMasterGateway.thenAccept(gateway -> {
				gateway.declineCheckpoint(new DeclineCheckpoint(
						jobGraph.getJobID(),
						new ExecutionAttemptID(1, 1),
						1,
						userException
					)
				);
			});

			Throwable throwable = declineCheckpointMessageFuture.get(testingTimeout.toMilliseconds(),
				TimeUnit.MILLISECONDS);
			assertThat(throwable, instanceOf(SerializedThrowable.class));
			assertThat(throwable.getMessage(), equalTo(userException.getMessage()));
		} finally {
			RpcUtils.terminateRpcServices(testingTimeout, rpcService1, rpcService2);
		}
	}