go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/system/filesystem/filepath_test.go (about)

     1  // Copyright 2019 The LUCI 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 filesystem
    16  
    17  import (
    18  	"context"
    19  	"os"
    20  	"path/filepath"
    21  	"testing"
    22  
    23  	. "github.com/smartystreets/goconvey/convey"
    24  )
    25  
    26  func TestSetReadOnly(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	Convey("Simple tests for SetReadOnly", t, func() {
    30  		tmpdir := t.TempDir()
    31  
    32  		tmpfile := filepath.Join(tmpdir, "tmp")
    33  		f, err := os.Create(tmpfile)
    34  		So(err, ShouldBeNil)
    35  		So(f.Close(), ShouldBeNil)
    36  
    37  		// make tmpfile readonly
    38  		So(SetReadOnly(tmpfile, true), ShouldBeNil)
    39  
    40  		_, err = os.Create(tmpfile)
    41  		So(err, ShouldNotBeNil)
    42  
    43  		f, err = os.Open(tmpfile)
    44  		So(err, ShouldBeNil)
    45  		So(f.Close(), ShouldBeNil)
    46  
    47  		// make tmpfile writable
    48  		So(SetReadOnly(tmpfile, false), ShouldBeNil)
    49  
    50  		f, err = os.Create(tmpfile)
    51  		So(err, ShouldBeNil)
    52  		So(f.Close(), ShouldBeNil)
    53  
    54  		f, err = os.Open(tmpfile)
    55  		So(err, ShouldBeNil)
    56  		So(f.Close(), ShouldBeNil)
    57  	})
    58  
    59  }
    60  
    61  func TestMakeTreeReadOnly(t *testing.T) {
    62  	Convey("Simple test for MakeTreeReadOnly", t, func() {
    63  		tmpdir := t.TempDir()
    64  
    65  		tmpfile := filepath.Join(tmpdir, "tmp")
    66  		f, err := os.Create(tmpfile)
    67  		So(err, ShouldBeNil)
    68  		So(f.Close(), ShouldBeNil)
    69  
    70  		So(MakeTreeReadOnly(context.Background(), tmpdir), ShouldBeNil)
    71  
    72  		_, err = os.Create(tmpfile)
    73  		So(err, ShouldNotBeNil)
    74  
    75  		// for os.RemoveAll
    76  		So(SetReadOnly(tmpdir, false), ShouldBeNil)
    77  	})
    78  }
    79  
    80  func TestMakeTreeFilesReadOnly(t *testing.T) {
    81  	Convey("Simple test for MakeTreeFilesReadOnly", t, func() {
    82  		tmpdir := t.TempDir()
    83  
    84  		tmpfile := filepath.Join(tmpdir, "tmp")
    85  		f, err := os.Create(tmpfile)
    86  		So(err, ShouldBeNil)
    87  		So(f.Close(), ShouldBeNil)
    88  
    89  		So(MakeTreeFilesReadOnly(context.Background(), tmpdir), ShouldBeNil)
    90  
    91  		Convey("cannot change existing file", func() {
    92  			_, err := os.Create(tmpfile)
    93  			So(err, ShouldNotBeNil)
    94  		})
    95  
    96  		Convey("but it is possible to create new file", func() {
    97  			f, err := os.Create(filepath.Join(tmpdir, "tmp2"))
    98  			So(err, ShouldBeNil)
    99  			So(f.Close(), ShouldBeNil)
   100  		})
   101  	})
   102  }
   103  
   104  func TestMakeTreeWritable(t *testing.T) {
   105  	Convey("Simple test for MakeTreeWritable", t, func() {
   106  		tmpdir := t.TempDir()
   107  
   108  		tmpfile := filepath.Join(tmpdir, "tmp")
   109  		f, err := os.Create(tmpfile)
   110  		So(err, ShouldBeNil)
   111  		So(f.Close(), ShouldBeNil)
   112  
   113  		So(MakeTreeReadOnly(context.Background(), tmpdir), ShouldBeNil)
   114  
   115  		Convey("cannot change existing file after MakeTreeReadOnly", func() {
   116  			_, err := os.Create(tmpfile)
   117  			So(err, ShouldNotBeNil)
   118  		})
   119  
   120  		So(MakeTreeWritable(context.Background(), tmpdir), ShouldBeNil)
   121  
   122  		Convey("can change existing file after MakeTreeWritable", func() {
   123  			f, err := os.Create(tmpfile)
   124  			So(err, ShouldBeNil)
   125  			So(f.Close(), ShouldBeNil)
   126  		})
   127  	})
   128  }
   129  
   130  func TestResolveSymlink(t *testing.T) {
   131  	t.Parallel()
   132  	Convey("ResolveSymlink", t, func() {
   133  		dir := t.TempDir()
   134  		regular, err := os.Create(filepath.Join(dir, "regular"))
   135  		So(err, ShouldBeNil)
   136  		So(regular.Close(), ShouldBeNil)
   137  
   138  		So(os.Symlink("regular", filepath.Join(dir, "symlink1")), ShouldBeNil)
   139  		So(os.Symlink("symlink1", filepath.Join(dir, "symlink2")), ShouldBeNil)
   140  		So(os.Symlink("symlink2", filepath.Join(dir, "symlink3")), ShouldBeNil)
   141  
   142  		path, _, err := ResolveSymlink(filepath.Join(dir, "symlink3"))
   143  		So(err, ShouldBeNil)
   144  		So(path, ShouldEqual, filepath.Join(dir, "regular"))
   145  	})
   146  }
   147  
   148  func TestGetFilenameNoExt(t *testing.T) {
   149  	t.Parallel()
   150  	Convey("Basic", t, func() {
   151  		p := filepath.Join("foo", "bar.txt")
   152  		name := GetFilenameNoExt(p)
   153  		So(name, ShouldResemble, "bar")
   154  
   155  		p = filepath.Join("foo", "bar", "baz")
   156  		name = GetFilenameNoExt(p)
   157  		So(name, ShouldResemble, "baz")
   158  
   159  		p = filepath.Join("foo.bar.baz")
   160  		name = GetFilenameNoExt(p)
   161  		So(name, ShouldResemble, "foo.bar")
   162  	})
   163  }