golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/xattr_zos_test.go (about)

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build zos
     6  
     7  package unix_test
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  func TestXattr(t *testing.T) {
    17  	defer chtmpdir(t)()
    18  
    19  	f := "xattr1"
    20  	touch(t, f)
    21  
    22  	xattrName := "system.filetag"
    23  	xattrDataSet := make([]byte, 4)
    24  	xattrDataSet[0] = 0xFF
    25  	xattrDataSet[1] = 0xFF
    26  	xattrDataSet[2] = 0
    27  	xattrDataSet[3] = 0
    28  
    29  	err := unix.Setxattr(f, xattrName, xattrDataSet, 0)
    30  	if err != nil {
    31  		t.Fatalf("Setxattr: %v", err)
    32  	}
    33  
    34  	// find size
    35  	size, err := unix.Listxattr(f, nil)
    36  	if err != nil {
    37  		t.Fatalf("Listxattr: %v", err)
    38  	}
    39  
    40  	if size <= 0 {
    41  		t.Fatalf("Listxattr returned an empty list of attributes")
    42  	}
    43  
    44  	buf := make([]byte, size)
    45  	read, err := unix.Listxattr(f, buf)
    46  	if err != nil {
    47  		t.Fatalf("Listxattr: %v", err)
    48  	}
    49  
    50  	xattrs := stringsFromByteSlice(buf[:read])
    51  
    52  	xattrWant := xattrName
    53  	found := false
    54  	for _, name := range xattrs {
    55  		if name == xattrWant {
    56  			found = true
    57  			break
    58  		}
    59  	}
    60  
    61  	if !found {
    62  		t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName)
    63  	}
    64  
    65  	// find size
    66  	size, err = unix.Getxattr(f, xattrName, nil)
    67  	if err != nil {
    68  		t.Fatalf("Getxattr: %v", err)
    69  	}
    70  
    71  	if size <= 0 {
    72  		t.Fatalf("Getxattr returned an empty attribute")
    73  	}
    74  
    75  	xattrDataGet := make([]byte, size)
    76  	_, err = unix.Getxattr(f, xattrName, xattrDataGet)
    77  	if err != nil {
    78  		t.Fatalf("Getxattr: %v", err)
    79  	}
    80  	got := string([]byte(xattrDataGet))
    81  	if got != string(xattrDataSet) {
    82  		t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got)
    83  	}
    84  
    85  	err = unix.Removexattr(f, xattrName)
    86  	if err != nil {
    87  		t.Fatalf("Removexattr: %v", err)
    88  	}
    89  
    90  	//confirm xattr removed
    91  	// find size
    92  	size, err = unix.Listxattr(f, nil)
    93  	if err != nil {
    94  		t.Fatalf("Listxattr: %v", err)
    95  	}
    96  	if size != 0 {
    97  		buf := make([]byte, size)
    98  		read, err = unix.Listxattr(f, buf)
    99  		if err != nil {
   100  			t.Fatalf("Listxattr: %v", err)
   101  		}
   102  
   103  		xattrs = stringsFromByteSlice(buf[:read])
   104  
   105  		found = false
   106  		for _, name := range xattrs {
   107  			if name == xattrWant {
   108  				found = true
   109  				break
   110  			}
   111  			if found {
   112  				t.Errorf("Removexattr failed to remove attribute '%s'", xattrName)
   113  			}
   114  		}
   115  	}
   116  	n := "nonexistent"
   117  	err = unix.Lsetxattr(n, xattrName, xattrDataSet, 0)
   118  	if err != unix.ENOENT {
   119  		t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENODATA, err)
   120  	}
   121  
   122  	_, err = unix.Lgetxattr(f, n, nil)
   123  	if err != unix.ENODATA {
   124  		t.Errorf("Lgetxattr: %v", err)
   125  	}
   126  
   127  	_, err = unix.Lgetxattr(n, xattrName, nil)
   128  	if err != unix.ENOENT {
   129  		t.Errorf("Lgetxattr: %v", err)
   130  	}
   131  }
   132  
   133  func TestFdXattr(t *testing.T) {
   134  	file, err := os.CreateTemp("", "TestFdXattr")
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	defer os.Remove(file.Name())
   139  	defer file.Close()
   140  
   141  	fd := int(file.Fd())
   142  	xattrName := "system.filetag"
   143  	xattrDataSet := make([]byte, 4)
   144  	xattrDataSet[0] = 0xFF
   145  	xattrDataSet[1] = 0xFF
   146  	xattrDataSet[2] = 0
   147  	xattrDataSet[3] = 0
   148  
   149  	err = unix.Fsetxattr(fd, xattrName, xattrDataSet, 0)
   150  	if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
   151  		t.Skip("filesystem does not support extended attributes, skipping test")
   152  	} else if err != nil {
   153  		t.Fatalf("Fsetxattr: %v", err)
   154  	}
   155  
   156  	// find size
   157  	size, err := unix.Flistxattr(fd, nil)
   158  	if err != nil {
   159  		t.Fatalf("Flistxattr: %v", err)
   160  	}
   161  	if size <= 0 {
   162  		t.Fatalf("Flistxattr returned an empty list of attributes")
   163  	}
   164  
   165  	buf := make([]byte, size)
   166  	read, err := unix.Flistxattr(fd, buf)
   167  	if err != nil {
   168  		t.Fatalf("Flistxattr: %v", err)
   169  	}
   170  
   171  	xattrs := stringsFromByteSlice(buf[:read])
   172  
   173  	xattrWant := xattrName
   174  	found := false
   175  	for _, name := range xattrs {
   176  		if name == xattrWant {
   177  			found = true
   178  			break
   179  		}
   180  	}
   181  
   182  	if !found {
   183  		t.Errorf("Flistxattr did not return previously set attribute '%s'", xattrName)
   184  	}
   185  
   186  	// find size
   187  	size, err = unix.Fgetxattr(fd, xattrName, nil)
   188  	if err != nil {
   189  		t.Fatalf("Fgetxattr: %v", err)
   190  	}
   191  
   192  	if size <= 0 {
   193  		t.Fatalf("Fgetxattr returned an empty attribute")
   194  	}
   195  
   196  	xattrDataGet := make([]byte, size)
   197  	_, err = unix.Fgetxattr(fd, xattrName, xattrDataGet)
   198  	if err != nil {
   199  		t.Fatalf("Fgetxattr: %v", err)
   200  	}
   201  
   202  	got := string([]byte(xattrDataGet))
   203  	if got != string(xattrDataSet) {
   204  		t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got)
   205  	}
   206  
   207  	err = unix.Fremovexattr(fd, xattrName)
   208  	if err != nil {
   209  		t.Fatalf("Fremovexattr: %v", err)
   210  	}
   211  
   212  	//confirm xattr removed
   213  	// find size
   214  	size, err = unix.Flistxattr(fd, nil)
   215  	if err != nil {
   216  		t.Fatalf("Flistxattr: %v", err)
   217  	}
   218  	if size != 0 {
   219  		buf := make([]byte, size)
   220  		read, err = unix.Flistxattr(fd, buf)
   221  		if err != nil {
   222  			t.Fatalf("Flistxattr: %v", err)
   223  		}
   224  
   225  		xattrs = stringsFromByteSlice(buf[:read])
   226  
   227  		found = false
   228  		for _, name := range xattrs {
   229  			if name == xattrWant {
   230  				found = true
   231  				break
   232  			}
   233  			if found {
   234  				t.Errorf("Fremovexattr failed to remove attribute '%s'", xattrName)
   235  			}
   236  		}
   237  	}
   238  }