Skip to content

Start restarting persistence in spec tests #1713

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 2 commits into from
Aug 28, 2018
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
17 changes: 14 additions & 3 deletions Firestore/Example/Tests/SpecTests/FSTLevelDBSpecTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#import "Firestore/Example/Tests/SpecTests/FSTSpecTests.h"

#import "Firestore/Source/Local/FSTLevelDB.h"
#include "Firestore/core/src/firebase/firestore/util/path.h"

#import "Firestore/Example/Tests/Local/FSTPersistenceTestHelpers.h"
#import "Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h"

using firebase::firestore::util::Path;

NS_ASSUME_NONNULL_BEGIN

/**
Expand All @@ -31,15 +34,23 @@
@interface FSTLevelDBSpecTests : FSTSpecTests
@end

@implementation FSTLevelDBSpecTests
@implementation FSTLevelDBSpecTests {
Path _levelDbDir;
}

- (void)setUpForSpecWithConfig:(NSDictionary *)config {
// Getting a new directory will ensure that it is empty.
_levelDbDir = [FSTPersistenceTestHelpers levelDBDir];
[super setUpForSpecWithConfig:config];
}

/** Overrides -[FSTSpecTests persistence] */
- (id<FSTPersistence>)persistenceWithGCEnabled:(__unused BOOL)GCEnabled {
return [FSTPersistenceTestHelpers levelDBPersistence];
return [FSTPersistenceTestHelpers levelDBPersistenceWithDir:_levelDbDir];
}

- (BOOL)shouldRunWithTags:(NSArray<NSString *> *)tags {
if ([tags containsObject:kNoLRUTag]) {
if ([tags containsObject:kEagerGC]) {
return NO;
}

Expand Down
8 changes: 8 additions & 0 deletions Firestore/Example/Tests/SpecTests/FSTMemorySpecTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ @implementation FSTMemorySpecTests
}
}

- (BOOL)shouldRunWithTags:(NSArray<NSString *> *)tags {
if ([tags containsObject:kDurablePersistence]) {
return NO;
}

return [super shouldRunWithTags:tags];
}

@end

NS_ASSUME_NONNULL_END
6 changes: 5 additions & 1 deletion Firestore/Example/Tests/SpecTests/FSTSpecTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

NS_ASSUME_NONNULL_BEGIN

extern NSString *const kNoLRUTag;
extern NSString *const kEagerGC;
extern NSString *const kDurablePersistence;

/**
* FSTSpecTests run a set of portable event specifications from JSON spec files against a
Expand All @@ -43,6 +44,9 @@ extern NSString *const kNoLRUTag;
/** Based on its tags, determine whether the test case should run. */
- (BOOL)shouldRunWithTags:(NSArray<NSString *> *)tags;

/** Do any necessary setup for a single spec test */
- (void)setUpForSpecWithConfig:(NSDictionary *)config;

@end

NS_ASSUME_NONNULL_END
27 changes: 12 additions & 15 deletions Firestore/Example/Tests/SpecTests/FSTSpecTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
// if `kRunBenchmarkTests` is set to 'YES'.
static NSString *const kBenchmarkTag = @"benchmark";

NSString *const kNoLRUTag = @"no-lru";
NSString *const kEagerGC = @"eager-gc";

NSString *const kDurablePersistence = @"durable-persistence";

static NSString *Describe(NSData *data) {
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Expand All @@ -85,11 +87,11 @@
@interface FSTSpecTests ()
@property(nonatomic, strong) FSTSyncEngineTestDriver *driver;

// Some config info for the currently running spec; used when restarting the driver (for doRestart).
@property(nonatomic, strong) id<FSTPersistence> driverPersistence;
@end

@implementation FSTSpecTests
@implementation FSTSpecTests {
BOOL _gcEnabled;
}

- (id<FSTPersistence>)persistenceWithGCEnabled:(BOOL)GCEnabled {
@throw FSTAbstractMethodException(); // NOLINT
Expand All @@ -107,20 +109,20 @@ - (BOOL)shouldRunWithTags:(NSArray<NSString *> *)tags {
}

- (void)setUpForSpecWithConfig:(NSDictionary *)config {
// Store persistence / GCEnabled so we can re-use it in doRestart.
// Store GCEnabled so we can re-use it in doRestart.
NSNumber *GCEnabled = config[@"useGarbageCollection"];
_gcEnabled = [GCEnabled boolValue];
NSNumber *numClients = config[@"numClients"];
if (numClients) {
XCTAssertEqualObjects(numClients, @1, @"The iOS client does not support multi-client tests");
}
self.driverPersistence = [self persistenceWithGCEnabled:[GCEnabled boolValue]];
self.driver = [[FSTSyncEngineTestDriver alloc] initWithPersistence:self.driverPersistence];
id<FSTPersistence> persistence = [self persistenceWithGCEnabled:_gcEnabled];
self.driver = [[FSTSyncEngineTestDriver alloc] initWithPersistence:persistence];
[self.driver start];
}

- (void)tearDownForSpec {
[self.driver shutdown];
[self.driverPersistence shutdown];
}

/**
Expand Down Expand Up @@ -410,13 +412,8 @@ - (void)doRestart {

[self.driver shutdown];

// NOTE: We intentionally don't shutdown / re-create driverPersistence, since we want to
// preserve the persisted state. This is a bit of a cheat since it means we're not exercising
// the initialization / start logic that would normally be hit, but simplifies the plumbing and
// allows us to run these tests against FSTMemoryPersistence as well (there would be no way to
// re-create FSTMemoryPersistence without losing all persisted state).

self.driver = [[FSTSyncEngineTestDriver alloc] initWithPersistence:self.driverPersistence
id<FSTPersistence> persistence = [self persistenceWithGCEnabled:_gcEnabled];
self.driver = [[FSTSyncEngineTestDriver alloc] initWithPersistence:persistence
initialUser:currentUser
outstandingWrites:outstandingWrites];
[self.driver start];
Expand Down
3 changes: 3 additions & 0 deletions Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ @interface FSTSyncEngineTestDriver ()
@property(nonatomic, strong, readonly) FSTLocalStore *localStore;
@property(nonatomic, strong, readonly) FSTSyncEngine *syncEngine;
@property(nonatomic, strong, readonly) FSTDispatchQueue *dispatchQueue;
@property(nonatomic, strong, readonly) id<FSTPersistence> persistence;

#pragma mark - Data structures for holding events sent by the watch stream.

Expand Down Expand Up @@ -129,6 +130,7 @@ - (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
dispatch_queue_t queue =
dispatch_queue_create("sync_engine_test_driver", DISPATCH_QUEUE_SERIAL);
_dispatchQueue = [FSTDispatchQueue queueWith:queue];
_persistence = persistence;
_localStore = [[FSTLocalStore alloc] initWithPersistence:persistence initialUser:initialUser];
_datastore = [[FSTMockDatastore alloc] initWithDatabaseInfo:&_databaseInfo
workerDispatchQueue:_dispatchQueue
Expand Down Expand Up @@ -203,6 +205,7 @@ - (void)validateUsage {
- (void)shutdown {
[self.dispatchQueue dispatchSync:^{
[self.remoteStore shutdown];
[self.persistence shutdown];
}];
}

Expand Down
14 changes: 10 additions & 4 deletions Firestore/Example/Tests/SpecTests/json/listen_spec_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"describeName": "Listens:",
"itName": "Contents of query are cleared when listen is removed.",
"tags": [
"no-lru"
"eager-gc"
],
"comment": "Explicitly tests eager GC behavior",
"config": {
Expand Down Expand Up @@ -1287,7 +1287,9 @@
"Will gracefully handle watch stream reverting snapshots (with restart)": {
"describeName": "Listens:",
"itName": "Will gracefully handle watch stream reverting snapshots (with restart)",
"tags": [],
"tags": [
"durable-persistence"
],
"config": {
"useGarbageCollection": false,
"numClients": 1
Expand Down Expand Up @@ -4248,7 +4250,9 @@
"Omits global resume tokens for a short while": {
"describeName": "Listens:",
"itName": "Omits global resume tokens for a short while",
"tags": [],
"tags": [
"durable-persistence"
],
"config": {
"useGarbageCollection": false,
"numClients": 1
Expand Down Expand Up @@ -4423,7 +4427,9 @@
"Persists global resume tokens if the snapshot is old enough": {
"describeName": "Listens:",
"itName": "Persists global resume tokens if the snapshot is old enough",
"tags": [],
"tags": [
"durable-persistence"
],
"config": {
"useGarbageCollection": false,
"numClients": 1
Expand Down
92 changes: 23 additions & 69 deletions Firestore/Example/Tests/SpecTests/json/offline_spec_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"Empty queries are resolved if client goes offline": {
"describeName": "Offline:",
"itName": "Empty queries are resolved if client goes offline",
"tags": [],
"tags": [
"no-android",
"no-ios"
],
"config": {
"useGarbageCollection": true,
"numClients": 1
Expand Down Expand Up @@ -30,15 +33,6 @@
}
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand Down Expand Up @@ -83,7 +77,10 @@
"A successful message delays offline status": {
"describeName": "Offline:",
"itName": "A successful message delays offline status",
"tags": [],
"tags": [
"no-android",
"no-ios"
],
"config": {
"useGarbageCollection": true,
"numClients": 1
Expand Down Expand Up @@ -125,15 +122,6 @@
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand Down Expand Up @@ -179,7 +167,9 @@
"describeName": "Offline:",
"itName": "Removing all listeners delays \"Offline\" status on next listen",
"tags": [
"no-lru"
"eager-gc",
"no-android",
"no-ios"
],
"comment": "Marked as no-lru because when a listen is re-added, it gets a new target id rather than reusing one",
"config": {
Expand Down Expand Up @@ -209,15 +199,6 @@
}
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand Down Expand Up @@ -283,15 +264,6 @@
}
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand All @@ -318,7 +290,10 @@
"Queries revert to fromCache=true when offline.": {
"describeName": "Offline:",
"itName": "Queries revert to fromCache=true when offline.",
"tags": [],
"tags": [
"no-android",
"no-ios"
],
"config": {
"useGarbageCollection": true,
"numClients": 1
Expand Down Expand Up @@ -422,15 +397,6 @@
}
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand Down Expand Up @@ -495,7 +461,10 @@
"Queries with limbo documents handle going offline.": {
"describeName": "Offline:",
"itName": "Queries with limbo documents handle going offline.",
"tags": [],
"tags": [
"no-android",
"no-ios"
],
"config": {
"useGarbageCollection": true,
"numClients": 1
Expand Down Expand Up @@ -669,15 +638,6 @@
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchAck": [
2
Expand Down Expand Up @@ -929,7 +889,10 @@
"New queries return immediately with fromCache=true when offline due to stream failures.": {
"describeName": "Offline:",
"itName": "New queries return immediately with fromCache=true when offline due to stream failures.",
"tags": [],
"tags": [
"no-android",
"no-ios"
],
"config": {
"useGarbageCollection": true,
"numClients": 1
Expand Down Expand Up @@ -957,15 +920,6 @@
}
}
},
{
"watchStreamClose": {
"error": {
"code": 14,
"message": "Simulated Backend Error"
},
"runBackoffTimer": true
}
},
{
"watchStreamClose": {
"error": {
Expand Down
Loading