1// Copyright 2023 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 unix 6 7package main 8 9import ( 10 "os" 11 "path/filepath" 12 "strings" 13 "testing" 14 "time" 15) 16 17func TestPermissions(t *testing.T) { 18 if os.Getuid() == 0 { 19 t.Skip("skipping permission test when running as root") 20 } 21 22 dir := t.TempDir() 23 fn := filepath.Join(dir, "perm.go") 24 25 // Create a file that needs formatting without write permission. 26 if err := os.WriteFile(filepath.Join(fn), []byte(" package main"), 0o400); err != nil { 27 t.Fatal(err) 28 } 29 30 // Set mtime of the file in the past. 31 past := time.Now().Add(-time.Hour) 32 if err := os.Chtimes(fn, past, past); err != nil { 33 t.Fatal(err) 34 } 35 36 info, err := os.Stat(fn) 37 if err != nil { 38 t.Fatal(err) 39 } 40 41 defer func() { *write = false }() 42 *write = true 43 44 initParserMode() 45 initRewrite() 46 47 const maxWeight = 2 << 20 48 var buf, errBuf strings.Builder 49 s := newSequencer(maxWeight, &buf, &errBuf) 50 s.Add(fileWeight(fn, info), func(r *reporter) error { 51 return processFile(fn, info, nil, r) 52 }) 53 if s.GetExitCode() == 0 { 54 t.Fatal("rewrite of read-only file succeeded unexpectedly") 55 } 56 if errBuf.Len() > 0 { 57 t.Log(errBuf) 58 } 59 60 info, err = os.Stat(fn) 61 if err != nil { 62 t.Fatal(err) 63 } 64 if !info.ModTime().Equal(past) { 65 t.Errorf("after rewrite mod time is %v, want %v", info.ModTime(), past) 66 } 67} 68