github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/watcherx/test_helpers.go (about) 1 package watcherx 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path" 7 "path/filepath" 8 "runtime" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/require" 13 ) 14 15 func kubernetesAtomicWrite(t *testing.T, dir, fileName, content string) { 16 // atomic write according to https://github.com/kubernetes/kubernetes/blob/master/pkg/volume/util/atomic_writer.go 17 const ( 18 dataDirName = "..data" 19 newDataDirName = "..data_tmp" 20 ) 21 // (2) 22 dataDirPath := filepath.Join(dir, dataDirName) 23 oldTsDir, err := os.Readlink(dataDirPath) 24 if err != nil { 25 require.True(t, os.IsNotExist(err), "%+v", err) 26 // although Readlink() returns "" on err, don't be fragile by relying on it (since it's not specified in docs) 27 // empty oldTsDir indicates that it didn't exist 28 oldTsDir = "" 29 } 30 oldTsPath := filepath.Join(dir, oldTsDir) 31 32 // (3) we are not interested in the case where a file gets deleted as we just operate on one file 33 // (4) we assume the file needs an update 34 35 // (5) 36 tsDir, err := ioutil.TempDir(dir, time.Now().UTC().Format("..2006_01_02_15_04_05.")) 37 require.NoError(t, err) 38 tsDirName := filepath.Base(tsDir) 39 40 // (6) 41 require.NoError( 42 t, 43 ioutil.WriteFile(path.Join(tsDir, fileName), []byte(content), 0600), 44 ) 45 46 // (7) 47 _, err = os.Readlink(filepath.Join(dir, fileName)) 48 if err != nil && os.IsNotExist(err) { 49 // The link into the data directory for this path doesn't exist; create it 50 require.NoError( 51 t, 52 os.Symlink(filepath.Join(dataDirName, fileName), filepath.Join(dir, fileName)), 53 ) 54 } 55 56 // (8) 57 newDataDirPath := filepath.Join(dir, newDataDirName) 58 require.NoError( 59 t, 60 os.Symlink(tsDirName, newDataDirPath), 61 ) 62 63 // (9) 64 if runtime.GOOS == "windows" { 65 require.NoError(t, os.Remove(dataDirPath)) 66 require.NoError(t, os.Symlink(tsDirName, dataDirPath)) 67 require.NoError(t, os.Remove(newDataDirPath)) 68 } else { 69 require.NoError(t, os.Rename(newDataDirPath, dataDirPath)) 70 } 71 72 // (10) in our case there is nothing to remove 73 74 // (11) 75 if len(oldTsDir) > 0 { 76 require.NoError(t, os.RemoveAll(oldTsPath)) 77 } 78 }