Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package at.bitfire.ical4android
import android.content.ContentValues
import android.net.Uri
import android.provider.CalendarContract.Attendees
import at.bitfire.synctools.storage.BatchOperation
import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.parameter.CuType
import net.fortuna.ical4j.model.parameter.Role
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import android.net.Uri
import at.bitfire.ical4android.impl.TestTask
import at.bitfire.ical4android.impl.TestTaskList
import at.bitfire.ical4android.util.DateUtils
import at.bitfire.synctools.LocalStorageException
import at.bitfire.synctools.storage.LocalStorageException
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.DateList
import net.fortuna.ical4j.model.DateTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import android.provider.CalendarContract.Events
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidEvent
import at.bitfire.ical4android.AndroidEventFactory
import at.bitfire.ical4android.BatchOperation
import at.bitfire.ical4android.Event
import at.bitfire.synctools.storage.BatchOperation
import java.util.UUID

class TestEvent: AndroidEvent {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of bitfireAT/synctools which is released under GPLv3.
* Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details.
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package at.bitfire.synctools.storage

import android.content.ContentProviderClient
import android.os.TransactionTooLargeException
import androidx.core.net.toUri
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.Test

class BatchOperationTest {

@Test
fun testSplitLargeTransaction() {
val provider = mockk<ContentProviderClient>(relaxed = true)

val maxSize = 100
every { provider.applyBatch(match { it.size > maxSize }) } throws TransactionTooLargeException()

val batch = BatchOperation(provider, null)
repeat(4*maxSize) {
batch += BatchOperation.CpoBuilder.newInsert("test://".toUri())
}
batch.commit()

// one too large batch (with 400 operations) +
// then two still too large batches with 200 operations each +
// then four batches with 100 operations each
verify(exactly = 7) { provider.applyBatch(any()) }
}

@Test(expected = LocalStorageException::class)
fun testSplitLargeTransaction_OneTooBigRow() {
val provider = mockk<ContentProviderClient>()

every { provider.applyBatch(any()) } throws TransactionTooLargeException()

val batch = BatchOperation(provider, null)
batch += BatchOperation.CpoBuilder.newInsert("test://".toUri())
batch.commit()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* This file is part of bitfireAT/synctools which is released under GPLv3.
* Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details.
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package at.bitfire.synctools.storage

import android.Manifest
import android.accounts.Account
import android.content.ContentProviderClient
import android.provider.CalendarContract
import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.util.MiscUtils.asSyncAdapter
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class CalendarBatchOperationTest {

@get:Rule
val permissionRule = GrantPermissionRule.grant(
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR
)

private val testAccount = Account(javaClass.name, CalendarContract.ACCOUNT_TYPE_LOCAL)

lateinit var provider: ContentProviderClient

@Before
fun setUp() {
provider = InstrumentationRegistry.getInstrumentation().targetContext.contentResolver
.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
}

@After
fun tearDown() {
// delete all events in test account
provider.delete(
Events.CONTENT_URI,
"${Events.ACCOUNT_TYPE}=? AND ${Events.ACCOUNT_NAME}=?",
arrayOf(testAccount.type, testAccount.name)
)
provider.closeCompat()
}


@Test
fun testCalendarProvider_OperationsPerYieldPoint_501() {
val batch = CalendarBatchOperation(provider)

// 501 operations should succeed with CalendarBatchOperation
repeat(501) { idx ->
batch += BatchOperation.CpoBuilder.newInsert(Events.CONTENT_URI.asSyncAdapter(testAccount))
.withValue(Events.TITLE, "Event $idx")
}
batch.commit()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* This file is part of bitfireAT/synctools which is released under GPLv3.
* Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details.
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package at.bitfire.synctools.storage

import android.Manifest
import android.accounts.Account
import android.content.ContentProviderClient
import android.provider.ContactsContract
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class ContactsBatchOperationTest {

@get:Rule
val permissionRule = GrantPermissionRule.grant(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
)

private val testAccount = Account(javaClass.name, javaClass.packageName)

lateinit var provider: ContentProviderClient

@Before
fun setUp() {
provider = InstrumentationRegistry.getInstrumentation().targetContext.contentResolver
.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
}

@After
fun tearDown() {
// delete all contacts in test account
provider.delete(
ContactsContract.RawContacts.CONTENT_URI,
"${ContactsContract.RawContacts.ACCOUNT_TYPE}=? AND ${ContactsContract.RawContacts.ACCOUNT_NAME}=?",
arrayOf(testAccount.type, testAccount.name)
)
provider.closeCompat()
}


@Test(expected = LocalStorageException::class)
fun testContactsProvider_OperationsPerYieldPoint_500_WithoutMax() {
val batch = BatchOperation(provider, maxOperationsPerYieldPoint = null)

// 500 operations should fail with BatchOperation(maxOperationsPerYieldPoint = null) (max. 499)
repeat(500) { idx ->
batch += BatchOperation.CpoBuilder.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, testAccount.type)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, testAccount.name)
}
batch.commit()
}

@Test
fun testContactsProvider_OperationsPerYieldPoint_501() {
val batch = ContactsBatchOperation(provider)

// 501 operations should succeed with ContactsBatchOperation
repeat(501) { idx ->
batch += BatchOperation.CpoBuilder.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, testAccount.type)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, testAccount.name)
}
batch.commit()
}

}
Loading