aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/config/merge.go15
-rw-r--r--pkg/config/merge_test.go49
-rw-r--r--tools/syz-testbed/checkout.go6
-rw-r--r--tools/syz-testbed/instance.go17
-rw-r--r--tools/syz-testbed/testbed.go14
5 files changed, 77 insertions, 24 deletions
diff --git a/pkg/config/merge.go b/pkg/config/merge.go
index 49a7254de..3d8193c02 100644
--- a/pkg/config/merge.go
+++ b/pkg/config/merge.go
@@ -9,7 +9,7 @@ import (
// Unfortunately, if we want to apply a JSON patch to some configuration, we cannot just unmarshal
// it twice - in that case json.RawMessage objects will be completely replaced, but not merged.
-func MergeJSONData(left, right []byte) ([]byte, error) {
+func MergeJSONs(left, right []byte) ([]byte, error) {
vLeft, err := parseFragment(left)
if err != nil {
return nil, err
@@ -18,8 +18,17 @@ func MergeJSONData(left, right []byte) ([]byte, error) {
if err != nil {
return nil, err
}
- merged := mergeRecursive(vLeft, vRight)
- return json.Marshal(merged)
+ return json.Marshal(mergeRecursive(vLeft, vRight))
+}
+
+// Recursively apply a patch to a raw JSON data.
+// Patch is supposed to be a map, which possibly nests other map objects.
+func PatchJSON(left []byte, patch map[string]interface{}) ([]byte, error) {
+ vLeft, err := parseFragment(left)
+ if err != nil {
+ return nil, err
+ }
+ return json.Marshal(mergeRecursive(vLeft, patch))
}
func parseFragment(input []byte) (parsed interface{}, err error) {
diff --git a/pkg/config/merge_test.go b/pkg/config/merge_test.go
index c5a45754e..6785534f1 100644
--- a/pkg/config/merge_test.go
+++ b/pkg/config/merge_test.go
@@ -10,7 +10,7 @@ import (
"github.com/google/syzkaller/pkg/config"
)
-func TestMergeJSONData(t *testing.T) {
+func TestMergeJSONs(t *testing.T) {
tests := []struct {
left string
right string
@@ -38,7 +38,52 @@ func TestMergeJSONData(t *testing.T) {
},
}
for _, test := range tests {
- res, err := config.MergeJSONData([]byte(test.left), []byte(test.right))
+ res, err := config.MergeJSONs([]byte(test.left), []byte(test.right))
+ if err != nil {
+ t.Errorf("unexpected error: %s", err)
+ }
+ if !bytes.Equal(res, []byte(test.result)) {
+ t.Errorf("expected %s, got %s", test.result, res)
+ }
+ }
+}
+
+func TestPatchJSON(t *testing.T) {
+ tests := []struct {
+ left string
+ patch map[string]interface{}
+ result string
+ }{
+ {
+ `{"a":1,"b":2}`,
+ map[string]interface{}{"b": "string val"},
+ `{"a":1,"b":"string val"}`,
+ },
+ {
+ `{"a":1,"b":2}`,
+ map[string]interface{}{
+ "a": map[string]interface{}{
+ "b": map[string]interface{}{
+ "c": 5,
+ },
+ },
+ },
+ `{"a":{"b":{"c":5}},"b":2}`,
+ },
+ {
+ `{}`,
+ map[string]interface{}{
+ "a": map[string]interface{}{
+ "b": map[string]interface{}{
+ "c": 0,
+ },
+ },
+ },
+ `{"a":{"b":{"c":0}}}`,
+ },
+ }
+ for _, test := range tests {
+ res, err := config.PatchJSON([]byte(test.left), test.patch)
if err != nil {
t.Errorf("unexpected error: %s", err)
}
diff --git a/tools/syz-testbed/checkout.go b/tools/syz-testbed/checkout.go
index 91508ff99..3a4265013 100644
--- a/tools/syz-testbed/checkout.go
+++ b/tools/syz-testbed/checkout.go
@@ -4,13 +4,13 @@
package main
import (
+ "encoding/json"
"fmt"
"log"
"path/filepath"
"time"
syz_instance "github.com/google/syzkaller/pkg/instance"
- "github.com/google/syzkaller/pkg/mgrconfig"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/vcs"
)
@@ -18,7 +18,7 @@ import (
type Checkout struct {
Path string
Name string
- ManagerConfig *mgrconfig.Config
+ ManagerConfig json.RawMessage
Running []*Instance
Completed []*RunResult
}
@@ -35,7 +35,7 @@ func (checkout *Checkout) ArchiveRunning() error {
return nil
}
-func (ctx *TestbedContext) NewCheckout(config *CheckoutConfig, mgrConfig *mgrconfig.Config) (*Checkout, error) {
+func (ctx *TestbedContext) NewCheckout(config *CheckoutConfig, mgrConfig json.RawMessage) (*Checkout, error) {
checkout := &Checkout{
Name: config.Name,
Path: filepath.Join(ctx.Config.Workdir, "checkouts", config.Name),
diff --git a/tools/syz-testbed/instance.go b/tools/syz-testbed/instance.go
index 6601a2c4a..bd25d55eb 100644
--- a/tools/syz-testbed/instance.go
+++ b/tools/syz-testbed/instance.go
@@ -20,7 +20,6 @@ type Instance struct {
Workdir string
BenchFile string
LogFile string
- HTTP string
ExecCommand string
ExecCommandArgs []string
stopChannel chan bool
@@ -111,11 +110,16 @@ func (ctx *TestbedContext) NewInstance(checkout *Checkout, mgrName string) (*Ins
}
log.Printf("[%s] Generating syz-manager config", name)
- managerCfg := *checkout.ManagerConfig
- managerCfg.Name = mgrName
- managerCfg.Workdir = workdir
- managerCfg.Syzkaller = checkout.Path
- err = config.SaveFile(managerCfgPath, managerCfg)
+ managerCfg, err := config.PatchJSON(checkout.ManagerConfig, map[string]interface{}{
+ "name": mgrName,
+ "workdir": workdir,
+ "syzkaller": checkout.Path,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("failed to patch mgr config")
+ }
+
+ err = osutil.WriteFile(managerCfgPath, managerCfg)
if err != nil {
return nil, fmt.Errorf("failed to save manager config to %s: %s", managerCfgPath, err)
}
@@ -125,7 +129,6 @@ func (ctx *TestbedContext) NewInstance(checkout *Checkout, mgrName string) (*Ins
Workdir: workdir,
BenchFile: bench,
LogFile: logFile,
- HTTP: managerCfg.HTTP,
ExecCommand: filepath.Join(checkout.Path, "bin", "syz-manager"),
ExecCommandArgs: []string{"-config", managerCfgPath, "-bench", bench},
stopChannel: make(chan bool, 1),
diff --git a/tools/syz-testbed/testbed.go b/tools/syz-testbed/testbed.go
index 12884d0a4..f83d1dfa9 100644
--- a/tools/syz-testbed/testbed.go
+++ b/tools/syz-testbed/testbed.go
@@ -19,7 +19,6 @@ import (
"time"
"github.com/google/syzkaller/pkg/config"
- "github.com/google/syzkaller/pkg/mgrconfig"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/tool"
"github.com/google/syzkaller/pkg/vcs"
@@ -107,18 +106,15 @@ func main() {
ctx.Loop(shutdown)
}
-func (ctx *TestbedContext) MakeMgrConfig(base, patch json.RawMessage) *mgrconfig.Config {
- mergedConfig, err := config.MergeJSONData(base, patch)
+func (ctx *TestbedContext) MakeMgrConfig(base, patch json.RawMessage) json.RawMessage {
+ mgrCfg, err := config.MergeJSONs(base, patch)
if err != nil {
tool.Failf("failed to apply a patch to the base manager config: %s", err)
}
- mgrCfg, err := mgrconfig.LoadPartialData(mergedConfig)
+ // We don't care much about the specific ports of syz-managers.
+ mgrCfg, err = config.PatchJSON(mgrCfg, map[string]interface{}{"HTTP": ":0"})
if err != nil {
- tool.Failf("failed to parse base manager config: %s", err)
- }
- if mgrCfg.HTTP == "" {
- // Actually, we don't care much about the specific ports of syz-managers.
- mgrCfg.HTTP = ":0"
+ tool.Failf("failed to assign empty HTTP value: %s", err)
}
return mgrCfg
}