Skip to content

Commit

Permalink
Squash test fixes and java backend PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
dae committed Jun 11, 2022
1 parent 167a21e commit d99ff7b
Show file tree
Hide file tree
Showing 17 changed files with 81 additions and 185 deletions.
22 changes: 22 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,20 @@
import com.ichi2.anki.services.BootService;
import com.ichi2.anki.services.NotificationService;
import com.ichi2.compat.CompatHelper;
import com.ichi2.libanki.backend.DroidBackend;
import com.ichi2.libanki.backend.RustDroidBackend;
import com.ichi2.libanki.backend.RustDroidV16Backend;
import com.ichi2.utils.AdaptionUtil;
import com.ichi2.utils.ExceptionUtil;
import com.ichi2.utils.LanguageUtil;
import com.ichi2.anki.analytics.UsageAnalytics;
import com.ichi2.utils.Permissions;

import net.ankiweb.rsdroid.BackendFactory;
import net.ankiweb.rsdroid.BackendV11Factory;
import net.ankiweb.rsdroid.BackendVNextFactory;
import net.ankiweb.rsdroid.RustCleanup;

import java.io.InputStream;
import java.util.Locale;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -492,4 +500,18 @@ protected void log(int priority, String tag, @NonNull String message, Throwable
}
}
}


/**
* Creates a backend instance using the currently configured backend implementation.
* @return
*/
@RustCleanup("Can remove after migrating to VNext")
public static BackendFactory currentBackendFactory() {
if (AnkiDroidApp.TESTING_USE_V16_BACKEND) {
return new BackendVNextFactory();
} else {
return new BackendV11Factory();
}
}
}
3 changes: 1 addition & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/InitialActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import com.ichi2.anki.servicelayer.PreferenceUpgradeService
import com.ichi2.anki.servicelayer.PreferenceUpgradeService.setPreferencesUpToDate
import com.ichi2.utils.VersionUtils.pkgVersionName
import net.ankiweb.rsdroid.BackendException.BackendDbException.BackendDbLockedException
import net.ankiweb.rsdroid.BackendFactory
import net.ankiweb.rsdroid.RustBackendFailedException
import timber.log.Timber
import java.lang.ref.WeakReference
Expand Down Expand Up @@ -94,7 +93,7 @@ object InitialActivity {
val collectionPath = CollectionHelper.getCollectionPath(deckPicker)
require(backupManager.performDowngradeBackupInForeground(collectionPath)) { "backup failed" }
Timber.d("Downgrading database to V11: '%s'", collectionPath)
BackendFactory.createInstance().backend.downgradeBackend(collectionPath)
AnkiDroidApp.currentBackendFactory().backend.downgradeBackend(collectionPath)
}

/** @return Whether any preferences were upgraded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ internal constructor(
// set the preferences to the new deck path + checks CollectionHelper
// sets migration variables (migrationIsInProgress will be true)
updatePreferences(destinationPath)

// updatePreferences() opened the collection in the new location, which will have created
// a -wal file if the new backend code is active. Close it again, so that tests don't
// fail due to the presence of a -wal file in the destination folder.
if (AnkiDroidApp.TESTING_USE_V16_BACKEND) {
closeCollection()
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/async/CollectionTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import com.ichi2.libanki.sched.DeckTreeNode
import com.ichi2.libanki.sched.TreeNode
import com.ichi2.utils.*
import com.ichi2.utils.SyncStatus.Companion.ignoreDatabaseModification
import net.ankiweb.rsdroid.RustCleanup
import org.apache.commons.compress.archivers.zip.ZipFile
import timber.log.Timber
import java.io.File
Expand Down Expand Up @@ -553,6 +554,7 @@ open class CollectionTask<Progress, Result>(val task: TaskDelegateBase<Progress,
* A class allowing to send partial search result to the browser to display while the search ends
*/
@KotlinCleanup("move variables to constructor")
@RustCleanup("This provides little value since moving to the backend for DB access. Strip out?")
class PartialSearch(cards: List<CardCache>, columnIndex1: Int, columnIndex2: Int, numCardsToRender: Int, collectionTask: ProgressSenderAndCancelListener<List<CardCache>>, col: Collection) : ProgressSenderAndCancelListener<List<Long>> {
private val mCards: MutableList<CardCache>
private val mColumn1Index: Int
Expand Down
6 changes: 1 addition & 5 deletions AnkiDroid/src/main/java/com/ichi2/libanki/Consts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.ichi2.libanki

import androidx.annotation.IntDef
import net.ankiweb.rsdroid.RustCleanup
import kotlin.annotation.Retention

object Consts {
Expand Down Expand Up @@ -116,10 +115,7 @@ object Consts {
@JvmField
val DEFAULT_HOST_NUM: Int? = null

/* Note: 10 if using Rust backend, 9 if using Java. Set in BackendFactory.getInstance */
@JvmField
@RustCleanup("Use 10")
var SYNC_VER = 9
const val SYNC_VER = 10

// Leech actions
const val LEECH_SUSPEND = 0
Expand Down
14 changes: 12 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/libanki/DB.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import com.ichi2.anki.dialogs.DatabaseErrorDialog;
import com.ichi2.utils.DatabaseChangeDecorator;

import net.ankiweb.rsdroid.BackendException;

import org.intellij.lang.annotations.Language;

import java.util.ArrayList;
Expand Down Expand Up @@ -77,9 +79,17 @@ public DB(@NonNull String ankiFilename, @Nullable OpenHelperFactory openHelperFa
.build();
SupportSQLiteOpenHelper helper = getSqliteOpenHelperFactory(openHelperFactory).create(configuration);
// Note: This line creates the database and schema when executed using a Rust backend
mDatabase = new DatabaseChangeDecorator(helper.getWritableDatabase());
try {
mDatabase = new DatabaseChangeDecorator(helper.getWritableDatabase());
} catch (BackendException.BackendDbException exc) {
throw exc.toSQLiteException("db open");
}
// No-op except when using the old Java backend
mDatabase.disableWriteAheadLogging();
mDatabase.query("PRAGMA synchronous = 2", null);
if (!AnkiDroidApp.TESTING_USE_V16_BACKEND) {
// full sync is not required when using a WAL
mDatabase.query("PRAGMA synchronous = 2", null);
}
mMod = false;
}

Expand Down
18 changes: 1 addition & 17 deletions AnkiDroid/src/main/java/com/ichi2/libanki/Storage.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"PMD.SwitchStmtsShouldHaveDefault","PMD.EmptyIfStmt","PMD.SimplifyBooleanReturns","PMD.CollapsibleIfStatements"})
public class Storage {

private static boolean sUseBackend = true;
private static boolean sUseInMemory = false;
/**
* The collection is locked from being opened via the {@link Storage} class. All collection accesses in the app
Expand Down Expand Up @@ -93,7 +92,7 @@ public static Collection Collection(Context context, @NonNull String path, boole

File dbFile = new File(path);
boolean create = !dbFile.exists();
DroidBackend backend = DroidBackendFactory.getInstance(useBackend());
DroidBackend backend = DroidBackendFactory.getInstance();
DB db = backend.openCollectionDatabase(sUseInMemory ? ":memory:" : path);

try {
Expand Down Expand Up @@ -136,16 +135,6 @@ private static void addNoteTypes(Collection col, DroidBackend backend) {
}
}


/**
* Whether the collection should try to be opened with a Rust-based DB Backend
* Falls back to Java if init fails.
* */
protected static boolean useBackend() {
return sUseBackend;
}


private static int _upgradeSchema(DB db, @NonNull Time time) {
int ver = db.queryScalar("SELECT ver FROM col");
if (ver == Consts.SCHEMA_VERSION) {
Expand Down Expand Up @@ -419,11 +408,6 @@ public static void addIndices(DB db) {
}


public static void setUseBackend(boolean useBackend) {
sUseBackend = useBackend;
}


public static void setUseInMemory(boolean useInMemoryDatabase) {
sUseInMemory = useInMemoryDatabase;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,20 @@ package com.ichi2.libanki.backend

import androidx.annotation.VisibleForTesting
import com.ichi2.anki.AnkiDroidApp
import com.ichi2.anki.CrashReportService
import com.ichi2.libanki.Consts
import net.ankiweb.rsdroid.BackendFactory
import net.ankiweb.rsdroid.RustBackendFailedException
import net.ankiweb.rsdroid.RustCleanup
import timber.log.Timber
import net.ankiweb.rsdroid.NativeMethods

/** Responsible for selection of either the Rust or Java-based backend */
/** Responsible for selection of legacy or new Rust backend */
object DroidBackendFactory {
@JvmStatic
private var sBackendForTesting: DroidBackend? = null

/**
* Obtains an instance of a [DroidBackend].
* Each call to this method will generate a separate instance which can handle a new Anki collection
*/
@JvmStatic
@RustCleanup("Change back to a constant SYNC_VER")
fun getInstance(useBackend: Boolean): DroidBackend {
if (sBackendForTesting != null) {
return sBackendForTesting!!
}
var backendFactory: BackendFactory? = null
if (useBackend) {
try {
backendFactory = BackendFactory.createInstance()
} catch (e: RustBackendFailedException) {
Timber.w(e, "Rust backend failed to load - falling back to Java")
CrashReportService.sendExceptionReport(e, "DroidBackendFactory::getInstance")
}
}
val instance = getInstance(backendFactory)
// Update the Sync version if we can load the Rust
Consts.SYNC_VER = if (backendFactory == null) 9 else 10
return instance
}

@JvmStatic
private fun getInstance(backendFactory: BackendFactory?): DroidBackend {
if (backendFactory == null) {
return JavaDroidBackend()
}
return if (AnkiDroidApp.TESTING_USE_V16_BACKEND) {
RustDroidV16Backend(backendFactory)
fun getInstance(): DroidBackend {
NativeMethods.ensureSetup()
return sBackendForTesting ?: if (AnkiDroidApp.TESTING_USE_V16_BACKEND) {
RustDroidV16Backend(AnkiDroidApp.currentBackendFactory())
} else {
RustDroidBackend(backendFactory)
RustDroidBackend(AnkiDroidApp.currentBackendFactory())
}
}

Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion AnkiDroid/src/test/java/com/ichi2/anki/NoteEditorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class NoteEditorTest : RobolectricTest() {
@Test
@Config(qualifiers = "en")
fun addToCurrentWithNoDeckSelectsDefault_issue_9616() {
assumeThat(getInstance(true), not(instanceOf(RustDroidV16Backend::class.java)))
assumeThat(getInstance(), not(instanceOf(RustDroidV16Backend::class.java)))
col.conf.put("addToCur", false)
val cloze = assertNotNull(col.models.byName("Cloze"))
cloze.remove("did")
Expand Down
4 changes: 1 addition & 3 deletions AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ open class RobolectricTest : CollectionGetter {

// Robolectric can't handle our default sqlite implementation of requery, it needs the framework
DB.setSqliteOpenHelperFactory(getHelperFactory())
// But, don't use the helper unless useLegacyHelper is true
Storage.setUseBackend(!useLegacyHelper())
Storage.setUseInMemory(useInMemoryDatabase())

// Reset static variable for custom tabs failure.
Expand Down Expand Up @@ -392,7 +390,7 @@ open class RobolectricTest : CollectionGetter {
protected fun addNonClozeModel(name: String, fields: Array<String>, qfmt: String?, afmt: String?): String {
val model = col.models.newModel(name)
for (field in fields) {
addField(model, field)
col.models.addFieldInNewModel(model, col.models.newField(field))
}
val t = Models.newTemplate("Card 1")
t.put("qfmt", qfmt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CollectionTaskCountModelsTest : AbstractCollectionTaskTest() {
val task = CountModels()
val initialCount = execute(task)!!.first.size

addNonClozeModel("testModel", arrayOf<String>(), qfmt = "{{ front }}", afmt = "{{FrontSide}}\n\n<hr id=answer>\n\n{{ back }}")
addNonClozeModel("testModel", arrayOf<String>("front"), qfmt = "{{ front }}", afmt = "{{FrontSide}}\n\n<hr id=answer>\n\n{{ back }}")

val finalCount = execute(task)!!.first.size
assertEquals(initialCount + 1, finalCount)
Expand Down
Loading

0 comments on commit d99ff7b

Please sign in to comment.