Skip to content

Commit

Permalink
asim: add zone config satisfiability check
Browse files Browse the repository at this point in the history
Now that we have added the option to generate random span configurations in
cockroachdb#110967, we want to have a way to check whether these configurations are
satisfiable with the cluster setting.

This patch adds the validation check. Please note that the validation process can
be expensive with a time complexity of O(max(node count in the cluster, number of
replica constraints, number of voter constraints)). To perform this validation
and see which span config could lead to failure, please use following command:

```
"eval" [verbose=validate]
```

See also: cockroachdb#110967
Part of: cockroachdb#106192
Release Note: none
Epic: none
  • Loading branch information
wenyihu6 committed Aug 18, 2024
1 parent 4823020 commit 1bbd967
Show file tree
Hide file tree
Showing 14 changed files with 1,210 additions and 50 deletions.
3 changes: 3 additions & 0 deletions pkg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ ALL_TESTS = [
"//pkg/kv/kvserver/asim/state:state_test",
"//pkg/kv/kvserver/asim/storerebalancer:storerebalancer_test",
"//pkg/kv/kvserver/asim/tests:tests_test",
"//pkg/kv/kvserver/asim/validator:validator_test",
"//pkg/kv/kvserver/asim/workload:workload_test",
"//pkg/kv/kvserver/asim:asim_test",
"//pkg/kv/kvserver/batcheval/result:result_test",
Expand Down Expand Up @@ -1412,6 +1413,8 @@ GO_TARGETS = [
"//pkg/kv/kvserver/asim/storerebalancer:storerebalancer_test",
"//pkg/kv/kvserver/asim/tests:tests",
"//pkg/kv/kvserver/asim/tests:tests_test",
"//pkg/kv/kvserver/asim/validator:validator",
"//pkg/kv/kvserver/asim/validator:validator_test",
"//pkg/kv/kvserver/asim/workload:workload",
"//pkg/kv/kvserver/asim/workload:workload_test",
"//pkg/kv/kvserver/asim:asim",
Expand Down
7 changes: 7 additions & 0 deletions pkg/kv/kvserver/asim/scheduled/scheduled_event_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type EventExecutor interface {
// events including details of mutation events, assertion checks, and assertion
// results.
PrintEventsExecuted() string
// ScheduledEvents returns the list of scheduled events.
ScheduledEvents() ScheduledEventList
}

// eventExecutor is the private implementation of the EventExecutor interface,
Expand Down Expand Up @@ -71,6 +73,11 @@ func newExecutorWithNoEvents() *eventExecutor {
}
}

// ScheduledEvents returns the list of scheduled events.
func (e *eventExecutor) ScheduledEvents() ScheduledEventList {
return e.scheduledEvents
}

// PrintEventSummary returns a string summarizing the executed mutation and
// assertion events.
func (e *eventExecutor) PrintEventSummary() string {
Expand Down
1 change: 1 addition & 0 deletions pkg/kv/kvserver/asim/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ go_library(
"//pkg/kv/kvserver/asim/history",
"//pkg/kv/kvserver/asim/scheduled",
"//pkg/kv/kvserver/asim/state",
"//pkg/kv/kvserver/asim/validator",
"//pkg/roachpb",
"//pkg/sql",
"//pkg/sql/catalog/catpb",
Expand Down
12 changes: 10 additions & 2 deletions pkg/kv/kvserver/asim/tests/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/gen"
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/history"
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/scheduled"
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/state"
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/asim/validator"
)

// OutputFlags sets flags for what to output in tests. If you want to add a flag
Expand All @@ -39,15 +41,18 @@ const (
OutputTopology // 1 << 3: 0000 1000
// OutputEvents displays delayed events executed.
OutputEvents // 1 << 4: 0001 0000
// OutputValidationResult displays validation result of whether any events are
// expected to lead to assertion failure.
OutputValidationResult // 1 << 5: 0010 0000
// OutputAll shows everything above.
OutputAll = (1 << (iota - 1)) - 1 // (1 << 5) - 1: 0001 1111
OutputAll = (1 << (iota - 1)) - 1 // (1 << 6) - 1: 0011 1111
)

// ScanFlags converts an array of input strings into a single flag.
func (o OutputFlags) ScanFlags(inputs []string) OutputFlags {
dict := map[string]OutputFlags{"result_only": OutputResultOnly, "test_settings": OutputTestSettings,
"initial_state": OutputInitialState, "config_gen": OutputConfigGen, "topology": OutputTopology,
"events": OutputEvents, "all": OutputAll}
"events": OutputEvents, "validate": OutputValidationResult, "all": OutputAll}
flag := OutputResultOnly
for _, input := range inputs {
flag = flag.set(dict[input])
Expand Down Expand Up @@ -169,6 +174,9 @@ func (tr testResultsReport) String() string {
if failed || tr.flags.Has(OutputEvents) {
buf.WriteString(output.eventExecutor.PrintEventsExecuted())
}
if failed || tr.flags.Has(OutputValidationResult) {
buf.WriteString(validator.Validate(output.initialState, output.eventExecutor))
}
if failed {
buf.WriteString(fmt.Sprintf("sample%d: failed assertion\n%s\n", nthSample, output.reason))
} else {
Expand Down
3 changes: 2 additions & 1 deletion pkg/kv/kvserver/asim/tests/rand_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ func randomlySelectDataPlacement(randSource *rand.Rand) descpb.DataPlacement {
// intervals defined by durationToAssert from the start time. These events apply
// a randomly generated zone configuration followed by an assertion event. Note
// that these random configurations might be unsatisfiable under the cluster
// setup.
// setup. To validate whether the configurations generated are satisfiable,
// please use "eval" [verbose=validate].
func generateRandomSurvivalGoalsEvents(
regions []state.Region,
startTime time.Time,
Expand Down
3 changes: 2 additions & 1 deletion pkg/kv/kvserver/asim/tests/rand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ const (
// 4. sum of weights in the array should be equal to 1

// 3. "eval" [seed=<int64>] [num_iterations=<int>] [duration=<time.Duration>]
// [verbose=(<[]("result_only","test_settings","initial_state","config_gen","event","topology","all")>)]
// [verbose=(<[]("result_only","test_settings","initial_state","config_gen",
// "event","topology","validate","all")>)]
// e.g. eval seed=20 duration=30m2s verbose=(test_settings,initial_state)
// - eval: generates a simulation based on the configuration set with the given
// commands.
Expand Down
6 changes: 6 additions & 0 deletions pkg/kv/kvserver/asim/tests/testdata/rand/default_settings
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ AU_EAST
AU_EAST_1
└── [1 2 3]
no events were scheduled
validation result:
valid
sample1: pass
----------------------------------
sample2: start running
Expand All @@ -247,6 +249,8 @@ AU_EAST
AU_EAST_1
└── [1 2 3]
no events were scheduled
validation result:
valid
sample2: pass
----------------------------------
sample3: start running
Expand All @@ -262,6 +266,8 @@ AU_EAST
AU_EAST_1
└── [1 2 3]
no events were scheduled
validation result:
valid
sample3: pass
----------------------------------

Expand Down
6 changes: 6 additions & 0 deletions pkg/kv/kvserver/asim/tests/testdata/rand/rand_cluster
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ US_West
US_West_1
└── [17 18]
no events were scheduled
validation result:
valid
sample1: pass
----------------------------------
sample2: start running
Expand Down Expand Up @@ -125,6 +127,8 @@ US_West
US_West_3
└── [21 22 23 24]
no events were scheduled
validation result:
valid
sample2: pass
----------------------------------
sample3: start running
Expand Down Expand Up @@ -159,6 +163,8 @@ US_West
US_West_1
└── [17 18]
no events were scheduled
validation result:
valid
sample3: pass
----------------------------------

Expand Down
Loading

0 comments on commit 1bbd967

Please sign in to comment.