github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/chmod/chmod_test.go (about)

     1  // Copyright 2016-2017 the u-root 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  package main
     6  
     7  import (
     8  	"bytes"
     9  	"io/ioutil"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/u-root/u-root/pkg/testutil"
    16  )
    17  
    18  type fileModeTrans struct {
    19  	before os.FileMode
    20  	after  os.FileMode
    21  }
    22  
    23  func run(c *exec.Cmd) (string, string, error) {
    24  	var o, e bytes.Buffer
    25  	c.Stdout, c.Stderr = &o, &e
    26  	err := c.Run()
    27  	return o.String(), e.String(), err
    28  }
    29  
    30  func TestChmodSimple(t *testing.T) {
    31  	// Temporary directories.
    32  	tempDir, err := ioutil.TempDir("", "TestChmodSimple")
    33  	if err != nil {
    34  		t.Fatalf("cannot create temporary directory: %v", err)
    35  	}
    36  	defer os.RemoveAll(tempDir)
    37  
    38  	f, err := ioutil.TempFile(tempDir, "BLAH1")
    39  	if err != nil {
    40  		t.Fatalf("cannot create temporary file: %v", err)
    41  	}
    42  	defer f.Close()
    43  
    44  	for k, v := range map[string]fileModeTrans{
    45  		"0777":       {before: 0000, after: 0777},
    46  		"0644":       {before: 0777, after: 0644},
    47  		"u-rwx":      {before: 0777, after: 0077},
    48  		"g-rx":       {before: 0777, after: 0727},
    49  		"a-xr":       {before: 0222, after: 0222},
    50  		"a-xw":       {before: 0666, after: 0444},
    51  		"u-xw":       {before: 0666, after: 0466},
    52  		"a=":         {before: 0777, after: 0000},
    53  		"u=":         {before: 0777, after: 0077},
    54  		"u-":         {before: 0777, after: 0777},
    55  		"o+":         {before: 0700, after: 0700},
    56  		"g=rx":       {before: 0777, after: 0757},
    57  		"u=rx":       {before: 0077, after: 0577},
    58  		"o=rx":       {before: 0077, after: 0075},
    59  		"u=xw":       {before: 0742, after: 0342},
    60  		"a-rwx":      {before: 0777, after: 0000},
    61  		"a-rx":       {before: 0777, after: 0222},
    62  		"a-x":        {before: 0777, after: 0666},
    63  		"o+rwx":      {before: 0000, after: 0007},
    64  		"a+rwx":      {before: 0000, after: 0777},
    65  		"a+xrw":      {before: 0000, after: 0777},
    66  		"a+xxxxxxxx": {before: 0000, after: 0111},
    67  		"o+xxxxx":    {before: 0000, after: 0001},
    68  		"a+rx":       {before: 0000, after: 0555},
    69  		"a+r":        {before: 0111, after: 0555},
    70  		"a=rwx":      {before: 0000, after: 0777},
    71  		"a=rx":       {before: 0000, after: 0555}} {
    72  		// Set up the 'before' state
    73  		err := os.Chmod(f.Name(), v.before)
    74  		if err != nil {
    75  			t.Fatalf("chmod(%q) failed: %v", f.Name(), err)
    76  		}
    77  
    78  		// Set permissions using chmod.
    79  		c := testutil.Command(t, k, f.Name())
    80  		err = c.Run()
    81  		if err != nil {
    82  			t.Fatalf("setting permissions failed: %v", err)
    83  		}
    84  
    85  		// Check that it worked.
    86  		checkPath(t, f.Name(), k, v)
    87  	}
    88  }
    89  
    90  func checkPath(t *testing.T, path string, instruction string, v fileModeTrans) {
    91  	info, err := os.Stat(path)
    92  	if err != nil {
    93  		t.Fatalf("stat(%q) failed: %v", path, err)
    94  	}
    95  	if got := info.Mode().Perm(); got != v.after {
    96  		t.Errorf("Wrong file permissions on %q: executed %s, before %0o, got %0o, want %0o", path, instruction, v.before, got, v.after)
    97  	}
    98  }
    99  
   100  func TestChmodRecursive(t *testing.T) {
   101  	// Temporary directories.
   102  	tempDir, err := ioutil.TempDir("", "TestChmodRecursive")
   103  	if err != nil {
   104  		t.Fatalf("cannot create temporary directory: %v", err)
   105  	}
   106  	defer os.RemoveAll(tempDir)
   107  
   108  	var targetDirectories []string
   109  	for _, dir := range []string{"L1_A", "L1_B", "L1_C",
   110  		filepath.Join("L1_A", "L2_A"),
   111  		filepath.Join("L1_A", "L2_B"),
   112  		filepath.Join("L1_A", "L2_C"),
   113  		filepath.Join("L1_B", "L2_A"),
   114  		filepath.Join("L1_B", "L2_B"),
   115  		filepath.Join("L1_B", "L2_C"),
   116  		filepath.Join("L1_C", "L2_A"),
   117  		filepath.Join("L1_C", "L2_B"),
   118  		filepath.Join("L1_C", "L2_C"),
   119  	} {
   120  		dir = filepath.Join(tempDir, dir)
   121  		err := os.Mkdir(dir, os.FileMode(0700))
   122  		if err != nil {
   123  			t.Fatalf("cannot create test directory: %v", err)
   124  		}
   125  		targetDirectories = append(targetDirectories, dir)
   126  	}
   127  
   128  	for k, v := range map[string]fileModeTrans{
   129  		"0707":      {before: 0755, after: 0707},
   130  		"0770":      {before: 0755, after: 0770},
   131  		"o-rwx":     {before: 0777, after: 0770},
   132  		"g-rx":      {before: 0777, after: 0727},
   133  		"a=rrrrrwx": {before: 0777, after: 0777},
   134  		"a+w":       {before: 0700, after: 0722},
   135  		"g+xr":      {before: 0700, after: 0750},
   136  		"a=rx":      {before: 0777, after: 0555}} {
   137  
   138  		// Set up the 'before' state
   139  		for _, dir := range targetDirectories {
   140  			err := os.Chmod(dir, v.before)
   141  			if err != nil {
   142  				t.Fatalf("chmod(%q) failed: %v", dir, err)
   143  			}
   144  		}
   145  
   146  		// Set permissions using chmod.
   147  		c := testutil.Command(t, "-R", k, tempDir)
   148  		err = c.Run()
   149  		if err != nil {
   150  			t.Fatalf("setting permissions failed: %v", err)
   151  		}
   152  
   153  		// Check that it worked.
   154  		for _, dir := range targetDirectories {
   155  			checkPath(t, dir, k, v)
   156  		}
   157  	}
   158  }
   159  
   160  func TestChmodReference(t *testing.T) {
   161  	// Temporary directories.
   162  	tempDir, err := ioutil.TempDir("", "TestChmodReference")
   163  	if err != nil {
   164  		t.Fatalf("cannot create temporary directory: %v", err)
   165  	}
   166  	defer os.RemoveAll(tempDir)
   167  
   168  	sourceFile, err := ioutil.TempFile(tempDir, "BLAH1")
   169  	if err != nil {
   170  		t.Fatalf("cannot create temporary file: %v", err)
   171  	}
   172  	defer sourceFile.Close()
   173  
   174  	targetFile, err := ioutil.TempFile(tempDir, "BLAH2")
   175  	if err != nil {
   176  		t.Fatalf("cannot create temporary file: %v", err)
   177  	}
   178  	defer targetFile.Close()
   179  
   180  	for _, perm := range []os.FileMode{0777, 0644} {
   181  		err = os.Chmod(sourceFile.Name(), perm)
   182  		if err != nil {
   183  			t.Fatalf("chmod(%q) failed: %v", sourceFile.Name(), err)
   184  		}
   185  
   186  		// Set target file permissions using chmod.
   187  		c := testutil.Command(t,
   188  			"--reference",
   189  			sourceFile.Name(),
   190  			targetFile.Name())
   191  		err = c.Run()
   192  		if err != nil {
   193  			t.Fatalf("setting permissions failed: %v", err)
   194  		}
   195  
   196  		// Check that it worked.
   197  		info, err := os.Stat(targetFile.Name())
   198  		if err != nil {
   199  			t.Fatalf("stat(%q) failed: %v", targetFile.Name(), err)
   200  		}
   201  		if got := info.Mode().Perm(); got != perm {
   202  			t.Fatalf("Wrong file permissions on file %q: got %0o, want %0o",
   203  				targetFile.Name(), got, perm)
   204  		}
   205  	}
   206  }
   207  
   208  func TestInvocationErrors(t *testing.T) {
   209  	tempDir, err := ioutil.TempDir("", "TestInvocationErrors")
   210  	if err != nil {
   211  		t.Fatalf("cannot create temporary directory: %v", err)
   212  	}
   213  	defer os.RemoveAll(tempDir)
   214  
   215  	f, err := ioutil.TempFile(tempDir, "BLAH1")
   216  	if err != nil {
   217  		t.Fatalf("cannot create temporary file: %v", err)
   218  	}
   219  	defer f.Close()
   220  
   221  	for _, v := range []struct {
   222  		args     []string
   223  		want     string
   224  		skipTo   int
   225  		skipFrom int
   226  	}{
   227  
   228  		{
   229  			args:     []string{f.Name()},
   230  			want:     "Usage",
   231  			skipTo:   0,
   232  			skipFrom: len("Usage"),
   233  		},
   234  		{
   235  			args:     []string{""},
   236  			want:     "Usage",
   237  			skipTo:   0,
   238  			skipFrom: len("Usage"),
   239  		},
   240  		{
   241  			args:     []string{"01777", f.Name()},
   242  			want:     "Invalid octal value 1777. Value should be less than or equal to 0777.\n",
   243  			skipTo:   20,
   244  			skipFrom: -1,
   245  		},
   246  		{
   247  			args:     []string{"0abas", f.Name()},
   248  			want:     "Unable to decode mode \"0abas\". Please use an octal value or a valid mode string.\n",
   249  			skipTo:   20,
   250  			skipFrom: -1,
   251  		},
   252  		{
   253  			args:     []string{"0777", "blah1234"},
   254  			want:     "chmod blah1234: no such file or directory\n",
   255  			skipTo:   20,
   256  			skipFrom: -1,
   257  		},
   258  		{
   259  			args:     []string{"a=9rwx", f.Name()},
   260  			want:     "Unable to decode mode \"a=9rwx\". Please use an octal value or a valid mode string.\n",
   261  			skipTo:   20,
   262  			skipFrom: -1,
   263  		},
   264  		{
   265  			args:     []string{"+r", f.Name()},
   266  			want:     "Unable to decode mode \"+r\". Please use an octal value or a valid mode string.\n",
   267  			skipTo:   20,
   268  			skipFrom: -1,
   269  		},
   270  		{
   271  			args:     []string{"a%rwx", f.Name()},
   272  			want:     "Unable to decode mode \"a%rwx\". Please use an octal value or a valid mode string.\n",
   273  			skipTo:   20,
   274  			skipFrom: -1,
   275  		},
   276  		{
   277  			args:     []string{"b=rwx", f.Name()},
   278  			want:     "Unable to decode mode \"b=rwx\". Please use an octal value or a valid mode string.\n",
   279  			skipTo:   20,
   280  			skipFrom: -1,
   281  		},
   282  	} {
   283  		cmd := testutil.Command(t, v.args...)
   284  		_, stderr, err := run(cmd)
   285  		if v.skipFrom == -1 {
   286  			v.skipFrom = len(stderr)
   287  		}
   288  		// Ignore the date and time because we're using Log.Fatalf
   289  		if got := stderr[v.skipTo:v.skipFrom]; got != v.want {
   290  			t.Errorf("Chmod for %q failed: got %q, want %q", v.args, got, v.want)
   291  		}
   292  		if err == nil {
   293  			t.Errorf("Chmod for %q failed: got nil want err", v.args)
   294  		}
   295  	}
   296  }
   297  
   298  func TestMain(m *testing.M) {
   299  	testutil.Run(m, main)
   300  }