Обзор
Lincheck — это фреймворк для тестирования конкурентного кода на JVM. При запуске тестов Lincheck исследует возможные чередования потоков в программе и сообщает о тех из них, которые приводят к некорректному поведению.
Для теста конкурентности в Lincheck достаточно перечислить операции для каждого потока и ожидаемые утверждения. Остальное Lincheck сделает сам:
class CounterTest {
@Test // Test function declaration
fun test() = Lincheck.runConcurrentTest {
var counter = 0
// Increments the counter concurrently
val t1 = thread { counter++ }
val t2 = thread { counter++ }
// Waits for the threads to finish
t1.join()
t2.join()
// Checks that both increments have been applied
assertEquals(2, counter)
}
}
Если тест завершается с ошибкой, Lincheck показывает чередование потоков и точки переключения между потоками, которые привели к ошибке:
| ------------------------------------------------------------------------------- | | Main Thread | Thread 1 | Thread 2 | | ------------------------------------------------------------------------------- | | thread(block = Lambda#2): Thread#1 | | | | thread(block = Lambda#3): Thread#2 | | | | switch (reason: waiting for Thread 1 to finish) | | | | | | run() | | | | counter ➜ 0 | | | | switch | | | run() | | | | counter ➜ 0 | | | | counter = 1 | | | | | counter = 1 | | Thread#1.join() | | | | Thread#2.join() | | | | counter.element ➜ 1 | | | | assertEquals(2, 1): threw AssertionFailedError | | | | ------------------------------------------------------------------------------- |
Как работает Lincheck
Каждый раз, когда JVM выполняет конкурентный код, порядок выполнения операций в потоках может меняться. Например, выполнение операции может быть прервано другой операцией в другом потоке. Само по себе это не является ошибкой, но может привести к ней, если в коде есть ошибки конкурентного выполнения.
Lincheck реализует две стратегии тестирования для поиска расписаний выполнения, приводящих к некорректному поведению:
Проверка модели. Lincheck управляет планированием, вставляя в программу явные инструкции переключения потоков. Эти инструкции размещаются в точках синхронизации или при обращении к общей памяти. Проверка модели позволяет Lincheck сгенерировать точную трассу выполнения, приводящую к ошибке.
Стресс-тестирование. Планированием управляет операционная система. Lincheck выполняет каждый сценарий несколько раз, чтобы повысить вероятность обнаружения ошибки.
Изучите Lincheck
Изучите возможности Lincheck шаг за шагом в разделе Начало работы с Lincheck.
Узнайте о декларативном подходе к тестированию конкурентных структур данных в Lincheck.
Узнайте больше
«Как мы тестируем конкурентные алгоритмы в Kotlin Coroutines» — доклад Никиты Коваля: видео. KotlinConf 2023
Мастер-класс Марии Соколовой «Lincheck: тестирование конкурентности на JVM»: часть 1, часть 2. Hydra 2021
«Lincheck: практический фреймворк для тестирования конкурентных структур данных на JVM» — статья Никиты Коваля и др.: статья. 2023
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/lincheck-guide.html