]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm/sync_test.go
2e5b3ab95106710d84ff2bdcdbacdb891b22a0a7
[safcm/safcm.git] / cmd / safcm / sync_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         "bytes"
20         "fmt"
21         "log"
22         "os"
23         "testing"
24
25         "ruderich.org/simon/safcm"
26         "ruderich.org/simon/safcm/cmd/safcm/config"
27         "ruderich.org/simon/safcm/rpc"
28         "ruderich.org/simon/safcm/testutil"
29 )
30
31 func TestHostsToSync(t *testing.T) {
32         cwd, err := os.Getwd()
33         if err != nil {
34                 t.Fatal(err)
35         }
36         defer os.Chdir(cwd)
37
38         err = os.Chdir("testdata/project")
39         if err != nil {
40                 t.Fatal(err)
41         }
42         _, allHosts, allGroups, err := LoadBaseFiles()
43         if err != nil {
44                 t.Fatal(err)
45         }
46
47         tests := []struct {
48                 name   string
49                 names  []string
50                 exp    []*config.Host
51                 expErr error
52         }{
53                 {
54                         "empty names",
55                         nil,
56                         nil,
57                         nil,
58                 },
59
60                 {
61                         "no match",
62                         []string{"unknown-host/group"},
63                         nil,
64                         fmt.Errorf("hosts/groups not found: \"unknown-host/group\""),
65                 },
66
67                 {
68                         "host: single name",
69                         []string{"host2"},
70                         []*config.Host{
71                                 allHosts.Map["host2"],
72                         },
73                         nil,
74                 },
75                 {
76                         "host: multiple names",
77                         []string{"host2", "host1.example.org"},
78                         []*config.Host{
79                                 allHosts.Map["host1.example.org"],
80                                 allHosts.Map["host2"],
81                         },
82                         nil,
83                 },
84                 {
85                         "host: multiple identical names",
86                         []string{"host2", "host2"},
87                         []*config.Host{
88                                 allHosts.Map["host2"],
89                         },
90                         nil,
91                 },
92                 {
93                         "host: multiple names, including unknown",
94                         []string{"host2", "unknown-host"},
95                         nil,
96                         fmt.Errorf("hosts/groups not found: \"unknown-host\""),
97                 },
98                 {
99                         "host: multiple names, including unknowns",
100                         []string{"host2", "unknown-host", "unknown-host-2"},
101                         nil,
102                         fmt.Errorf("hosts/groups not found: \"unknown-host\" \"unknown-host-2\""),
103                 },
104
105                 {
106                         "group: single name",
107                         []string{"group"},
108                         []*config.Host{
109                                 allHosts.Map["host1.example.org"],
110                         },
111                         nil,
112                 },
113                 {
114                         "group: multiple names",
115                         []string{"group", "group2"},
116                         []*config.Host{
117                                 allHosts.Map["host1.example.org"],
118                                 allHosts.Map["host2"],
119                         },
120                         nil,
121                 },
122                 {
123                         "group: multiple identical names",
124                         []string{"group", "group2", "group"},
125                         []*config.Host{
126                                 allHosts.Map["host1.example.org"],
127                                 allHosts.Map["host2"],
128                         },
129                         nil,
130                 },
131                 {
132                         "group: multiple names, including unknown",
133                         []string{"group", "group2", "unknown-group"},
134                         nil,
135                         fmt.Errorf("hosts/groups not found: \"unknown-group\""),
136                 },
137                 {
138                         "group: \"all\"",
139                         []string{"all"},
140                         []*config.Host{
141                                 allHosts.Map["host1.example.org"],
142                                 allHosts.Map["host2"],
143                                 allHosts.Map["host3.example.net"],
144                         },
145                         nil,
146                 },
147
148                 {
149                         "\"all\" and name",
150                         []string{"all", "group2"},
151                         []*config.Host{
152                                 allHosts.Map["host1.example.org"],
153                                 allHosts.Map["host2"],
154                                 allHosts.Map["host3.example.net"],
155                         },
156                         nil,
157                 },
158                 {
159                         "\"all\" and names",
160                         []string{"all", "group2", "host2"},
161                         []*config.Host{
162                                 allHosts.Map["host1.example.org"],
163                                 allHosts.Map["host2"],
164                                 allHosts.Map["host3.example.net"],
165                         },
166                         nil,
167                 },
168         }
169
170         for _, tc := range tests {
171                 t.Run(tc.name, func(t *testing.T) {
172                         res, err := hostsToSync(tc.names, allHosts, allGroups)
173                         testutil.AssertEqual(t, "res", res, tc.exp)
174                         testutil.AssertErrorEqual(t, "err", err, tc.expErr)
175                 })
176         }
177 }
178
179 func TestLogEvent(t *testing.T) {
180         // Restore default logger
181         defer log.SetFlags(log.Flags())
182         defer log.SetOutput(os.Stderr)
183
184         tests := []struct {
185                 name      string
186                 event     Event
187                 level     safcm.LogLevel
188                 isTTY     bool
189                 exp       string
190                 expFailed bool
191         }{
192
193                 {
194                         "Error",
195                         Event{
196                                 Error: fmt.Errorf("fake error"),
197                         },
198                         safcm.LogDebug3,
199                         false,
200                         "[error]   [fake-host] fake error\n",
201                         true,
202                 },
203                 {
204                         "Error (tty)",
205                         Event{
206                                 Error: fmt.Errorf("fake error"),
207                         },
208                         safcm.LogDebug3,
209                         true,
210                         "[error]   [\x1b[31mfake-host\x1b[0m] fake error\n",
211                         true,
212                 },
213                 {
214                         "Error: escape",
215                         Event{
216                                 Error: fmt.Errorf("\x00"),
217                         },
218                         safcm.LogDebug3,
219                         false,
220                         "[error]   [fake-host] \\x00\n",
221                         true,
222                 },
223                 {
224                         "Error: escape (tty)",
225                         Event{
226                                 Error: fmt.Errorf("\x00"),
227                         },
228                         safcm.LogDebug3,
229                         true,
230                         "[error]   [\x1b[31mfake-host\x1b[0m] \x1b[35m\\x00\x1b[0m\n",
231                         true,
232                 },
233
234                 {
235                         "Log: info",
236                         Event{
237                                 Log: Log{
238                                         Level: safcm.LogInfo,
239                                         Text:  "info log",
240                                 },
241                         },
242                         safcm.LogDebug3,
243                         false,
244                         "[info]    [fake-host] info log\n",
245                         false,
246                 },
247                 {
248                         "Log: info (tty)",
249                         Event{
250                                 Log: Log{
251                                         Level: safcm.LogInfo,
252                                         Text:  "info log",
253                                 },
254                         },
255                         safcm.LogDebug3,
256                         true,
257                         "[info]    [fake-host] info log\n",
258                         false,
259                 },
260                 {
261                         "Log: verbose",
262                         Event{
263                                 Log: Log{
264                                         Level: safcm.LogVerbose,
265                                         Text:  "verbose log",
266                                 },
267                         },
268                         safcm.LogDebug3,
269                         false,
270                         "[verbose] [fake-host] verbose log\n",
271                         false,
272                 },
273                 {
274                         "Log: debug",
275                         Event{
276                                 Log: Log{
277                                         Level: safcm.LogDebug,
278                                         Text:  "debug log",
279                                 },
280                         },
281                         safcm.LogDebug3,
282                         false,
283                         "[debug]   [fake-host] debug log\n",
284                         false,
285                 },
286                 {
287                         "Log: debug2",
288                         Event{
289                                 Log: Log{
290                                         Level: safcm.LogDebug2,
291                                         Text:  "debug2 log",
292                                 },
293                         },
294                         safcm.LogDebug3,
295                         false,
296                         "[debug2]  [fake-host] debug2 log\n",
297                         false,
298                 },
299                 {
300                         "Log: debug3",
301                         Event{
302                                 Log: Log{
303                                         Level: safcm.LogDebug3,
304                                         Text:  "debug3 log",
305                                 },
306                         },
307                         safcm.LogDebug3,
308                         false,
309                         fmt.Sprintf("[INVALID=%d] [fake-host] debug3 log\n",
310                                 safcm.LogDebug3),
311                         false,
312                 },
313                 {
314                         "Log: debug3 (tty)",
315                         Event{
316                                 Log: Log{
317                                         Level: safcm.LogDebug3,
318                                         Text:  "debug3 log",
319                                 },
320                         },
321                         safcm.LogDebug3,
322                         true,
323                         fmt.Sprintf("[INVALID=%d] [\x1b[31mfake-host\x1b[0m] debug3 log\n",
324                                 safcm.LogDebug3),
325                         false,
326                 },
327                 {
328                         "Log: escape",
329                         Event{
330                                 Log: Log{
331                                         Level: safcm.LogInfo,
332                                         Text:  "\x00",
333                                 },
334                         },
335                         safcm.LogDebug3,
336                         false,
337                         "[info]    [fake-host] \\x00\n",
338                         false,
339                 },
340                 {
341                         "Log: escape (tty)",
342                         Event{
343                                 Log: Log{
344                                         Level: safcm.LogInfo,
345                                         Text:  "\x00",
346                                 },
347                         },
348                         safcm.LogDebug3,
349                         true,
350                         "[info]    [fake-host] \x1b[35m\\x00\x1b[0m\n",
351                         false,
352                 },
353
354                 {
355                         "ConnEvent: stderr",
356                         Event{
357                                 ConnEvent: rpc.ConnEvent{
358                                         Type: rpc.ConnEventStderr,
359                                         Data: "fake stderr",
360                                 },
361                         },
362                         safcm.LogDebug3,
363                         false,
364                         "[stderr]  [fake-host] fake stderr\n",
365                         false,
366                 },
367                 {
368                         "ConnEvent: stderr (tty)",
369                         Event{
370                                 ConnEvent: rpc.ConnEvent{
371                                         Type: rpc.ConnEventStderr,
372                                         Data: "fake stderr",
373                                 },
374                         },
375                         safcm.LogDebug3,
376                         true,
377                         "[stderr]  [fake-host] fake stderr\n",
378                         false,
379                 },
380                 {
381                         "ConnEvent: debug",
382                         Event{
383                                 ConnEvent: rpc.ConnEvent{
384                                         Type: rpc.ConnEventDebug,
385                                         Data: "conn debug",
386                                 },
387                         },
388                         safcm.LogDebug3,
389                         false,
390                         "[debug3]  [fake-host] conn debug\n",
391                         false,
392                 },
393                 {
394                         "ConnEvent: upload",
395                         Event{
396                                 ConnEvent: rpc.ConnEvent{
397                                         Type: rpc.ConnEventUpload,
398                                 },
399                         },
400                         safcm.LogDebug3,
401                         false,
402                         "[info]    [fake-host] remote helper upload in progress\n",
403                         false,
404                 },
405                 {
406                         "ConnEvent: upload (ignored)",
407                         Event{
408                                 ConnEvent: rpc.ConnEvent{
409                                         Type: rpc.ConnEventUpload,
410                                 },
411                         },
412                         safcm.LogError,
413                         false,
414                         "",
415                         false,
416                 },
417                 {
418                         "ConnEvent: invalid",
419                         Event{
420                                 ConnEvent: rpc.ConnEvent{
421                                         Type: 42,
422                                         Data: "invalid",
423                                 },
424                         },
425                         safcm.LogError,
426                         false,
427                         "[INVALID=42] [fake-host] invalid\n",
428                         false,
429                 },
430                 {
431                         "ConnEvent: invalid (tty)",
432                         Event{
433                                 ConnEvent: rpc.ConnEvent{
434                                         Type: 42,
435                                         Data: "invalid",
436                                 },
437                         },
438                         safcm.LogError,
439                         true,
440                         "[INVALID=42] [\x1b[31mfake-host\x1b[0m] invalid\n",
441                         false,
442                 },
443                 {
444                         "ConnEvent: escape",
445                         Event{
446                                 ConnEvent: rpc.ConnEvent{
447                                         Type: rpc.ConnEventStderr,
448                                         Data: "\x00",
449                                 },
450                         },
451                         safcm.LogDebug3,
452                         false,
453                         "[stderr]  [fake-host] \\x00\n",
454                         false,
455                 },
456                 {
457                         "ConnEvent: escape (tty)",
458                         Event{
459                                 ConnEvent: rpc.ConnEvent{
460                                         Type: rpc.ConnEventDebug,
461                                         Data: "\x01",
462                                 },
463                         },
464                         safcm.LogDebug3,
465                         true,
466                         "[debug3]  [fake-host] \x1b[35m\\x01\x1b[0m\n",
467                         false,
468                 },
469
470                 {
471                         "Escaped",
472                         Event{
473                                 Log: Log{
474                                         Level: safcm.LogInfo,
475                                         Text:  "\x00",
476                                 },
477                                 Escaped: true,
478                         },
479                         safcm.LogDebug3,
480                         false,
481                         "[info]    [fake-host] \x00\n",
482                         false,
483                 },
484                 {
485                         "Escaped (tty)",
486                         Event{
487                                 Log: Log{
488                                         Level: safcm.LogInfo,
489                                         Text:  "\x00",
490                                 },
491                                 Escaped: true,
492                         },
493                         safcm.LogDebug3,
494                         true,
495                         "[info]    [fake-host] \x00\n",
496                         false,
497                 },
498
499                 {
500                         "empty (invalid)",
501                         Event{},
502                         safcm.LogDebug3,
503                         false,
504                         "[INVALID=0] [fake-host] \n",
505                         false,
506                 },
507         }
508
509         for _, tc := range tests {
510                 t.Run(tc.name, func(t *testing.T) {
511                         tc.event.Host = &config.Host{
512                                 Name: "fake-host",
513                         }
514
515                         var buf bytes.Buffer
516                         log.SetFlags(0)
517                         log.SetOutput(&buf)
518
519                         var failed bool
520                         logEvent(tc.event, tc.level, tc.isTTY, &failed)
521
522                         testutil.AssertEqual(t, "log",
523                                 buf.String(), tc.exp)
524                         testutil.AssertEqual(t, "failed",
525                                 failed, tc.expFailed)
526                 })
527         }
528 }