1 package patchmanager
2
3 import (
4 "archive/tar"
5 "compress/gzip"
6 "errors"
7 "fmt"
8 "io"
9 fsPkg "io/fs"
10 "os"
11 "path/filepath"
12 "reflect"
13 "strings"
14 "testing"
15
16 "github.com/go-logr/logr"
17 versionPkg "github.com/hashicorp/go-version"
18 "gotest.tools/v3/fs"
19
20 "edge-infra.dev/pkg/lib/logging"
21 common "edge-infra.dev/pkg/sds/patching/common"
22 )
23
24 func newConfig(t *testing.T) common.Config {
25 dir := fs.NewDir(t, "testing")
26 MountPath := dir.Path()
27
28 c := common.Config{
29 MountPath: MountPath,
30 ArtefactsPath: MountPath + "/versions",
31 ArtefactsTempPath: MountPath + "/versions/.tmp",
32 LiveBootPath: MountPath + "/live",
33 ScriptsPath: MountPath + "/patching",
34 ScriptsTempPath: MountPath + "/patching/.tmp",
35 EnvFilePath: MountPath + "/patching/patching.env",
36 LegacyScriptsPath: MountPath + "/upgrade",
37
38 BootFiles: MountPath + "/boot/",
39 ScriptFiles: MountPath + "/patching/",
40
41 PatchsetMount: MountPath + "/mnt/patchset",
42 RebootPath: MountPath + "/mnt/run/reboot-required",
43 }
44 return c
45 }
46
47 func createFileTree(cfg common.Config) error {
48 items := []string{
49 cfg.MountPath,
50 cfg.ArtefactsPath,
51 cfg.ArtefactsTempPath,
52 cfg.LiveBootPath,
53 cfg.ScriptsPath,
54 cfg.ScriptsTempPath,
55 cfg.EnvFilePath,
56 cfg.LegacyScriptsPath,
57 cfg.BootFiles,
58 cfg.ScriptFiles,
59 cfg.MountPath + "/mnt",
60 cfg.MountPath + "/mnt/run",
61 cfg.MountPath + "/boot",
62 }
63
64 for _, item := range items {
65 if err := os.MkdirAll(item, 0744); err != nil {
66 return err
67 }
68 }
69 return nil
70 }
71
72 func createTempFile(dir string, count int) ([]os.File, error) {
73 tempFiles := make([]os.File, count)
74
75 for i := 0; i < count; i++ {
76 tempFile, err := os.CreateTemp(dir, "")
77 if err != nil {
78 return nil, fmt.Errorf("error creating tempfile: %s", err)
79 }
80
81 tempFiles[i] = *tempFile
82 tempFile.Close()
83 }
84 return tempFiles, nil
85 }
86
87 func setupTarArchive(filePath string, tempFiles []os.File, cfg common.Config) (*os.File, error) {
88 writeArchive, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0744)
89 if err != nil {
90 return nil, fmt.Errorf("error opening archive file: %s", err)
91 }
92
93 gw := gzip.NewWriter(writeArchive)
94 defer gw.Close()
95 tw := tar.NewWriter(gw)
96 defer tw.Close()
97
98 for _, f := range tempFiles {
99 file, err := os.Open(f.Name())
100 if err != nil {
101 return nil, fmt.Errorf("error opening tempfile: %s", err)
102 }
103
104 tempFileInfo, err := file.Stat()
105 if err != nil {
106 return nil, fmt.Errorf("%s", err)
107 }
108
109 header, err := tar.FileInfoHeader(tempFileInfo, tempFileInfo.Name())
110 if err != nil {
111 return nil, fmt.Errorf("error creating tempfile header: %s", err)
112 }
113
114 header.Name = strings.TrimPrefix(strings.Replace(file.Name(), cfg.MountPath, "", -1), string(filepath.Separator))
115
116 err = tw.WriteHeader(header)
117 if err != nil {
118 return nil, fmt.Errorf("error writing header to archive: %s", err)
119 }
120
121 _, err = io.Copy(tw, file)
122 if err != nil {
123 return nil, fmt.Errorf("error copying tempfile to archive: %s", err)
124 }
125
126 if err := file.Close(); err != nil {
127 return nil, fmt.Errorf("error closing tempfile: %s", err)
128 }
129 }
130
131 readArchive, err := os.OpenFile(filePath, os.O_RDONLY, 0744)
132 if err != nil {
133 return nil, fmt.Errorf("error opening archive file: %s", err)
134 }
135 return readArchive, nil
136 }
137
138 func createDummyScripts(t *testing.T, filePath, phaseScriptsTempPath, phaseScriptsPath string) {
139 if err := os.MkdirAll(phaseScriptsTempPath, 0744); err != nil {
140 t.Errorf("unable to create temp script phase directories: %s", err)
141 }
142
143 if err := os.MkdirAll(phaseScriptsPath, 0744); err != nil {
144 t.Errorf("unable to create script phase directories: %s", err)
145 }
146
147 file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0744)
148 if err != nil {
149 t.Errorf("unable to create dummy scripts: %s", err)
150 }
151 defer file.Close()
152 }
153
154 func TestGetArtefactsPath(t *testing.T) {
155 cfg := newConfig(t)
156 version := "v1.10.1"
157
158 got := GetArtefactsPath(version, cfg)
159 expect := cfg.MountPath + "/versions/v1.10.1"
160 if got != expect {
161 t.Errorf("unexpected result. Wanted: %s; Got: %s", expect, got)
162 }
163
164 t.Logf("ArtefactsPath: %s", got)
165 }
166
167 func TestValidateChecksum(t *testing.T) {
168 scenarios := []struct {
169 cfg common.Config
170 checksum, contents string
171 }{
172 {cfg: newConfig(t), checksum: "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", contents: "foobar"},
173 }
174
175 for _, s := range scenarios {
176 file, err := os.CreateTemp(s.cfg.MountPath, "TestValidateChecksum")
177 if err != nil {
178 t.Errorf("error while creating temp file: %s", err)
179 }
180 defer file.Close()
181
182 _, err = file.Write([]byte(s.contents))
183 if err != nil {
184 t.Errorf("error while writing to temp file: %s", err)
185 }
186
187 err = ValidateChecksum(file.Name(), s.checksum)
188 if err != nil {
189 t.Errorf("error: Got %s. Wanted %s.", err, s.checksum)
190 }
191
192 t.Logf("Checksum: %s", s.checksum)
193 }
194 }
195
196 func TestGetSha256(t *testing.T) {
197 scenarios := []struct {
198 cfg common.Config
199 checksum, contents string
200 }{
201 {cfg: newConfig(t), checksum: "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2", contents: "foobar"},
202 }
203
204 for _, s := range scenarios {
205 file, err := os.CreateTemp(s.cfg.MountPath, "TestValidateChecksum")
206 if err != nil {
207 t.Errorf("error while creating temp file: %s", err)
208 }
209 defer file.Close()
210
211 _, err = file.Write([]byte(s.contents))
212 if err != nil {
213 t.Errorf("error while writing to temp file: %s", err)
214 }
215
216 sha, err := GetSha256(file.Name())
217 if len(sha) != 64 {
218 t.Errorf("SHA256sum value is invalid; not 64 characters")
219 } else if err != nil {
220 t.Errorf("error: Got %s. Wanted %s.", err, s.checksum)
221 }
222 }
223 }
224
225 func TestLoadDirectivesConfig(t *testing.T) {
226 scenarios := []struct {
227 cfg common.Config
228 versions []string
229 source string
230 expect []DirectivesConfig
231 }{
232 {
233 cfg: newConfig(t),
234 versions: []string{
235 "v1.11.0",
236 },
237 source: `directives:
238 - regex: (v1.10.1)
239 script_options:
240 - name: v1.09.4
241 skip: false
242 weight: 1
243 - name: v1.10.1
244 skip: true
245 weight: 2
246 - name: v1.10.1
247 - regex: (v1.11.1)
248 script_options:
249 - name: v1.11.1
250 skip: false
251 weight: 3`,
252 expect: []DirectivesConfig{
253 {
254
255 Directives: []struct {
256 Regex string `yaml:"regex"`
257 ScriptOptions []struct {
258 Name string
259 Skip bool
260 Weight int
261 } `yaml:"script_options"`
262 }{
263 {
264 Regex: "(v1.10.1)",
265 ScriptOptions: []struct {
266 Name string
267 Skip bool
268 Weight int
269 }{
270 {
271 Name: "v1.09.4",
272 Skip: false,
273 Weight: 1,
274 },
275 {
276 Name: "v1.10.1",
277 Skip: true,
278 Weight: 2,
279 },
280 {
281 Name: "v1.10.1",
282 Skip: false,
283 Weight: 0,
284 },
285 },
286 },
287 {
288 Regex: "(v1.11.1)",
289 ScriptOptions: []struct {
290 Name string
291 Skip bool
292 Weight int
293 }{
294 {
295 Name: "v1.11.1",
296 Skip: false,
297 Weight: 3,
298 },
299 },
300 },
301 },
302 },
303 },
304 },
305 }
306
307 for _, s := range scenarios {
308 versions := make([]*versionPkg.Version, len(s.versions))
309
310 for i, v := range s.versions {
311 version, err := versionPkg.NewVersion(v)
312 if err != nil {
313 t.Errorf("error converting slice of version strings into version structs: %s", err)
314 }
315 versions[i] = version
316
317 configPath := filepath.Join(s.cfg.ScriptsTempPath, version.Original(), "config.yaml")
318
319 if err := os.MkdirAll(filepath.Dir(configPath), 0744); err != nil {
320 t.Errorf("error creating filepath: %s", err)
321 }
322
323 file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE, 0744)
324 if err != nil {
325 t.Errorf("error creating config.yaml: %s", err)
326 }
327
328 _, err = file.Write([]byte(s.source))
329 if err != nil {
330 t.Errorf("error writing YAML string to config.yaml: %s", err)
331 }
332
333 if err := file.Close(); err != nil {
334 t.Errorf("error closing file: %s", err)
335 }
336 }
337
338 got, err := loadDirectivesConfig(versions, s.cfg)
339 if err != nil {
340 t.Errorf("%s", err)
341 }
342
343 if reflect.DeepEqual(got, s.expect) != true {
344 t.Errorf("unexpected return value for loadDirectivesConfig. Got %v. Expected %v", got, s.expect)
345 }
346 }
347 }
348
349 func TestInstallScriptsVersion(t *testing.T) {
350 scenarios := []struct {
351 cfg common.Config
352 version, currentVer string
353 isControlPlane bool
354 log logr.Logger
355 hashMaps map[string]map[string]string
356 configs []DirectivesConfig
357 }{
358 {
359 cfg: newConfig(t),
360 version: "v1.11.0",
361 currentVer: "v1.10.1",
362 isControlPlane: true,
363 log: logging.NewLogger().Logger,
364 hashMaps: make(map[string]map[string]string),
365 configs: []DirectivesConfig{
366 {
367 Directives: []struct {
368 Regex string `yaml:"regex"`
369 ScriptOptions []struct {
370 Name string
371 Skip bool
372 Weight int
373 } `yaml:"script_options"`
374 }{
375 {
376 Regex: "v1.10.1",
377 ScriptOptions: []struct {
378 Name string
379 Skip bool
380 Weight int
381 }{
382 {
383 Name: "01_script.sh",
384 Skip: false,
385 Weight: 1,
386 },
387 },
388 },
389 },
390 },
391 },
392 },
393 }
394
395 for _, s := range scenarios {
396 version, err := versionPkg.NewVersion(s.version)
397 if err != nil {
398 t.Errorf("error converting slice of version strings into version structs: %s", err)
399 }
400
401 currentVer, err := versionPkg.NewVersion(s.currentVer)
402 if err != nil {
403 t.Errorf("error converting slice of version strings into version structs: %s", err)
404 }
405
406 for _, phase := range upgradePhases {
407 var (
408 phaseScriptsTempPath = filepath.Join(s.cfg.ScriptsTempPath, version.Original(), phase)
409 phaseScriptsPath = filepath.Join(s.cfg.ScriptsPath, phase)
410 filePaths []string
411 )
412
413 filePaths = append(filePaths, filepath.Join(phaseScriptsTempPath, "01_script.sh"))
414 if phase == "post-reboot" {
415 filePaths = append(filePaths, filepath.Join(phaseScriptsTempPath, "02_script.sh"))
416 }
417
418 for _, filePath := range filePaths {
419 createDummyScripts(t, filePath, phaseScriptsPath, phaseScriptsTempPath)
420 }
421 s.hashMaps[phase] = make(map[string]string)
422 }
423 err = installScriptsVersion(currentVer, version, s.configs, s.isControlPlane, s.log, s.cfg, s.hashMaps)
424 if err != nil {
425 t.Errorf("%s", err)
426 }
427 }
428 }
429
430 func TestExtractTarFile(t *testing.T) {
431 scenarios := []struct {
432 cfg common.Config
433 log logr.Logger
434 subPath string
435 }{
436 {cfg: newConfig(t), log: logging.NewLogger().Logger, subPath: "boot"},
437 {cfg: newConfig(t), log: logging.NewLogger().Logger, subPath: "patching"},
438 }
439
440 for _, s := range scenarios {
441 var dir = filepath.Join(s.cfg.MountPath, s.subPath)
442 var path = filepath.Join(dir, "archive.tar.gz")
443
444 if err := createFileTree(s.cfg); err != nil {
445 t.Errorf("unable to create file tree: %s", err)
446 }
447
448 tempFiles, err := createTempFile(dir, 1)
449 if err != nil {
450 t.Errorf("error creating tempfile: %s", err)
451 }
452
453 archive, err := setupTarArchive(path, tempFiles, s.cfg)
454 if err != nil {
455 t.Errorf("error creating archive file: %s", err)
456 }
457
458 err = extractTarFile(archive, s.log, s.cfg)
459 if err != nil {
460 t.Errorf("error extracting tar archive: %s", err)
461 }
462 }
463 }
464
465 func TestPrepareDirectories(t *testing.T) {
466 scenarios := []struct {
467 cfg common.Config
468 targetPath string
469 }{
470 {cfg: newConfig(t), targetPath: "/boot/versions/v1.11.0"},
471 }
472
473 for _, s := range scenarios {
474 if err := prepareDirectories(s.targetPath, s.cfg); err != nil {
475 t.Errorf("%s", err)
476 }
477
478 dirs, err := os.ReadDir(s.cfg.ScriptsPath)
479 if err != nil {
480 t.Errorf("error reading prepared directories: %s", err)
481 }
482
483 t.Logf("Script directories: %v", dirs)
484 }
485 }
486
487 func TestCreateScriptDirectories(t *testing.T) {
488 scenarios := []struct {
489 cfg common.Config
490 }{
491 {cfg: newConfig(t)},
492 }
493
494 for _, s := range scenarios {
495 if err := createScriptDirectories(s.cfg); err != nil {
496 t.Errorf("%s", err)
497 }
498
499 dirs, err := os.ReadDir(s.cfg.ScriptsPath)
500 if err != nil {
501 t.Errorf("error reading prepared directories: %s", err)
502 }
503
504 t.Logf("Script directories: %v", dirs)
505 }
506 }
507
508 func TestHousekeepVersions(t *testing.T) {
509 scenarios := []struct {
510 cfg common.Config
511 retentionVers []string
512 log logr.Logger
513 }{
514 {
515 cfg: newConfig(t),
516 retentionVers: []string{"v1.10.1", "v1.11.0"},
517 log: logging.NewLogger().Logger,
518 },
519 }
520
521 for _, s := range scenarios {
522 if err := createFileTree(s.cfg); err != nil {
523 t.Errorf("unable to create file tree: %s", err)
524 }
525
526 versions := []string{"v1.9.2", "v1.10.1", "v1.11.0", "v1.12.0"}
527 for _, v := range versions {
528 _, err := os.Create(filepath.Join(s.cfg.ArtefactsPath, v))
529 if err != nil {
530 t.Errorf("unable to create version files: %s", err)
531 }
532 }
533
534 if err := housekeepVersions(s.retentionVers, s.log, s.cfg); err != nil {
535 t.Errorf("%s", err)
536 }
537 }
538 }
539
540 func TestVersionSort(t *testing.T) {
541 scenarios := []struct {
542 cfg common.Config
543 unsortedVersions, expect []string
544 }{
545 {
546 cfg: newConfig(t),
547 unsortedVersions: []string{"v1.12.0", "v1.9.2", "v1.11.0", "v1.10.1", "v1.12.0-123456"},
548 expect: []string{"v1.9.2", "v1.10.1", "v1.11.0", "v1.12.0-123456", "v1.12.0"},
549 },
550 }
551
552 for _, s := range scenarios {
553 var (
554 versionsRaw = make([]fsPkg.FileInfo, len(s.unsortedVersions))
555 sortedVersions = make([]string, len(s.unsortedVersions))
556 )
557
558 if err := createFileTree(s.cfg); err != nil {
559 t.Errorf("unable to create file tree: %s", err)
560 }
561
562 for i, v := range s.unsortedVersions {
563 filePath := filepath.Join(s.cfg.ArtefactsPath, v)
564
565 _, err := os.Create(filePath)
566 if err != nil {
567 t.Errorf("unable to create version files: %s", err)
568 }
569
570 fileInfo, err := os.Stat(filePath)
571 if err != nil {
572 t.Errorf("%s", err)
573 }
574
575 versionsRaw[i] = fileInfo
576 }
577
578 got, err := versionSort(versionsRaw)
579 if err != nil {
580 t.Errorf("%s", err)
581 }
582
583 for i := range got {
584 sortedVersions[i] = got[i].Original()
585 }
586
587 if reflect.DeepEqual(sortedVersions, s.expect) != true {
588 t.Errorf("unexpected return value for versionSort. Got %v. Expected %v", got, s.expect)
589 }
590
591 t.Logf("Sorted versions: %s", sortedVersions)
592 }
593 }
594
595 func TestPrepareLegacy(t *testing.T) {
596 scenarios := []struct {
597 cfg common.Config
598 currentVer string
599 log logr.Logger
600 legacy bool
601 }{
602 {
603 cfg: newConfig(t),
604 currentVer: "v1.11.0",
605 log: logging.NewLogger().Logger,
606 legacy: false,
607 },
608 {
609 cfg: newConfig(t),
610 currentVer: "v1.9.2",
611 log: logging.NewLogger().Logger,
612 legacy: false,
613 },
614 {
615 cfg: newConfig(t),
616 currentVer: "v1.9.2",
617 log: logging.NewLogger().Logger,
618 legacy: true,
619 },
620 }
621
622 for _, s := range scenarios {
623 if s.legacy == true {
624 if err := os.MkdirAll(s.cfg.LegacyScriptsPath, 0744); err != nil {
625 t.Errorf("error creating upgrade directory: %s", err)
626 }
627 }
628
629 if err := prepareLegacy(s.currentVer, s.log, s.cfg); err != nil {
630 t.Errorf("%s", err)
631 }
632 }
633 }
634
635 func TestPadVersion(t *testing.T) {
636 scenarios := []struct {
637 versionString, expect string
638 }{
639 {
640 versionString: "v1.11.0",
641 expect: "v01.11.00",
642 },
643 {
644 versionString: "v1.11.0-beta+012345",
645 expect: "v01.11.00-beta",
646 },
647 }
648
649 for _, s := range scenarios {
650 version, err := versionPkg.NewVersion(s.versionString)
651 if err != nil {
652 t.Errorf("%s", err)
653 }
654
655 got := padVersion(version)
656 if got != s.expect {
657 t.Errorf("unexpected return value. Got: %s, expected: %s", got, s.expect)
658 }
659
660 t.Logf("Padded version: %s", got)
661 }
662 }
663
664 func TestRoleFilter(t *testing.T) {
665 scenarios := []struct {
666 fileName string
667 isControlPlane, expect bool
668 }{
669 {
670 fileName: "01_script.cp.sh",
671 isControlPlane: true,
672 expect: false,
673 },
674 {
675 fileName: "01_script.cp.sh",
676 isControlPlane: false,
677 expect: true,
678 },
679 {
680 fileName: "01_script.tp.sh",
681 isControlPlane: true,
682 expect: true,
683 },
684 {
685 fileName: "01_script.tp.sh",
686 isControlPlane: false,
687 expect: false,
688 },
689 {
690 fileName: "01_script.sh",
691 isControlPlane: true,
692 expect: false,
693 },
694 {
695 fileName: "01_script.sh",
696 isControlPlane: false,
697 expect: false,
698 },
699 }
700
701 for _, s := range scenarios {
702 if got := roleFilter(s.fileName, s.isControlPlane); got != s.expect {
703 t.Errorf("unexpected return value. Got: %t, expected: %t\n", got, s.expect)
704 }
705 }
706 }
707
708 func TestIsExecutable(t *testing.T) {
709 scenarios := []struct {
710 cfg common.Config
711 filePath string
712 expect bool
713 }{
714 {
715 cfg: newConfig(t),
716 filePath: "01_script.cp.sh",
717 expect: true,
718 },
719 {
720 cfg: newConfig(t),
721 filePath: "01_script.cp.sh",
722 expect: false,
723 },
724 }
725
726 for _, s := range scenarios {
727 if err := createFileTree(s.cfg); err != nil {
728 t.Errorf("error creating file tree: %s", err)
729 }
730
731 var filePath = filepath.Join(s.cfg.MountPath, s.filePath)
732 file, err := os.Create(filePath)
733 if err != nil {
734 t.Errorf("%s", err)
735 }
736
737 switch s.expect {
738 case true:
739 if err := os.Chmod(file.Name(), 0777); err != nil {
740 t.Errorf("an error occurred when modifying file permissions: %s", err)
741 }
742 case false:
743 if err := os.Chmod(file.Name(), 0666); err != nil {
744 t.Errorf("an error occurred when modifying file permissions: %s", err)
745 }
746 }
747
748 if got := IsExecutable(filePath); got != s.expect {
749 t.Errorf("unexpected return value. Got: %t, expected: %t\n", got, s.expect)
750 }
751 }
752 }
753
754 func TestCheckDirectives(t *testing.T) {
755 scenarios := []struct {
756 name, currentVer string
757 expect struct {
758 skip bool
759 weight int
760 }
761 }{
762 {
763 name: "01_script.sh",
764 currentVer: "v1.11.1",
765 expect: struct {
766 skip bool
767 weight int
768 }{
769 skip: false,
770 weight: 10,
771 },
772 },
773 {
774 name: "100_script.sh",
775 currentVer: "v1.10.1",
776 expect: struct {
777 skip bool
778 weight int
779 }{
780 skip: false,
781 weight: 10,
782 },
783 },
784 {
785 name: "01_script.sh",
786 currentVer: "v1.10.1",
787 expect: struct {
788 skip bool
789 weight int
790 }{
791 skip: true,
792 weight: 1,
793 },
794 },
795 }
796
797 config := []DirectivesConfig{
798 {
799 Directives: []struct {
800 Regex string `yaml:"regex"`
801 ScriptOptions []struct {
802 Name string
803 Skip bool
804 Weight int
805 } `yaml:"script_options"`
806 }{
807 {
808 Regex: "v1.10.1",
809 ScriptOptions: []struct {
810 Name string
811 Skip bool
812 Weight int
813 }{
814 {
815 Name: "01_script.sh",
816 Skip: true,
817 Weight: 1,
818 },
819 },
820 },
821 },
822 },
823 }
824
825 for _, s := range scenarios {
826 skip, weight := checkDirectives(config, s.currentVer, s.name)
827 if skip != s.expect.skip {
828 t.Errorf("unexpected return value. Got: %+v, expected: %+v\n", skip, s.expect.skip)
829 }
830 if weight != s.expect.weight {
831 t.Errorf("unexpected return value. Got: %+v, expected: %+v\n", weight, s.expect.weight)
832 }
833 }
834 }
835
836 func TestGetDestPath(t *testing.T) {
837 scenarios := []struct {
838 cfg common.Config
839 subPath string
840 }{
841 {
842 cfg: newConfig(t),
843 subPath: "boot",
844 },
845 {
846 cfg: newConfig(t),
847 subPath: "patching",
848 },
849 }
850
851 for _, s := range scenarios {
852 var path = filepath.Join(s.cfg.MountPath, s.subPath)
853 if err := createFileTree(s.cfg); err != nil {
854 t.Errorf("error creating file tree: %s", err)
855 }
856
857 tempFile, err := os.CreateTemp(path, "")
858 if err != nil {
859 t.Errorf("error creating tempfile: %s", err)
860 }
861
862 var header = strings.TrimPrefix(strings.Replace(tempFile.Name(), s.cfg.MountPath, "", -1), "/")
863 got, err := getDestPath(header, s.cfg)
864 if err != nil {
865 t.Errorf("%s", err)
866 }
867
868 var expect string
869 switch s.subPath {
870 case "boot":
871 var fileName = strings.TrimPrefix(strings.Replace(tempFile.Name(), s.cfg.BootFiles, "", -1), "/")
872 expect = filepath.Join(s.cfg.ArtefactsTempPath, fileName)
873 case "patching":
874 var fileName = strings.TrimPrefix(strings.Replace(tempFile.Name(), s.cfg.ScriptFiles, "", -1), "/")
875 expect = filepath.Join(s.cfg.ScriptsTempPath, fileName)
876 }
877
878 if got != expect {
879 t.Errorf("unexpected return value. Got: %s, expected: %s", got, expect)
880 }
881
882 t.Logf("DestPath for %s: %s", s.subPath, got)
883 }
884 }
885
886 func TestWriteFile(t *testing.T) {
887 scenarios := []struct {
888 cfg common.Config
889 log logr.Logger
890 path, dir string
891 }{
892 {
893 cfg: newConfig(t),
894 log: logging.NewLogger().Logger,
895 },
896 }
897
898 for _, s := range scenarios {
899 if err := createFileTree(s.cfg); err != nil {
900 t.Errorf("error creating file tree: %s", err)
901 }
902
903 tempFiles, err := createTempFile(s.cfg.ArtefactsTempPath, 2)
904 if err != nil {
905 t.Errorf("error creating tempfiles: %s", err)
906 }
907
908 var filepath = filepath.Join(s.cfg.ArtefactsTempPath, "archive.tar.gz")
909 archive, err := setupTarArchive(filepath, tempFiles, s.cfg)
910 if err != nil {
911 t.Errorf("error creating archive: %s", err)
912 }
913
914 gr, err := gzip.NewReader(archive)
915 if err != nil {
916 t.Errorf("error creating gzip reader: %s", err)
917 }
918 defer gr.Close()
919 tr := tar.NewReader(gr)
920
921 for _, file := range tempFiles {
922 filePath := file.Name()
923 if err := os.Remove(filePath); err != nil {
924 t.Errorf("error deleting file: %s", err)
925 }
926
927 header, err := tr.Next()
928 if err != nil {
929 t.Errorf("error advancing to next archive entry: %s", err)
930 }
931
932 if err := writeFile(filePath, tr, header, s.log); err != nil {
933 t.Errorf("error extracting patchset: %s", err)
934 }
935
936 file, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
937 if errors.Is(err, fsPkg.ErrNotExist) {
938 t.Errorf("file does not exist: %s", err)
939 } else if err != nil {
940 t.Errorf("error opening file: %s", err)
941 }
942 defer file.Close()
943 }
944 }
945 }
946
947 func TestExtractPatchset(t *testing.T) {
948 scenarios := []struct {
949 cfg common.Config
950 log logr.Logger
951 targetVersion string
952 }{
953 {
954 cfg: newConfig(t),
955 log: logging.NewLogger().Logger,
956 targetVersion: "v1.11.0",
957 },
958 }
959
960 for _, s := range scenarios {
961 if err := createFileTree(s.cfg); err != nil {
962 t.Errorf("error creating file tree: %s", err)
963 }
964
965 tempFiles, err := createTempFile(s.cfg.BootFiles, 2)
966 if err != nil {
967 t.Errorf("error creating temp files: %s", err)
968 }
969 _, err = setupTarArchive(s.cfg.PatchsetMount, tempFiles, s.cfg)
970 if err != nil {
971 t.Errorf("error creating archive: %s", err)
972 }
973
974 if err := extractPatchset(s.targetVersion, s.log, s.cfg); err != nil {
975 t.Errorf("error extracting patchset, %s", err)
976 }
977 }
978 }
979
980 func TestMain(m *testing.M) {
981 os.Exit(m.Run())
982 }
983
View as plain text