github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/tmpfs/file_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tmpfs 16 17 import ( 18 "bytes" 19 "testing" 20 21 "github.com/SagerNet/gvisor/pkg/context" 22 "github.com/SagerNet/gvisor/pkg/hostarch" 23 "github.com/SagerNet/gvisor/pkg/sentry/fs" 24 "github.com/SagerNet/gvisor/pkg/sentry/kernel/contexttest" 25 "github.com/SagerNet/gvisor/pkg/sentry/usage" 26 "github.com/SagerNet/gvisor/pkg/usermem" 27 ) 28 29 func newFileInode(ctx context.Context) *fs.Inode { 30 m := fs.NewCachingMountSource(ctx, &Filesystem{}, fs.MountSourceFlags{}) 31 iops := NewInMemoryFile(ctx, usage.Tmpfs, fs.WithCurrentTime(ctx, fs.UnstableAttr{})) 32 return fs.NewInode(ctx, iops, m, fs.StableAttr{ 33 DeviceID: tmpfsDevice.DeviceID(), 34 InodeID: tmpfsDevice.NextIno(), 35 BlockSize: hostarch.PageSize, 36 Type: fs.RegularFile, 37 }) 38 } 39 40 func newFile(ctx context.Context) *fs.File { 41 inode := newFileInode(ctx) 42 f, _ := inode.GetFile(ctx, fs.NewDirent(ctx, inode, "stub"), fs.FileFlags{Read: true, Write: true}) 43 return f 44 } 45 46 // Allocate once, write twice. 47 func TestGrow(t *testing.T) { 48 ctx := contexttest.Context(t) 49 f := newFile(ctx) 50 defer f.DecRef(ctx) 51 52 abuf := bytes.Repeat([]byte{'a'}, 68) 53 n, err := f.Pwritev(ctx, usermem.BytesIOSequence(abuf), 0) 54 if n != int64(len(abuf)) || err != nil { 55 t.Fatalf("Pwritev got (%d, %v) want (%d, nil)", n, err, len(abuf)) 56 } 57 58 bbuf := bytes.Repeat([]byte{'b'}, 856) 59 n, err = f.Pwritev(ctx, usermem.BytesIOSequence(bbuf), 68) 60 if n != int64(len(bbuf)) || err != nil { 61 t.Fatalf("Pwritev got (%d, %v) want (%d, nil)", n, err, len(bbuf)) 62 } 63 64 rbuf := make([]byte, len(abuf)+len(bbuf)) 65 n, err = f.Preadv(ctx, usermem.BytesIOSequence(rbuf), 0) 66 if n != int64(len(rbuf)) || err != nil { 67 t.Fatalf("Preadv got (%d, %v) want (%d, nil)", n, err, len(rbuf)) 68 } 69 70 if want := append(abuf, bbuf...); !bytes.Equal(rbuf, want) { 71 t.Fatalf("Read %v, want %v", rbuf, want) 72 } 73 }