JetBrains / lincheck

Framework for testing concurrent data structures
Mozilla Public License 2.0
579 stars 34 forks source link

Provide a DSL to declare algorithms #359

Closed CLOVIS-AI closed 1 month ago

CLOVIS-AI commented 2 months ago

Instead of writing

class CounterTest {
    private val c = Counter() // Initial state

    // Operations on the Counter
    @Operation
    fun inc() = c.inc()

    @Operation
    fun get() = c.get()

    @Test // Run the test
    fun stressTest() = StressOptions().check(this::class)
}

I would prefer to write

val model = lincheckModel {
    private val c = Counter() // Initial state

    operation("inc") {
        c.inc()
    }

    operation("get") {
        c.get()
    }
}

class CounterTest {
    @Test // Run the test
    fun stressTest() = StressOptions().check(model)
}

(or a similar DSL).

The usage of a DSL would:


My main use-case is that I have multiple cache algorithms. They all have a common interface, and all have the exact same operations. I want to test all of them with Lincheck. With this DSL implemented, and using a DSL-based test framework (Prepared in this example):

fun SuiteDsl.lincheck(algorithm: Prepared<Cache<Int, Int>>) {
    val model by prepared {
        val algorithm = algorithm()
        lincheckModel {
            operation("get") { it: Int -> algorithm[it] }
            operation("expire") { it: Int -> algorithm.expire(it) }
            operation("clear") { algorithm.clear() }
        }
    }

    test("Stress testing") {
        StressOptions().check(model())
    }

    test("Model checking") {
        ModelCheckingOptions().check(model())
    }
}

Currently, without this feature, the only way is to duplicate the entire test class for each implementation.

ndkoval commented 2 months ago

Hi @CLOVIS-AI! Thanks for raising this issue. We are now working on a new API for Lincheck.

Meanwhile, I would suggest leveraging inheritance to avoid code duplication -- take a look at how we test different channels in Kotlin coroutines: https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/lincheck/ChannelsLincheckTest.kt#L18

CLOVIS-AI commented 2 months ago

Thanks. Is there a place to follow the work on the new API? I'd like to follow development, if possible.

ndkoval commented 1 month ago

@CLOVIS-AI, we will create an issue with the API design when we have a preliminary version.