| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | 
							- // Copyright (C) 2018 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 model
 
- import (
 
- 	"path/filepath"
 
- 	"slices"
 
- 	"testing"
 
- 	"github.com/d4l3k/messagediff"
 
- 	"github.com/syncthing/syncthing/lib/build"
 
- 	"github.com/syncthing/syncthing/lib/config"
 
- 	"github.com/syncthing/syncthing/lib/fs"
 
- 	"github.com/syncthing/syncthing/lib/protocol"
 
- 	"github.com/syncthing/syncthing/lib/rand"
 
- )
 
- type unifySubsCase struct {
 
- 	in     []string // input to unifySubs
 
- 	exists []string // paths that exist in the database
 
- 	out    []string // expected output
 
- }
 
- func unifySubsCases() []unifySubsCase {
 
- 	cases := []unifySubsCase{
 
- 		{
 
- 			// 0. trailing slashes are cleaned, known paths are just passed on
 
- 			[]string{"foo/", "bar//"},
 
- 			[]string{"foo", "bar"},
 
- 			[]string{"bar", "foo"}, // the output is sorted
 
- 		},
 
- 		{
 
- 			// 1. "foo/bar" gets trimmed as it's covered by foo
 
- 			[]string{"foo", "bar/", "foo/bar/"},
 
- 			[]string{"foo", "bar"},
 
- 			[]string{"bar", "foo"},
 
- 		},
 
- 		{
 
- 			// 2. "" gets simplified to the empty list; ie scan all
 
- 			[]string{"foo", ""},
 
- 			[]string{"foo"},
 
- 			nil,
 
- 		},
 
- 		{
 
- 			// 3. "foo/bar" is unknown, but it's kept
 
- 			// because its parent is known
 
- 			[]string{"foo/bar"},
 
- 			[]string{"foo"},
 
- 			[]string{"foo/bar"},
 
- 		},
 
- 		{
 
- 			// 4. two independent known paths, both are kept
 
- 			// "usr/lib" is not a prefix of "usr/libexec"
 
- 			[]string{"usr/lib", "usr/libexec"},
 
- 			[]string{"usr", "usr/lib", "usr/libexec"},
 
- 			[]string{"usr/lib", "usr/libexec"},
 
- 		},
 
- 		{
 
- 			// 5. "usr/lib" is a prefix of "usr/lib/exec"
 
- 			[]string{"usr/lib", "usr/lib/exec"},
 
- 			[]string{"usr", "usr/lib", "usr/libexec"},
 
- 			[]string{"usr/lib"},
 
- 		},
 
- 		{
 
- 			// 6. .stignore and .stfolder are special and are passed on
 
- 			// verbatim even though they are unknown
 
- 			[]string{config.DefaultMarkerName, ".stignore"},
 
- 			[]string{},
 
- 			[]string{config.DefaultMarkerName, ".stignore"},
 
- 		},
 
- 		{
 
- 			// 7. but the presence of something else unknown forces an actual
 
- 			// scan
 
- 			[]string{config.DefaultMarkerName, ".stignore", "foo/bar"},
 
- 			[]string{},
 
- 			[]string{config.DefaultMarkerName, ".stignore", "foo"},
 
- 		},
 
- 		{
 
- 			// 8. explicit request to scan all
 
- 			nil,
 
- 			[]string{"foo"},
 
- 			nil,
 
- 		},
 
- 		{
 
- 			// 9. empty list of subs
 
- 			[]string{},
 
- 			[]string{"foo"},
 
- 			nil,
 
- 		},
 
- 		{
 
- 			// 10. absolute path
 
- 			[]string{"/foo"},
 
- 			[]string{"foo"},
 
- 			[]string{"foo"},
 
- 		},
 
- 	}
 
- 	if build.IsWindows {
 
- 		// Fixup path separators
 
- 		for i := range cases {
 
- 			for j, p := range cases[i].in {
 
- 				cases[i].in[j] = filepath.FromSlash(p)
 
- 			}
 
- 			for j, p := range cases[i].exists {
 
- 				cases[i].exists[j] = filepath.FromSlash(p)
 
- 			}
 
- 			for j, p := range cases[i].out {
 
- 				cases[i].out[j] = filepath.FromSlash(p)
 
- 			}
 
- 		}
 
- 	}
 
- 	return cases
 
- }
 
- func TestUnifySubs(t *testing.T) {
 
- 	cases := unifySubsCases()
 
- 	for i, tc := range cases {
 
- 		exists := func(f string) bool {
 
- 			return slices.Contains(tc.exists, f)
 
- 		}
 
- 		out := unifySubs(tc.in, exists)
 
- 		if diff, equal := messagediff.PrettyDiff(tc.out, out); !equal {
 
- 			t.Errorf("Case %d failed; got %v, expected %v, diff:\n%s", i, out, tc.out, diff)
 
- 		}
 
- 	}
 
- }
 
- func BenchmarkUnifySubs(b *testing.B) {
 
- 	cases := unifySubsCases()
 
- 	b.ReportAllocs()
 
- 	b.ResetTimer()
 
- 	for i := 0; i < b.N; i++ {
 
- 		for _, tc := range cases {
 
- 			exists := func(f string) bool {
 
- 				return slices.Contains(tc.exists, f)
 
- 			}
 
- 			unifySubs(tc.in, exists)
 
- 		}
 
- 	}
 
- }
 
- func TestSetPlatformData(t *testing.T) {
 
- 	// Checks that setPlatformData runs without error when applied to a temp
 
- 	// file, named differently than the given FileInfo.
 
- 	fs := fs.NewFilesystem(fs.FilesystemTypeFake, rand.String(32))
 
- 	if fd, err := fs.Create("file.tmp"); err != nil {
 
- 		t.Fatal(err)
 
- 	} else {
 
- 		fd.Close()
 
- 	}
 
- 	xattr := []protocol.Xattr{{Name: "user.foo", Value: []byte("bar")}}
 
- 	fi := &protocol.FileInfo{
 
- 		Name:        "should be ignored",
 
- 		Permissions: 0o400,
 
- 		ModifiedS:   1234567890,
 
- 		Platform: protocol.PlatformData{
 
- 			Linux:   &protocol.XattrData{Xattrs: xattr},
 
- 			Darwin:  &protocol.XattrData{Xattrs: xattr},
 
- 			FreeBSD: &protocol.XattrData{Xattrs: xattr},
 
- 			NetBSD:  &protocol.XattrData{Xattrs: xattr},
 
- 		},
 
- 	}
 
- 	// Minimum required to support setPlatformData
 
- 	sr := &sendReceiveFolder{
 
- 		folder: folder{
 
- 			FolderConfiguration: config.FolderConfiguration{
 
- 				SyncXattrs: true,
 
- 			},
 
- 			mtimefs: fs,
 
- 		},
 
- 	}
 
- 	if err := sr.setPlatformData(fi, "file.tmp"); err != nil {
 
- 		t.Error(err)
 
- 	}
 
- }
 
 
  |