@@ -2,10 +2,13 @@ package xunix_test
2
2
3
3
import (
4
4
"context"
5
+ "os"
5
6
"path/filepath"
7
+ "sort"
6
8
"testing"
7
9
8
10
"github.com/spf13/afero"
11
+ "github.com/stretchr/testify/assert"
9
12
"github.com/stretchr/testify/require"
10
13
"k8s.io/mount-utils"
11
14
@@ -112,3 +115,103 @@ func TestGPUs(t *testing.T) {
112
115
}
113
116
})
114
117
}
118
+
119
+ func Test_SameDirSymlinks (t * testing.T ) {
120
+ t .Parallel ()
121
+
122
+ var (
123
+ ctx = context .Background ()
124
+ // We need to test with a real filesystem as the fake one doesn't
125
+ // support creating symlinks.
126
+ tmpDir = t .TempDir ()
127
+ // We do test with the interface though!
128
+ afs = xunix .GetFS (ctx )
129
+ )
130
+
131
+ // Create some files in the temporary directory.
132
+ _ , err := os .Create (filepath .Join (tmpDir , "file1.real" ))
133
+ require .NoError (t , err , "create file" )
134
+ _ , err = os .Create (filepath .Join (tmpDir , "file2.real" ))
135
+ require .NoError (t , err , "create file2" )
136
+ _ , err = os .Create (filepath .Join (tmpDir , "file3.real" ))
137
+ require .NoError (t , err , "create file3" )
138
+ _ , err = os .Create (filepath .Join (tmpDir , "file4.real" ))
139
+ require .NoError (t , err , "create file4" )
140
+
141
+ // Create a symlink to the file in the temporary directory.
142
+ // This needs to be done by the real os package.
143
+ err = os .Symlink (filepath .Join (tmpDir , "file1.real" ), filepath .Join (tmpDir , "file1.link1" ))
144
+ require .NoError (t , err , "create first symlink" )
145
+
146
+ // Create another symlink to the previous symlink.
147
+ err = os .Symlink (filepath .Join (tmpDir , "file1.link1" ), filepath .Join (tmpDir , "file1.link2" ))
148
+ require .NoError (t , err , "create second symlink" )
149
+
150
+ // Create a symlink to a file outside of the temporary directory.
151
+ err = os .MkdirAll (filepath .Join (tmpDir , "dir" ), 0o755 )
152
+ require .NoError (t , err , "create dir" )
153
+ // Create a symlink from file2 to inside the dir.
154
+ err = os .Symlink (filepath .Join (tmpDir , "file2.real" ), filepath .Join (tmpDir , "dir" , "file2.link1" ))
155
+ require .NoError (t , err , "create dir symlink" )
156
+
157
+ // Create a symlink with a relative path. To do this, we need to
158
+ // change the working directory to the temporary directory.
159
+ oldWorkingDir , err := os .Getwd ()
160
+ require .NoError (t , err , "get working dir" )
161
+ // Change the working directory to the temporary directory.
162
+ require .NoError (t , os .Chdir (tmpDir ), "change working dir" )
163
+ err = os .Symlink (filepath .Join (tmpDir , "file4.real" ), "file4.link1" )
164
+ require .NoError (t , err , "create relative symlink" )
165
+ // Change the working directory back to the original.
166
+ require .NoError (t , os .Chdir (oldWorkingDir ), "change working dir back" )
167
+
168
+ for _ , tt := range []struct {
169
+ name string
170
+ expected []string
171
+ }{
172
+ {
173
+ // Two symlinks to the same file.
174
+ name : "file1.real" ,
175
+ expected : []string {
176
+ filepath .Join (tmpDir , "file1.link1" ),
177
+ filepath .Join (tmpDir , "file1.link2" ),
178
+ },
179
+ },
180
+ {
181
+ // Mid-way in the symlink chain.
182
+ name : "file1.link1" ,
183
+ expected : []string {
184
+ filepath .Join (tmpDir , "file1.link2" ),
185
+ },
186
+ },
187
+ {
188
+ // End of the symlink chain.
189
+ name : "file1.link2" ,
190
+ expected : []string {},
191
+ },
192
+ {
193
+ // Symlink to a file outside of the temporary directory.
194
+ name : "file2.real" ,
195
+ expected : []string {},
196
+ },
197
+ {
198
+ // No symlinks to this file.
199
+ name : "file3.real" ,
200
+ expected : []string {},
201
+ },
202
+ {
203
+ // One relative symlink.
204
+ name : "file4.real" ,
205
+ expected : []string {filepath .Join (tmpDir , "file4.link1" )},
206
+ },
207
+ } {
208
+ t .Run (tt .name , func (t * testing.T ) {
209
+ t .Parallel ()
210
+ fullPath := filepath .Join (tmpDir , tt .name )
211
+ actual , err := xunix .SameDirSymlinks (afs , fullPath )
212
+ require .NoError (t , err , "find symlink" )
213
+ sort .Strings (actual )
214
+ assert .Equal (t , tt .expected , actual , "find symlinks %q" , tt .name )
215
+ })
216
+ }
217
+ }
0 commit comments