github.com/rminnich/u-root@v7.0.0+incompatible/cmds/core/mv/mv_test.go (about)

     1  // Copyright 2015-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  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"syscall"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/u-root/u-root/pkg/testutil"
    17  )
    18  
    19  type makeIt struct {
    20  	n string      // name
    21  	m os.FileMode // mode
    22  	c []byte      // content
    23  }
    24  
    25  var hiFileContent = []byte("hi")
    26  
    27  var old = makeIt{
    28  	n: "old.txt",
    29  	m: 0777,
    30  	c: []byte("old"),
    31  }
    32  
    33  var new = makeIt{
    34  	n: "new.txt",
    35  	m: 0777,
    36  	c: []byte("new"),
    37  }
    38  
    39  var tests = []makeIt{
    40  	{
    41  		n: "hi1.txt",
    42  		m: 0666,
    43  		c: hiFileContent,
    44  	},
    45  	{
    46  		n: "hi2.txt",
    47  		m: 0777,
    48  		c: hiFileContent,
    49  	},
    50  	old,
    51  	new,
    52  }
    53  
    54  func setup() (string, error) {
    55  	d, err := ioutil.TempDir(os.TempDir(), "hi.dir")
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  
    60  	tmpdir := filepath.Join(d, "hi.sub.dir")
    61  	if err := os.Mkdir(tmpdir, 0777); err != nil {
    62  		return "", err
    63  	}
    64  
    65  	for _, t := range tests {
    66  		if err := ioutil.WriteFile(filepath.Join(d, t.n), []byte(t.c), t.m); err != nil {
    67  			return "", err
    68  		}
    69  	}
    70  
    71  	return d, nil
    72  }
    73  
    74  func getInode(file string) (uint64, error) {
    75  	var stat syscall.Stat_t
    76  	if err := syscall.Stat(file, &stat); err != nil {
    77  		return 0, err
    78  	}
    79  	return stat.Ino, nil
    80  }
    81  
    82  func TestMv(t *testing.T) {
    83  	d, err := setup()
    84  	if err != nil {
    85  		t.Fatal("err")
    86  	}
    87  	defer os.RemoveAll(d)
    88  
    89  	t.Logf("Renaming file...")
    90  	{
    91  		originalInode, err := getInode(filepath.Join(d, "hi1.txt"))
    92  		if err != nil {
    93  			t.Error(err)
    94  		}
    95  
    96  		files := []string{filepath.Join(d, "hi1.txt"), filepath.Join(d, "hi4.txt")}
    97  		res := testutil.Command(t, files...)
    98  		_, err = res.CombinedOutput()
    99  		if err = testutil.IsExitCode(err, 0); err != nil {
   100  			t.Error(err)
   101  		}
   102  
   103  		t.Logf("Verify renamed file integrity...")
   104  		{
   105  			content, err := ioutil.ReadFile(filepath.Join(d, "hi4.txt"))
   106  			if err != nil {
   107  				t.Error(err)
   108  			}
   109  
   110  			if !bytes.Equal(hiFileContent, content) {
   111  				t.Errorf("Expected file content to equal %s, got %s", hiFileContent, content)
   112  			}
   113  
   114  			movedInode, err := getInode(filepath.Join(d, "hi4.txt"))
   115  			if err != nil {
   116  				t.Error(err)
   117  			}
   118  
   119  			if originalInode != movedInode {
   120  				t.Errorf("Expected inode to equal. Expected %d, got %d", originalInode, movedInode)
   121  			}
   122  		}
   123  	}
   124  
   125  	dsub := filepath.Join(d, "hi.sub.dir")
   126  
   127  	t.Logf("Moving files to directory...")
   128  	{
   129  		originalInode, err := getInode(filepath.Join(d, "hi2.txt"))
   130  		if err != nil {
   131  			t.Error(err)
   132  		}
   133  
   134  		originalInodeFour, err := getInode(filepath.Join(d, "hi4.txt"))
   135  		if err != nil {
   136  			t.Error(err)
   137  		}
   138  
   139  		files := []string{filepath.Join(d, "hi2.txt"), filepath.Join(d, "hi4.txt"), dsub}
   140  		res := testutil.Command(t, files...)
   141  		_, err = res.CombinedOutput()
   142  		if err = testutil.IsExitCode(err, 0); err != nil {
   143  			t.Error(err)
   144  		}
   145  
   146  		t.Logf("Verify moved files into directory file integrity...")
   147  		{
   148  			content, err := ioutil.ReadFile(filepath.Join(dsub, "hi4.txt"))
   149  			if err != nil {
   150  				t.Error(err)
   151  			}
   152  
   153  			if !bytes.Equal(hiFileContent, content) {
   154  				t.Errorf("Expected file content to equal %s, got %s", hiFileContent, content)
   155  			}
   156  
   157  			movedInode, err := getInode(filepath.Join(dsub, "hi2.txt"))
   158  			if err != nil {
   159  				t.Error(err)
   160  			}
   161  
   162  			movedInodeFour, err := getInode(filepath.Join(dsub, "hi4.txt"))
   163  			if err != nil {
   164  				t.Error(err)
   165  			}
   166  
   167  			if originalInode != movedInode {
   168  				t.Errorf("Expected inode to equal. Expected %d, got %d", originalInode, movedInode)
   169  			}
   170  
   171  			if originalInodeFour != movedInodeFour {
   172  				t.Errorf("Expected inode to equal. Expected %d, got %d", originalInodeFour, movedInodeFour)
   173  			}
   174  		}
   175  	}
   176  }
   177  
   178  func TestMvUpdate(t *testing.T) {
   179  	*update = true
   180  	d, err := setup()
   181  	if err != nil {
   182  		t.Error(err)
   183  	}
   184  	defer os.RemoveAll(d)
   185  	t.Logf("Testing mv -u...")
   186  
   187  	// Ensure that the newer file actually has a newer timestamp
   188  	currentTime := time.Now().Local()
   189  	oldTime := currentTime.Add(-10 * time.Second)
   190  	err = os.Chtimes(filepath.Join(d, old.n), oldTime, oldTime)
   191  	if err != nil {
   192  		t.Error(err)
   193  	}
   194  	err = os.Chtimes(filepath.Join(d, new.n), currentTime, currentTime)
   195  	if err != nil {
   196  		t.Error(err)
   197  	}
   198  
   199  	// Check that it doesn't downgrade files with -u switch
   200  	{
   201  		files := []string{"-u", filepath.Join(d, old.n), filepath.Join(d, new.n)}
   202  		res := testutil.Command(t, files...)
   203  		_, err = res.CombinedOutput()
   204  		if err = testutil.IsExitCode(err, 0); err != nil {
   205  			t.Error(err)
   206  		}
   207  		newContent, err := ioutil.ReadFile(filepath.Join(d, new.n))
   208  		if err != nil {
   209  			t.Error(err)
   210  		}
   211  		if bytes.Equal(newContent, old.c) {
   212  			t.Error("Newer file was overwritten by older file. Should not happen with -u.")
   213  		}
   214  	}
   215  
   216  	// Check that it does update files with -u switch
   217  	{
   218  		files := []string{"-u", filepath.Join(d, new.n), filepath.Join(d, old.n)}
   219  		res := testutil.Command(t, files...)
   220  		_, err = res.CombinedOutput()
   221  		if err = testutil.IsExitCode(err, 0); err != nil {
   222  			t.Error(err)
   223  		}
   224  		newContent, err := ioutil.ReadFile(filepath.Join(d, old.n))
   225  		if err != nil {
   226  			t.Error(err)
   227  		}
   228  		if !bytes.Equal(newContent, new.c) {
   229  			t.Error("Older file was not overwritten by newer file. Should happen with -u.")
   230  		}
   231  		if _, err := os.Lstat(filepath.Join(d, old.n)); err != nil {
   232  			t.Error("The new file shouldn't be there anymore.")
   233  		}
   234  	}
   235  }
   236  
   237  func TestMvNoClobber(t *testing.T) {
   238  	*noClobber = true
   239  	d, err := setup()
   240  	if err != nil {
   241  		t.Error(err)
   242  	}
   243  	defer os.RemoveAll(d)
   244  	t.Logf("Testing mv -n...")
   245  
   246  	// Check that it doesn't override files with -n switch
   247  	{
   248  		files := []string{"-n", filepath.Join(d, old.n), filepath.Join(d, new.n)}
   249  		res := testutil.Command(t, files...)
   250  		_, err = res.CombinedOutput()
   251  		if err = testutil.IsExitCode(err, 0); err != nil {
   252  			t.Error(err)
   253  		}
   254  		newContent, err := ioutil.ReadFile(filepath.Join(d, new.n))
   255  		if err != nil {
   256  			t.Error(err)
   257  		}
   258  		if bytes.Equal(newContent, old.c) {
   259  			t.Error("File was overwritten. Should not happen with -u.")
   260  		}
   261  	}
   262  
   263  	// Check that it does mv files with -u switch
   264  	{
   265  		files := []string{"-n", filepath.Join(d, new.n), filepath.Join(d, "hi3.txt")}
   266  		res := testutil.Command(t, files...)
   267  		_, err = res.CombinedOutput()
   268  		if err = testutil.IsExitCode(err, 0); err != nil {
   269  			t.Error(err)
   270  		}
   271  		newContent, err := ioutil.ReadFile(filepath.Join(d, "hi3.txt"))
   272  		if err != nil {
   273  			t.Error(err)
   274  		}
   275  		if !bytes.Equal(newContent, new.c) {
   276  			t.Error("File was not moved. Should happen with -u.")
   277  		}
   278  		if _, err := os.Lstat(filepath.Join(d, old.n)); err != nil {
   279  			t.Error("File was copied but not moved.")
   280  		}
   281  	}
   282  }
   283  
   284  func TestMain(m *testing.M) {
   285  	testutil.Run(m, main)
   286  }