Skip to content

crypto migration tests #7645

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 3 commits into from
Dec 13, 2022
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
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
Copy link
Member

Choose a reason for hiding this comment

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

Looks like the db file has been added without using git LFS, because the script validate_lfs.sh is complaining. Can you check please?

1 change: 1 addition & 0 deletions changelog.d/7645.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Crypto database migration tests
55 changes: 55 additions & 0 deletions docs/database_migration_test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!--- TOC -->

* [Testing database migration](#testing-database-migration)
* [Creating a reference database](#creating-a-reference-database)
* [Testing](#testing)

<!--- END -->

## Testing database migration

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the doc!

Not a big deal, but for consistency, it could be great to have a table of content.

Just manually add these 2 lines here:

<!--- TOC -->

<!--- END -->

and run ./gradlew knit to generate it.

### 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/gradle.properties` (to avoid committing by mistake)

Launch the app in your emulator, login and use the app to fill 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.realm for crypto
- disk_store.realm 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 if a migration is missing:

```
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.

Git LFS file not shown
Binary file modified matrix-sdk-android/src/androidTest/assets/session_42.realm
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 0L
}
})
val realmConfiguration = configurationFactory.createConfiguration(
realmName,
"7b9a21a8a311e85d75b069a343c23fc952fc3fec5e0c83ecfa13f24b787479c487c3ed587db3dd1f5805d52041fc0ac246516e94b27ffa699ff928622e621aca",
RealmCryptoStoreModule(),
migration.schemaVersion,
migration
)
configurationFactory.copyRealmFromAssets(context, realmName, realmName)

realm = Realm.getInstance(realmConfiguration)
}
}