2022-08-12 08:05:00 -07:00
|
|
|
package cash.z.ecc.android.sdk.db
|
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
import androidx.test.core.app.ApplicationProvider
|
2022-08-12 08:05:00 -07:00
|
|
|
import androidx.test.filters.SmallTest
|
2022-10-19 13:52:54 -07:00
|
|
|
import cash.z.ecc.android.sdk.internal.db.DatabaseCoordinator
|
2023-05-18 04:36:15 -07:00
|
|
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
2022-08-12 08:05:00 -07:00
|
|
|
import cash.z.ecc.android.sdk.test.getAppContext
|
2023-03-08 07:04:04 -08:00
|
|
|
import cash.z.ecc.fixture.DatabaseCacheFilesRootFixture
|
2022-08-12 08:05:00 -07:00
|
|
|
import cash.z.ecc.fixture.DatabaseNameFixture
|
|
|
|
import cash.z.ecc.fixture.DatabasePathFixture
|
2022-12-13 05:25:09 -08:00
|
|
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
2022-08-12 08:05:00 -07:00
|
|
|
import kotlinx.coroutines.test.runTest
|
|
|
|
import org.junit.Assert.assertEquals
|
|
|
|
import org.junit.Assert.assertFalse
|
|
|
|
import org.junit.Assert.assertTrue
|
|
|
|
import org.junit.Before
|
|
|
|
import org.junit.Test
|
|
|
|
import java.io.File
|
|
|
|
|
|
|
|
class DatabaseCoordinatorTest {
|
|
|
|
|
|
|
|
private val dbCoordinator = DatabaseCoordinator.getInstance(getAppContext())
|
|
|
|
|
|
|
|
@Before
|
|
|
|
fun clear_test_files() {
|
|
|
|
val databaseDir = DatabasePathFixture.new(baseFolderPath = DatabasePathFixture.DATABASE_DIR_PATH)
|
|
|
|
val noBackupDir = DatabasePathFixture.new(baseFolderPath = DatabasePathFixture.NO_BACKUP_DIR_PATH)
|
|
|
|
File(databaseDir).deleteRecursively()
|
|
|
|
File(noBackupDir).deleteRecursively()
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
2022-12-13 05:25:09 -08:00
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
2023-03-08 07:04:04 -08:00
|
|
|
fun database_cache_root_directory_creation_test() = runTest {
|
|
|
|
val parentDirectory = File(DatabasePathFixture.new())
|
|
|
|
val destinationDirectory = DatabaseCacheFilesRootFixture.newCacheRoot()
|
|
|
|
val expectedDirectoryPath = File(parentDirectory, destinationDirectory).path
|
2022-08-12 08:05:00 -07:00
|
|
|
|
2023-03-08 07:04:04 -08:00
|
|
|
dbCoordinator.fsBlockDbRoot(
|
2022-08-12 08:05:00 -07:00
|
|
|
DatabaseNameFixture.TEST_DB_NETWORK,
|
|
|
|
DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
).also { resultFile ->
|
2023-03-08 07:04:04 -08:00
|
|
|
assertEquals(expectedDirectoryPath, resultFile.absolutePath)
|
2022-08-12 08:05:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
2022-12-13 05:25:09 -08:00
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
2022-08-12 08:05:00 -07:00
|
|
|
fun database_data_file_creation_test() = runTest {
|
|
|
|
val directory = File(DatabasePathFixture.new())
|
|
|
|
val fileName = DatabaseNameFixture.newDb(name = DatabaseCoordinator.DB_DATA_NAME)
|
|
|
|
val expectedFilePath = File(directory, fileName).path
|
|
|
|
|
|
|
|
dbCoordinator.dataDbFile(
|
|
|
|
DatabaseNameFixture.TEST_DB_NETWORK,
|
|
|
|
DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
).also { resultFile ->
|
|
|
|
assertEquals(expectedFilePath, resultFile.absolutePath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
2022-12-13 05:25:09 -08:00
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
2022-08-12 08:05:00 -07:00
|
|
|
fun database_transactions_file_creation_test() = runTest {
|
|
|
|
val directory = File(DatabasePathFixture.new())
|
|
|
|
val fileName = DatabaseNameFixture.newDb(name = DatabaseCoordinator.DB_PENDING_TRANSACTIONS_NAME)
|
|
|
|
val expectedFilePath = File(directory, fileName).path
|
|
|
|
|
|
|
|
dbCoordinator.pendingTransactionsDbFile(
|
|
|
|
DatabaseNameFixture.TEST_DB_NETWORK,
|
|
|
|
DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
).also { resultFile ->
|
|
|
|
assertEquals(expectedFilePath, resultFile.absolutePath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
2022-12-13 05:25:09 -08:00
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
2023-03-08 07:04:04 -08:00
|
|
|
fun data_database_files_move_test() = runTest {
|
2022-08-12 08:05:00 -07:00
|
|
|
val parentFile = File(
|
|
|
|
DatabasePathFixture.new(
|
|
|
|
baseFolderPath = DatabasePathFixture.DATABASE_DIR_PATH,
|
|
|
|
internalPath = ""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val originalDbFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDb(
|
2023-03-08 07:04:04 -08:00
|
|
|
name = DatabaseCoordinator.DB_DATA_NAME_LEGACY,
|
2022-08-12 08:05:00 -07:00
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val originalDbJournalFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbJournal(
|
2023-03-08 07:04:04 -08:00
|
|
|
name = DatabaseCoordinator.DB_DATA_NAME_LEGACY,
|
2022-08-12 08:05:00 -07:00
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val originalDbWalFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbWal(
|
2023-03-08 07:04:04 -08:00
|
|
|
name = DatabaseCoordinator.DB_DATA_NAME_LEGACY,
|
2022-08-12 08:05:00 -07:00
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val expectedDbFile = File(
|
|
|
|
DatabasePathFixture.new(),
|
2023-03-08 07:04:04 -08:00
|
|
|
DatabaseNameFixture.newDb(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
val expectedDbJournalFile = File(
|
|
|
|
DatabasePathFixture.new(),
|
2023-03-08 07:04:04 -08:00
|
|
|
DatabaseNameFixture.newDbJournal(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
val expectedDbWalFile = File(
|
|
|
|
DatabasePathFixture.new(),
|
2023-03-08 07:04:04 -08:00
|
|
|
DatabaseNameFixture.newDbWal(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(originalDbFile.exists())
|
|
|
|
assertTrue(originalDbJournalFile.exists())
|
|
|
|
assertTrue(originalDbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertFalse(expectedDbFile.exists())
|
|
|
|
assertFalse(expectedDbJournalFile.exists())
|
|
|
|
assertFalse(expectedDbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
|
2023-03-08 07:04:04 -08:00
|
|
|
dbCoordinator.dataDbFile(
|
2022-08-12 08:05:00 -07:00
|
|
|
DatabaseNameFixture.TEST_DB_NETWORK,
|
|
|
|
DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
).also { resultFile ->
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(resultFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
assertEquals(expectedDbFile.absolutePath, resultFile.absolutePath)
|
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(expectedDbFile.exists())
|
|
|
|
assertTrue(expectedDbJournalFile.exists())
|
|
|
|
assertTrue(expectedDbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertFalse(originalDbFile.exists())
|
|
|
|
assertFalse(originalDbJournalFile.exists())
|
|
|
|
assertFalse(originalDbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-19 13:52:54 -07:00
|
|
|
private fun getEmptyFile(parent: File, fileName: String): File {
|
2022-08-12 08:05:00 -07:00
|
|
|
return File(parent, fileName).apply {
|
|
|
|
assertTrue(parentFile != null)
|
|
|
|
parentFile!!.mkdirs()
|
2022-10-19 13:52:54 -07:00
|
|
|
assertTrue(parentFile!!.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
|
2022-10-19 13:52:54 -07:00
|
|
|
createNewFile()
|
|
|
|
assertTrue(exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
2022-12-13 05:25:09 -08:00
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
2023-03-08 07:04:04 -08:00
|
|
|
fun delete_data_database_files_test() = runTest {
|
2022-08-12 08:05:00 -07:00
|
|
|
val parentFile = File(
|
|
|
|
DatabasePathFixture.new(
|
|
|
|
baseFolderPath = DatabasePathFixture.NO_BACKUP_DIR_PATH,
|
|
|
|
internalPath = DatabasePathFixture.INTERNAL_DATABASE_PATH
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val dbFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
2023-03-08 07:04:04 -08:00
|
|
|
fileName = DatabaseNameFixture.newDb(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
val dbJournalFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
2023-03-08 07:04:04 -08:00
|
|
|
fileName = DatabaseNameFixture.newDbJournal(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
val dbWalFile = getEmptyFile(
|
|
|
|
parent = parentFile,
|
2023-03-08 07:04:04 -08:00
|
|
|
fileName = DatabaseNameFixture.newDbWal(name = DatabaseCoordinator.DB_DATA_NAME)
|
2022-08-12 08:05:00 -07:00
|
|
|
)
|
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(dbFile.exists())
|
|
|
|
assertTrue(dbJournalFile.exists())
|
|
|
|
assertTrue(dbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
|
|
|
|
dbCoordinator.deleteDatabases(DatabaseNameFixture.TEST_DB_NETWORK, DatabaseNameFixture.TEST_DB_ALIAS).also {
|
2023-05-18 04:36:15 -07:00
|
|
|
assertFalse(dbFile.exists())
|
|
|
|
assertFalse(dbJournalFile.exists())
|
|
|
|
assertFalse(dbWalFile.exists())
|
2022-08-12 08:05:00 -07:00
|
|
|
}
|
|
|
|
}
|
2023-03-08 07:04:04 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Note that this situation is just hypothetical, as the legacy database files should be placed only on one of
|
|
|
|
* the legacy locations, not both, but it is alright to test it together.
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
|
|
fun delete_all_legacy_database_files_test() = runTest {
|
|
|
|
// create older location legacy files
|
|
|
|
val olderLegacyParentFile = File(
|
|
|
|
DatabasePathFixture.new(
|
|
|
|
baseFolderPath = DatabasePathFixture.DATABASE_DIR_PATH,
|
|
|
|
internalPath = ""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val olderLegacyDbFile = getEmptyFile(
|
|
|
|
parent = olderLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDb(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_OLDER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val olderLegacyDbJournalFile = getEmptyFile(
|
|
|
|
parent = olderLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbJournal(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_OLDER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val olderLegacyDbWalFile = getEmptyFile(
|
|
|
|
parent = olderLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbWal(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_OLDER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseCoordinator.ALIAS_LEGACY
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
// create newer location legacy files
|
|
|
|
val newerLegacyParentFile = File(
|
|
|
|
DatabasePathFixture.new(
|
|
|
|
baseFolderPath = DatabasePathFixture.NO_BACKUP_DIR_PATH,
|
|
|
|
internalPath = DatabasePathFixture.INTERNAL_DATABASE_PATH
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val newerLegacyDbFile = getEmptyFile(
|
|
|
|
parent = newerLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDb(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_NEWER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val newerLegacyDbJournalFile = getEmptyFile(
|
|
|
|
parent = newerLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbJournal(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_NEWER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
val newerLegacyDbWalFile = getEmptyFile(
|
|
|
|
parent = newerLegacyParentFile,
|
|
|
|
fileName = DatabaseNameFixture.newDbWal(
|
|
|
|
name = DatabaseCoordinator.DB_CACHE_NEWER_NAME_LEGACY,
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK.networkName,
|
|
|
|
alias = DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
// check all files in place
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(olderLegacyDbFile.exists())
|
|
|
|
assertTrue(olderLegacyDbJournalFile.exists())
|
|
|
|
assertTrue(olderLegacyDbWalFile.exists())
|
2023-03-08 07:04:04 -08:00
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertTrue(newerLegacyDbFile.exists())
|
|
|
|
assertTrue(newerLegacyDbJournalFile.exists())
|
|
|
|
assertTrue(newerLegacyDbWalFile.exists())
|
2023-03-08 07:04:04 -08:00
|
|
|
|
|
|
|
// once we access the latest file system blocks storage root directory, all the legacy database files should
|
|
|
|
// be removed
|
|
|
|
dbCoordinator.fsBlockDbRoot(
|
|
|
|
network = DatabaseNameFixture.TEST_DB_NETWORK,
|
|
|
|
alias = DatabaseNameFixture.TEST_DB_ALIAS
|
|
|
|
).also {
|
2023-05-18 04:36:15 -07:00
|
|
|
assertFalse(olderLegacyDbFile.exists())
|
|
|
|
assertFalse(olderLegacyDbJournalFile.exists())
|
|
|
|
assertFalse(olderLegacyDbWalFile.exists())
|
2023-03-08 07:04:04 -08:00
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
assertFalse(newerLegacyDbFile.exists())
|
|
|
|
assertFalse(newerLegacyDbJournalFile.exists())
|
|
|
|
assertFalse(newerLegacyDbWalFile.exists())
|
2023-03-08 07:04:04 -08:00
|
|
|
}
|
|
|
|
}
|
2023-05-18 04:36:15 -07:00
|
|
|
|
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
|
|
|
fun data_db_path() = runTest {
|
|
|
|
val coordinator = DatabaseCoordinator.getInstance(ApplicationProvider.getApplicationContext())
|
|
|
|
val dataDbFile = coordinator.dataDbFile(ZcashNetwork.Testnet, "TestWallet")
|
|
|
|
assertTrue(
|
|
|
|
"Invalid DataDB file",
|
|
|
|
dataDbFile.absolutePath.endsWith(
|
|
|
|
"no_backup/co.electricoin.zcash/TestWallet_testnet_${DatabaseCoordinator.DB_DATA_NAME}"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
|
|
@Test
|
|
|
|
@SmallTest
|
|
|
|
fun cache_path() = runTest {
|
|
|
|
val coordinator = DatabaseCoordinator.getInstance(ApplicationProvider.getApplicationContext())
|
|
|
|
val cache = coordinator.fsBlockDbRoot(ZcashNetwork.Testnet, "TestWallet")
|
|
|
|
assertTrue(
|
|
|
|
"Invalid CacheDB file",
|
|
|
|
cache.absolutePath.endsWith(
|
|
|
|
"no_backup/co.electricoin.zcash/TestWallet_testnet_${DatabaseCoordinator.DB_FS_BLOCK_DB_ROOT_NAME}"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2022-08-12 08:05:00 -07:00
|
|
|
}
|