@@ -26,25 +26,24 @@ import (
2626 "context"
2727 "errors"
2828 "fmt"
29+ fuzz "github.com/AdaLogics/go-fuzz-headers"
30+ "github.com/containerd/containerd"
31+ "github.com/containerd/containerd/oci"
32+ "github.com/containerd/containerd/sys"
2933 "io"
3034 "io/ioutil"
3135 "os"
3236 "os/exec"
3337 "strings"
3438 "time"
35-
36- fuzz "github.com/AdaLogics/go-fuzz-headers"
37-
38- "github.com/containerd/containerd"
39- "github.com/containerd/containerd/oci"
40- "github.com/containerd/containerd/sys"
4139)
4240
4341func init () {
4442 err := updatePathEnv ()
4543 if err != nil {
4644 panic (err )
4745 }
46+
4847}
4948
5049func tearDown () error {
@@ -61,11 +60,25 @@ func tearDown() error {
6160 if err := sys .ForceRemoveAll (defaultRoot ); err != nil {
6261 return err
6362 }
63+
6464 return nil
6565}
6666
67+ // checkIfShouldRestart() checks if an error indicates that
68+ // the daemon is not running. If the daemon is not running,
69+ // it deletes it to allow the fuzzer to create a new and
70+ // working socket.
71+ func checkIfShouldRestart (err error ) {
72+ if strings .Contains (err .Error (), "daemon is not running" ) {
73+ err2 := deleteSocket ()
74+ if err2 != nil {
75+ panic (err2 )
76+ }
77+ }
78+ }
79+
6780// startDaemon() starts the daemon.
68- func startDaemon (ctx context.Context ) {
81+ func startDaemon (ctx context.Context , shouldTearDown bool ) {
6982 buf := bytes .NewBuffer (nil )
7083 stdioFile , err := ioutil .TempFile ("" , "" )
7184 if err != nil {
@@ -94,16 +107,14 @@ func startDaemon(ctx context.Context) {
94107 panic (err )
95108 }
96109 }
97- // Whether or not we should tear down after each fuzz iteration
98- // requires further investigation. The fuzzer runs fine without
99- // but if there is no performance-penalty, then we should tear down.
100- // To-do @AdamKorcz
101- /*defer func() {
102- err = tearDown()
103- if err != nil {
104- panic(err)
105- }
106- }()*/
110+ if shouldTearDown {
111+ defer func () {
112+ err = tearDown ()
113+ if err != nil {
114+ checkIfShouldRestart (err )
115+ }
116+ }()
117+ }
107118 seconds := 4 * time .Second
108119 waitCtx , waitCancel := context .WithTimeout (ctx , seconds )
109120
@@ -123,8 +134,7 @@ func startDaemon(ctx context.Context) {
123134// refuse a connection to it, and deleting it allows us
124135// to create a new socket when invoking containerd.New()
125136func deleteSocket () error {
126- cmd := exec .Command ("rm" , "/run/containerd-test/containerd.sock" )
127- err := cmd .Run ()
137+ err := os .Remove ("/run/containerd-test/containerd.sock" )
128138 if err != nil {
129139 return err
130140 }
@@ -252,18 +262,20 @@ func newContainer(client *containerd.Client, f *fuzz.ConsumeFuzzer, ctx context.
252262 return nil , errors .New ("Could not create container" )
253263}
254264
255- // FuzzCreateContainer() implements the fuzzer.
265+ // doFuzz() implements the logic of FuzzCreateContainerNoTearDown()
266+ // and FuzzCreateContainerWithTearDown() and allows for
267+ // the option to turn on/off teardown after each iteration.
256268// From a high level it:
257269// - Creates a client
258270// - Imports a bunch of fuzzed tar archives
259271// - Creates a bunch of containers
260- func FuzzCreateContainer (data []byte ) int {
272+ func doFuzz (data []byte , shouldTearDown bool ) int {
261273 ctx , cancel := testContext (nil )
262274 defer cancel ()
263275
264276 // Check if daemon is running and start it if it isn't
265277 if ctrd .cmd == nil {
266- startDaemon (ctx )
278+ startDaemon (ctx , shouldTearDown )
267279 }
268280 client , err := containerd .New (address )
269281 if err != nil {
@@ -318,3 +330,22 @@ func FuzzCreateContainer(data []byte) int {
318330
319331 return 1
320332}
333+
334+ // FuzzCreateContainerNoTearDown() implements a fuzzer
335+ // similar to FuzzCreateContainerWithTearDown() with
336+ // with one minor distinction: One tears down the
337+ // daemon after each iteration whereas the other doesn't.
338+ // The two fuzzers' performance will be compared over time.
339+ func FuzzCreateContainerNoTearDown (data []byte ) int {
340+ ret := doFuzz (data , false )
341+ return ret
342+ }
343+
344+ // FuzzCreateContainerWithTearDown() is similar to
345+ // FuzzCreateContainerNoTearDown() except that
346+ // FuzzCreateContainerWithTearDown tears down the daemon
347+ // after each iteration.
348+ func FuzzCreateContainerWithTearDown (data []byte ) int {
349+ ret := doFuzz (data , true )
350+ return ret
351+ }
0 commit comments