Use a minimal job spec representation in memory.

This commit is contained in:
Greyson Parrelli
2024-07-16 10:53:10 -04:00
committed by Nicholas Tinsley
parent eb59afc33c
commit 973dc72cfa
5 changed files with 340 additions and 142 deletions

View File

@@ -1,7 +1,9 @@
package org.thoughtcrime.securesms.jobs
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.Test
import org.mockito.Mockito
import org.thoughtcrime.securesms.assertIs
import org.thoughtcrime.securesms.database.JobDatabase
import org.thoughtcrime.securesms.jobmanager.Job
@@ -15,7 +17,7 @@ import java.nio.charset.Charset
class FastJobStorageTest {
@Test
fun `init - all stored data available`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
DataSet1.assertJobsMatch(subject.allJobSpecs)
@@ -25,7 +27,7 @@ class FastJobStorageTest {
@Test
fun `init - removes circular dependencies`() {
val subject = FastJobStorage(fixedDataDatabase(DataSetCircularDependency.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSetCircularDependency.FULL_SPECS))
subject.init()
DataSetCircularDependency.assertJobsMatch(subject.allJobSpecs)
@@ -35,27 +37,27 @@ class FastJobStorageTest {
@Test
fun `insertJobs - writes to database`() {
val database = noopDatabase()
val database = mockDatabase()
val subject = FastJobStorage(database)
subject.insertJobs(DataSet1.FULL_SPECS)
Mockito.verify(database).insertJobs(DataSet1.FULL_SPECS)
verify { database.insertJobs(DataSet1.FULL_SPECS) }
}
@Test
fun `insertJobs - memory-only job does not write to database`() {
val database = noopDatabase()
val database = mockDatabase()
val subject = FastJobStorage(database)
subject.insertJobs(DataSetMemory.FULL_SPECS)
Mockito.verify(database, Mockito.times(0)).insertJobs(DataSet1.FULL_SPECS)
verify(exactly = 0) { database.insertJobs(DataSet1.FULL_SPECS) }
}
@Test
fun `insertJobs - data can be found`() {
val subject = FastJobStorage(noopDatabase())
val subject = FastJobStorage(mockDatabase())
subject.insertJobs(DataSet1.FULL_SPECS)
DataSet1.assertJobsMatch(subject.allJobSpecs)
DataSet1.assertConstraintsMatch(subject.allConstraintSpecs)
@@ -64,7 +66,7 @@ class FastJobStorageTest {
@Test
fun `insertJobs - individual job can be found`() {
val subject = FastJobStorage(noopDatabase())
val subject = FastJobStorage(mockDatabase())
subject.insertJobs(DataSet1.FULL_SPECS)
subject.getJobSpec(DataSet1.JOB_1.id) assertIs DataSet1.JOB_1
@@ -73,10 +75,10 @@ class FastJobStorageTest {
@Test
fun `updateAllJobsToBePending - writes to database`() {
val database = noopDatabase()
val database = mockDatabase()
val subject = FastJobStorage(database)
subject.updateAllJobsToBePending()
Mockito.verify(database).updateAllJobsToBePending()
verify { database.updateAllJobsToBePending() }
}
@Test
@@ -84,7 +86,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", isRunning = true), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", isRunning = true), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
subject.updateAllJobsToBePending()
@@ -94,26 +96,26 @@ class FastJobStorageTest {
@Test
fun `updateJobs - writes to database`() {
val database = fixedDataDatabase(DataSet1.FULL_SPECS)
val database = mockDatabase(DataSet1.FULL_SPECS)
val jobs = listOf(jobSpec(id = "id1", factoryKey = "f1"))
val subject = FastJobStorage(database)
subject.init()
subject.updateJobs(jobs)
Mockito.verify(database).updateJobs(jobs)
verify { database.updateJobs(jobs) }
}
@Test
fun `updateJobs - memory-only job does not write to database`() {
val database = fixedDataDatabase(DataSetMemory.FULL_SPECS)
val database = mockDatabase(DataSetMemory.FULL_SPECS)
val jobs = listOf(jobSpec(id = "id1", factoryKey = "f1"))
val subject = FastJobStorage(database)
subject.init()
subject.updateJobs(jobs)
Mockito.verify(database, Mockito.times(0)).updateJobs(jobs)
verify(exactly = 0) { database.updateJobs(jobs) }
}
@Test
@@ -153,7 +155,7 @@ class FastJobStorageTest {
isMemoryOnly = false
)
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2, fullSpec3)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2, fullSpec3)))
subject.init()
subject.updateJobs(listOf(update1, update2))
@@ -164,19 +166,19 @@ class FastJobStorageTest {
@Test
fun `markJobAsRunning - writes to database`() {
val database = fixedDataDatabase(DataSet1.FULL_SPECS)
val database = mockDatabase(DataSet1.FULL_SPECS)
val subject = FastJobStorage(database)
subject.init()
subject.markJobAsRunning(id = "id1", currentTime = 42)
Mockito.verify(database).markJobAsRunning(id = "id1", currentTime = 42)
verify { database.markJobAsRunning(id = "id1", currentTime = 42) }
}
@Test
fun `markJobAsRunning - state updated`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.markJobAsRunning(id = DataSet1.JOB_1.id, currentTime = 42)
@@ -187,7 +189,7 @@ class FastJobStorageTest {
@Test
fun `updateJobAfterRetry - writes to database`() {
val database = fixedDataDatabase(DataSet1.FULL_SPECS)
val database = mockDatabase(DataSet1.FULL_SPECS)
val subject = FastJobStorage(database)
subject.init()
@@ -200,12 +202,12 @@ class FastJobStorageTest {
serializedData = "a".toByteArray()
)
Mockito.verify(database).updateJobAfterRetry(id = "id1", currentTime = 0, runAttempt = 1, nextBackoffInterval = 10, serializedData = "a".toByteArray())
verify { database.updateJobAfterRetry(id = "id1", currentTime = 0, runAttempt = 1, nextBackoffInterval = 10, serializedData = "a".toByteArray()) }
}
@Test
fun `updateJobAfterRetry - memory-only job does not write to database`() {
val database = fixedDataDatabase(DataSetMemory.FULL_SPECS)
val database = mockDatabase(DataSetMemory.FULL_SPECS)
val subject = FastJobStorage(database)
subject.init()
@@ -218,14 +220,14 @@ class FastJobStorageTest {
serializedData = "a".toByteArray()
)
Mockito.verify(database, Mockito.times(0)).updateJobAfterRetry(id = "id1", currentTime = 0, runAttempt = 1, nextBackoffInterval = 10, serializedData = "a".toByteArray())
verify(exactly = 0) { database.updateJobAfterRetry(id = "id1", currentTime = 0, runAttempt = 1, nextBackoffInterval = 10, serializedData = "a".toByteArray()) }
}
@Test
fun `updateJobAfterRetry - state updated`() {
val fullSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", isRunning = true), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec)))
subject.init()
subject.updateJobAfterRetry(
@@ -250,7 +252,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", isRunning = true), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = "q"), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(1).size assertIs 0
@@ -260,7 +262,7 @@ class FastJobStorageTest {
fun `getPendingJobsWithNoDependenciesInCreatedOrder - none when all jobs are running`() {
val fullSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", isRunning = true), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size assertIs 0
@@ -271,7 +273,7 @@ class FastJobStorageTest {
val currentTime = 0L
val fullSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", lastRunAttemptTime = 0, nextBackoffInterval = 10), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(currentTime).size assertIs 0
@@ -282,7 +284,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", isRunning = true), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2"), emptyList(), listOf(DependencySpec("2", "1", false)))
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(0).size assertIs 0
@@ -292,7 +294,7 @@ class FastJobStorageTest {
fun `getPendingJobsWithNoDependenciesInCreatedOrder - single eligible job`() {
val fullSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q"), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size assertIs 1
@@ -303,7 +305,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1"), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2"), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size assertIs 2
@@ -314,7 +316,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", isRunning = true), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2"), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -327,7 +329,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q"), emptyList(), emptyList())
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = "q"), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -341,7 +343,7 @@ class FastJobStorageTest {
val fullSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = "q", createTime = 2, priority = Job.Parameters.PRIORITY_HIGH), emptyList(), emptyList())
val fullSpec3 = FullSpec(jobSpec(id = "3", factoryKey = "f3", queueKey = "q", createTime = 3, priority = Job.Parameters.PRIORITY_DEFAULT), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2, fullSpec3)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2, fullSpec3)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -361,7 +363,7 @@ class FastJobStorageTest {
val fullSpec8 = FullSpec(jobSpec(id = "8", factoryKey = "f8", queueKey = null, createTime = 8, priority = Job.Parameters.PRIORITY_LOW), emptyList(), emptyList())
val fullSpec9 = FullSpec(jobSpec(id = "9", factoryKey = "f9", queueKey = null, createTime = 9, priority = Job.Parameters.PRIORITY_DEFAULT), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1, fullSpec2, fullSpec3, fullSpec4, fullSpec5, fullSpec6, fullSpec7, fullSpec8, fullSpec9)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1, fullSpec2, fullSpec3, fullSpec4, fullSpec5, fullSpec6, fullSpec7, fullSpec8, fullSpec9)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -380,7 +382,7 @@ class FastJobStorageTest {
val fullSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", lastRunAttemptTime = 100, nextBackoffInterval = 5), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(fullSpec1)))
val subject = FastJobStorage(mockDatabase(listOf(fullSpec1)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(currentTime)
@@ -393,7 +395,7 @@ class FastJobStorageTest {
val plainSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", createTime = 0), emptyList(), emptyList())
val migrationSpec = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 5), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(plainSpec, migrationSpec)))
val subject = FastJobStorage(mockDatabase(listOf(plainSpec, migrationSpec)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -406,7 +408,7 @@ class FastJobStorageTest {
val plainSpec = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = "q", createTime = 0), emptyList(), emptyList())
val migrationSpec = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 5, isRunning = true), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(plainSpec, migrationSpec)))
val subject = FastJobStorage(mockDatabase(listOf(plainSpec, migrationSpec)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -418,7 +420,7 @@ class FastJobStorageTest {
val migrationSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 0, isRunning = true), emptyList(), emptyList())
val migrationSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 5), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(migrationSpec1, migrationSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(migrationSpec1, migrationSpec2)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -430,7 +432,7 @@ class FastJobStorageTest {
val migrationSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 0), emptyList(), emptyList())
val migrationSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 5), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(migrationSpec1, migrationSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(migrationSpec1, migrationSpec2)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10)
@@ -445,7 +447,7 @@ class FastJobStorageTest {
val migrationSpec1 = FullSpec(jobSpec(id = "1", factoryKey = "f1", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 0, lastRunAttemptTime = 0, nextBackoffInterval = 999), emptyList(), emptyList())
val migrationSpec2 = FullSpec(jobSpec(id = "2", factoryKey = "f2", queueKey = Job.Parameters.MIGRATION_QUEUE_KEY, createTime = 5, lastRunAttemptTime = 0, nextBackoffInterval = 0), emptyList(), emptyList())
val subject = FastJobStorage(fixedDataDatabase(listOf(migrationSpec1, migrationSpec2)))
val subject = FastJobStorage(mockDatabase(listOf(migrationSpec1, migrationSpec2)))
subject.init()
val jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(currentTime)
@@ -454,7 +456,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - after deleted, no longer is in eligible list`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
var jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(100)
@@ -468,7 +470,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - after marked running, no longer is in eligible list`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
var jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(100)
@@ -482,7 +484,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - after updateJobAfterRetry to be invalid, no longer is in eligible list`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
var jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(100)
@@ -496,7 +498,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - after invalid then marked pending, is in eligible list`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.markJobAsRunning("id1", 1)
@@ -511,7 +513,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - after updateJobs to be invalid, no longer is in eligible list`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
var jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(100)
@@ -525,7 +527,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - newly-inserted higher-priority job in queue replaces old`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
var jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(100)
@@ -541,7 +543,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - updating job to have a higher priority replaces lower priority in queue`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val lowerPriorityJob = DataSet1.JOB_1.copy(id = "id-bigboi", priority = Job.Parameters.PRIORITY_LOW)
@@ -561,7 +563,7 @@ class FastJobStorageTest {
@Test
fun `getPendingJobsWithNoDependenciesInCreatedOrder - updating job to have an older createTime replaces newer in queue`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val newerJob = DataSet1.JOB_1.copy(id = "id-bigboi", createTime = 1000)
@@ -581,7 +583,7 @@ class FastJobStorageTest {
@Test
fun `deleteJobs - writes to database`() {
val database = fixedDataDatabase(DataSet1.FULL_SPECS)
val database = mockDatabase(DataSet1.FULL_SPECS)
val ids: List<String> = listOf("id1", "id2")
val subject = FastJobStorage(database)
@@ -589,12 +591,12 @@ class FastJobStorageTest {
subject.deleteJobs(ids)
Mockito.verify(database).deleteJobs(ids)
verify { database.deleteJobs(ids) }
}
@Test
fun `deleteJobs - memory-only job does not write to database`() {
val database = fixedDataDatabase(DataSetMemory.FULL_SPECS)
val database = mockDatabase(DataSetMemory.FULL_SPECS)
val ids = listOf("id1")
val subject = FastJobStorage(database)
@@ -602,12 +604,12 @@ class FastJobStorageTest {
subject.deleteJobs(ids)
Mockito.verify(database, Mockito.times(0)).deleteJobs(ids)
verify(exactly = 0) { database.deleteJobs(ids) }
}
@Test
fun `deleteJobs - deletes all relevant pieces`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.deleteJobs(listOf("id1"))
@@ -622,11 +624,12 @@ class FastJobStorageTest {
constraints.size assertIs 1
constraints[0] assertIs DataSet1.CONSTRAINT_2
dependencies.size assertIs 1
subject.getJobSpec("id1") assertIs null
}
@Test
fun `getDependencySpecsThatDependOnJob - start of chain`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val result = subject.getDependencySpecsThatDependOnJob("id1")
@@ -637,7 +640,7 @@ class FastJobStorageTest {
@Test
fun `getDependencySpecsThatDependOnJob - mid-chain`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val result = subject.getDependencySpecsThatDependOnJob("id2")
@@ -647,7 +650,7 @@ class FastJobStorageTest {
@Test
fun `getDependencySpecsThatDependOnJob - end of chain`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val result = subject.getDependencySpecsThatDependOnJob("id3")
@@ -656,7 +659,7 @@ class FastJobStorageTest {
@Test
fun `getJobsInQueue - empty`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val result = subject.getJobsInQueue("x")
@@ -665,7 +668,7 @@ class FastJobStorageTest {
@Test
fun `getJobsInQueue - single job`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
val result = subject.getJobsInQueue("q1")
@@ -675,7 +678,7 @@ class FastJobStorageTest {
@Test
fun `getJobCountForFactory - general`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.getJobCountForFactory("f1") assertIs 1
@@ -684,7 +687,7 @@ class FastJobStorageTest {
@Test
fun `getJobCountForFactoryAndQueue - general`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.getJobCountForFactoryAndQueue("f1", "q1") assertIs 1
@@ -694,7 +697,7 @@ class FastJobStorageTest {
@Test
fun `areQueuesEmpty - all non-empty`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.areQueuesEmpty(TestHelpers.setOf("q1")) assertIs false
@@ -703,7 +706,7 @@ class FastJobStorageTest {
@Test
fun `areQueuesEmpty - mixed empty`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.areQueuesEmpty(TestHelpers.setOf("q1", "q5")) assertIs false
@@ -711,27 +714,78 @@ class FastJobStorageTest {
@Test
fun `areQueuesEmpty - queue does not exist`() {
val subject = FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS))
val subject = FastJobStorage(mockDatabase(DataSet1.FULL_SPECS))
subject.init()
subject.areQueuesEmpty(TestHelpers.setOf("q4")) assertIs true
subject.areQueuesEmpty(TestHelpers.setOf("q4", "q5")) assertIs true
}
private fun noopDatabase(): JobDatabase {
val database = Mockito.mock(JobDatabase::class.java)
Mockito.`when`(database.getAllJobSpecs()).thenReturn(emptyList())
Mockito.`when`(database.getAllConstraintSpecs()).thenReturn(emptyList())
Mockito.`when`(database.getAllDependencySpecs()).thenReturn(emptyList())
return database
}
private fun mockDatabase(fullSpecs: List<FullSpec> = emptyList()): JobDatabase {
val jobs = fullSpecs.map { it.jobSpec }.toMutableList()
val constraints = fullSpecs.map { it.constraintSpecs }.flatten().toMutableList()
val dependencies = fullSpecs.map { it.dependencySpecs }.flatten().toMutableList()
private fun fixedDataDatabase(fullSpecs: List<FullSpec>): JobDatabase {
val database = Mockito.mock(JobDatabase::class.java)
Mockito.`when`(database.getAllJobSpecs()).thenReturn(fullSpecs.map { it.jobSpec })
Mockito.`when`(database.getAllConstraintSpecs()).thenReturn(fullSpecs.map { it.constraintSpecs }.flatten())
Mockito.`when`(database.getAllDependencySpecs()).thenReturn(fullSpecs.map { it.dependencySpecs }.flatten())
return database
val mock = mockk<JobDatabase>(relaxed = true)
every { mock.getAllJobSpecs() } returns jobs
every { mock.getAllMinimalJobSpecs() } returns jobs.map { it.toMinimalJobSpec() }
every { mock.getOldestJobSpecs(any()) } answers { jobs.sortedBy { it.createTime }.take(firstArg()) }
every { mock.getAllConstraintSpecs() } returns constraints
every { mock.getAllDependencySpecs() } returns dependencies
every { mock.getJobSpec(any()) } answers { jobs.first { it.id == firstArg() } }
every { mock.insertJobs(any()) } answers {
val inserts: List<FullSpec> = firstArg()
for (insert in inserts) {
jobs += insert.jobSpec
constraints += insert.constraintSpecs
dependencies += insert.dependencySpecs
}
}
every { mock.deleteJobs(any()) } answers {
val ids: List<String> = firstArg()
jobs.removeIf { ids.contains(it.id) }
constraints.removeIf { ids.contains(it.jobSpecId) }
dependencies.removeIf { ids.contains(it.jobId) || ids.contains(it.dependsOnJobId) }
}
every { mock.updateJobs(any()) } answers {
val updates: List<JobSpec> = firstArg()
for (update in updates) {
jobs.removeIf { it.id == update.id }
jobs += update
}
}
every { mock.updateAllJobsToBePending() } answers {
val iterator = jobs.listIterator()
while (iterator.hasNext()) {
val job = iterator.next()
iterator.set(job.copy(isRunning = false))
}
}
every { mock.updateJobAfterRetry(any(), any(), any(), any(), any()) } answers {
val id = args[0] as String
val currentTime = args[1] as Long
val runAttempt = args[2] as Int
val nextBackoffInterval = args[3] as Long
val serializedData = args[4] as ByteArray?
val iterator = jobs.listIterator()
while (iterator.hasNext()) {
val job = iterator.next()
if (job.id == id) {
iterator.set(
job.copy(
isRunning = false,
runAttempt = runAttempt,
lastRunAttemptTime = currentTime,
nextBackoffInterval = nextBackoffInterval,
serializedData = serializedData
)
)
}
}
}
return mock
}
private fun jobSpec(