]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm/sync_changes_test.go
tests: go fmt and rewrap
[safcm/safcm.git] / cmd / safcm / sync_changes_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 main
17
18 import (
19         "io/fs"
20         "testing"
21
22         "github.com/google/go-cmp/cmp"
23
24         "ruderich.org/simon/safcm"
25         "ruderich.org/simon/safcm/cmd/safcm/config"
26 )
27
28 func TestFormatFileChanges(t *testing.T) {
29         tests := []struct {
30                 name    string
31                 dryRun  bool
32                 changes []safcm.FileChange
33                 exp     string
34         }{
35
36                 {
37                         "regular",
38                         false,
39                         []safcm.FileChange{
40                                 {
41                                         Path:    "created: file",
42                                         Created: true,
43                                         New: safcm.FileChangeInfo{
44                                                 Mode:  0644,
45                                                 User:  "user",
46                                                 Uid:   1000,
47                                                 Group: "group",
48                                                 Gid:   2000,
49                                         },
50                                 },
51                                 {
52                                         Path:    "created: link",
53                                         Created: true,
54                                         New: safcm.FileChangeInfo{
55                                                 Mode:  fs.ModeSymlink | 0777,
56                                                 User:  "user",
57                                                 Uid:   1000,
58                                                 Group: "group",
59                                                 Gid:   2000,
60                                         },
61                                 },
62                                 {
63                                         Path: "type change: file -> dir",
64                                         Old: safcm.FileChangeInfo{
65                                                 Mode:  0751,
66                                                 User:  "user",
67                                                 Uid:   1000,
68                                                 Group: "group",
69                                                 Gid:   2000,
70                                         },
71                                         New: safcm.FileChangeInfo{
72                                                 Mode:  fs.ModeDir | 0751,
73                                                 User:  "user",
74                                                 Uid:   1000,
75                                                 Group: "group",
76                                                 Gid:   2000,
77                                         },
78                                         DataDiff: `@@ -1,2 +1 @@
79 -content
80  
81 `,
82                                 },
83                                 {
84                                         Path: "user change",
85                                         Old: safcm.FileChangeInfo{
86                                                 Mode:  0755,
87                                                 User:  "user",
88                                                 Uid:   1000,
89                                                 Group: "group",
90                                                 Gid:   2000,
91                                         },
92                                         New: safcm.FileChangeInfo{
93                                                 Mode:  0755,
94                                                 User:  "user2",
95                                                 Uid:   1001,
96                                                 Group: "group",
97                                                 Gid:   2000,
98                                         },
99                                 },
100                                 {
101                                         Path: "group change",
102                                         Old: safcm.FileChangeInfo{
103                                                 Mode:  0755,
104                                                 User:  "user",
105                                                 Uid:   1000,
106                                                 Group: "group",
107                                                 Gid:   2000,
108                                         },
109                                         New: safcm.FileChangeInfo{
110                                                 Mode:  0755,
111                                                 User:  "user",
112                                                 Uid:   1000,
113                                                 Group: "group2",
114                                                 Gid:   2001,
115                                         },
116                                 },
117                                 {
118                                         Path: "mode change",
119                                         Old: safcm.FileChangeInfo{
120                                                 Mode:  0755,
121                                                 User:  "user",
122                                                 Uid:   1000,
123                                                 Group: "group",
124                                                 Gid:   2000,
125                                         },
126                                         New: safcm.FileChangeInfo{
127                                                 Mode:  0750,
128                                                 User:  "user",
129                                                 Uid:   1000,
130                                                 Group: "group",
131                                                 Gid:   2000,
132                                         },
133                                 },
134                                 {
135                                         Path: "mode change (setuid)",
136                                         Old: safcm.FileChangeInfo{
137                                                 Mode:  0755,
138                                                 User:  "user",
139                                                 Uid:   1000,
140                                                 Group: "group",
141                                                 Gid:   2000,
142                                         },
143                                         New: safcm.FileChangeInfo{
144                                                 Mode:  0755 | fs.ModeSetuid,
145                                                 User:  "user",
146                                                 Uid:   1000,
147                                                 Group: "group",
148                                                 Gid:   2000,
149                                         },
150                                 },
151                                 {
152                                         Path: "content change",
153                                         Old: safcm.FileChangeInfo{
154                                                 Mode:  0644,
155                                                 User:  "user",
156                                                 Uid:   1000,
157                                                 Group: "group",
158                                                 Gid:   2000,
159                                         },
160                                         New: safcm.FileChangeInfo{
161                                                 Mode:  0644,
162                                                 User:  "user",
163                                                 Uid:   1000,
164                                                 Group: "group",
165                                                 Gid:   2000,
166                                         },
167                                         DataDiff: `@@ -1,2 +1,2 @@
168 -old content
169 +content
170  
171 `,
172                                 },
173                                 {
174                                         Path: "multiple changes",
175                                         Old: safcm.FileChangeInfo{
176                                                 Mode:  0644,
177                                                 User:  "user",
178                                                 Uid:   1000,
179                                                 Group: "group",
180                                                 Gid:   2000,
181                                         },
182                                         New: safcm.FileChangeInfo{
183                                                 Mode:  fs.ModeDir | 0755,
184                                                 User:  "user2",
185                                                 Uid:   1001,
186                                                 Group: "group2",
187                                                 Gid:   2001,
188                                         },
189                                         DataDiff: `@@ -1,2 +1 @@
190 -content
191  
192 `,
193                                 },
194                         },
195                         `changed 9 file(s):
196 "created: file": created, file, user(1000) group(2000), 0644
197 "created: link": created, symlink, user(1000) group(2000), 0777
198 "type change: file -> dir": file -> dir
199    @@ -1,2 +1 @@
200    -content
201     
202 "user change": user(1000) group(2000) -> user2(1001) group(2000)
203 "group change": user(1000) group(2000) -> user(1000) group2(2001)
204 "mode change": 0755 -> 0750
205 "mode change (setuid)": 0755 -> 04755
206 "content change":
207    @@ -1,2 +1,2 @@
208    -old content
209    +content
210     
211 "multiple changes": file -> dir, user(1000) group(2000) -> user2(1001) group2(2001), 0644 -> 0755
212    @@ -1,2 +1 @@
213    -content
214     
215 `,
216                 },
217
218                 {
219                         "dry-run",
220                         true,
221                         []safcm.FileChange{
222                                 {
223                                         Path:    "file",
224                                         Created: true,
225                                         New: safcm.FileChangeInfo{
226                                                 Mode:  0644,
227                                                 User:  "user",
228                                                 Uid:   1000,
229                                                 Group: "group",
230                                                 Gid:   2000,
231                                         },
232                                 },
233                         },
234                         `changed 1 file(s): (dry-run)
235 "file": created, file, user(1000) group(2000), 0644
236 `,
237                 },
238
239                 {
240                         "escaping",
241                         false,
242                         []safcm.FileChange{
243                                 {
244                                         Path:    "\x00",
245                                         Created: true,
246                                         New: safcm.FileChangeInfo{
247                                                 Mode:  0xFFFFFFFF,
248                                                 User:  "\x01",
249                                                 Uid:   -1,
250                                                 Group: "\x02",
251                                                 Gid:   -2,
252                                         },
253                                         DataDiff: "\x03",
254                                 },
255                                 {
256                                         Path: "\x00",
257                                         Old: safcm.FileChangeInfo{
258                                                 Mode:  0x00000000,
259                                                 User:  "\x01",
260                                                 Uid:   -1,
261                                                 Group: "\x02",
262                                                 Gid:   -2,
263                                         },
264                                         New: safcm.FileChangeInfo{
265                                                 Mode:  0xFFFFFFFF,
266                                                 User:  "\x03",
267                                                 Uid:   -3,
268                                                 Group: "\x04",
269                                                 Gid:   -4,
270                                         },
271                                         DataDiff: "\x05",
272                                 },
273                         },
274                         `changed 2 file(s):
275 "\x00": created, invalid type dLDpSc?---------, \x01(-1) \x02(-2), 07777
276    \x03
277    \ No newline at end of file
278 "\x00": file -> invalid type dLDpSc?---------, \x01(-1) \x02(-2) -> \x03(-3) \x04(-4), 0 -> 07777
279    \x05
280    \ No newline at end of file
281 `,
282                 },
283         }
284
285         for _, tc := range tests {
286                 t.Run(tc.name, func(t *testing.T) {
287                         s := &Sync{
288                                 config: &config.Config{
289                                         DryRun: tc.dryRun,
290                                 },
291                         }
292
293                         res := s.formatFileChanges(tc.changes)
294                         if tc.exp != res {
295                                 t.Errorf("res: %s", cmp.Diff(tc.exp, res))
296                         }
297                 })
298         }
299 }
300
301 func TestFormatPackageChanges(t *testing.T) {
302         tests := []struct {
303                 name    string
304                 dryRun  bool
305                 changes []safcm.PackageChange
306                 exp     string
307         }{
308
309                 {
310                         "regular",
311                         false,
312                         []safcm.PackageChange{
313                                 {
314                                         Name: "package-one",
315                                 },
316                                 {
317                                         Name: "package-two",
318                                 },
319                         },
320                         `installed 2 package(s):
321 "package-one"
322 "package-two"
323 `,
324                 },
325
326                 {
327                         "dry-run",
328                         true,
329                         []safcm.PackageChange{
330                                 {
331                                         Name: "package-one",
332                                 },
333                                 {
334                                         Name: "package-two",
335                                 },
336                         },
337                         `installed 2 package(s): (dry-run)
338 "package-one"
339 "package-two"
340 `,
341                 },
342
343                 {
344                         "escaping",
345                         false,
346                         []safcm.PackageChange{
347                                 {
348                                         Name: "\x00",
349                                 },
350                         },
351                         `installed 1 package(s):
352 "\x00"
353 `,
354                 },
355         }
356
357         for _, tc := range tests {
358                 t.Run(tc.name, func(t *testing.T) {
359                         s := &Sync{
360                                 config: &config.Config{
361                                         DryRun: tc.dryRun,
362                                 },
363                         }
364
365                         res := s.formatPackageChanges(tc.changes)
366                         if tc.exp != res {
367                                 t.Errorf("res: %s", cmp.Diff(tc.exp, res))
368                         }
369                 })
370         }
371 }
372
373 func TestFormatServiceChanges(t *testing.T) {
374         tests := []struct {
375                 name    string
376                 dryRun  bool
377                 changes []safcm.ServiceChange
378                 exp     string
379         }{
380
381                 {
382                         "regular",
383                         false,
384                         []safcm.ServiceChange{
385                                 {
386                                         Name:    "service-one",
387                                         Started: true,
388                                 },
389                                 {
390                                         Name:    "service-two",
391                                         Enabled: true,
392                                 },
393                                 {
394                                         Name:    "service-three",
395                                         Started: true,
396                                         Enabled: true,
397                                 },
398                         },
399                         `modified 3 service(s):
400 "service-one": started
401 "service-two": enabled
402 "service-three": started, enabled
403 `,
404                 },
405
406                 {
407                         "dry-run",
408                         true,
409                         []safcm.ServiceChange{
410                                 {
411                                         Name:    "service-one",
412                                         Started: true,
413                                 },
414                                 {
415                                         Name:    "service-two",
416                                         Enabled: true,
417                                 },
418                                 {
419                                         Name:    "service-three",
420                                         Started: true,
421                                         Enabled: true,
422                                 },
423                         },
424                         `modified 3 service(s): (dry-run)
425 "service-one": started
426 "service-two": enabled
427 "service-three": started, enabled
428 `,
429                 },
430
431                 {
432                         "escaping",
433                         false,
434                         []safcm.ServiceChange{
435                                 {
436                                         Name: "\x00",
437                                 },
438                                 {
439                                         Name:    "\x01",
440                                         Started: true,
441                                         Enabled: true,
442                                 },
443                         },
444                         `modified 2 service(s):
445 "\x00": 
446 "\x01": started, enabled
447 `,
448                 },
449         }
450
451         for _, tc := range tests {
452                 t.Run(tc.name, func(t *testing.T) {
453                         s := &Sync{
454                                 config: &config.Config{
455                                         DryRun: tc.dryRun,
456                                 },
457                         }
458
459                         res := s.formatServiceChanges(tc.changes)
460                         if tc.exp != res {
461                                 t.Errorf("res: %s", cmp.Diff(tc.exp, res))
462                         }
463                 })
464         }
465 }
466
467 func TestFormatCommandChanges(t *testing.T) {
468         tests := []struct {
469                 name    string
470                 dryRun  bool
471                 quiet   bool
472                 changes []safcm.CommandChange
473                 exp     string
474         }{
475
476                 {
477                         "regular",
478                         false,
479                         false,
480                         []safcm.CommandChange{
481                                 {
482                                         Command: "fake command",
483                                         Output:  "fake output",
484                                 },
485                                 {
486                                         Command: "fake command with no output",
487                                 },
488                                 {
489                                         Command: "fake command with newline",
490                                         Output:  "fake output\n",
491                                 },
492                                 {
493                                         Command: "fake command with more output",
494                                         Output:  "fake out\nfake put\nfake\n",
495                                 },
496                                 {
497                                         Command: "fake failed command",
498                                         Output:  "fake output",
499                                         Error:   "fake error",
500                                 },
501                         },
502                         `executed 5 command(s):
503 "fake command":
504    > fake output
505    > \ No newline at end of file
506 "fake command with no output"
507 "fake command with newline":
508    > fake output
509 "fake command with more output":
510    > fake out
511    > fake put
512    > fake
513 "fake failed command", failed: "fake error":
514    > fake output
515    > \ No newline at end of file
516 `,
517                 },
518
519                 {
520                         "dry-run",
521                         true,
522                         false,
523                         []safcm.CommandChange{
524                                 {
525                                         Command: "fake command",
526                                         Output:  "fake output",
527                                 },
528                         },
529                         `executed 1 command(s): (dry-run)
530 "fake command":
531    > fake output
532    > \ No newline at end of file
533 `,
534                 },
535
536                 {
537                         "quiet",
538                         false,
539                         true,
540                         []safcm.CommandChange{
541                                 {
542                                         Command: "fake command",
543                                         Output:  "fake output",
544                                 },
545                                 {
546                                         Command: "fake command with no output",
547                                 },
548                                 {
549                                         Command: "fake command with newline",
550                                         Output:  "fake output\n",
551                                 },
552                                 {
553                                         Command: "fake command with more output",
554                                         Output:  "fake out\nfake put\nfake\n",
555                                 },
556                                 {
557                                         Command: "fake failed command",
558                                         Output:  "fake output",
559                                         Error:   "fake error",
560                                 },
561                         },
562                         `executed 5 command(s), 1 with no output:
563 "fake command":
564    > fake output
565    > \ No newline at end of file
566 "fake command with newline":
567    > fake output
568 "fake command with more output":
569    > fake out
570    > fake put
571    > fake
572 "fake failed command", failed: "fake error":
573    > fake output
574    > \ No newline at end of file
575 `,
576                 },
577
578                 {
579                         "quiet (only quiet commands)",
580                         false,
581                         true,
582                         []safcm.CommandChange{
583                                 {
584                                         Command: "fake command with no output",
585                                 },
586                                 {
587                                         Command: "fake command with no output",
588                                 },
589                         },
590                         `executed 2 command(s), 2 with no output
591 `,
592                 },
593
594                 {
595                         "quiet (quiet with errors)",
596                         false,
597                         true,
598                         []safcm.CommandChange{
599                                 {
600                                         Command: "fake command with no output but error",
601                                         Error:   "fake error",
602                                 },
603                                 {
604                                         Command: "fake command with no output",
605                                 },
606                         },
607                         `executed 2 command(s), 1 with no output:
608 "fake command with no output but error", failed: "fake error"
609 `,
610                 },
611
612                 {
613                         "quiet & dry-run",
614                         true,
615                         true,
616                         []safcm.CommandChange{
617                                 {
618                                         Command: "fake command",
619                                 },
620                                 {
621                                         Command: "fake command with no output",
622                                 },
623                                 {
624                                         Command: "fake command with newline",
625                                 },
626                                 {
627                                         Command: "fake command with more output",
628                                 },
629                                 {
630                                         Command: "fake failed command",
631                                 },
632                         },
633                         `executed 5 command(s): (dry-run)
634 "fake command"
635 "fake command with no output"
636 "fake command with newline"
637 "fake command with more output"
638 "fake failed command"
639 `,
640                 },
641
642                 {
643                         "escaping",
644                         false,
645                         false,
646                         []safcm.CommandChange{
647                                 {
648                                         Command: "\x00",
649                                         Trigger: "\x01",
650                                         Output:  "\x02",
651                                         Error:   "\x03",
652                                 },
653                         },
654                         `executed 1 command(s):
655 "\x00", trigger for "\x01", failed: "\x03":
656    > \x02
657    > \ No newline at end of file
658 `,
659                 },
660         }
661
662         for _, tc := range tests {
663                 t.Run(tc.name, func(t *testing.T) {
664                         s := &Sync{
665                                 config: &config.Config{
666                                         DryRun: tc.dryRun,
667                                         Quiet:  tc.quiet,
668                                 },
669                         }
670
671                         res := s.formatCommandChanges(tc.changes)
672                         if tc.exp != res {
673                                 t.Errorf("res: %s", cmp.Diff(tc.exp, res))
674                         }
675                 })
676         }
677 }