Skip to content

引數產生約束

為了測試並行資料結構,Lincheck 會將操作隨機放置在不同的執行緒中,並使用隨機引數呼叫它們,藉此產生一組並行情境。

您可以約束操作引數的範圍,以增加發現並行錯誤的機會。例如,如果可能的主鍵值範圍受到限制,hash map 中的並行操作就更有可能存取同一個鍵。這使 Lincheck 能夠更有效地揭示競態條件和其他並行錯誤。

若要限制 Lincheck 中產生的引數值範圍:

  1. 使用 @Param 註解來宣告引數產生器:

    kotlin
    @Param(name = "key", gen = IntGen::class, conf = "1:2")
    class MultiMapTest {
        // 測試
    }
    • name – 引數產生器的名稱。
    • gen – 產生器的型別
    • conf – 產生器的配置字串。在此,Lincheck 會產生 1 到 2 之間的整數值。

    Lincheck 為多種值型別提供了產生器。每種型別都使用不同的配置字串範本。

    請參閱產生器型別章節以進一步了解。

  2. 為操作參數加上 @Param 註解以套用約束:

    kotlin
    @Operation
    fun add(@Param(name = "key") key: Int, value: Int) = map.add(key, value)
    
    @Operation
    fun get(@Param(name = "key") key: Int) = map.get(key)

設定好約束後,Lincheck 產生的情境將僅使用指定範圍內的值:

text
| ---------------------------------- |
|    Thread 1     |     Thread 2     |
| ---------------------------------- |
| add(2, 0): void | add(2, -1): void |
| ---------------------------------- |
| get(2): [-1]    |                  |
| ---------------------------------- |

產生器型別

Lincheck 提供以下引數產生器型別:

產生器配置範本說明
IntGen"min:max"產生介於 minmax 之間(含)的 Int 值。

如果配置字串為空,則使用從 Int.MIN_VALUEInt.MAX_VALUE 的完整整數範圍。

範例: "1:3" -> [1, 2, 3]
StringGen"maxWordLength:alphabet"
"maxWordLength"
""
從提供的 alphabet 中產生長度最高為 maxWordLength 的隨機字串值。 預設 alphabet[a-zA-Z\d _]
預設 maxWordLength15

範例:
text
EnumGen"Enum.Const1,Enum.Const2,..."從指定的列舉值清單中產生隨機值。

範例:
text
BooleanGen""產生 truefalse 值。不需要特定的配置字串。

範例: "" -> [true, false]
DoubleGen"start:step:end"
"start:end"
""
產生從 startendDouble 值,並以 step 遞增。

預設 step 值為 (end - start)/100

如果配置字串為空,則產生從 Int.MIN_VALUEInt.MAX_VALUEstep = 0.1 的值。

範例: "0.0:0.1:1.0" -> [0.0, 0.1, 0.2, ..., 0.9, 1.0]
FloatGen"start:step:end"
"start:end"
""
DoubleGen 相同,但值會轉換為 Float

範例: "0.0:0.1:1.0" -> [0.0, 0.1, 0.2, ..., 0.9, 1.0]
LongGen"min:max"IntGen 相同,但值會轉換為 Long

範例: "1:3" -> [1, 2, 3]
ShortGen"min:max"產生介於 minmax 之間(含)的 Short 值。

如果配置字串為空,則使用從 -3276832767 的完整短整數範圍。

範例: "1:3" -> [1, 2, 3]
ByteGen"min:max"產生介於 minmax 之間(含)的 Byte 值。

如果配置字串為空,則使用從 -128127 的完整位元組範圍。

範例: "1:3" -> [1, 2, 3]
ThreadIdGen""回傳目前執行緒的 ID 編號。不需要特定的配置字串。

範例: "" -> [1, 2]

下一步

了解如何在 Lincheck 中將特定操作限制在單一執行緒

另請參閱