Skip to content

Closing the write and watch stream after 60s of idleness #388

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 14 commits into from
Oct 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions Firestore/Example/Firestore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
AFE6114F0D4DAECBA7B7C089 /* Pods_Firestore_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */; };
C4E749275AD0FBDF9F4716A8 /* Pods_SwiftBuildTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32AD40BF6B0E849B07FFD05E /* Pods_SwiftBuildTest.framework */; };
D5B2532E4676014F57A7EAB9 /* FSTStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D5B25C0D4AADFCA3ADB883E4 /* FSTStreamTests.m */; };
D5B25474286C9800CE42B8C2 /* FSTTestDispatchQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D5B25292CED31B81FDED0411 /* FSTTestDispatchQueue.m */; };
D5B259FDEE8094E8D710C5BF /* FSTTestDispatchQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D5B25292CED31B81FDED0411 /* FSTTestDispatchQueue.m */; };
DE03B2C91F2149D600A30B9C /* FSTTransactionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DE51B1C61F0D48AC0013853F /* FSTTransactionTests.m */; };
DE03B2D41F2149D600A30B9C /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
DE03B2D51F2149D600A30B9C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
Expand Down Expand Up @@ -222,6 +224,8 @@
B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CE00BABB5A3AAB44A4C209E2 /* Pods-Firestore_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests/Pods-Firestore_Tests.debug.xcconfig"; sourceTree = "<group>"; };
D3CC3DC5338DCAF43A211155 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
D5B25292CED31B81FDED0411 /* FSTTestDispatchQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSTTestDispatchQueue.m; sourceTree = "<group>"; };
D5B259DAA9149B80D6245B57 /* FSTTestDispatchQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSTTestDispatchQueue.h; sourceTree = "<group>"; };
D5B25C0D4AADFCA3ADB883E4 /* FSTStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSTStreamTests.m; sourceTree = "<group>"; };
DB17FEDFB80770611A935A60 /* Pods-Firestore_IntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_IntegrationTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_IntegrationTests/Pods-Firestore_IntegrationTests.release.xcconfig"; sourceTree = "<group>"; };
DE03B2E91F2149D600A30B9C /* Firestore_IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Firestore_IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -561,6 +565,8 @@
DE51B18A1F0D48AC0013853F /* FSTUtilTests.m */,
54E9282A1F339CAD00C1953E /* XCTestCase+Await.h */,
54E9282B1F339CAD00C1953E /* XCTestCase+Await.m */,
D5B259DAA9149B80D6245B57 /* FSTTestDispatchQueue.h */,
D5B25292CED31B81FDED0411 /* FSTTestDispatchQueue.m */,
);
path = Util;
sourceTree = "<group>";
Expand Down Expand Up @@ -1175,6 +1181,7 @@
DE51B1CD1F0D48CD0013853F /* FSTDatabaseInfoTests.m in Sources */,
DE51B1F21F0D49140013853F /* FSTPathTests.m in Sources */,
DE51B1DD1F0D490D0013853F /* FSTLocalStoreTests.m in Sources */,
D5B25474286C9800CE42B8C2 /* FSTTestDispatchQueue.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1199,6 +1206,7 @@
DE03B2C91F2149D600A30B9C /* FSTTransactionTests.m in Sources */,
54DA12B11F315F3800DD57A1 /* FIRValidationTests.m in Sources */,
D5B2532E4676014F57A7EAB9 /* FSTStreamTests.m in Sources */,
D5B259FDEE8094E8D710C5BF /* FSTTestDispatchQueue.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
18 changes: 18 additions & 0 deletions Firestore/Example/Tests/Integration/API/FIRDatabaseTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -913,4 +913,22 @@ - (void)testCantGetDocumentsWhileOffline {
[self awaitExpectations];
}

- (void)testWriteStreamReconnectsAfterIdle {
FIRDocumentReference *doc = [self documentRef];
FIRFirestore *firestore = doc.firestore;

[self writeDocumentRef:doc data:@{@"foo" : @"bar"}];
[self waitForIdleFirestore:firestore];
[self writeDocumentRef:doc data:@{@"foo" : @"bar"}];
}

- (void)testWatchStreamReconnectsAfterIdle {
FIRDocumentReference *doc = [self documentRef];
FIRFirestore *firestore = doc.firestore;

[self readSnapshotForRef:[self documentRef] requireOnline:YES];
[self waitForIdleFirestore:firestore];
[self readSnapshotForRef:[self documentRef] requireOnline:YES];
}

@end
88 changes: 69 additions & 19 deletions Firestore/Example/Tests/Integration/FSTStreamTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
#import "Core/FSTDatabaseInfo.h"
#import "FSTHelpers.h"
#import "FSTIntegrationTestCase.h"
#import "FSTTestDispatchQueue.h"
#import "Model/FSTDatabaseID.h"
#import "Remote/FSTDatastore.h"
#import "Util/FSTAssert.h"
#import "Util/FSTDispatchQueue.h"

/** Exposes otherwise private methods for testing. */
@interface FSTStream (Testing)
Expand Down Expand Up @@ -79,14 +79,14 @@ - (void)writeStreamDidCompleteHandshake {
_expectation = nil;
}

- (void)writeStreamDidClose:(NSError *_Nullable)error {
[_states addObject:@"writeStreamDidClose"];
- (void)writeStreamWasInterruptedWithError:(nullable NSError *)error {
[_states addObject:@"writeStreamWasInterrupted"];
[_expectation fulfill];
_expectation = nil;
}

- (void)watchStreamDidClose:(NSError *_Nullable)error {
[_states addObject:@"watchStreamDidClose"];
- (void)watchStreamWasInterruptedWithError:(nullable NSError *)error {
[_states addObject:@"watchStreamWasInterrupted"];
[_expectation fulfill];
_expectation = nil;
}
Expand Down Expand Up @@ -126,10 +126,10 @@ @interface FSTStreamTests : XCTestCase

@implementation FSTStreamTests {
dispatch_queue_t _testQueue;
FSTTestDispatchQueue *_workerDispatchQueue;
FSTDatabaseInfo *_databaseInfo;
FSTEmptyCredentialsProvider *_credentials;
FSTStreamStatusDelegate *_delegate;
FSTDispatchQueue *_workerDispatchQueue;

/** Single mutation to send to the write stream. */
NSArray<FSTMutation *> *_mutations;
Expand All @@ -138,38 +138,37 @@ @implementation FSTStreamTests {
- (void)setUp {
[super setUp];

_mutations = @[ FSTTestSetMutation(@"foo/bar", @{}) ];

FIRFirestoreSettings *settings = [FSTIntegrationTestCase settings];
FSTDatabaseID *databaseID =
[FSTDatabaseID databaseIDWithProject:[FSTIntegrationTestCase projectID]
database:kDefaultDatabaseID];

_testQueue = dispatch_queue_create("FSTStreamTestWorkerQueue", DISPATCH_QUEUE_SERIAL);
_workerDispatchQueue = [[FSTTestDispatchQueue alloc] initWithQueue:_testQueue];

_databaseInfo = [FSTDatabaseInfo databaseInfoWithDatabaseID:databaseID
persistenceKey:@"test-key"
host:settings.host
sslEnabled:settings.sslEnabled];
_testQueue = dispatch_queue_create("FSTStreamTestWorkerQueue", DISPATCH_QUEUE_SERIAL);
_workerDispatchQueue = [FSTDispatchQueue queueWith:_testQueue];
_credentials = [[FSTEmptyCredentialsProvider alloc] init];

_delegate = [[FSTStreamStatusDelegate alloc] initWithTestCase:self queue:_workerDispatchQueue];

_mutations = @[ FSTTestSetMutation(@"foo/bar", @{}) ];
}

- (FSTWriteStream *)setUpWriteStream {
FSTDatastore *datastore = [[FSTDatastore alloc] initWithDatabaseInfo:_databaseInfo
workerDispatchQueue:_workerDispatchQueue
credentials:_credentials];

_delegate = [[FSTStreamStatusDelegate alloc] initWithTestCase:self queue:_workerDispatchQueue];
return [datastore createWriteStreamWithDelegate:_delegate];
return [datastore createWriteStream];
}

- (FSTWatchStream *)setUpWatchStream {
FSTDatastore *datastore = [[FSTDatastore alloc] initWithDatabaseInfo:_databaseInfo
workerDispatchQueue:_workerDispatchQueue
credentials:_credentials];

_delegate = [[FSTStreamStatusDelegate alloc] initWithTestCase:self queue:_workerDispatchQueue];
return [datastore createWatchStreamWithDelegate:_delegate];
return [datastore createWatchStream];
}

/**
Expand All @@ -190,7 +189,7 @@ - (void)testWatchStreamStopBeforeHandshake {
FSTWatchStream *watchStream = [self setUpWatchStream];

[_delegate awaitNotificationFromBlock:^{
[watchStream start];
[watchStream startWithDelegate:_delegate];
}];

// Stop must not call watchStreamDidClose because the full implementation of the delegate could
Expand All @@ -210,7 +209,7 @@ - (void)testWriteStreamStopBeforeHandshake {
FSTWriteStream *writeStream = [self setUpWriteStream];

[_delegate awaitNotificationFromBlock:^{
[writeStream start];
[writeStream startWithDelegate:_delegate];
}];

// Don't start the handshake.
Expand All @@ -231,7 +230,7 @@ - (void)testWriteStreamStopAfterHandshake {
FSTWriteStream *writeStream = [self setUpWriteStream];

[_delegate awaitNotificationFromBlock:^{
[writeStream start];
[writeStream startWithDelegate:_delegate];
}];

// Writing before the handshake should throw
Expand All @@ -258,4 +257,55 @@ - (void)testWriteStreamStopAfterHandshake {
]];
}

- (void)testStreamClosesWhenIdle {
FSTWriteStream *writeStream = [self setUpWriteStream];

[_delegate awaitNotificationFromBlock:^{
[writeStream startWithDelegate:_delegate];
}];

[_delegate awaitNotificationFromBlock:^{
[writeStream writeHandshake];
}];

[_delegate awaitNotificationFromBlock:^{
[writeStream markIdle];
}];

dispatch_sync(_testQueue, ^{
XCTAssertFalse([writeStream isOpen]);
});

[self verifyDelegateObservedStates:@[
@"writeStreamDidOpen", @"writeStreamDidCompleteHandshake", @"writeStreamWasInterrupted"
]];
}

- (void)testStreamCancelsIdleOnWrite {
FSTWriteStream *writeStream = [self setUpWriteStream];

[_delegate awaitNotificationFromBlock:^{
[writeStream startWithDelegate:_delegate];
}];

[_delegate awaitNotificationFromBlock:^{
[writeStream writeHandshake];
}];

// Mark the stream idle, but immediately cancel the idle timer by issuing another write.
[_delegate awaitNotificationFromBlock:^{
[writeStream markIdle];
[writeStream writeMutations:_mutations];
}];

dispatch_sync(_testQueue, ^{
XCTAssertTrue([writeStream isOpen]);
});

[self verifyDelegateObservedStates:@[
@"writeStreamDidOpen", @"writeStreamDidCompleteHandshake",
@"writeStreamDidReceiveResponseWithVersion"
]];
}

@end
Loading