]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm-remote/ainsl/ainsl_test.go
2526dca0860da6685453c29e6e36e6d5dddfac98
[safcm/safcm.git] / cmd / safcm-remote / ainsl / ainsl_test.go
1 // Copyright (C) 2021  Simon Ruderich
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package ainsl
17
18 import (
19         "fmt"
20         "io/fs"
21         "os"
22         "path/filepath"
23         "syscall"
24         "testing"
25
26         ft "ruderich.org/simon/safcm/cmd/safcm-remote/sync/filetest"
27         "ruderich.org/simon/safcm/testutil"
28 )
29
30 func TestHandle(t *testing.T) {
31         cwd, err := os.Getwd()
32         if err != nil {
33                 t.Fatal(err)
34         }
35         defer os.Chdir(cwd)
36
37         err = os.RemoveAll("testdata")
38         if err != nil {
39                 t.Fatal(err)
40         }
41         err = os.Mkdir("testdata", 0700)
42         if err != nil {
43                 t.Fatal(err)
44         }
45
46         // Set umask to test mode for new files
47         umask := syscall.Umask(027)
48         defer syscall.Umask(umask)
49
50         root := ft.File{
51                 Path: ".",
52                 Mode: fs.ModeDir | 0700,
53         }
54         _, uid, _, gid := ft.CurrentUserAndGroup()
55
56         tests := []struct {
57                 name       string
58                 path       string
59                 line       string
60                 create     bool
61                 prepare    func()
62                 expFiles   []ft.File
63                 expChanges []string
64                 expErr     error
65         }{
66
67                 // TODO: Add tests for chown and run them only as root
68
69                 {
70                         "missing",
71                         "file",
72                         "line",
73                         false,
74                         nil,
75                         []ft.File{
76                                 root,
77                         },
78                         nil,
79                         fmt.Errorf("\"file\": file does not exist, use -create"),
80                 },
81
82                 {
83                         "missing: create",
84                         "file",
85                         "line",
86                         true,
87                         nil,
88                         []ft.File{
89                                 root,
90                                 ft.File{
91                                         Path: "file",
92                                         Mode: 0640,
93                                         Data: []byte("line\n"),
94                                 },
95                         },
96                         []string{
97                                 fmt.Sprintf(`"file": created file (%d/%d -rw-r-----)`, uid, gid),
98                                 `"file": added line "line"`,
99                         },
100                         nil,
101                 },
102                 {
103                         "missing: create (empty line)",
104                         "file",
105                         "",
106                         true,
107                         nil,
108                         []ft.File{
109                                 root,
110                         },
111                         nil,
112                         fmt.Errorf("empty line"),
113                 },
114                 {
115                         "missing: create (newline)",
116                         "file",
117                         "line\n",
118                         true,
119                         nil,
120                         []ft.File{
121                                 root,
122                         },
123                         nil,
124                         fmt.Errorf("line must not contain newlines: \"line\\n\""),
125                 },
126
127                 {
128                         "exists: unchanged",
129                         "file",
130                         "line",
131                         true,
132                         func() {
133                                 ft.CreateFile("file", "line\n", 0641)
134                         },
135                         []ft.File{
136                                 root,
137                                 ft.File{
138                                         Path: "file",
139                                         Mode: 0641,
140                                         Data: []byte("line\n"),
141                                 },
142                         },
143                         nil,
144                         nil,
145                 },
146
147                 {
148                         "exists: append",
149                         "file",
150                         "line",
151                         true,
152                         func() {
153                                 ft.CreateFile("file", "existing\n", 0641)
154                         },
155                         []ft.File{
156                                 root,
157                                 ft.File{
158                                         Path: "file",
159                                         Mode: 0641,
160                                         Data: []byte("existing\nline\n"),
161                                 },
162                         },
163                         []string{
164                                 `"file": added line "line"`,
165                         },
166                         nil,
167                 },
168                 {
169                         "exists: append (no newline in file)",
170                         "file",
171                         "line",
172                         true,
173                         func() {
174                                 ft.CreateFile("file", "existing", 0641)
175                         },
176                         []ft.File{
177                                 root,
178                                 ft.File{
179                                         Path: "file",
180                                         Mode: 0641,
181                                         Data: []byte("existing\nline\n"),
182                                 },
183                         },
184                         []string{
185                                 `"file": added missing trailing newline`,
186                                 `"file": added line "line"`,
187                         },
188                         nil,
189                 },
190                 {
191                         "exists: append (only trailing newline I)",
192                         "file",
193                         "line",
194                         true,
195                         func() {
196                                 ft.CreateFile("file", "first\nline", 0641)
197                         },
198                         []ft.File{
199                                 root,
200                                 ft.File{
201                                         Path: "file",
202                                         Mode: 0641,
203                                         Data: []byte("first\nline\n"),
204                                 },
205                         },
206                         []string{
207                                 `"file": added missing trailing newline`,
208                         },
209                         nil,
210                 },
211                 {
212                         "exists: append (only trailing newline II)",
213                         "file",
214                         "first",
215                         true,
216                         func() {
217                                 ft.CreateFile("file", "first\nline", 0641)
218                         },
219                         []ft.File{
220                                 root,
221                                 ft.File{
222                                         Path: "file",
223                                         Mode: 0641,
224                                         Data: []byte("first\nline\n"),
225                                 },
226                         },
227                         []string{
228                                 `"file": added missing trailing newline`,
229                         },
230                         nil,
231                 },
232                 {
233                         "exists: append (partial line)",
234                         "file",
235                         "line with spaces",
236                         true,
237                         func() {
238                                 ft.CreateFile("file", "# line with spaces\n", 0641)
239                         },
240                         []ft.File{
241                                 root,
242                                 ft.File{
243                                         Path: "file",
244                                         Mode: 0641,
245                                         Data: []byte("# line with spaces\nline with spaces\n"),
246                                 },
247                         },
248                         []string{
249                                 `"file": added line "line with spaces"`,
250                         },
251                         nil,
252                 },
253
254                 {
255                         "exists: symlink",
256                         "file",
257                         "line",
258                         true,
259                         func() {
260                                 ft.CreateSymlink("file", "target")
261                         },
262                         []ft.File{
263                                 root,
264                                 ft.File{
265                                         Path: "file",
266                                         Mode: fs.ModeSymlink | 0777,
267                                         Data: []byte("target"),
268                                 },
269                         },
270                         nil,
271                         fmt.Errorf("open file: too many levels of symbolic links"),
272                 },
273                 {
274                         "exists: fifo",
275                         "file",
276                         "line",
277                         true,
278                         func() {
279                                 ft.CreateFifo("file", 0640)
280                         },
281                         []ft.File{
282                                 root,
283                                 ft.File{
284                                         Path: "file",
285                                         Mode: fs.ModeNamedPipe | 0640,
286                                 },
287                         },
288                         nil,
289                         fmt.Errorf("\"file\" is not a regular file but p---------"),
290                 },
291         }
292
293         for _, tc := range tests {
294                 t.Run(tc.name, func(t *testing.T) {
295                         // Create separate test directory for each test case
296                         path := filepath.Join(cwd, "testdata", tc.name)
297                         err = os.Mkdir(path, 0700)
298                         if err != nil {
299                                 t.Fatal(err)
300                         }
301                         err = os.Chdir(path)
302                         if err != nil {
303                                 t.Fatal(err)
304                         }
305
306                         if tc.prepare != nil {
307                                 tc.prepare()
308                         }
309
310                         changes, err := handle(tc.path, tc.line, tc.create)
311                         testutil.AssertEqual(t, "changes",
312                                 changes, tc.expChanges)
313                         testutil.AssertErrorEqual(t, "err", err, tc.expErr)
314
315                         files, err := ft.WalkDir(path)
316                         if err != nil {
317                                 t.Fatal(err)
318                         }
319                         testutil.AssertEqual(t, "files", files, tc.expFiles)
320                 })
321         }
322
323         if !t.Failed() {
324                 err = os.RemoveAll(filepath.Join(cwd, "testdata"))
325                 if err != nil {
326                         t.Fatal(err)
327                 }
328         }
329 }