gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/p9/p9_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 p9
    16  
    17  import (
    18  	"os"
    19  	"testing"
    20  )
    21  
    22  func TestFileModeHelpers(t *testing.T) {
    23  	fns := map[FileMode]struct {
    24  		// name identifies the file mode.
    25  		name string
    26  
    27  		// function is the function that should return true given the
    28  		// right FileMode.
    29  		function func(m FileMode) bool
    30  	}{
    31  		ModeRegular: {
    32  			name:     "regular",
    33  			function: FileMode.IsRegular,
    34  		},
    35  		ModeDirectory: {
    36  			name:     "directory",
    37  			function: FileMode.IsDir,
    38  		},
    39  		ModeNamedPipe: {
    40  			name:     "named pipe",
    41  			function: FileMode.IsNamedPipe,
    42  		},
    43  		ModeCharacterDevice: {
    44  			name:     "character device",
    45  			function: FileMode.IsCharacterDevice,
    46  		},
    47  		ModeBlockDevice: {
    48  			name:     "block device",
    49  			function: FileMode.IsBlockDevice,
    50  		},
    51  		ModeSymlink: {
    52  			name:     "symlink",
    53  			function: FileMode.IsSymlink,
    54  		},
    55  		ModeSocket: {
    56  			name:     "socket",
    57  			function: FileMode.IsSocket,
    58  		},
    59  	}
    60  	for mode, info := range fns {
    61  		// Make sure the mode doesn't identify as anything but itself.
    62  		for testMode, testfns := range fns {
    63  			if mode != testMode && testfns.function(mode) {
    64  				t.Errorf("Mode %s returned true when asked if it was mode %s", info.name, testfns.name)
    65  			}
    66  		}
    67  
    68  		// Make sure mode identifies as itself.
    69  		if !info.function(mode) {
    70  			t.Errorf("Mode %s returned false when asked if it was itself", info.name)
    71  		}
    72  	}
    73  }
    74  
    75  func TestFileModeToQID(t *testing.T) {
    76  	for _, test := range []struct {
    77  		// name identifies the test.
    78  		name string
    79  
    80  		// mode is the FileMode we start out with.
    81  		mode FileMode
    82  
    83  		// want is the corresponding QIDType we expect.
    84  		want QIDType
    85  	}{
    86  		{
    87  			name: "Directories are of type directory",
    88  			mode: ModeDirectory,
    89  			want: TypeDir,
    90  		},
    91  		{
    92  			name: "Sockets are append-only files",
    93  			mode: ModeSocket,
    94  			want: TypeAppendOnly,
    95  		},
    96  		{
    97  			name: "Named pipes are append-only files",
    98  			mode: ModeNamedPipe,
    99  			want: TypeAppendOnly,
   100  		},
   101  		{
   102  			name: "Character devices are append-only files",
   103  			mode: ModeCharacterDevice,
   104  			want: TypeAppendOnly,
   105  		},
   106  		{
   107  			name: "Symlinks are of type symlink",
   108  			mode: ModeSymlink,
   109  			want: TypeSymlink,
   110  		},
   111  		{
   112  			name: "Regular files are of type regular",
   113  			mode: ModeRegular,
   114  			want: TypeRegular,
   115  		},
   116  		{
   117  			name: "Block devices are regular files",
   118  			mode: ModeBlockDevice,
   119  			want: TypeRegular,
   120  		},
   121  	} {
   122  		if qidType := test.mode.QIDType(); qidType != test.want {
   123  			t.Errorf("ModeToQID test %s failed: got %o, wanted %o", test.name, qidType, test.want)
   124  		}
   125  	}
   126  }
   127  
   128  func TestP9ModeConverters(t *testing.T) {
   129  	for _, m := range []FileMode{
   130  		ModeRegular,
   131  		ModeDirectory,
   132  		ModeCharacterDevice,
   133  		ModeBlockDevice,
   134  		ModeSocket,
   135  		ModeSymlink,
   136  		ModeNamedPipe,
   137  	} {
   138  		if mb := ModeFromOS(m.OSMode()); mb != m {
   139  			t.Errorf("Converting %o to OS.FileMode gives %o and is converted back as %o", m, m.OSMode(), mb)
   140  		}
   141  	}
   142  }
   143  
   144  func TestOSModeConverters(t *testing.T) {
   145  	// Modes that can be converted back and forth.
   146  	for _, m := range []os.FileMode{
   147  		0, // Regular file.
   148  		os.ModeDir,
   149  		os.ModeCharDevice | os.ModeDevice,
   150  		os.ModeDevice,
   151  		os.ModeSocket,
   152  		os.ModeSymlink,
   153  		os.ModeNamedPipe,
   154  	} {
   155  		if mb := ModeFromOS(m).OSMode(); mb != m {
   156  			t.Errorf("Converting %o to p9.FileMode gives %o and is converted back as %o", m, ModeFromOS(m), mb)
   157  		}
   158  	}
   159  
   160  	// Modes that will be converted to a regular file since p9 cannot
   161  	// express these.
   162  	for _, m := range []os.FileMode{
   163  		os.ModeAppend,
   164  		os.ModeExclusive,
   165  		os.ModeTemporary,
   166  	} {
   167  		if p9Mode := ModeFromOS(m); p9Mode != ModeRegular {
   168  			t.Errorf("Converting %o to p9.FileMode should have given ModeRegular, but yielded %o", m, p9Mode)
   169  		}
   170  	}
   171  }
   172  
   173  func TestAttrMaskContains(t *testing.T) {
   174  	req := AttrMask{Mode: true, Size: true}
   175  	have := AttrMask{}
   176  	if have.Contains(req) {
   177  		t.Fatalf("AttrMask %v should not be a superset of %v", have, req)
   178  	}
   179  	have.Mode = true
   180  	if have.Contains(req) {
   181  		t.Fatalf("AttrMask %v should not be a superset of %v", have, req)
   182  	}
   183  	have.Size = true
   184  	have.MTime = true
   185  	if !have.Contains(req) {
   186  		t.Fatalf("AttrMask %v should be a superset of %v", have, req)
   187  	}
   188  }