Skip to content

Commit

Permalink
crypto migration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BillCarsonFr committed Nov 25, 2022
1 parent 9349b1a commit 38c3dc6
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
**/src/androidTest/assets/*.realm filter=lfs diff=lfs merge=lfs -text
47 changes: 47 additions & 0 deletions docs/database_migration_test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## Testing database migration

### Creating a reference database

Databases are encrypted, the key to decrypt is needed to setup the test.
A special build property must be enabled to extract it.

Set `vector.debugPrivateData=true` in `gradle.properties`

Launch the app in your emulator, login and use the app to feel up the database.

Save the key for the tested database
```
RealmKeysUtils W Database key for alias `session_db_fe9f212a611ccf6dea1141777065ed0a`: 935a6dfa0b0fc5cce1414194ed190....
RealmKeysUtils W Database key for alias `crypto_module_fe9f212a611ccf6dea1141777065ed0a`: 7b9a21a8a311e85d75b069a343.....
```


Use the [Device File Explorer](https://developer.android.com/studio/debug/device-file-explorer) to extrat the database file from the emulator.

Go to `data/data/im.vector.app.debug/files/<hash>/`
Pick the database you want to test (name can be found in SessionRealmConfigurationFactory):
- crypto_store.real for crypto
- disk_store for session
- etc...

Download the file on your disk

### Testing

Copy the file in `src/AndroidTest/assets`

see `CryptoSanityMigrationTest` or `RealmSessionStoreMigration43Test` for sample tests.

There are already some databases in the assets folder.
The existing test will properly detect schema changes, and fail with such errors:

```
io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
- Property 'CryptoMetadataEntity.foo' has been added.
```

If you want to test properly more complex database migration (dynamic transforms) ensure that the database contains
the entity you want to migrate.

You can explore the database with [realm studio](https://www.mongodb.com/docs/realm/studio/) if needed.

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.database

import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import io.realm.Realm
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
import org.matrix.android.sdk.internal.util.time.Clock

class CryptoSanityMigrationTest {
@get:Rule val configurationFactory = TestRealmConfigurationFactory()

lateinit var context: Context
var realm: Realm? = null

@Before
fun setUp() {
context = InstrumentationRegistry.getInstrumentation().context
}

@After
fun tearDown() {
realm?.close()
}

@Test
fun cryptoDatabaseShouldMigrateGracefully() {
val realmName = "crypto_store_20.realm"
val migration = RealmCryptoStoreMigration(object : Clock {
override fun epochMillis(): Long {
return System.currentTimeMillis()
}
})
val realmConfiguration = configurationFactory.createConfiguration(
realmName,
"7b9a21a8a311e85d75b069a343c23fc952fc3fec5e0c83ecfa13f24b787479c487c3ed587db3dd1f5805d52041fc0ac246516e94b27ffa699ff928622e621aca",
RealmCryptoStoreModule(),
migration.schemaVersion,
migration
)
configurationFactory.copyRealmFromAssets(context, realmName, realmName)

realm = Realm.getInstance(realmConfiguration)
}
}

0 comments on commit 38c3dc6

Please sign in to comment.