commit 984c4e8ee06560d78b52e3f1e58a3c4b735ccf57
parent 904e1888746017b8082fe78eaab0675622cf85b8
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 20 Jan 2024 11:54:58 +0900
add fuzz test for client.File.Write
Diffstat:
3 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/client/file.go b/client/file.go
@@ -32,6 +32,17 @@ func (cf *File) Stat() (*lib9p.FileInfo, error) {
 	return &lib9p.FileInfo{Stat: *st}, nil
 }
 
+// TODO: check permission?
+func (cf *File) WStat(stat *lib9p.Stat) error {
+	tag, err := cf.fs.tPool.add()
+	if err != nil {
+		return err
+	}
+	err = cf.fs.c.Wstat(tag, cf.fid.fid, stat)
+	cf.fs.tPool.delete(tag)
+	return err
+}
+
 // Don't use closed file.
 func (cf *File) Close() error {
 	tag, err := cf.fs.tPool.add()
diff --git a/client/file_test.go b/client/file_test.go
@@ -13,6 +13,13 @@ import (
 	"git.mtkn.jp/lib9p"
 )
 
+func TestFileInterface(t *testing.T) {
+	var _ lib9p.File = &File{}
+	var _ lib9p.WriterFile = &File{}
+	var _ lib9p.WriterStatFile = &File{}
+	var _ lib9p.ReadDirFile = &File{}
+}
+
 // Mount runs a server with fs and mounts it as *FS.
 func mount(ctx context.Context, fs lib9p.FS) (cfs *FS, err error) {
 	cr, sw := io.Pipe()
@@ -57,6 +64,17 @@ func TestFileStat(t *testing.T) {
 	}
 }
 
+// TODO: implement
+func TestFileWStat(t *testing.T) {
+	ctx, cancel := context.WithCancel(context.Background())
+	cfs, err := mount(ctx, testfs)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer cancel()
+	_, _ = ctx, cfs
+}
+
 // TestClose checks it *File.Close calls are transmitted to the server and
 // *testFile.Close is called for each *File.Close.
 func TestClose(t *testing.T) {
@@ -144,6 +162,9 @@ func TestFileRead(t *testing.T) {
 	}
 }
 
+// TestFileWrite tests the Write method of the struct File.
+// It writes some bytes to a testFile using File.Write and checks if
+// the underlying content of testFile is changed correctly.
 func TestFileWrite(t *testing.T) {
 	tests := []struct{
 		b []byte
@@ -204,6 +225,37 @@ func TestFileWrite(t *testing.T) {
 	}
 }
 
+func FuzzFileWrite(f *testing.F) {
+	ctx, cancel := context.WithCancel(context.Background())
+	cfs, err := mount(ctx, testfs)
+	if err != nil {
+		f.Fatal(err)
+	}
+	defer cancel()
+	tf, err := testfs.walkPath("dir/file")
+	if err != nil {
+		f.Fatal(err)
+	}
+	orig := bytes.Clone(tf.content)
+	f.Fuzz(func(t *testing.T, in []byte) {
+		t.Log(in)
+		defer func() { tf.content = bytes.Clone(orig) }()
+		cf, err := cfs.OpenFile("dir/file", lib9p.O_RDWR)
+		if err != nil {
+			t.Fatal(err)
+		}
+		_, err = cf.(lib9p.WriterFile).Write(in)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(tf.content[:len(in)], in) {
+			t.Errorf("not written propperly: want: %v, got: %v",
+				string(in), string(tf.content[:len(in)]))
+		}
+		cf.Close()
+	})
+}
+
 // TestReadDir tests whether ReadDir returns the same dir entries as testfs
 // by comparing their *lib9p.Stat.
 func TestReadDir(t *testing.T) {
diff --git a/client/testdata/fuzz/FuzzFileWrite/bfeadd9adcc0bb47 b/client/testdata/fuzz/FuzzFileWrite/bfeadd9adcc0bb47
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("xxxxx00x")