Skip to content

Commit db2bc7a

Browse files
fix: Improve test coverage for internal/wire folder. (#214)
* fix: Add a test for SinglePartitionPublisherBuilder. * fix: Add a test for Versions. * fix: Add a test for ChannelCache. * fix: Improve ConnectedSubscriberImpl coverage. * fix: Add a test for RoutingPublisher. * fix: Add a test for PublisherBuilder. * fix: Add test coverage for remaining builders. * fix: Add licence headers.
1 parent fa49931 commit db2bc7a

File tree

12 files changed

+587
-18
lines changed

12 files changed

+587
-18
lines changed

google-cloud-pubsublite/src/main/java/com/google/cloud/pubsublite/internal/ChannelCache.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,31 @@
1616

1717
package com.google.cloud.pubsublite.internal;
1818

19+
import com.google.common.annotations.VisibleForTesting;
1920
import io.grpc.Channel;
2021
import io.grpc.ManagedChannel;
2122
import io.grpc.ManagedChannelBuilder;
2223
import java.util.concurrent.ConcurrentHashMap;
2324
import java.util.concurrent.TimeUnit;
25+
import java.util.function.Function;
2426

2527
/** A ChannelCache creates and stores default channels for use with api methods. */
2628
public class ChannelCache {
29+
private final Function<String, ManagedChannel> channelFactory;
2730
private final ConcurrentHashMap<String, ManagedChannel> channels = new ConcurrentHashMap<>();
2831

2932
public ChannelCache() {
33+
this(ChannelCache::newChannel);
3034
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown));
3135
}
3236

33-
private void onShutdown() {
37+
@VisibleForTesting
38+
ChannelCache(Function<String, ManagedChannel> channelFactory) {
39+
this.channelFactory = channelFactory;
40+
}
41+
42+
@VisibleForTesting
43+
void onShutdown() {
3444
channels.forEachValue(
3545
channels.size(),
3646
channel -> {
@@ -43,10 +53,10 @@ private void onShutdown() {
4353
}
4454

4555
public Channel get(String target) {
46-
return channels.computeIfAbsent(target, this::newChannel);
56+
return channels.computeIfAbsent(target, channelFactory);
4757
}
4858

49-
private ManagedChannel newChannel(String target) {
59+
private static ManagedChannel newChannel(String target) {
5060
return ManagedChannelBuilder.forTarget(target).build();
5161
}
5262
}

google-cloud-pubsublite/src/main/java/com/google/cloud/pubsublite/internal/wire/SinglePartitionPublisherBuilder.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,13 @@ public abstract class SinglePartitionPublisherBuilder {
3939
// Rarely set parameters.
4040
abstract PubsubContext context();
4141

42+
// For testing.
43+
abstract PublisherBuilder.Builder underlyingBuilder();
44+
4245
public static Builder newBuilder() {
43-
return new AutoValue_SinglePartitionPublisherBuilder.Builder().setContext(PubsubContext.of());
46+
return new AutoValue_SinglePartitionPublisherBuilder.Builder()
47+
.setContext(PubsubContext.of())
48+
.setUnderlyingBuilder(PublisherBuilder.builder());
4449
}
4550

4651
@AutoValue.Builder
@@ -59,12 +64,16 @@ public abstract static class Builder {
5964
// Rarely set parameters.
6065
public abstract Builder setContext(PubsubContext context);
6166

67+
// For testing.
68+
abstract Builder setUnderlyingBuilder(PublisherBuilder.Builder underlyingBuilder);
69+
6270
abstract SinglePartitionPublisherBuilder autoBuild();
6371

6472
public SinglePartitionPublisher build() throws StatusException {
6573
SinglePartitionPublisherBuilder builder = autoBuild();
6674
PublisherBuilder.Builder publisherBuilder =
67-
PublisherBuilder.builder()
75+
builder
76+
.underlyingBuilder()
6877
.setTopic(builder.topic())
6978
.setPartition(builder.partition())
7079
.setContext(builder.context());

google-cloud-pubsublite/src/main/java/com/google/cloud/pubsublite/internal/wire/Versions.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,32 @@
1717
package com.google.cloud.pubsublite.internal.wire;
1818

1919
import com.google.api.gax.core.GaxProperties;
20+
import com.google.common.annotations.VisibleForTesting;
2021

2122
/** The version number of this library. */
2223
final class Versions {
23-
private Versions() {}
24+
private final String versionString;
2425

25-
private static String[] GetVersionSplits() {
26+
@VisibleForTesting
27+
Versions(String versionString) {
28+
this.versionString = versionString;
29+
}
30+
31+
private Versions() {
32+
this(GaxProperties.getLibraryVersion(Versions.class));
33+
}
34+
35+
private String[] getVersionSplits() {
2636
try {
27-
String versionString = GaxProperties.getLibraryVersion(Versions.class);
2837
return versionString.split("\\.");
2938
} catch (Exception e) {
3039
return new String[0];
3140
}
3241
}
3342

34-
private static int GetMajorVersion() {
35-
String[] splits = GetVersionSplits();
43+
@VisibleForTesting
44+
int getMajorVersion() {
45+
String[] splits = getVersionSplits();
3646
if (splits.length != 3) return 0;
3747
try {
3848
return Integer.parseInt(splits[0]);
@@ -41,8 +51,9 @@ private static int GetMajorVersion() {
4151
}
4252
}
4353

44-
private static int GetMinorVersion() {
45-
String[] splits = GetVersionSplits();
54+
@VisibleForTesting
55+
int getMinorVersion() {
56+
String[] splits = getVersionSplits();
4657
if (splits.length != 3) return 0;
4758
try {
4859
return Integer.parseInt(splits[1]);
@@ -51,7 +62,8 @@ private static int GetMinorVersion() {
5162
}
5263
}
5364

65+
private static final Versions VERSIONS = new Versions();
5466
// TODO: Do this using generation automation as opposed to maven packaging.
55-
static final int MAJOR_VERSION = GetMajorVersion();
56-
static final int MINOR_VERSION = GetMinorVersion();
67+
static final int MAJOR_VERSION = VERSIONS.getMajorVersion();
68+
static final int MINOR_VERSION = VERSIONS.getMinorVersion();
5769
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2020 Google LLC
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.google.cloud.pubsublite.internal;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
import static org.mockito.ArgumentMatchers.any;
21+
import static org.mockito.Mockito.times;
22+
import static org.mockito.Mockito.verify;
23+
import static org.mockito.Mockito.when;
24+
import static org.mockito.MockitoAnnotations.initMocks;
25+
26+
import io.grpc.Channel;
27+
import io.grpc.ManagedChannel;
28+
import java.util.function.Function;
29+
import org.junit.Before;
30+
import org.junit.Test;
31+
import org.junit.runner.RunWith;
32+
import org.junit.runners.JUnit4;
33+
import org.mockito.Mock;
34+
35+
@RunWith(JUnit4.class)
36+
public class ChannelCacheTest {
37+
@Mock ManagedChannel mockChannel;
38+
@Mock Function<String, ManagedChannel> channelFactory;
39+
40+
@Before
41+
public void setUp() {
42+
initMocks(this);
43+
}
44+
45+
@Test
46+
public void reusesChannels() {
47+
when(channelFactory.apply(any())).thenReturn(mockChannel);
48+
ChannelCache cache = new ChannelCache(channelFactory);
49+
Channel chan1 = cache.get("abc");
50+
Channel chan2 = cache.get("abc");
51+
assertThat(chan1).isEqualTo(chan2);
52+
verify(channelFactory, times(1)).apply("abc");
53+
when(mockChannel.shutdownNow()).thenReturn(mockChannel);
54+
cache.onShutdown();
55+
verify(mockChannel, times(1)).shutdownNow();
56+
}
57+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2020 Google LLC
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.google.cloud.pubsublite.internal.wire;
18+
19+
import static org.mockito.Mockito.mock;
20+
21+
import com.google.cloud.pubsublite.CloudRegion;
22+
import com.google.cloud.pubsublite.CloudZone;
23+
import com.google.cloud.pubsublite.ProjectNumber;
24+
import com.google.cloud.pubsublite.SubscriptionName;
25+
import com.google.cloud.pubsublite.SubscriptionPaths;
26+
import com.google.cloud.pubsublite.proto.PartitionAssignmentServiceGrpc;
27+
import io.grpc.Channel;
28+
import org.junit.Test;
29+
import org.junit.runner.RunWith;
30+
import org.junit.runners.JUnit4;
31+
32+
@RunWith(JUnit4.class)
33+
public class AssignerBuilderTest {
34+
@Test
35+
public void testBuilder() throws Exception {
36+
AssignerBuilder.newBuilder()
37+
.setSubscriptionPath(
38+
SubscriptionPaths.newBuilder()
39+
.setZone(CloudZone.of(CloudRegion.of("us-central1"), 'a'))
40+
.setProjectNumber(ProjectNumber.of(3))
41+
.setSubscriptionName(SubscriptionName.of("abc"))
42+
.build())
43+
.setReceiver(mock(PartitionAssignmentReceiver.class))
44+
.setAssignmentStub(PartitionAssignmentServiceGrpc.newStub(mock(Channel.class)))
45+
.build();
46+
}
47+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2020 Google LLC
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.google.cloud.pubsublite.internal.wire;
18+
19+
import static org.mockito.Mockito.mock;
20+
21+
import com.google.cloud.pubsublite.CloudRegion;
22+
import com.google.cloud.pubsublite.CloudZone;
23+
import com.google.cloud.pubsublite.Partition;
24+
import com.google.cloud.pubsublite.ProjectNumber;
25+
import com.google.cloud.pubsublite.SubscriptionName;
26+
import com.google.cloud.pubsublite.SubscriptionPaths;
27+
import com.google.cloud.pubsublite.proto.CursorServiceGrpc;
28+
import com.google.cloud.pubsublite.proto.PartitionAssignmentServiceGrpc;
29+
import io.grpc.Channel;
30+
import org.junit.Test;
31+
import org.junit.runner.RunWith;
32+
import org.junit.runners.JUnit4;
33+
34+
@RunWith(JUnit4.class)
35+
public class CommitterBuilderTest {
36+
@Test
37+
public void testBuilder() throws Exception {
38+
CommitterBuilder.newBuilder()
39+
.setSubscriptionPath(
40+
SubscriptionPaths.newBuilder()
41+
.setZone(CloudZone.of(CloudRegion.of("us-central1"), 'a'))
42+
.setProjectNumber(ProjectNumber.of(3))
43+
.setSubscriptionName(SubscriptionName.of("abc"))
44+
.build())
45+
.setPartition(Partition.of(987))
46+
.setCursorStub(CursorServiceGrpc.newStub(mock(Channel.class)))
47+
.build();
48+
}
49+
}

0 commit comments

Comments
 (0)