gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/fd/fd_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 fd
    16  
    17  import (
    18  	"math"
    19  	"os"
    20  	"testing"
    21  
    22  	"golang.org/x/sys/unix"
    23  	"gvisor.dev/gvisor/pkg/atomicbitops"
    24  )
    25  
    26  func TestSetNegOne(t *testing.T) {
    27  	type entry struct {
    28  		name string
    29  		file *FD
    30  		fn   func() error
    31  	}
    32  	var tests []entry
    33  
    34  	fd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
    35  	if err != nil {
    36  		t.Fatal("unix.Socket:", err)
    37  	}
    38  	f1 := New(fd)
    39  	tests = append(tests, entry{
    40  		"Release",
    41  		f1,
    42  		func() error {
    43  			return unix.Close(f1.Release())
    44  		},
    45  	})
    46  
    47  	fd, err = unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
    48  	if err != nil {
    49  		t.Fatal("unix.Socket:", err)
    50  	}
    51  	f2 := New(fd)
    52  	tests = append(tests, entry{
    53  		"Close",
    54  		f2,
    55  		f2.Close,
    56  	})
    57  
    58  	for _, test := range tests {
    59  		if err := test.fn(); err != nil {
    60  			t.Errorf("%s: %v", test.name, err)
    61  			continue
    62  		}
    63  		if fd := test.file.FD(); fd != -1 {
    64  			t.Errorf("%s: got FD() = %d, want = -1", test.name, fd)
    65  		}
    66  	}
    67  }
    68  
    69  func TestStartsNegOne(t *testing.T) {
    70  	type entry struct {
    71  		name string
    72  		file *FD
    73  	}
    74  
    75  	tests := []entry{
    76  		{"-1", New(-1)},
    77  		{"-2", New(-2)},
    78  		{"MinInt32", New(math.MinInt32)},
    79  		{"MinInt64", New(math.MinInt64)},
    80  	}
    81  
    82  	for _, test := range tests {
    83  		if fd := test.file.FD(); fd != -1 {
    84  			t.Errorf("%s: got FD() = %d, want = -1", test.name, fd)
    85  		}
    86  	}
    87  }
    88  
    89  func TestFileDotFile(t *testing.T) {
    90  	fd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
    91  	if err != nil {
    92  		t.Fatal("unix.Socket:", err)
    93  	}
    94  
    95  	f := New(fd)
    96  	of, err := f.File()
    97  	if err != nil {
    98  		t.Fatalf("File got err %v want nil", err)
    99  	}
   100  
   101  	if ofd, nfd := int(of.Fd()), f.FD(); ofd == nfd || ofd == -1 {
   102  		// Try not to double close the FD.
   103  		f.Release()
   104  
   105  		t.Fatalf("got %#v.File().Fd() = %d, want new FD", f, ofd)
   106  	}
   107  
   108  	f.Close()
   109  	of.Close()
   110  }
   111  
   112  func TestFileDotFileError(t *testing.T) {
   113  	f := &FD{ReadWriter{atomicbitops.FromInt64(-2)}}
   114  
   115  	if of, err := f.File(); err == nil {
   116  		t.Errorf("File %v got nil err want non-nil", of)
   117  		of.Close()
   118  	}
   119  }
   120  
   121  func TestNewFromFile(t *testing.T) {
   122  	f, err := NewFromFile(os.Stdin)
   123  	if err != nil {
   124  		t.Fatalf("NewFromFile got err %v want nil", err)
   125  	}
   126  	if nfd, ofd := f.FD(), int(os.Stdin.Fd()); nfd == -1 || nfd == ofd {
   127  		t.Errorf("got FD() = %d, want = new FD (old FD was %d)", nfd, ofd)
   128  	}
   129  	f.Close()
   130  }
   131  
   132  func TestNewFromFileError(t *testing.T) {
   133  	f, err := NewFromFile(nil)
   134  	if err == nil {
   135  		t.Errorf("NewFromFile got %v with nil err want non-nil", f)
   136  		f.Close()
   137  	}
   138  }