Skip to content

Improving Unit Test Coverage #100

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

Merged
merged 76 commits into from
Dec 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
705abcd
Prototyping Firestore integration for Java
hiranya911 Aug 31, 2017
084453e
Some code cleanup
hiranya911 Aug 31, 2017
39dec4c
Updating comments
hiranya911 Sep 2, 2017
cd8030c
Code cleanup
hiranya911 Sep 2, 2017
9be05c9
Merge branch 'master' into hkj-firestore-java
hiranya911 Sep 7, 2017
dfc6bec
Removed getInstance() methods from FirestoreClient and added getFires…
hiranya911 Sep 7, 2017
ef3881f
Merge branch 'hkj-firestore-java' of github.com:FirebasePrivate/fireb…
hiranya911 Sep 7, 2017
0cf020b
Merged with master
hiranya911 Oct 6, 2017
ab3469a
Minor cleanup
hiranya911 Oct 6, 2017
d64b4f6
Adding Firestore OAuth scopes
hiranya911 Oct 6, 2017
d87f364
Merge branch 'master' into hkj-firestore-java
hiranya911 Oct 9, 2017
8ed4e5f
Some documentation updates
hiranya911 Oct 9, 2017
48104da
Reverted a doc change
hiranya911 Oct 9, 2017
1771a01
Updating GCS dependency version (#89)
hiranya911 Oct 11, 2017
4201ff1
Netty-based websocket impl
hiranya911 Oct 17, 2017
7e7f694
Refactored the Netty stuff to a separate util class
hiranya911 Oct 17, 2017
7a74047
More code clean up and removing tubesock package
hiranya911 Oct 17, 2017
8e90610
Using the SDK ThreadManager for DB websocket threads
hiranya911 Oct 17, 2017
b910380
More code cleanup and error checks
hiranya911 Oct 17, 2017
a227cae
Handling connection drop events
hiranya911 Oct 19, 2017
6d8d90f
Handling connection loss events
hiranya911 Oct 19, 2017
e276f9a
Adding documentation
hiranya911 Oct 19, 2017
c10753d
Removed string list reader
hiranya911 Oct 19, 2017
da73c79
Merged with latest master
hiranya911 Oct 20, 2017
193fcde
Merge branch 'master' into hkj-firestore-java
hiranya911 Oct 20, 2017
a6613ce
Merge branch 'hkj-firestore-java' into hkj-netty-rtdb
hiranya911 Oct 20, 2017
59d1f5a
Removing redundant whitespace
hiranya911 Oct 23, 2017
e03a896
Revert "Using the SDK ThreadManager for DB websocket threads"
hiranya911 Oct 24, 2017
b87f536
src/main/java/com/google/firebase/database/connection/util/StringList…
hiranya911 Oct 24, 2017
4d7c74a
Added StringListReader back
hiranya911 Oct 24, 2017
536eb61
Re-updated websocket client
hiranya911 Oct 24, 2017
83c4e8b
reverting more syntactic changes
hiranya911 Oct 24, 2017
06f5515
Adding new line
hiranya911 Oct 24, 2017
bc74249
Added documentation; Using a more secure trust manager; Other cleanup
hiranya911 Oct 26, 2017
8829759
Removed unused import
hiranya911 Oct 26, 2017
a3411d6
Using the port on URI when available
hiranya911 Oct 27, 2017
2ef9002
Added jacoco plugin and parser
hiranya911 Nov 3, 2017
363bf4e
Coverage reporter impl
hiranya911 Nov 3, 2017
5cdd35b
Merged with master
hiranya911 Nov 3, 2017
f545040
More unit tests and cleaning up dead code
hiranya911 Nov 3, 2017
1bbc655
More tests for RTDB
hiranya911 Nov 4, 2017
d1cbf6f
More database tests
hiranya911 Nov 4, 2017
75a952b
Some unit tests for Repo
hiranya911 Nov 5, 2017
e292c5b
More tests for Repo
hiranya911 Nov 5, 2017
49039e5
Cleaning up mocks
hiranya911 Nov 5, 2017
c5bf95f
debug info
hiranya911 Nov 5, 2017
2a53e72
More debug info
hiranya911 Nov 5, 2017
c5e8dc2
Updated repo test
hiranya911 Nov 5, 2017
7d7ec88
Cleaned up test code
hiranya911 Nov 5, 2017
5396d41
Removed some code changes
hiranya911 Nov 5, 2017
56d4849
Connection tests
hiranya911 Nov 5, 2017
0cd2323
More unit tests
hiranya911 Nov 6, 2017
91808fb
Updated test
hiranya911 Nov 6, 2017
98de850
More unit tests for PersistentConnectionImpl
hiranya911 Nov 6, 2017
c8cbbe5
Refactored persistent conn tests
hiranya911 Nov 6, 2017
b9ffca3
More connection tests
hiranya911 Nov 6, 2017
811cf7f
Some user management and DB Node tests
hiranya911 Nov 6, 2017
b80fb3e
StorageClient unit tests
hiranya911 Nov 7, 2017
d5ce73a
cleaned up PersistentConnectionTest
hiranya911 Nov 7, 2017
fd5c79e
Fixed typo
hiranya911 Nov 8, 2017
3adf4a7
Merged with master
hiranya911 Nov 10, 2017
884bd18
Removing websocket commpression handler
hiranya911 Nov 10, 2017
931ce8a
Merged with hkj-netty-rtdb
hiranya911 Nov 10, 2017
6bc58f5
Unit tests for Connection class
hiranya911 Nov 10, 2017
ec33e35
More tests for the connection package
hiranya911 Nov 10, 2017
de41e44
Unit tests for GaeExecutorService
hiranya911 Nov 11, 2017
c28da33
Updated test
hiranya911 Nov 11, 2017
bd3fafc
Fixing a lint error
hiranya911 Nov 11, 2017
768ed57
Added more tests
hiranya911 Nov 11, 2017
45e4a49
More test coverage
hiranya911 Nov 14, 2017
03cbd15
Merged with master
hiranya911 Nov 22, 2017
48db4d8
Refactored GaeExecutorService class
hiranya911 Dec 1, 2017
67e0d74
Refactored various connection factory interfaces
hiranya911 Dec 1, 2017
c3aad51
Minor refactoring
hiranya911 Dec 4, 2017
fa9addf
Merged with master
hiranya911 Dec 6, 2017
5fc783d
Refactoring iterative test case with a map
hiranya911 Dec 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/main/java/com/google/firebase/cloud/StorageClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.firebase.FirebaseApp;
import com.google.firebase.ImplFirebaseTrampolines;
Expand All @@ -41,12 +42,10 @@ public class StorageClient {
private final FirebaseApp app;
private final Storage storage;

private StorageClient(FirebaseApp app) {
@VisibleForTesting
StorageClient(FirebaseApp app, Storage storage) {
this.app = checkNotNull(app, "FirebaseApp must not be null");
this.storage = StorageOptions.newBuilder()
.setCredentials(ImplFirebaseTrampolines.getCredentials(app))
.build()
.getService();
this.storage = checkNotNull(storage, "Storage must not be null");
}

public static StorageClient getInstance() {
Expand All @@ -57,7 +56,12 @@ public static synchronized StorageClient getInstance(FirebaseApp app) {
StorageClientService service = ImplFirebaseTrampolines.getService(app, SERVICE_ID,
StorageClientService.class);
if (service == null) {
service = ImplFirebaseTrampolines.addService(app, new StorageClientService(app));
Storage storage = StorageOptions.newBuilder()
.setCredentials(ImplFirebaseTrampolines.getCredentials(app))
.build()
.getService();
StorageClient client = new StorageClient(app, storage);
service = ImplFirebaseTrampolines.addService(app, new StorageClientService(client));
}
return service.getInstance();
}
Expand Down Expand Up @@ -99,8 +103,8 @@ public Bucket bucket(String name) {

private static class StorageClientService extends FirebaseService<StorageClient> {

StorageClientService(FirebaseApp app) {
super(SERVICE_ID, new StorageClient(app));
StorageClientService(StorageClient client) {
super(SERVICE_ID, client);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.firebase.database.connection;

import com.google.common.annotations.VisibleForTesting;
import com.google.firebase.database.logging.LogWrapper;

import java.util.HashMap;
Expand All @@ -39,24 +40,36 @@ class Connection implements WebsocketConnection.Delegate {
private static final String SERVER_HELLO_HOST = "h";
private static final String SERVER_HELLO_SESSION_ID = "s";
private static long connectionIds = 0;

private final LogWrapper logger;
private HostInfo hostInfo;
private final HostInfo hostInfo;
private final Delegate delegate;

private WebsocketConnection conn;
private Delegate delegate;
private State state;

public Connection(
Connection(
ConnectionContext context,
HostInfo hostInfo,
String cachedHost,
Delegate delegate,
String optLastSessionId) {
this(context, hostInfo, delegate,
new DefaultWebsocketConnectionFactory(context, hostInfo, cachedHost, optLastSessionId));
}

@VisibleForTesting
Connection(
ConnectionContext context,
HostInfo hostInfo,
Delegate delegate,
WebsocketConnectionFactory connFactory) {
long connId = connectionIds++;
this.hostInfo = hostInfo;
this.delegate = delegate;
this.logger = new LogWrapper(context.getLogger(), Connection.class, "conn_" + connId);
this.state = State.REALTIME_CONNECTING;
this.conn = new WebsocketConnection(context, hostInfo, cachedHost, this, optLastSessionId);
this.conn = connFactory.newConnection(this);
}

public void open() {
Expand Down Expand Up @@ -246,11 +259,6 @@ private void sendData(Map<String, Object> data, boolean isSensitive) {
}
}

// For testing
public void injectConnectionFailure() {
this.close();
}

public enum DisconnectReason {
SERVER_RESET,
OTHER
Expand All @@ -262,6 +270,34 @@ private enum State {
REALTIME_DISCONNECTED
}

interface WebsocketConnectionFactory {
WebsocketConnection newConnection(WebsocketConnection.Delegate delegate);
}

private static class DefaultWebsocketConnectionFactory implements WebsocketConnectionFactory {

final ConnectionContext context;
final HostInfo hostInfo;
final String cachedHost;
final String optLastSessionId;

DefaultWebsocketConnectionFactory(
ConnectionContext context,
HostInfo hostInfo,
String cachedHost,
String optLastSessionId) {
this.context = context;
this.hostInfo = hostInfo;
this.cachedHost = cachedHost;
this.optLastSessionId = optLastSessionId;
}

@Override
public WebsocketConnection newConnection(WebsocketConnection.Delegate delegate) {
return new WebsocketConnection(context, hostInfo, cachedHost, delegate, optLastSessionId);
}
}

public interface Delegate {

void onCacheHost(String host);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import com.google.firebase.database.connection.util.RetryHelper;
import com.google.firebase.database.logging.LogWrapper;
import com.google.firebase.database.util.AndroidSupport;
import com.google.firebase.database.util.GAuthToken;

import java.util.ArrayList;
Expand Down Expand Up @@ -93,13 +92,16 @@ public class PersistentConnectionImpl implements Connection.Delegate, Persistent
private static final String IDLE_INTERRUPT_REASON = "connection_idle";
private static final String TOKEN_REFRESH_INTERRUPT_REASON = "token_refresh";
private static long connectionIds = 0;

private final Delegate delegate;
private final HostInfo hostInfo;
private final ConnectionContext context;
private final ConnectionFactory connFactory;
private final ConnectionAuthTokenProvider authTokenProvider;
private final ScheduledExecutorService executorService;
private final LogWrapper logger;
private final RetryHelper retryHelper;

private String cachedHost;
private HashSet<String> interruptReasons = new HashSet<>();
private boolean firstConnection = true;
Expand All @@ -123,13 +125,19 @@ public class PersistentConnectionImpl implements Connection.Delegate, Persistent
private long lastWriteTimestamp;
private boolean hasOnDisconnects;

public PersistentConnectionImpl(
ConnectionContext context, HostInfo info, final Delegate delegate) {
this.delegate = delegate;
public PersistentConnectionImpl(ConnectionContext context, HostInfo info, Delegate delegate) {
this(context, info, delegate, new DefaultConnectionFactory());
}

PersistentConnectionImpl(
ConnectionContext context, HostInfo info, Delegate delegate, ConnectionFactory connFactory) {

this.context = context;
this.hostInfo = info;
this.delegate = delegate;
this.connFactory = connFactory;
this.executorService = context.getExecutorService();
this.authTokenProvider = context.getAuthTokenProvider();
this.hostInfo = info;
this.listens = new HashMap<>();
this.requestCBHash = new HashMap<>();
this.outstandingPuts = new HashMap<>();
Expand Down Expand Up @@ -422,7 +430,7 @@ public boolean isInterrupted(String reason) {
return interruptReasons.contains(reason);
}

boolean shouldReconnect() {
private boolean shouldReconnect() {
return interruptReasons.size() == 0;
}

Expand Down Expand Up @@ -524,20 +532,19 @@ public void onError(String error) {
}
}

public void openNetworkConnection(String token) {
private void openNetworkConnection(String token) {
hardAssert(
this.connectionState == ConnectionState.GettingToken,
connectionState == ConnectionState.GettingToken,
"Trying to open network connection while in the wrong state: %s",
this.connectionState);
connectionState);
// User might have logged out. Positive auth status is handled after authenticating with
// the server
if (token == null) {
this.delegate.onAuthStatus(false);
delegate.onAuthStatus(false);
}
this.authToken = token;
this.connectionState = ConnectionState.Connecting;
realtime =
new Connection(this.context, this.hostInfo, this.cachedHost, this, this.lastSessionId);
authToken = token;
connectionState = ConnectionState.Connecting;
realtime = connFactory.newConnection(this);
realtime.open();
}

Expand Down Expand Up @@ -1054,17 +1061,9 @@ private void warnOnListenerWarnings(List<String> warnings, ListenQuerySpec query

private void sendConnectStats() {
Map<String, Integer> stats = new HashMap<>();
if (AndroidSupport.isAndroid()) {
if (this.context.isPersistenceEnabled()) {
stats.put("persistence.android.enabled", 1);
}
stats.put("sdk.android." + context.getClientSdkVersion().replace('.', '-'), 1);
// TODO: Also send stats for connection version
} else {
assert !this.context.isPersistenceEnabled()
: "Stats for persistence on JVM missing (persistence not yet supported)";
stats.put("sdk.admin_java." + context.getClientSdkVersion().replace('.', '-'), 1);
}
assert !this.context.isPersistenceEnabled()
: "Stats for persistence on JVM missing (persistence not yet supported)";
stats.put("sdk.admin_java." + context.getClientSdkVersion().replace('.', '-'), 1);
if (logger.logsDebug()) {
logger.debug("Sending first connection stats");
}
Expand Down Expand Up @@ -1137,13 +1136,6 @@ private boolean idleHasTimedOut() {
return isIdle() && now > (this.lastWriteTimestamp + IDLE_TIMEOUT);
}

// For testing
public void injectConnectionFailure() {
if (this.realtime != null) {
this.realtime.injectConnectionFailure();
}
}

private enum ConnectionState {
Disconnected,
GettingToken,
Expand Down Expand Up @@ -1215,15 +1207,15 @@ private OutstandingListen(
this.tag = tag;
}

public ListenQuerySpec getQuery() {
ListenQuerySpec getQuery() {
return query;
}

public Long getTag() {
Long getTag() {
return this.tag;
}

public ListenHashProvider getHashFunction() {
ListenHashProvider getHashFunction() {
return this.hashFunction;
}

Expand All @@ -1247,23 +1239,23 @@ private OutstandingPut(
this.onComplete = onComplete;
}

public String getAction() {
String getAction() {
return action;
}

public Map<String, Object> getRequest() {
Map<String, Object> getRequest() {
return request;
}

public RequestResultCallback getOnComplete() {
RequestResultCallback getOnComplete() {
return onComplete;
}

public void markSent() {
void markSent() {
this.sent = true;
}

public boolean wasSent() {
boolean wasSent() {
return this.sent;
}
}
Expand Down Expand Up @@ -1299,4 +1291,18 @@ public RequestResultCallback getOnComplete() {
return onComplete;
}
}

interface ConnectionFactory {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Do you think we could combine this factory and the websocketfactory (if you do decide to keep it?). I think we can remove one of them with a little templating magic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting we introduce a new generic ConnectionFactory<T> type? Looks a little overkill.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it made more sense in the original PR as it had a lot of shared method parameters. I like the way it is structured now.

Connection newConnection(PersistentConnectionImpl delegate);
}

private static class DefaultConnectionFactory implements ConnectionFactory {
@Override
public Connection newConnection(PersistentConnectionImpl delegate) {
return new Connection(delegate.context, delegate.hostInfo, delegate.cachedHost,
delegate, delegate.lastSessionId);
}
}


}
Loading