diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-01-17 13:16:29 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-02-19 11:54:01 +0000 |
| commit | 8cb16e665dbb5f87aa58856049c1ad6067dc6293 (patch) | |
| tree | cb8eacf9619ce1ea3df3aa5891cf6ab44ebf83b8 /prog/expr_test.go | |
| parent | 0936819b9f980bde731cb6191677f9aa2cbfd9aa (diff) | |
prog: handle multiple matching union fields
If conditions of several union fields are satisfied, select one
randomly. This would be a more logical semantics.
When conditional struct fields are translated to unions, negate the
condition for the union alternative.
Diffstat (limited to 'prog/expr_test.go')
| -rw-r--r-- | prog/expr_test.go | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/prog/expr_test.go b/prog/expr_test.go index 69bd790db..f6c8c8603 100644 --- a/prog/expr_test.go +++ b/prog/expr_test.go @@ -90,10 +90,11 @@ func TestEvaluateConditionalFields(t *testing.T) { `test$parent_conditions(&AUTO={0x2, @with_flag1=0x123, {0x0, @void}})`, `test$parent_conditions(&AUTO={0x4, @without_flag1=0x123, {0x0, @value=0x0}})`, `test$parent_conditions(&AUTO={0x6, @with_flag1=0x123, {0x0, @value=0x0}})`, + // The @without_flag1 option is still possible. + `test$parent_conditions(&AUTO={0x2, @without_flag1=0x123, {0x0, @void}})`, }, bad: []string{ `test$parent_conditions(&AUTO={0x0, @with_flag1=0x123, {0x0, @void}})`, - `test$parent_conditions(&AUTO={0x2, @without_flag1=0x123, {0x0, @void}})`, `test$parent_conditions(&AUTO={0x4, @with_flag1=0x123, {0x0, @void}})`, `test$parent_conditions(&AUTO={0x4, @with_flag1=0x123, {0x0, @value=0x0}})`, }, @@ -108,7 +109,8 @@ func TestEvaluateConditionalFields(t *testing.T) { } for _, bad := range test.bad { _, err := target.Deserialize([]byte(bad), Strict) - assert.ErrorIs(tt, err, ErrViolatedConditions) + assert.ErrorIs(tt, err, ErrViolatedConditions, + "prog: %s", bad) } }) } @@ -224,3 +226,37 @@ func parseConditionalStructCall(t *testing.T, c *Call) (bool, bool) { assert.Equal(t, mask&FLAG2 != 0, f2, "flag2 must only be set if mask&FLAG2") return f1, f2 } + +func TestConditionalUnionFields(t *testing.T) { + // Ensure that we reach different combinations of conditional fields. + target, rs, _ := initRandomTargetTest(t, "test", "64") + ct := target.DefaultChoiceTable() + r := newRand(target, rs) + + var zeroU1, zeroU2 int + var nonzeroU2 int + for i := 0; i < 100; i++ { + s := newState(target, ct, nil) + p := &Prog{ + Target: target, + Calls: r.generateParticularCall(s, target.SyscallMap["test$conditional_union"]), + } + if len(p.Calls) > 1 { + continue + } + text := string(p.SerializeVerbose()) + if strings.Contains(text, "{0x0,") { + if strings.Contains(text, "@u1") { + zeroU1++ + } else if strings.Contains(text, "@u2") { + zeroU2++ + } + } else { + assert.NotContains(t, text, "@u1") + nonzeroU2++ + } + } + assert.Greater(t, zeroU1, 0) + assert.Greater(t, zeroU2, 0) + assert.Greater(t, nonzeroU2, 0) +} |
