Welcome to mirror list, hosted at ThFree Co, Russian Federation.

file_writer_test.go « safe « internal - gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b7d3e4f9a2e991d7c70523dae3773e92eea12773 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package safe_test

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/stretchr/testify/require"
	"gitlab.com/gitlab-org/gitaly/internal/safe"
	"gitlab.com/gitlab-org/gitaly/internal/testhelper"
)

func TestFileWriter_successful(t *testing.T) {
	dir := testhelper.TempDir(t)

	filePath := filepath.Join(dir, "test_file_contents")
	fileContents := "very important contents"
	file, err := safe.NewFileWriter(filePath)
	require.NoError(t, err)

	_, err = io.Copy(file, bytes.NewBufferString(fileContents))
	require.NoError(t, err)

	require.NoFileExists(t, filePath)

	require.NoError(t, file.Commit())

	writtenContents := testhelper.MustReadFile(t, filePath)
	require.Equal(t, fileContents, string(writtenContents))

	filesInTempDir, err := os.ReadDir(dir)
	require.NoError(t, err)
	require.Len(t, filesInTempDir, 1)
	require.Equal(t, filepath.Base(filePath), filesInTempDir[0].Name())
}

func TestFileWriter_multipleConfigs(t *testing.T) {
	_, err := safe.NewFileWriter("something", safe.FileWriterConfig{},
		safe.FileWriterConfig{})
	require.Equal(t, fmt.Errorf("file writer created with more than one config"), err)
}

func TestFileWriter_mode(t *testing.T) {
	dir := testhelper.TempDir(t)

	target := filepath.Join(dir, "file")
	require.NoError(t, os.WriteFile(target, []byte("contents"), 0o600))

	writer, err := safe.NewFileWriter(target, safe.FileWriterConfig{
		FileMode: 0o060,
	})
	require.NoError(t, err)
	require.NoError(t, writer.Commit())

	fi, err := os.Stat(target)
	require.NoError(t, err)
	require.Equal(t, os.FileMode(0o060), fi.Mode())
}

func TestFileWriter_race(t *testing.T) {
	dir := testhelper.TempDir(t)

	filePath := filepath.Join(dir, "test_file_contents")

	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			w, err := safe.NewFileWriter(filePath)
			require.NoError(t, err)
			_, err = w.Write([]byte(fmt.Sprintf("message # %d", i)))
			require.NoError(t, err)
			require.NoError(t, w.Commit())
			wg.Done()
		}(i)
	}
	wg.Wait()

	require.FileExists(t, filePath)
	filesInTempDir, err := os.ReadDir(dir)
	require.NoError(t, err)
	require.Len(t, filesInTempDir, 1, "make sure no other files were written")
}

func TestFileWriter_closeBeforeCommit(t *testing.T) {
	dir := testhelper.TempDir(t)

	dstPath := filepath.Join(dir, "safety_meow")
	sf, err := safe.NewFileWriter(dstPath)
	require.NoError(t, err)

	require.True(t, !dirEmpty(t, dir), "should contain something")

	_, err = sf.Write([]byte("MEOW MEOW MEOW MEOW"))
	require.NoError(t, err)

	require.NoError(t, sf.Close())
	require.True(t, dirEmpty(t, dir), "should be empty")

	require.Equal(t, safe.ErrAlreadyDone, sf.Commit())
}

func TestFileWriter_commitBeforeClose(t *testing.T) {
	dir := testhelper.TempDir(t)

	dstPath := filepath.Join(dir, "safety_meow")
	sf, err := safe.NewFileWriter(dstPath)
	require.NoError(t, err)

	require.False(t, dirEmpty(t, dir), "should contain something")

	_, err = sf.Write([]byte("MEOW MEOW MEOW MEOW"))
	require.NoError(t, err)

	require.NoError(t, sf.Commit())
	require.FileExists(t, dstPath)

	require.Equal(t, safe.ErrAlreadyDone, sf.Close(),
		"Close should be impotent after call to commit",
	)
	require.FileExists(t, dstPath)
}

func dirEmpty(t testing.TB, dirPath string) bool {
	infos, err := os.ReadDir(dirPath)
	require.NoError(t, err)
	return len(infos) == 0
}