aboutsummaryrefslogtreecommitdiffstats
path: root/prog/resources_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-01-04 16:59:51 +0100
committerDmitry Vyukov <dvyukov@google.com>2022-01-11 16:30:08 +0100
commit3f590eebf929ad4443e80dc9fae1f86500b1857c (patch)
tree3f840d0926dae7d4e22c1d2409a9d4a3b48d2ecf /prog/resources_test.go
parent4180aae2ad95a5f5c3bb20660f87f80c7d8c595b (diff)
prog: refactor generation of resources
Currnetly we loop up to 1000 times in randGen.createResource, this is necessary because we can't guarantee that the generated syscall will indeed contain the necessary resources. This is ugly. Now that we have stricter constructors (no unions) with few additional tweaks we can guarantee that we generate the resource every time. Generate at least 1 array element when in createResource. Don't generate special empty pointers when in createResource. Record only resource constructors in Syscall.outputResource, this makes rotation logic to include at least 1 of them.
Diffstat (limited to 'prog/resources_test.go')
-rw-r--r--prog/resources_test.go48
1 files changed, 48 insertions, 0 deletions
diff --git a/prog/resources_test.go b/prog/resources_test.go
index b041bf8e9..e48efa65c 100644
--- a/prog/resources_test.go
+++ b/prog/resources_test.go
@@ -4,6 +4,7 @@
package prog
import (
+ "math/rand"
"strings"
"testing"
@@ -115,3 +116,50 @@ func TestClockGettime(t *testing.T) {
len(calls), len(trans), len(disabled))
}
}
+
+func TestCreateResourceRotation(t *testing.T) {
+ target, rs, _ := initTest(t)
+ allCalls := make(map[*Syscall]bool)
+ for _, call := range target.Syscalls {
+ allCalls[call] = true
+ }
+ rotator := MakeRotator(target, allCalls, rand.New(rs))
+ testCreateResource(t, target, rotator.Select(), rs)
+}
+
+func TestCreateResourceHalf(t *testing.T) {
+ target, rs, _ := initTest(t)
+ r := rand.New(rs)
+ var halfCalls map[*Syscall]bool
+ for len(halfCalls) == 0 {
+ halfCalls = make(map[*Syscall]bool)
+ for _, call := range target.Syscalls {
+ if r.Intn(10) == 0 {
+ halfCalls[call] = true
+ }
+ }
+ halfCalls, _ = target.TransitivelyEnabledCalls(halfCalls)
+ }
+ testCreateResource(t, target, halfCalls, rs)
+}
+
+func testCreateResource(t *testing.T, target *Target, calls map[*Syscall]bool, rs rand.Source) {
+ r := newRand(target, rs)
+ r.inGenerateResource = true
+ ct := target.BuildChoiceTable(nil, calls)
+ for call := range calls {
+ t.Logf("testing call %v", call.Name)
+ ForeachCallType(call, func(typ Type, ctx *TypeCtx) {
+ if res, ok := typ.(*ResourceType); ok && ctx.Dir != DirOut {
+ s := newState(target, ct, nil)
+ arg, calls := r.createResource(s, res, DirIn)
+ if arg == nil && !res.Optional() {
+ t.Fatalf("failed to create resource %v", res.Name())
+ }
+ if arg != nil && len(calls) == 0 {
+ t.Fatalf("created resource %v, but got no calls", res.Name())
+ }
+ }
+ })
+ }
+}