{"id":25776820,"url":"https://github.com/JetBrains/lincheck","last_synced_at":"2025-02-27T06:06:57.638Z","repository":{"id":38132382,"uuid":"194697638","full_name":"JetBrains/lincheck","owner":"JetBrains","description":"Framework for testing concurrent data structures","archived":false,"fork":false,"pushed_at":"2025-02-21T23:31:29.000Z","size":10423,"stargazers_count":596,"open_issues_count":137,"forks_count":34,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-02-22T05:08:28.004Z","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}},"created_at":"2019-07-01T15:19:34.000Z","updated_at":"2025-02-18T21:03:17.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":43,"template":false,"template_full_name":null,"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","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240987435,"owners_count":19889335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2025-02-27T06:06:57.623Z","avatar_url":"https://github.com/JetBrains.png","language":"Kotlin","funding_links":[],"categories":["测试"],"sub_categories":[],"readme":"# Lincheck\n\n[![Kotlin Beta](https://kotl.in/badges/beta.svg)](https://kotlinlang.org/docs/components-stability.html)\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 testing concurrent algorithms on the JVM. It provides a simple\nand declarative way to write concurrent tests.\n\nWith the Lincheck framework, instead of describing how to perform tests, you can specify _what to test_\nby just declaring all the data structure operations to examine. After that, Lincheck automatically \ngenerates 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## 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## Using in Your Project\n\nTo use Lincheck in your project, you 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.kotlinx:lincheck:2.36\")\n}\n```\n\n## Example \n\nThe following Lincheck test easily finds a bug in the standard Java's `ConcurrentLinkedDeque`:\n\n```kotlin\nimport org.jetbrains.kotlinx.lincheck.*\nimport org.jetbrains.kotlinx.lincheck.annotations.*\nimport org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.*\nimport org.junit.*\nimport java.util.concurrent.*\n\nclass ConcurrentDequeTest {\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 not only detects a bug but also provides a comprehensive interleaving trace that explains it:\n\n```text\n= Invalid execution results =\n| -------------------------------------- |\n|     Thread 1     |      Thread 2       |\n| -------------------------------------- |\n| addLast(4): void |                     |\n| -------------------------------------- |\n| pollFirst(): 4   | addFirst(-4): void  |\n|                  | peekLast(): 4 [-,1] |\n| -------------------------------------- |\n\n---\nAll operations above the horizontal line | ----- | happen before those below the line\n---\nValues in \"[..]\" brackets indicate the number of completed operations\nin each of the parallel threads seen at the beginning of the current operation\n---\n\nThe following interleaving leads to the error:\n| addLast(4): void                                                                                          |                      |\n| pollFirst()                                                                                               |                      |\n|   pollFirst(): 4 at ConcurrentLinkedDequeTest.pollFirst(ConcurrentLinkedDequeTest.kt:29)                  |                      |\n|     first(): Node@1 at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:915)                    |                      |\n|     item.READ: null at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:917)                    |                      |\n|     next.READ: Node@2 at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:925)                  |                      |\n|     item.READ: 4 at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:917)                       |                      |\n|     prev.READ: null at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:919)                    |                      |\n|     switch                                                                                                |                      |\n|                                                                                                           | addFirst(-4): void   |\n|                                                                                                           | peekLast(): 4        |\n|     compareAndSet(Node@2,4,null): true at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:920) |                      |\n|     unlink(Node@2) at ConcurrentLinkedDeque.pollFirst(ConcurrentLinkedDeque.java:921)                     |                      |\n|   result: 4                                                                                               |                      |\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"}