Skip to content
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

Migrating and enabling sync session integration test #6884

Merged
merged 19 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f6c4d3a
Move integration tests to Kotlin source set
rorbech May 26, 2020
1a254cf
Automatic conversion of integration test to Kotlin
rorbech May 26, 2020
b25841a
Fix serialization of partition values
rorbech May 28, 2020
914fa1a
Revert conversion of SyncedRealmIntegrationTests to keep PR smaller
rorbech May 28, 2020
8e3a5b9
Updated SyncSessionTests
rorbech May 28, 2020
5b7b4c1
Add primary keys for synced classes
rorbech May 28, 2020
de03563
Make SyncConfigurations with diffferent partitionValue differ
rorbech May 28, 2020
6d434c0
Revert "Add primary keys for synced classes"
rorbech May 28, 2020
fbcef54
Add separate sync entities with primary keys
rorbech May 28, 2020
e501096
Move partition value serialization out of basic flavor
rorbech May 29, 2020
661b2fc
Merge branch 'v10' into cr/sync-integration-test-session
rorbech May 30, 2020
8c1aa7f
Fix SyncConfigruation equals
rorbech May 30, 2020
ec7162d
Add scheme with supported types only to allow testing without bad cha…
rorbech Jun 2, 2020
ecf4751
Clean up test cases for sync with different partition values
rorbech Jun 2, 2020
bdb01a3
Merge branch 'v10' into cr/sync-integration-test-session
rorbech Jun 3, 2020
fee820b
Merge branch 'v10' into cr/sync-integration-test-session
rorbech Jun 4, 2020
72af903
Fix sync session connection state listeners
rorbech Jun 4, 2020
1760905
Merge branch 'v10' into cr/sync-integration-test-session
rorbech Jun 4, 2020
c88ffd7
Merge branch 'v10' into cr/sync-integration-test-session
rorbech Jun 4, 2020
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
5 changes: 4 additions & 1 deletion realm/realm-library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ android {
java.srcDirs += ['src/androidTest/kotlin', 'src/testUtils/java', 'src/testUtils/kotlin']
}
androidTestObjectServer {
java.srcDirs += [/* FIXME 'src/syncIntegrationTest/java', */ 'src/androidTestObjectServer/kotlin', 'src/syncTestUtils/java', 'src/syncTestUtils/kotlin']
java.srcDirs += [/* FIXME 'src/syncIntegrationTest/java', */
'src/syncIntegrationTest/kotlin',
'src/androidTestObjectServer/kotlin', 'src/syncTestUtils/java'
, 'src/syncTestUtils/kotlin']
assets.srcDirs += ['src/syncIntegrationTest/assets/']
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ const val defaultPartitionValue = "default"
/**
* The set of classes initially supported by MongoDB Realm.
*/
@RealmModule(classes = [SyncDog::class, SyncPerson::class])
@RealmModule(classes = [SyncDog::class, SyncPerson::class, SyncSupportedTypes::class])
class DefaultSyncSchema {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.entities

import io.realm.MutableRealmInteger
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.TestHelper
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmField
import io.realm.annotations.Required
import org.bson.types.Decimal128
import org.bson.types.ObjectId
import java.math.BigDecimal
import java.util.*

open class SyncAllTypes : RealmObject() {

companion object {
const val CLASS_NAME = "AllTypes"
const val FIELD_STRING = "columnString"
const val FIELD_LONG = "columnLong"
const val FIELD_FLOAT = "columnFloat"
const val FIELD_DOUBLE = "columnDouble"
const val FIELD_BOOLEAN = "columnBoolean"
const val FIELD_DATE = "columnDate"
const val FIELD_BINARY = "columnBinary"
const val FIELD_MUTABLEREALMINTEGER = "columnMutableRealmInteger"
const val FIELD_DECIMAL128 = "columnDecimal128"
const val FIELD_OBJECT_ID = "columnObjectId"
const val FIELD_REALMOBJECT = "columnRealmObject"
const val FIELD_REALMLIST = "columnRealmList"
const val FIELD_STRING_LIST = "columnStringList"
const val FIELD_BINARY_LIST = "columnBinaryList"
const val FIELD_BOOLEAN_LIST = "columnBooleanList"
const val FIELD_LONG_LIST = "columnLongList"
const val FIELD_DOUBLE_LIST = "columnDoubleList"
const val FIELD_FLOAT_LIST = "columnFloatList"
const val FIELD_DATE_LIST = "columnDateList"
val INVALID_TYPES_FIELDS_FOR_DISTINCT = arrayOf(FIELD_REALMOBJECT, FIELD_REALMLIST, FIELD_DOUBLE, FIELD_FLOAT,
FIELD_STRING_LIST, FIELD_BINARY_LIST, FIELD_BOOLEAN_LIST, FIELD_LONG_LIST,
FIELD_DOUBLE_LIST, FIELD_FLOAT_LIST, FIELD_DATE_LIST)
}

@PrimaryKey
@RealmField(name = "_id")
var id = ObjectId()

@Required
var columnString = ""
var columnLong: Long = 0
var columnFloat = 0f
var columnDouble = 0.0
var isColumnBoolean = false

@Required
var columnDate = Date(0)

@Required
var columnBinary = ByteArray(0)

@Required
var columnDecimal128 = Decimal128(BigDecimal.ZERO)

@Required
var columnObjectId = ObjectId(TestHelper.randomObjectIdHexString())
val columnRealmInteger = MutableRealmInteger.ofNull()
var columnRealmObject: SyncDog? = null
var columnRealmList: RealmList<SyncDog>? = null
var columnStringList: RealmList<String>? = null
Copy link
Contributor

Choose a reason for hiding this comment

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

Most of these will fail unless made @required, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Tests using this are currently all ignore. It took me some time to realise that lists with null elements where not supported on the server. The initial upload worked and the subsequent sync failed because of mismatched schema as the server just "truncated" the nullable parameter on the initial upload. Issue is raised on the server. Will fix in another PR when the issue is also fixed on the server.

var columnBinaryList: RealmList<ByteArray>? = null
var columnBooleanList: RealmList<Boolean>? = null
var columnLongList: RealmList<Long>? = null
var columnDoubleList: RealmList<Double>? = null
var columnFloatList: RealmList<Float>? = null
var columnDateList: RealmList<Date>? = null
var columnDecimal128List: RealmList<Decimal128>? = null

var columnObjectIdList: RealmList<ObjectId>? = null

fun setColumnMutableRealmInteger(value: Int) {
columnRealmInteger.set(value.toLong())
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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.
*/

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

License is duplicated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix in another PR along with the other SyncAllTypesSchema comments.

* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.entities

import io.realm.annotations.RealmModule

/**
* The set of classes initially supported by MongoDB Realm.
*/
@RealmModule(classes = [SyncDog::class, SyncPerson::class, SyncAllTypes::class])
class SyncAllTypesSchema {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.entities

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmField
import org.bson.types.ObjectId

open class SyncStringOnly : RealmObject() {

companion object {
const val CLASS_NAME = "StringOnly"
const val FIELD_CHARS = "chars"
}

@PrimaryKey
@RealmField(name = "_id")
var id = ObjectId()

var chars: String? = null

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.entities

import io.realm.annotations.RealmModule

@RealmModule(classes = [SyncStringOnly::class])
class SyncStringOnlyModule
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.entities

import io.realm.MutableRealmInteger
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.TestHelper
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmField
import io.realm.annotations.Required
import org.bson.types.Decimal128
import org.bson.types.ObjectId
import java.math.BigDecimal
import java.util.*

open class SyncSupportedTypes : RealmObject() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I get having both this class and SyncAllTypes we should probably only keep one of them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I introduced this one to enable successful testing while keeping the SyncAllTypes to track the issues of re-syncing with the server. Did not have the overview of what actually caused the trouble (lacking server support for Double and lists with nullable elements). Will clean it up in another PR along with the other SyncAlllTypesSchema


companion object {
const val CLASS_NAME = "AllTypes"
const val FIELD_STRING = "columnString"
const val FIELD_LONG = "columnLong"
const val FIELD_FLOAT = "columnFloat"
const val FIELD_DOUBLE = "columnDouble"
const val FIELD_BOOLEAN = "columnBoolean"
const val FIELD_DATE = "columnDate"
const val FIELD_BINARY = "columnBinary"
const val FIELD_MUTABLEREALMINTEGER = "columnMutableRealmInteger"
const val FIELD_DECIMAL128 = "columnDecimal128"
const val FIELD_OBJECT_ID = "columnObjectId"
const val FIELD_REALMOBJECT = "columnRealmObject"
const val FIELD_REALMLIST = "columnRealmList"
const val FIELD_STRING_LIST = "columnStringList"
const val FIELD_BINARY_LIST = "columnBinaryList"
const val FIELD_BOOLEAN_LIST = "columnBooleanList"
const val FIELD_LONG_LIST = "columnLongList"
const val FIELD_DOUBLE_LIST = "columnDoubleList"
const val FIELD_FLOAT_LIST = "columnFloatList"
const val FIELD_DATE_LIST = "columnDateList"
val INVALID_TYPES_FIELDS_FOR_DISTINCT = arrayOf(FIELD_REALMOBJECT, FIELD_REALMLIST, FIELD_DOUBLE, FIELD_FLOAT,
FIELD_STRING_LIST, FIELD_BINARY_LIST, FIELD_BOOLEAN_LIST, FIELD_LONG_LIST,
FIELD_DOUBLE_LIST, FIELD_FLOAT_LIST, FIELD_DATE_LIST)
}

@PrimaryKey
@RealmField(name = "_id")
var id = ObjectId()

@Required
var columnString = ""
var columnLong: Long = 0
var columnFloat = 0f
var isColumnBoolean = false

@Required
var columnDate = Date(0)

@Required
var columnBinary = ByteArray(0)

@Required
var columnDecimal128 = Decimal128(BigDecimal.ZERO)

@Required
var columnObjectId = ObjectId(TestHelper.randomObjectIdHexString())
val columnRealmInteger = MutableRealmInteger.ofNull()
var columnRealmObject: SyncDog? = null
var columnRealmList: RealmList<SyncDog>? = null

// FIXME These are the fields needed to be removed from SyncAllTypes for sync to work when
// updating the partitionValue
// var columnDouble = 0.0
// var columnStringList: RealmList<String>? = null
// var columnBinaryList: RealmList<ByteArray>? = null
// var columnBooleanList: RealmList<Boolean>? = null
// var columnLongList: RealmList<Long>? = null
// var columnDoubleList: RealmList<Double>? = null
// var columnFloatList: RealmList<Float> = RealmList()
// var columnDateList: RealmList<Date>? = null
// var columnDecimal128List: RealmList<Decimal128>? = null

// var columnObjectIdList: RealmList<ObjectId>? = null

fun setColumnMutableRealmInteger(value: Int) {
columnRealmInteger.set(value.toLong())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class SyncConfigurationTests {
}

@Test
// FIXME Tests are not exhaustive
fun equals_not() {
val user1: User = createTestUser(app)
val user2: User = createTestUser(app)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ package io.realm.mongodb.sync
fun Sync.testReset() {
this.reset()
}

fun Sync.simulateClientReset(session: SyncSession) {
this.simulateClientReset(session)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Realm Inc.
*
* Licensed 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 io.realm.mongodb.sync

// Helper to expose package protected methods for testing purpose
fun SyncSession.testClose() {
this.close()
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ResourceContainer : Closeable {
@Synchronized
override fun close() {
resources.map { it.close() }
resources.clear()
}

@Synchronized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#endif

#include <linux/errno.h>
#include <jni_util/bson_util.hpp>

#include "java_accessor.hpp"
#include "util.hpp"
Expand Down Expand Up @@ -332,8 +333,13 @@ JNIEXPORT jstring JNICALL Java_io_realm_internal_OsRealmConfig_nativeCreateAndSe
SyncSessionStopPolicy session_stop_policy = static_cast<SyncSessionStopPolicy>(j_session_stop_policy);

JStringAccessor realm_url(env, j_sync_realm_url);
JStringAccessor partion_key_value(env, j_partion_key_value);
config.sync_config = std::make_shared<SyncConfig>(SyncConfig{user, partion_key_value});
// TODO Simplify. Java serialization only allows writing full documents, so the partition
// key is embedded in a document with key 'value'. To get is as string were we parse it
// and reformat with C++ bson serialization as it supports serializing single values.
Bson bson(JniBsonProtocol::jstring_to_bson(env, j_partion_key_value));
std::stringstream buffer;
buffer << bson;
config.sync_config = std::make_shared<SyncConfig>(SyncConfig{user, buffer.str()});
config.sync_config->stop_policy = session_stop_policy;
config.sync_config->error_handler = std::move(error_handler);
switch (j_client_reset_mode) {
Expand Down
Loading