mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 02:18:44 -07:00
a3c724f2c3
all: Add package runtimeos for runtime.GOOS comparisons I grew tired of hand written string comparisons. This adds generated constants for the GOOS values, and predefined Is$OS constants that can be iffed on. In a couple of places I rewrote trivial switch:es to if:s, and added Illumos where we checked for Solaris (because they are effectively the same, and if we're going to target one of them that would be Illumos...).
135 lines
3.3 KiB
Go
135 lines
3.3 KiB
Go
// Copyright (C) 2019 The Syncthing Authors.
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
package fs
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
osexec "os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/syncthing/syncthing/lib/build"
|
|
)
|
|
|
|
func testWalkSkipSymlink(t *testing.T, fsType FilesystemType, uri string) {
|
|
if build.IsWindows {
|
|
t.Skip("Symlinks skipping is not tested on windows")
|
|
}
|
|
|
|
fs := NewFilesystem(fsType, uri)
|
|
|
|
if err := fs.MkdirAll("target/foo", 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := fs.Mkdir("towalk", 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := fs.CreateSymlink("target", "towalk/symlink"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if info.Name() != "symlink" && info.Name() != "towalk" {
|
|
t.Fatal("Walk unexpected file", info.Name())
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func createDirJunct(target string, name string) error {
|
|
output, err := osexec.Command("cmd", "/c", "mklink", "/J", name, target).CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to run mklink %v %v: %v %q", name, target, err, output)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func testWalkTraverseDirJunct(t *testing.T, fsType FilesystemType, uri string) {
|
|
if !build.IsWindows {
|
|
t.Skip("Directory junctions are available and tested on windows only")
|
|
}
|
|
|
|
fs := NewFilesystem(fsType, uri, new(OptionJunctionsAsDirs))
|
|
|
|
if err := fs.MkdirAll("target/foo", 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := fs.Mkdir("towalk", 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := createDirJunct(filepath.Join(uri, "target"), filepath.Join(uri, "towalk/dirjunct")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
traversed := false
|
|
if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if info.Name() == "foo" {
|
|
traversed = true
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !traversed {
|
|
t.Fatal("Directory junction was not traversed")
|
|
}
|
|
}
|
|
|
|
func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string) {
|
|
if !build.IsWindows {
|
|
t.Skip("Infinite recursion detection is tested on windows only")
|
|
}
|
|
|
|
fs := NewFilesystem(fsType, uri, new(OptionJunctionsAsDirs))
|
|
|
|
if err := fs.MkdirAll("target/foo", 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := fs.Mkdir("towalk", 0); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := createDirJunct(filepath.Join(uri, "target"), filepath.Join(uri, "towalk/dirjunct")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := createDirJunct(filepath.Join(uri, "towalk"), filepath.Join(uri, "target/foo/recurse")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
dirjunctCnt := 0
|
|
fooCnt := 0
|
|
found := false
|
|
if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
|
|
if err != nil {
|
|
if errors.Is(err, ErrInfiniteRecursion) {
|
|
if found {
|
|
t.Fatal("second infinite recursion detected at", path)
|
|
}
|
|
found = true
|
|
return nil
|
|
}
|
|
t.Fatal(err)
|
|
}
|
|
if info.Name() == "dirjunct" {
|
|
dirjunctCnt++
|
|
} else if info.Name() == "foo" {
|
|
fooCnt++
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if dirjunctCnt != 2 || fooCnt != 1 || !found {
|
|
t.Fatal("Infinite recursion not detected correctly")
|
|
}
|
|
}
|