{"id":25776820,"url":"https://github.com/JetBrains/lincheck","last_synced_at":"2026-08-13T13:30:15.608Z","repository":{"id":38132382,"uuid":"194697638","full_name":"JetBrains/lincheck","owner":"JetBrains","description":"Framework for testing concurrent code on JVM languages","archived":false,"fork":false,"pushed_at":"2026-08-06T09:38:40.000Z","size":20174,"stargazers_count":685,"open_issues_count":99,"forks_count":43,"subscribers_count":26,"default_branch":"master","last_synced_at":"2026-08-07T07:50:05.644Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JetBrains.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-07-01T15:19:34.000Z","updated_at":"2026-08-01T23:39:36.000Z","dependencies_parsed_at":"2023-12-18T16:57:25.454Z","dependency_job_id":"7cb02b80-c5fc-4284-9b58-5c0eb41f6a07","html_url":"https://github.com/JetBrains/lincheck","commit_stats":{"total_commits":322,"total_committers":20,"mean_commits":16.1,"dds":0.422360248447205,"last_synced_commit":"800f590ef453c3eab5c87b7264c29e580060cec4"},"previous_names":["kotlin/kotlinx-lincheck"],"tags_count":74,"template":false,"template_full_name":null,"purl":"pkg:github/JetBrains/lincheck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Flincheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Flincheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Flincheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Flincheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JetBrains","download_url":"https://codeload.github.com/JetBrains/lincheck/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Flincheck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36610019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-08-06T04:43:03.162Z","status":"online","status_checked_at":"2026-08-13T02:00:06.325Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-27T06:01:31.729Z","updated_at":"2026-08-13T13:30:15.600Z","avatar_url":"https://github.com/JetBrains.png","language":"Kotlin","funding_links":[],"categories":["测试"],"sub_categories":[],"readme":"# Lincheck\n\n[![JetBrains official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)\n[![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0)\n\nLincheck is a practical and user-friendly framework for writing deterministic and robust concurrent tests on JVM. \nWhen detecting an error, \nLincheck provides a reproducible execution trace an ability to debug it step-by-step in IntelliJ IDEA.\n\n\u003e **⚠️ Lincheck 3.0 Changes️:** \n\u003e * Lincheck now focuses on testing arbitrary concurrent code \n    still providing declarative API for testing concurrent data structures\n\u003e * The API has been moved from `org.jetbrains.kotlinx.lincheck` to `org.jetbrains.lincheck`\n\u003e * The artifact is now published to Maven Central under the `org.jetbrains.lincheck` group ID\n\n## Quick Start\n\n### 1. Add Lincheck dependency\nTo use Lincheck in your project, you first need to add it as a dependency. If you use Gradle, add the following lines to `build.gradle.kts`:\n\n```kotlin\nrepositories {\n   mavenCentral()\n}\n\ndependencies {\n   // Lincheck dependency\n   testImplementation(\"org.jetbrains.lincheck:lincheck:3.7\")\n}\n```\n\n### 2. Write your first Lincheck test\n\nTo write a Lincheck test,\nyou need to wrap your concurrent logic with the `Lincheck.runConcurrentTest { ... }` function.\nLincheck will automatically study different thread interleavings and report an error\nif one leads to a test failure.\n\nAs an example, see the Lincheck test for a counter:\n\n```kotlin\n@Test // JUnit test\nfun test() = Lincheck.runConcurrentTest {\n    var counter = 0\n    // Increment the counter concurrently\n    val t1 = thread { counter++ }\n    val t2 = thread { counter++ }\n    // Wait for the threads to finish\n    t1.join()\n    t2.join()\n    // Check both increments have been applied\n    assertEquals(2, counter)\n}\n```\n\n### 3. Run the test\n\nIf you run the counter test above, it finishes with an error,\nwith Lincheck providing a step-by-step execution trace to reproduce it.\n\n```\nAssertionFailedError: expected:\u003c2\u003e but was:\u003c1\u003e\n\nThe following interleaving leads to the error:\n| ------------------------------------------------------------------------------- |\n|                   Main Thread                   |   Thread 1    |   Thread 2    |\n| ------------------------------------------------------------------------------- |\n| thread(block = Lambda#1): Thread#1              |               |               |\n| thread(block = Lambda#2): Thread#2              |               |               |\n| switch (reason: waiting for Thread 1 to finish) |               |               |\n|                                                 |               | run()         |\n|                                                 |               |   counter ➜ 0 |\n|                                                 |               |   switch      |\n|                                                 | run()         |               |\n|                                                 |   counter ➜ 0 |               |\n|                                                 |   counter = 1 |               |\n|                                                 |               |   counter = 1 |\n| Thread#1.join()                                 |               |               |\n| Thread#2.join()                                 |               |               |\n| ------------------------------------------------------------------------------- |\n```\n\n## Data Structures Testing\n\nLincheck provides a special API to simplify testing concurrent data structures. \nInstead of describing how to perform tests, you can specify _what to test_\nby just declaring all the data structure operations to examine.\nAfter that, Lincheck automatically generates a set of random concurrent scenarios,\nexamines them using either stress-testing or bounded model checking, and\nverifies that the results of each invocation satisfy the required correctness property (linearizability by default).\n\n\n### Example \n\nThe following Lincheck test easily finds a bug in the standard Java's `ConcurrentLinkedDeque`:\n\n```kotlin\nclass ConcurrentLinkedDequeTest {\n    private val deque = ConcurrentLinkedDeque\u003cInt\u003e()\n\n    @Operation\n    fun addFirst(e: Int) = deque.addFirst(e)\n\n    @Operation\n    fun addLast(e: Int) = deque.addLast(e)\n\n    @Operation\n    fun pollFirst() = deque.pollFirst()\n\n    @Operation\n    fun pollLast() = deque.pollLast()\n\n    @Operation\n    fun peekFirst() = deque.peekFirst()\n\n    @Operation\n    fun peekLast() = deque.peekLast()\n\n    // Run Lincheck in the stress testing mode\n    @Test\n    fun stressTest() = StressOptions().check(this::class)\n\n    // Run Lincheck in the model checking testing mode\n    @Test\n    fun modelCheckingTest() = ModelCheckingOptions().check(this::class)\n}\n```\n\nWhen running `modelCheckingTest(),` Lincheck provides a short concurrent scenario \nthat discovers the bug with a detailed execution trace to reproduce it.\n\n```text\n= Invalid execution results =\n| ------------------------------ |\n|    Thread 1    |    Thread 2   |\n| ------------------------------ |\n| addLast(1)     |               |\n| ------------------------------ |\n| pollFirst(): 1 | addFirst(0):  |\n|                | peekLast(): 1 |\n| ------------------------------ |\n\n---\nAll operations above the horizontal line | ----- | happen before those below the line\n---\n\nThe following interleaving leads to the error:\n| ------------------------------------------------------- |\n|                Thread 1                 |   Thread 2    |\n| ------------------------------------------------------- |\n| addLast(1)                              |               |\n| ------------------------------------------------------- |\n| pollFirst(): 1                          |               |\n|   deque.pollFirst(): 1                  |               |\n|     first(): Node#2                     |               |\n|     p.item ➜ null                       |               |\n|     p.next ➜ Node#1                     |               |\n|     p.item ➜ 1                          |               |\n|     first.prev ➜ null                   |               |\n|     switch                              |               |\n|                                         | addFirst(0)   |\n|                                         | peekLast(): 1 |\n|     p.item.compareAndSet(1, null): true |               |\n|     unlink(Node#1)                      |               |\n|   result: 1                             |               |\n| ------------------------------------------------------- |\n```\n\n## Documentation and Presentations\n\nPlease see the [official tutorial](https://kotlinlang.org/docs/lincheck-guide.html) that showcases Lincheck features through examples.\n\nYou may also be interested in the following resources:\n\n* [\"Lincheck: A Practical Framework for Testing Concurrent Data Structures on JVM\"](https://link.springer.com/content/pdf/10.1007/978-3-031-37706-8_8.pdf?pdf=inline%20link) paper by N. Koval, A. Fedorov, M. Sokolova, D. Tsitelov, and D. Alistarh published at CAV '23.\n* [\"How we test concurrent algorithms in Kotlin Coroutines\"](https://youtu.be/jZqkWfa11Js) talk by Nikita Koval at KotlinConf '23.\n* \"Lincheck: Testing concurrency on the JVM\" workshop ([Part 1](https://www.youtube.com/watch?v=YNtUK9GK4pA), [Part 2](https://www.youtube.com/watch?v=EW7mkAOErWw)) by Maria Sokolova at Hydra '21.\n\n\n## Contributing \n\nSee [Contributing Guidelines](CONTRIBUTING.md).\n\n## Acknowledgements\n\nThis is a fork of the [Lin-Check framework](https://github.com/Devexperts/lin-check) by Devexperts.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJetBrains%2Flincheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJetBrains%2Flincheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJetBrains%2Flincheck/lists"}