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

     1  // Copyright 2018 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  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"reflect"
    15  	"strings"
    16  	"syscall"
    17  	"testing"
    18  
    19  	"github.com/u-root/u-root/pkg/testutil"
    20  )
    21  
    22  type MkdirErrorTestcase struct {
    23  	name string
    24  	args []string
    25  	exp  string
    26  }
    27  
    28  type MkdirPermTestCase struct {
    29  	name     string
    30  	args     []string
    31  	perm     os.FileMode
    32  	dirNames []string
    33  }
    34  
    35  var (
    36  	stubDirNames   = []string{"stub", "stub2"}
    37  	umaskDefault   = 022
    38  	errorTestCases = []MkdirErrorTestcase{
    39  		{
    40  			name: "No Arg Error",
    41  			args: nil,
    42  			exp:  "Usage",
    43  		},
    44  		{
    45  			name: "Perm Mode Bits over 7 Error",
    46  			args: []string{"-m=7778", stubDirNames[0]},
    47  			exp:  `invalid mode '7778'`,
    48  		},
    49  		{
    50  			name: "More than 4 Perm Mode Bits Error",
    51  			args: []string{"-m=11111", stubDirNames[0]},
    52  			exp:  `invalid mode '11111'`,
    53  		},
    54  	}
    55  
    56  	regularTestCases = []struct {
    57  		name string
    58  		args []string
    59  		exp  []string
    60  	}{
    61  		{
    62  			name: "Create 1 Directory",
    63  			args: []string{stubDirNames[0]},
    64  			exp:  []string{stubDirNames[0]},
    65  		},
    66  		{
    67  			name: "Create 2 Directories",
    68  			args: stubDirNames,
    69  			exp:  stubDirNames,
    70  		},
    71  	}
    72  
    73  	permTestCases = []MkdirPermTestCase{
    74  		{
    75  			name:     "Default Perm",
    76  			args:     []string{stubDirNames[0]},
    77  			perm:     os.FileMode(0755 | os.ModeDir),
    78  			dirNames: []string{stubDirNames[0]},
    79  		},
    80  		{
    81  			name:     "Custom Perm in Octal Form",
    82  			args:     []string{"-m=0777", stubDirNames[0]},
    83  			perm:     os.FileMode(0777 | os.ModeDir),
    84  			dirNames: []string{stubDirNames[0]},
    85  		},
    86  		{
    87  			name:     "Custom Perm not in Octal Form",
    88  			args:     []string{"-m=777", stubDirNames[0]},
    89  			perm:     os.FileMode(0777 | os.ModeDir),
    90  			dirNames: []string{stubDirNames[0]},
    91  		},
    92  		{
    93  			name:     "Custom Perm with Sticky Bit",
    94  			args:     []string{"-m=1777", stubDirNames[0]},
    95  			perm:     os.FileMode(0777 | os.ModeDir | os.ModeSticky),
    96  			dirNames: []string{stubDirNames[0]},
    97  		},
    98  		{
    99  			name:     "Custom Perm with SGID Bit",
   100  			args:     []string{"-m=2777", stubDirNames[0]},
   101  			perm:     os.FileMode(0777 | os.ModeDir | os.ModeSetgid),
   102  			dirNames: []string{stubDirNames[0]},
   103  		},
   104  		{
   105  			name:     "Custom Perm with SUID Bit",
   106  			args:     []string{"-m=4777", stubDirNames[0]},
   107  			perm:     os.FileMode(0777 | os.ModeDir | os.ModeSetuid),
   108  			dirNames: []string{stubDirNames[0]},
   109  		},
   110  		{
   111  			name:     "Custom Perm with Sticky Bit and SUID Bit",
   112  			args:     []string{"-m=5777", stubDirNames[0]},
   113  			perm:     os.FileMode(0777 | os.ModeDir | os.ModeSticky | os.ModeSetuid),
   114  			dirNames: []string{stubDirNames[0]},
   115  		},
   116  		{
   117  			name:     "Custom Perm for 2 Directories",
   118  			args:     []string{"-m=5777", stubDirNames[0], stubDirNames[1]},
   119  			perm:     os.FileMode(0777 | os.ModeDir | os.ModeSticky | os.ModeSetuid),
   120  			dirNames: stubDirNames,
   121  		},
   122  	}
   123  )
   124  
   125  func run(c *exec.Cmd) (string, string, error) {
   126  	var o, e bytes.Buffer
   127  	c.Stdout, c.Stderr = &o, &e
   128  	err := c.Run()
   129  	return o.String(), e.String(), err
   130  }
   131  
   132  func printError(t *testing.T, testname string, execStmt string, out interface{}, exp interface{}) {
   133  	t.Logf("TEST %v", testname)
   134  	t.Errorf("%s\ngot:%v\nwant:%v", execStmt, out, exp)
   135  }
   136  
   137  func findFile(dir string, filename string) (os.FileInfo, error) {
   138  	files, err := ioutil.ReadDir(dir)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  	for _, file := range files {
   143  		if file.Name() == filename {
   144  			return file, nil
   145  		}
   146  	}
   147  	return nil, nil
   148  }
   149  
   150  func removeCreatedFiles(tmpDir string) {
   151  	for _, dirName := range stubDirNames {
   152  		os.Remove(filepath.Join(tmpDir, dirName))
   153  	}
   154  }
   155  
   156  func TestMkdirErrors(t *testing.T) {
   157  	// Set Up
   158  	tmpDir, err := ioutil.TempDir("", "ls")
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	defer os.RemoveAll(tmpDir)
   163  	syscall.Umask(umaskDefault)
   164  
   165  	// Error Tests
   166  	for _, test := range errorTestCases {
   167  		removeCreatedFiles(tmpDir)
   168  		c := testutil.Command(t, test.args...)
   169  		execStmt := fmt.Sprintf("exec(mkdir %s)", strings.Trim(fmt.Sprint(test.args), "[]"))
   170  		c.Dir = tmpDir
   171  		_, e, err := run(c)
   172  		if err == nil || !strings.Contains(e, test.exp) {
   173  			printError(t, test.name, execStmt, e, test.exp)
   174  			continue
   175  		}
   176  		f, err := findFile(tmpDir, stubDirNames[0])
   177  		if err != nil {
   178  			printError(t, test.name, execStmt, err, "No error while finding the file")
   179  			continue
   180  		}
   181  		if f != nil {
   182  			printError(t, test.name, execStmt, "A directory was created", "No directory should be created")
   183  		}
   184  	}
   185  }
   186  
   187  func TestMkdirRegular(t *testing.T) {
   188  	// Set Up
   189  	tmpDir, err := ioutil.TempDir("", "ls")
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	defer os.RemoveAll(tmpDir)
   194  	syscall.Umask(umaskDefault)
   195  
   196  	// Regular Tests
   197  	for _, test := range regularTestCases {
   198  		removeCreatedFiles(tmpDir)
   199  		c := testutil.Command(t, test.args...)
   200  		execStmt := fmt.Sprintf("exec(mkdir %s)", strings.Trim(fmt.Sprint(test.args), "[]"))
   201  		c.Dir = tmpDir
   202  		_, e, err := run(c)
   203  		if err != nil {
   204  			printError(t, test.name, execStmt, e, "No error while mkdir")
   205  			continue
   206  		}
   207  		for _, dirName := range test.exp {
   208  			f, err := findFile(tmpDir, dirName)
   209  			if err != nil {
   210  				printError(t, test.name, execStmt, err, "No error while finding the file")
   211  				break
   212  			}
   213  			if f == nil {
   214  				printError(t, test.name, execStmt, fmt.Sprintf("%s not found", dirName), fmt.Sprintf("%s should have been created", dirName))
   215  				break
   216  			}
   217  		}
   218  	}
   219  }
   220  
   221  func TestMkdirPermission(t *testing.T) {
   222  	// Set Up
   223  	tmpDir, err := ioutil.TempDir("", "ls")
   224  	if err != nil {
   225  		t.Fatal(err)
   226  	}
   227  	defer os.RemoveAll(tmpDir)
   228  	syscall.Umask(umaskDefault)
   229  
   230  	// Permission Tests
   231  	for _, test := range permTestCases {
   232  		removeCreatedFiles(tmpDir)
   233  		c := testutil.Command(t, test.args...)
   234  		execStmt := fmt.Sprintf("exec(mkdir %s)", strings.Trim(fmt.Sprint(test.args), "[]"))
   235  		c.Dir = tmpDir
   236  		_, e, err := run(c)
   237  		if err != nil {
   238  			printError(t, test.name, execStmt, e, "No error while mkdir")
   239  			continue
   240  		}
   241  		for _, dirName := range test.dirNames {
   242  			f, err := findFile(tmpDir, dirName)
   243  			if err != nil {
   244  				printError(t, test.name, execStmt, err, "No error while finding the file")
   245  				break
   246  			}
   247  			if f == nil {
   248  				printError(t, test.name, execStmt, fmt.Sprintf("%s not found", dirName), fmt.Sprintf("%s should have been created", dirName))
   249  				break
   250  			}
   251  			if f != nil && !reflect.DeepEqual(f.Mode(), test.perm) {
   252  				printError(t, test.name, execStmt, f.Mode(), test.perm)
   253  				break
   254  			}
   255  		}
   256  	}
   257  }
   258  
   259  func TestMain(m *testing.M) {
   260  	testutil.Run(m, main)
   261  }