blob: 8c42998ab0b2917c7c8085b2cdae11d88f4bd26d [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.pulsar.broker.testcontext;
import lombok.Value;
import org.apache.pulsar.broker.BrokerTestUtil;
import org.apache.pulsar.broker.PulsarService;
import org.mockito.Mockito;
import org.mockito.internal.creation.instance.ConstructorInstantiator;
/**
* Configuration for what kind of Mockito spy to use on collaborator objects
* of the PulsarService managed by {@link PulsarTestContext}.
*
* This configuration is applied using {@link PulsarTestContext.Builder#spyConfig(SpyConfig)} or by
* calling {@link PulsarTestContext.Builder#spyByDefault()} to enable spying for all configurable collaborator
* objects.
*
* For verifying interactions with Mockito's {@link Mockito#verify(Object)} method, the spy type must be set to
* {@link SpyType#SPY_ALSO_INVOCATIONS}. This is because the default spy type {@link SpyType#SPY}
* does not record invocations.
*/
@lombok.Builder(builderClassName = "Builder", toBuilder = true)
@Value
public class SpyConfig {
/**
* Type of spy to use.
*/
public enum SpyType {
NONE, // No spy
SPY, // Spy without recording invocations
SPY_ALSO_INVOCATIONS; // Spy and record invocations
public <T> T spy(T object) {
if (object == null) {
return null;
}
switch (this) {
case NONE:
return object;
case SPY:
return BrokerTestUtil.spyWithoutRecordingInvocations(object);
case SPY_ALSO_INVOCATIONS:
return Mockito.spy(object);
default:
throw new UnsupportedOperationException("Unknown spy type: " + this);
}
}
public <T> T spy(Class<T> clazz, Object... args) {
switch (this) {
case NONE:
// Use Mockito's internal class to instantiate the object
return new ConstructorInstantiator(false, args).newInstance(clazz);
case SPY:
return BrokerTestUtil.spyWithClassAndConstructorArgs(clazz, args);
case SPY_ALSO_INVOCATIONS:
return BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations(clazz, args);
default:
throw new UnsupportedOperationException("Unknown spy type: " + this);
}
}
}
/**
* Spy configuration for {@link PulsarTestContext#getPulsarService()}.
*/
private final SpyType pulsarService;
/**
* Spy configuration for {@link PulsarService#getPulsarResources()}.
*/
private final SpyType pulsarResources;
/**
* Spy configuration for {@link PulsarService#getBrokerService()}.
*/
private final SpyType brokerService;
/**
* Spy configuration for {@link PulsarService#getBookKeeperClient()}.
* In the test context, this is the same as {@link PulsarTestContext#getBookKeeperClient()} .
* It is a client that wraps an in-memory mock bookkeeper implementation.
*/
private final SpyType bookKeeperClient;
/**
* Spy configuration for {@link PulsarService#getCompactionServiceFactory#getCompactor()}.
*/
private final SpyType compactor;
/**
* Spy configuration for {@link PulsarService#getCompactionServiceFactory()}.
*/
private final SpyType compactedServiceFactory;
/**
* Spy configuration for {@link PulsarService#getNamespaceService()}.
*/
private final SpyType namespaceService;
/**
* Create a builder for SpyConfig with no spies by default.
*
* @return a builder
*/
public static Builder builder() {
return builder(SpyType.NONE);
}
/**
* Create a builder for SpyConfig with the given spy type for all configurable collaborator objects.
*
* @param defaultSpyType the spy type to use for all configurable collaborator objects
* @return a builder
*/
public static Builder builder(SpyType defaultSpyType) {
Builder spyConfigBuilder = new Builder();
spyConfigBuilder.pulsarService(defaultSpyType);
spyConfigBuilder.pulsarResources(defaultSpyType);
spyConfigBuilder.brokerService(defaultSpyType);
spyConfigBuilder.bookKeeperClient(defaultSpyType);
spyConfigBuilder.compactor(defaultSpyType);
spyConfigBuilder.compactedServiceFactory(defaultSpyType);
spyConfigBuilder.namespaceService(defaultSpyType);
return spyConfigBuilder;
}
}