lib9p

Go 9P library.
Log | Files | Refs | LICENSE

commit 52156521b60ac65a9c5199ff0f957ed75d945de7
parent 9ea6d89879fdf596905e9c7e03023decf9e71b46
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue,  2 Jan 2024 10:05:23 +0900

copy testfs to lib9p for whitebox testing

Diffstat:
Dserver2_test.go | 255-------------------------------------------------------------------------------
Mserver_test.go | 451+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 327 insertions(+), 379 deletions(-)

diff --git a/server2_test.go b/server2_test.go @@ -1,255 +0,0 @@ -package lib9p - -import ( - "bytes" - "context" - "errors" - "io" - "os" - "reflect" - "sync" - "testing" -) - -// TestRunListener tests if the listener goroutine receives 9P messages -// and send them through the server's listenChan channel. -func TestRunListener(t *testing.T) { - tFile, err := os.Open("testdata/test_Tmsg.dat") - if err != nil { - t.Fatalf("open file: %v", err) - } - defer tFile.Close() - tFile2, err := os.Open("testdata/test_Tmsg.dat") - if err != nil { - t.Fatalf("open file: %v", err) - } - defer tFile2.Close() - c := &Conn{ - s: &Server{chatty9P: false}, - r: tFile, - } - oldReqPoolAdd := reqPoolAdd - defer func() { reqPoolAdd = oldReqPoolAdd }() - reqPoolAdd = func(*reqPool, uint16) (*request, error) { return &request{}, nil } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - c.runListener(ctx, newReqPool()) - for { - want, err := RecvMsg(tFile2) - if err == io.EOF { - break - } else if err != nil { - t.Fatalf("recvmsg: %v", err) - } - r := <-c.listenChan - if r.listenErr != nil { - t.Fatalf("listenErr: %v", r.listenErr) - } - got := r.ifcall - if !reflect.DeepEqual(want, got) { - t.Errorf("listener modified message:\n\twant: %v\n\tgot: %v", - want, got) - } - } -} - -// TestRunSpeaker tests if the speaker goroutine receives 9P messages -// and send them through the server's speakChan channel. -func TestRunResponder(t *testing.T) { - rFile, err := os.Open("testdata/test_Rmsg.dat") - if err != nil { - t.Fatalf("open file: %v", err) - } - defer rFile.Close() - r, w := io.Pipe() - c := &Conn{s: &Server{chatty9P: false}, w: w} - rp := newReqPool() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - c.runResponder(ctx, rp) - for { - want, err := readMsg(rFile) - if err == io.EOF { - break - } else if err != nil { - t.Fatalf("readmsg: %v", err) - } - msg, err := unmarshal(want) - if err != nil { - t.Fatalf("unmarshal %v", err) - } - c.respChan <- &request{ - tag: msg.GetTag(), - ofcall: msg, - } - got := make([]byte, len(want)) - _, err = io.ReadFull(r, got) - if err != nil { - t.Fatalf("readfull: %v", err) - } - if !bytes.Equal(want, got) { - t.Errorf("responder modified message:\n\twant: %v\n\tgot: %v", - want, got) - } - } -} - -// TestGetReq tests if getReq returns the same Msg as RecvMsg and -// registers the Msg to the ReqPool. -func TestGetReq(t *testing.T) { - tFile, err := os.Open("testdata/test_Tmsg.dat") - if err != nil { - t.Fatalf("open file: %v", err) - } - defer tFile.Close() - tFile2, err := os.Open("testdata/test_Tmsg.dat") - if err != nil { - t.Fatalf("open file: %v", err) - } - defer tFile2.Close() - rp := newReqPool() - for { - got := getReq(tFile, rp, false) - if got.listenErr == io.EOF { - break - } else if got.listenErr != nil { - t.Fatalf("getReq: %v", got.listenErr) - } - wantMsg, err := RecvMsg(tFile2) - if err != nil { - t.Fatalf("recvmsg: %v", err) - } - if got.tag != wantMsg.GetTag() { - t.Errorf("r.tag: want: %v, got: %v", wantMsg.GetTag(), got.tag) - } - if !reflect.DeepEqual(got.ifcall, wantMsg) { - t.Errorf("r.ifcall:\n\twant: %v,\n\tgot: %v", wantMsg, got.ifcall) - } - got2, ok := rp.lookup(wantMsg.GetTag()) - if !ok { - t.Errorf("request not registered to the pool") - } - if got != got2 { - t.Errorf("wrong message in pool:\n\twant: %p,\n\tgot: %p", got, got2) - } - rp.delete(wantMsg.GetTag()) - } -} - -func TestSVersion(t *testing.T) { - tests := []struct { - input *request - want *request - }{ - {&request{ifcall: &TVersion{Msize: 1024, Version: "9P2000"}}, - &request{ofcall: &RVersion{Msize: 1024, Version: "9P2000"}}}, - {&request{ifcall: &TVersion{Msize: 564, Version: "9P2000"}}, - &request{ofcall: &RVersion{Msize: 564, Version: "9P2000"}}}, - {&request{ifcall: &TVersion{Msize: 8 * 1024, Version: "9P2000"}}, - &request{ofcall: &RVersion{Msize: 1024, Version: "9P2000"}}}, - {&request{ifcall: &TVersion{Msize: 1024, Version: "unko"}}, - &request{ofcall: &RVersion{Msize: 1024, Version: "unknown"}}}, - } - tc := make(chan *request) - rc := make(chan *request) - c := &Conn{msize: 1024, mSizeLock: new(sync.Mutex), respChan: rc} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go sVersion(ctx, c, tc) - for _, test := range tests { - oldMsize := c.msize - tc <- test.input - ifcall := test.input.ifcall.(*TVersion) - wantmsg := test.want.ofcall.(*RVersion) - gotmsg := (<-rc).ofcall.(*RVersion) - if !reflect.DeepEqual(wantmsg, gotmsg) { - t.Errorf("want: %v,\n\tgot: %v", wantmsg, gotmsg) - } - if ifcall.Msize < oldMsize && c.msize != ifcall.Msize { - t.Errorf("msize not changed") - } - if ifcall.Msize >= oldMsize && c.msize != oldMsize { - t.Errorf("msize changed unexpectedly") - } - c.msize = oldMsize - } -} - -func TestSAuth(t *testing.T) { - tests := []struct { - input *request - want *request - authFunc func(context.Context, *request) - }{ - {&request{ifcall: &TAuth{Afid: NOFID, Uname: "kenji", Aname: ""}}, - &request{ofcall: &RError{Ename: errors.New("authentication not required")}}, nil}, - {&request{ifcall: &TAuth{Afid: NOFID, Uname: "kenji", Aname: ""}}, - &request{ofcall: &RError{Ename: errors.New("NOFID can't be used for afid")}}, - func(ctx context.Context, r *request) {}}, - {&request{ifcall: &TAuth{Afid: 0, Uname: "kenji", Aname: ""}}, - &request{ofcall: &RAuth{Tag: 0, Aqid: Qid{0, 1, 2}}}, - func(ctx context.Context, r *request) { - r.ofcall = &RAuth{Tag: 0, Aqid: Qid{0, 1, 2}} - }}, - } - for _, test := range tests { - func() { - tc := make(chan *request) - rc := make(chan *request) - defer close(tc) - defer close(rc) - s := &Server{Auth: test.authFunc} - c := &Conn{s: s, respChan: rc, fPool: newFidPool()} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go sAuth(ctx, c, tc) - tc <- test.input - ofcall := (<-rc).ofcall - switch wantmsg := test.want.ofcall.(type) { - case *RAuth: - gotmsg, ok := ofcall.(*RAuth) - if !ok { - t.Errorf("unexpected message: %v", ofcall) - return - } - if !reflect.DeepEqual(wantmsg, gotmsg) { - t.Errorf("want: %v,\n\tgot: %v", wantmsg, gotmsg) - return - } - case *RError: - _, ok := ofcall.(*RError) - if !ok { - t.Errorf("unexpected message: %v", ofcall) - return - } - default: - t.Fatalf("unexpected message: %v", wantmsg) - } - }() - } -} - -func TestSFlush(t *testing.T) { - rp := newReqPool() - tests := []struct { - input *request - }{ - {&request{ifcall: &TFlush{}, - oldreq: &request{pool: rp, done: make(chan struct{})}}}, - } - tc := make(chan *request) - rc := make(chan *request) - c := &Conn{msize: 1024, mSizeLock: new(sync.Mutex), respChan: rc} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go sFlush(ctx, c, tc) - for _, test := range tests { - tc <- test.input - if gotmsg, ok := (<-rc).ofcall.(*RFlush); !ok { - t.Errorf("unexpected message: %v", gotmsg) - } - if _, ok := <-test.input.oldreq.done; ok { - t.Errorf("done channel not closed") - } - } -} diff --git a/server_test.go b/server_test.go @@ -1,67 +1,306 @@ -package lib9p_test +package lib9p import ( + "bytes" "context" "errors" - "path" - "strings" + "io" + "os" + "reflect" + "sync" "testing" - - "git.mtkn.jp/lib9p" - "git.mtkn.jp/lib9p/testfs" ) +// TestRunListener tests if the listener goroutine receives 9P messages +// and send them through the server's listenChan channel. +func TestRunListener(t *testing.T) { + tFile, err := os.Open("testdata/test_Tmsg.dat") + if err != nil { + t.Fatalf("open file: %v", err) + } + defer tFile.Close() + tFile2, err := os.Open("testdata/test_Tmsg.dat") + if err != nil { + t.Fatalf("open file: %v", err) + } + defer tFile2.Close() + c := &Conn{ + s: &Server{chatty9P: false}, + r: tFile, + } + oldReqPoolAdd := reqPoolAdd + defer func() { reqPoolAdd = oldReqPoolAdd }() + reqPoolAdd = func(*reqPool, uint16) (*request, error) { return &request{}, nil } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + c.runListener(ctx, newReqPool()) + for { + want, err := RecvMsg(tFile2) + if err == io.EOF { + break + } else if err != nil { + t.Fatalf("recvmsg: %v", err) + } + r := <-c.listenChan + if r.listenErr != nil { + t.Fatalf("listenErr: %v", r.listenErr) + } + got := r.ifcall + if !reflect.DeepEqual(want, got) { + t.Errorf("listener modified message:\n\twant: %v\n\tgot: %v", + want, got) + } + } +} + +// TestRunSpeaker tests if the speaker goroutine receives 9P messages +// and send them through the server's speakChan channel. +func TestRunResponder(t *testing.T) { + rFile, err := os.Open("testdata/test_Rmsg.dat") + if err != nil { + t.Fatalf("open file: %v", err) + } + defer rFile.Close() + r, w := io.Pipe() + c := &Conn{s: &Server{chatty9P: false}, w: w} + rp := newReqPool() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + c.runResponder(ctx, rp) + for { + want, err := readMsg(rFile) + if err == io.EOF { + break + } else if err != nil { + t.Fatalf("readmsg: %v", err) + } + msg, err := unmarshal(want) + if err != nil { + t.Fatalf("unmarshal %v", err) + } + c.respChan <- &request{ + tag: msg.GetTag(), + ofcall: msg, + } + got := make([]byte, len(want)) + _, err = io.ReadFull(r, got) + if err != nil { + t.Fatalf("readfull: %v", err) + } + if !bytes.Equal(want, got) { + t.Errorf("responder modified message:\n\twant: %v\n\tgot: %v", + want, got) + } + } +} + +// TestGetReq tests if getReq returns the same Msg as RecvMsg and +// registers the Msg to the ReqPool. +func TestGetReq(t *testing.T) { + tFile, err := os.Open("testdata/test_Tmsg.dat") + if err != nil { + t.Fatalf("open file: %v", err) + } + defer tFile.Close() + tFile2, err := os.Open("testdata/test_Tmsg.dat") + if err != nil { + t.Fatalf("open file: %v", err) + } + defer tFile2.Close() + rp := newReqPool() + for { + got := getReq(tFile, rp, false) + if got.listenErr == io.EOF { + break + } else if got.listenErr != nil { + t.Fatalf("getReq: %v", got.listenErr) + } + wantMsg, err := RecvMsg(tFile2) + if err != nil { + t.Fatalf("recvmsg: %v", err) + } + if got.tag != wantMsg.GetTag() { + t.Errorf("r.tag: want: %v, got: %v", wantMsg.GetTag(), got.tag) + } + if !reflect.DeepEqual(got.ifcall, wantMsg) { + t.Errorf("r.ifcall:\n\twant: %v,\n\tgot: %v", wantMsg, got.ifcall) + } + got2, ok := rp.lookup(wantMsg.GetTag()) + if !ok { + t.Errorf("request not registered to the pool") + } + if got != got2 { + t.Errorf("wrong message in pool:\n\twant: %p,\n\tgot: %p", got, got2) + } + rp.delete(wantMsg.GetTag()) + } +} + +func TestSVersion(t *testing.T) { + tests := []struct { + input *request + want *request + }{ + {&request{ifcall: &TVersion{Msize: 1024, Version: "9P2000"}}, + &request{ofcall: &RVersion{Msize: 1024, Version: "9P2000"}}}, + {&request{ifcall: &TVersion{Msize: 564, Version: "9P2000"}}, + &request{ofcall: &RVersion{Msize: 564, Version: "9P2000"}}}, + {&request{ifcall: &TVersion{Msize: 8 * 1024, Version: "9P2000"}}, + &request{ofcall: &RVersion{Msize: 1024, Version: "9P2000"}}}, + {&request{ifcall: &TVersion{Msize: 1024, Version: "unko"}}, + &request{ofcall: &RVersion{Msize: 1024, Version: "unknown"}}}, + } + tc := make(chan *request) + rc := make(chan *request) + c := &Conn{msize: 1024, mSizeLock: new(sync.Mutex), respChan: rc} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go sVersion(ctx, c, tc) + for _, test := range tests { + oldMsize := c.msize + tc <- test.input + ifcall := test.input.ifcall.(*TVersion) + wantmsg := test.want.ofcall.(*RVersion) + gotmsg := (<-rc).ofcall.(*RVersion) + if !reflect.DeepEqual(wantmsg, gotmsg) { + t.Errorf("want: %v,\n\tgot: %v", wantmsg, gotmsg) + } + if ifcall.Msize < oldMsize && c.msize != ifcall.Msize { + t.Errorf("msize not changed") + } + if ifcall.Msize >= oldMsize && c.msize != oldMsize { + t.Errorf("msize changed unexpectedly") + } + c.msize = oldMsize + } +} + +func TestSAuth(t *testing.T) { + tests := []struct { + input *request + want *request + authFunc func(context.Context, *request) + }{ + {&request{ifcall: &TAuth{Afid: NOFID, Uname: "kenji", Aname: ""}}, + &request{ofcall: &RError{Ename: errors.New("authentication not required")}}, nil}, + {&request{ifcall: &TAuth{Afid: NOFID, Uname: "kenji", Aname: ""}}, + &request{ofcall: &RError{Ename: errors.New("NOFID can't be used for afid")}}, + func(ctx context.Context, r *request) {}}, + {&request{ifcall: &TAuth{Afid: 0, Uname: "kenji", Aname: ""}}, + &request{ofcall: &RAuth{Tag: 0, Aqid: Qid{0, 1, 2}}}, + func(ctx context.Context, r *request) { + r.ofcall = &RAuth{Tag: 0, Aqid: Qid{0, 1, 2}} + }}, + } + for _, test := range tests { + func() { + tc := make(chan *request) + rc := make(chan *request) + defer close(tc) + defer close(rc) + s := &Server{Auth: test.authFunc} + c := &Conn{s: s, respChan: rc, fPool: newFidPool()} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go sAuth(ctx, c, tc) + tc <- test.input + ofcall := (<-rc).ofcall + switch wantmsg := test.want.ofcall.(type) { + case *RAuth: + gotmsg, ok := ofcall.(*RAuth) + if !ok { + t.Errorf("unexpected message: %v", ofcall) + return + } + if !reflect.DeepEqual(wantmsg, gotmsg) { + t.Errorf("want: %v,\n\tgot: %v", wantmsg, gotmsg) + return + } + case *RError: + _, ok := ofcall.(*RError) + if !ok { + t.Errorf("unexpected message: %v", ofcall) + return + } + default: + t.Fatalf("unexpected message: %v", wantmsg) + } + }() + } +} + +func TestSFlush(t *testing.T) { + rp := newReqPool() + tests := []struct { + input *request + }{ + {&request{ifcall: &TFlush{}, + oldreq: &request{pool: rp, done: make(chan struct{})}}}, + } + tc := make(chan *request) + rc := make(chan *request) + c := &Conn{msize: 1024, mSizeLock: new(sync.Mutex), respChan: rc} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go sFlush(ctx, c, tc) + for _, test := range tests { + tc <- test.input + if gotmsg, ok := (<-rc).ofcall.(*RFlush); !ok { + t.Errorf("unexpected message: %v", gotmsg) + } + if _, ok := <-test.input.oldreq.done; ok { + t.Errorf("done channel not closed") + } + } +} + func TestSAttach(t *testing.T) { - dammyAuth := func(context.Context, *lib9p.Req) {} - af := &lib9p.AuthFile{ - Qid: lib9p.Qid{Type: lib9p.QTAUTH}, + dammyAuth := func(context.Context, *Req) {} + af := &AuthFile{ + Qid: Qid{Type: QTAUTH}, Uname: "kenji", Aname: "", } - fp := lib9p.NewFidPool() - fid, err := fp.Add(0) + fp := newFidPool() + fid, err := fp.add(0) if err != nil { t.Fatal(err) } - fid.SetFile(af) + fid.file = af tests := []struct { - input lib9p.Msg + input Msg auth bool authOK bool - want lib9p.Msg + want Msg }{ - {&lib9p.TAttach{Fid: 0, Afid: lib9p.NOFID, Uname: "kenji", Aname: ""}, + {&TAttach{Fid: 0, Afid: NOFID, Uname: "kenji", Aname: ""}, false, false, - &lib9p.RError{}}, // duplicate fid - {&lib9p.TAttach{Fid: 1, Afid: lib9p.NOFID, Uname: "kenji", Aname: ""}, + &RError{}}, // duplicate fid + {&TAttach{Fid: 1, Afid: NOFID, Uname: "kenji", Aname: ""}, false, true, - &lib9p.RAttach{}}, // ok - {&lib9p.TAttach{Fid: 2, Afid: lib9p.NOFID, Uname: "kenji", Aname: ""}, + &RAttach{}}, // ok + {&TAttach{Fid: 2, Afid: NOFID, Uname: "kenji", Aname: ""}, true, false, - &lib9p.RError{}}, // afid is not set - {&lib9p.TAttach{Fid: 2, Afid: 0, Uname: "kenji", Aname: ""}, + &RError{}}, // afid is not set + {&TAttach{Fid: 2, Afid: 0, Uname: "kenji", Aname: ""}, true, false, - &lib9p.RError{}}, // not authOK - {&lib9p.TAttach{Fid: 2, Afid: 0, Uname: "unko", Aname: ""}, + &RError{}}, // not authOK + {&TAttach{Fid: 2, Afid: 0, Uname: "unko", Aname: ""}, true, true, - &lib9p.RError{}}, // wrong user - {&lib9p.TAttach{Fid: 2, Afid: 0, Uname: "kenji", Aname: ""}, + &RError{}}, // wrong user + {&TAttach{Fid: 2, Afid: 0, Uname: "kenji", Aname: ""}, true, true, - &lib9p.RAttach{}}, // ok + &RAttach{}}, // ok } - tc := make(chan *lib9p.Req) - rc := make(chan *lib9p.Req) + tc := make(chan *Req) + rc := make(chan *Req) defer close(tc) defer close(rc) - s := &lib9p.Server{} - s.SetFS(testfs.Fsys) - c := &lib9p.Conn{} - c.SetServer(s) - c.SetRespChan(rc) - c.SetFPool(fp) + s := &Server{fs: testfs} + c := &conn{s: s, respChan: rc, fPool: fp} ctx, cancel := context.WithCancel(context.Background()) defer cancel() - go lib9p.SAttach(ctx, c, tc) + go sAttach(ctx, c, tc) for i, test := range tests { af.AuthOK = test.authOK if test.auth { @@ -69,19 +308,18 @@ func TestSAttach(t *testing.T) { } else { s.Auth = nil } - req := new(lib9p.Req) - req.SetIfcall(test.input) + req := &request{ifcall: test.input} tc <- req - ofcall := (<-rc).Ofcall() + ofcall := (<-rc).ofcall switch wantmsg := test.want.(type) { - case *lib9p.RAttach: - _, ok := ofcall.(*lib9p.RAttach) + case *RAttach: + _, ok := ofcall.(*RAttach) if !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) return } - case *lib9p.RError: - _, ok := ofcall.(*lib9p.RError) + case *RError: + _, ok := ofcall.(*RError) if !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) return @@ -94,51 +332,46 @@ func TestSAttach(t *testing.T) { func TestSWalk(t *testing.T) { tests := []struct { - input lib9p.Msg - wantLen int // len(Ofcall.(*lib9p.RWalk).Qids) + input Msg + wantLen int // len(Ofcall.(*RWalk).Qids) wantErr error }{ - {&lib9p.TWalk{Fid: 0, Newfid: 1, Wnames: []string{"a"}}, + {&TWalk{Fid: 0, Newfid: 1, Wnames: []string{"a"}}, 1, nil}, - {&lib9p.TWalk{Fid: 0, Newfid: 2, Wnames: []string{"b"}}, + {&TWalk{Fid: 0, Newfid: 2, Wnames: []string{"b"}}, 1, nil}, - {&lib9p.TWalk{Fid: 0, Newfid: 3, Wnames: []string{"dir", "file"}}, + {&TWalk{Fid: 0, Newfid: 3, Wnames: []string{"dir", "file"}}, 2, nil}, - {&lib9p.TWalk{Fid: 0, Newfid: 4, Wnames: []string{"dir", "unko"}}, + {&TWalk{Fid: 0, Newfid: 4, Wnames: []string{"dir", "unko"}}, 1, nil}, // short walk // 9P document says: // If the first element cant be walked for any reason, // RError is returned. - {&lib9p.TWalk{Fid: 0, Newfid: 5, Wnames: []string{"unko", "unko"}}, + {&TWalk{Fid: 0, Newfid: 5, Wnames: []string{"unko", "unko"}}, 0, errors.New("not found")}, } - tc := make(chan *lib9p.Req) - rc := make(chan *lib9p.Req) + tc := make(chan *Req) + rc := make(chan *Req) defer close(tc) defer close(rc) - fp := lib9p.NewFidPool() - fid, err := fp.Add(0) + fp := newFidPool() + fid, err := fp.add(0) if err != nil { t.Fatal(err) } - fid.SetOmode(-1) - fid.SetPath(".") - s := &lib9p.Server{} - s.SetFS(testfs.Fsys) - c := &lib9p.Conn{} - c.SetServer(s) - c.SetRespChan(rc) - c.SetFPool(fp) + fid.omode = -1 + fid.path = "." + s := &Server{fs: testfs} + c := &conn{s: s, respChan: rc, fPool: fp} ctx, cancel := context.WithCancel(context.Background()) defer cancel() - go lib9p.SWalk(ctx, c, tc) + go sWalk(ctx, c, tc) for i, test := range tests { - req := new(lib9p.Req) - req.SetIfcall(test.input) + req := &Req{ifcall: test.input} tc <- req - ofcall := (<-rc).Ofcall() + ofcall := (<-rc).ofcall if test.wantErr == nil { - gotMsg, ok := ofcall.(*lib9p.RWalk) + gotMsg, ok := ofcall.(*RWalk) if !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) continue @@ -149,7 +382,7 @@ func TestSWalk(t *testing.T) { continue } } else { - _, ok := ofcall.(*lib9p.RError) + _, ok := ofcall.(*RError) if !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) continue @@ -163,63 +396,56 @@ func TestSOpen(t *testing.T) { tests := []struct { filePath string // file to open. uid string - input lib9p.Msg - wantMsg lib9p.Msg + input Msg + wantMsg Msg }{ // ok - {"a", "glenda", &lib9p.TOpen{Fid: 0, Mode: lib9p.OREAD}, &lib9p.ROpen{}}, + {"a", "glenda", &TOpen{Fid: 0, Mode: OREAD}, &ROpen{}}, // fid not found - {"a", "glenda", &lib9p.TOpen{Fid: 1, Mode: lib9p.OREAD}, &lib9p.RError{}}, + {"a", "glenda", &TOpen{Fid: 1, Mode: OREAD}, &RError{}}, // permission denied - {"b", "glenda", &lib9p.TOpen{Fid: 0, Mode: lib9p.OREAD}, &lib9p.RError{}}, - {"b", "ken", &lib9p.TOpen{Fid: 0, Mode: lib9p.ORDWR}, &lib9p.ROpen{}}, - {"dir", "glenda", &lib9p.TOpen{Fid: 0, Mode: lib9p.OREAD}, &lib9p.ROpen{}}, + {"b", "glenda", &TOpen{Fid: 0, Mode: OREAD}, &RError{}}, + {"b", "ken", &TOpen{Fid: 0, Mode: ORDWR}, &ROpen{}}, + {"dir", "glenda", &TOpen{Fid: 0, Mode: OREAD}, &ROpen{}}, // is a directory - {"dir", "glenda", &lib9p.TOpen{Fid: 0, Mode: lib9p.OWRITE}, &lib9p.RError{}}, + {"dir", "glenda", &TOpen{Fid: 0, Mode: OWRITE}, &RError{}}, } - tc := make(chan *lib9p.Req) - rc := make(chan *lib9p.Req) + tc := make(chan *Req) + rc := make(chan *Req) defer close(tc) defer close(rc) - fp := lib9p.NewFidPool() - s := &lib9p.Server{} - s.SetFS(testfs.Fsys) - c := &lib9p.Conn{} - c.SetServer(s) - c.SetRespChan(rc) - c.SetFPool(fp) - c.NewMSizeLock() - c.SetMSize(1024) + fp := newFidPool() + s := &Server{fs: testfs} + c := &conn{s: s, respChan: rc, fPool: fp, mSizeLock: new(sync.Mutex), msize: 1024} ctx, cancel := context.WithCancel(context.Background()) defer cancel() - go lib9p.SOpen(ctx, c, tc) + go sOpen(ctx, c, tc) for i, test := range tests { - fp.Delete(0) - fid, err := fp.Add(0) + fp.delete(0) + fid, err := fp.add(0) if err != nil { t.Error(i, err) continue } - fid.SetOmode(-1) - fid.SetPath(test.filePath) - fid.SetUid(test.uid) - f, err := testfs.Fsys.WalkPath(test.filePath) + fid.omode = -1 + fid.path = test.filePath + fid.uid = test.uid + f, err := testfs.WalkPath(test.filePath) if err != nil { t.Error(i, err) continue } - fid.SetFile(f) - req := new(lib9p.Req) - req.SetIfcall(test.input) + fid.file = f + req := &Req{ifcall:test.input} tc <- req - ofcall := (<-rc).Ofcall() + ofcall := (<-rc).ofcall switch test.wantMsg.(type) { - case *lib9p.ROpen: - if _, ok := ofcall.(*lib9p.ROpen); !ok { + case *ROpen: + if _, ok := ofcall.(*ROpen); !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) } - case *lib9p.RError: - if _, ok := ofcall.(*lib9p.RError); !ok { + case *RError: + if _, ok := ofcall.(*RError); !ok { t.Errorf("%d: unexpected message: %v", i, ofcall) } default: @@ -227,26 +453,3 @@ func TestSOpen(t *testing.T) { } } } - -// This function does the actual work for TestWalk(). -func testWalk(t *testing.T, fs *testfs.FS, pathname string, file *testfs.File) { - t.Logf("walk %s", pathname) - f, err := fs.Walk(strings.Split(pathname, "/")) - if err != nil { - t.Errorf("open %s: %v", pathname, err) - } - if f != file { - t.Errorf("open %s: wrong file", pathname) - } - for _, child := range file.Children { - childpath := path.Join(pathname, child.St.Name) - testWalk(t, fs, childpath, child) - } -} - -// TestWalk walk through testFS in depth-first fassion, -// checks if all files can be opened without error and if -// the opened file is the same as the file accessed via testFS.child -func TestWalk(t *testing.T) { - testWalk(t, testfs.Fsys, ".", testfs.Fsys.Root) -}