Skip to content

Commit fbbe55d

Browse files
authored
Added switch to only show warnings instead of errors in automatic update public index (#656)
## Fixes - no errors anymore when problems while automatic update index runs ## Changes - introduced a switch for that and checked in several places ## Checklist <!-- Put an `x` in the boxes. All tasks must be completed and boxes checked before merging. --> - [x] 🤖 This change is covered by unit tests (if applicable). - [x] 🤹 Manual testing has been performed (if necessary). - [x] 🛡️ Security impacts have been considered (if relevant). - [x] 📖 Documentation updates are complete (if required). - [x] 🧠 Third-party dependencies and TPIP updated (if required).
1 parent bd79416 commit fbbe55d

File tree

2 files changed

+276
-8
lines changed

2 files changed

+276
-8
lines changed

cmd/installer/root.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -900,19 +900,21 @@ func UpdateInstalledPDSCFiles(pidxXML, cidxXML *xml.PidxXML, updatePrivatePdsc,
900900
func UpdatePublicIndexIfOnline() error {
901901
// If public index already exists then first check if online, then its timestamp
902902
// if we are online and it is too old then download a current version
903+
903904
if utils.FileExists(Installation.PublicIndex) {
904905
err := utils.CheckConnection(ConnectionTryURL, 0)
905906
if err != nil && errors.Unwrap(err) != errs.ErrOffline {
906-
return err
907+
log.Warnf("Cannot check for public index update: %v", err)
907908
}
908909
if errors.Unwrap(err) != errs.ErrOffline {
909910
var updateConf updateCfg
910-
err = Installation.checkUpdateCfg(&updateConf)
911+
err = Installation.checkUpdateCfg(&updateConf, true)
911912
if err != nil {
912913
UnlockPackRoot()
913914
err1 := UpdatePublicIndex(ActualPublicIndex, false, false, false, false, false, 0, 0)
914915
if err1 != nil {
915-
return err1
916+
log.Warnf("Cannot update public index: %v", err1)
917+
return nil
916918
}
917919
_ = Installation.updateUpdateCfg(&updateConf)
918920
}
@@ -925,7 +927,8 @@ func UpdatePublicIndexIfOnline() error {
925927
UnlockPackRoot()
926928
err1 := UpdatePublicIndex(ActualPublicIndex, false, false, false, false, false, 0, 0)
927929
if err1 != nil {
928-
return err1
930+
log.Warnf("Cannot update public index: %v", err1)
931+
return nil
929932
}
930933
var updateConf updateCfg
931934
updateConf.Auto = true
@@ -1385,9 +1388,9 @@ func ListInstalledPacks(listCached, listPublic, listUpdates, listRequirements, t
13851388
// 1.2.1. if pack's pdsc file not found in Installation.LocalDir then raise errs.ErrPackURLCannotBeFound
13861389
// 1.2.2. read .Local/PDSC file into pdscXML
13871390
// 1.2.3. releastTag = pdscXML.FindReleaseTagByVersion(pack.Version)
1388-
// 1.2.3. if releaseTag == nil then raise ErrPackVersionNotFoundInPdsc
1389-
// 1.2.4. if releaseTag.URL != "", return releaseTag.URL
1390-
// 1.2.5. return pdscTag.URL + pack.Vendor + "." + pack.Name + "." + pack.Version + ".pack"
1391+
// 1.2.4. if releaseTag == nil then raise ErrPackVersionNotFoundInPdsc
1392+
// 1.2.5. if releaseTag.URL != "", return releaseTag.URL
1393+
// 1.2.6. return pdscTag.URL + pack.Vendor + "." + pack.Name + "." + pack.Version + ".pack"
13911394
//
13921395
// The function resolves the version modifier to determine the correct version of the pack to fetch.
13931396
// It then checks the release tag for the specified version and returns the URL if found.
@@ -1747,14 +1750,19 @@ type updateCfg struct {
17471750
// Parameters:
17481751
// - conf (*updateCfg): A pointer to the updateCfg structure that will be populated
17491752
// with the parsed configuration values.
1753+
// - WarningInsteadOfErrors (bool): A flag indicating whether to log warnings instead of returning errors.
17501754
//
17511755
// Returns:
17521756
// - error: An error is returned if the "update.cfg" file cannot be opened, if the
17531757
// "Date" field cannot be parsed, or if the timestamp in the "Date" field is older
17541758
// than 24 hours. If no errors occur, nil is returned.
1755-
func (p *PacksInstallationType) checkUpdateCfg(conf *updateCfg) error {
1759+
func (p *PacksInstallationType) checkUpdateCfg(conf *updateCfg, WarningInsteadOfErrors bool) error {
17561760
f, err := os.Open(filepath.Join(p.WebDir, "update.cfg"))
17571761
if err != nil {
1762+
if WarningInsteadOfErrors {
1763+
log.Warnf("Could not open update.cfg: %v", err)
1764+
return nil
1765+
}
17581766
return err
17591767
}
17601768
defer f.Close()

cmd/installer/root_test.go

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,266 @@ func TestGetDefaultCmsisPackRoot(t *testing.T) {
470470
}
471471
}
472472

473+
func TestUpdatePublicIndexIfOnline(t *testing.T) {
474+
assert := assert.New(t)
475+
476+
t.Run("test with existing index and recent update.cfg", func(t *testing.T) {
477+
localTestingDir := "test-update-online-no-update-needed"
478+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
479+
installer.UnlockPackRoot()
480+
defer removePackRoot(localTestingDir)
481+
482+
// Create a test server
483+
server := NewServer()
484+
defer server.httpsServer.Close()
485+
486+
// Create a public index file
487+
publicIndexContent, err := os.ReadFile(samplePublicIndex)
488+
assert.Nil(err)
489+
490+
// Add route for the public index
491+
server.AddRoute("index.pidx", publicIndexContent)
492+
493+
// Update the Installation to use the test server
494+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
495+
installer.ActualPublicIndex = server.URL() + "index.pidx"
496+
497+
// Create an existing index file
498+
assert.Nil(utils.TouchFile(installer.Installation.PublicIndex))
499+
500+
// Create a recent update.cfg file (less than one day old)
501+
updateCfgPath := filepath.Join(installer.Installation.WebDir, "update.cfg")
502+
recentDate := time.Now().Format("2-1-2006")
503+
updateCfgContent := "Date: " + recentDate + "\nAuto: true\n"
504+
assert.Nil(os.WriteFile(updateCfgPath, []byte(updateCfgContent), 0600))
505+
506+
// Get modification time before
507+
statBefore, err := os.Stat(installer.Installation.PublicIndex)
508+
assert.Nil(err)
509+
modTimeBefore := statBefore.ModTime()
510+
511+
// Call UpdatePublicIndexIfOnline - should not update because update.cfg is recent
512+
err = installer.UpdatePublicIndexIfOnline()
513+
// May fail internally due to connection check, but always returns nil
514+
assert.Nil(err)
515+
516+
// public index should not be modified since update.cfg is recent
517+
statAfter, err2 := os.Stat(installer.Installation.PublicIndex)
518+
assert.Nil(err2)
519+
modTimeAfter := statAfter.ModTime()
520+
521+
// File modification times should be very close (within filesystem precision)
522+
// If the index was updated, the mod time would be significantly different
523+
timeDiff := modTimeAfter.Sub(modTimeBefore).Abs()
524+
assert.True(timeDiff < 2*time.Second, "Index should not be updated when update.cfg is recent (time diff: %v)", timeDiff)
525+
})
526+
527+
t.Run("test with existing index and old update.cfg", func(t *testing.T) {
528+
localTestingDir := "test-update-online-old-updatecfg"
529+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
530+
installer.UnlockPackRoot()
531+
defer removePackRoot(localTestingDir)
532+
533+
// Create a test server
534+
server := NewServer()
535+
defer server.httpsServer.Close()
536+
537+
// Create a public index file
538+
publicIndexContent, err := os.ReadFile(samplePublicIndex)
539+
assert.Nil(err)
540+
541+
// Add route for the public index
542+
server.AddRoute("index.pidx", publicIndexContent)
543+
544+
// Update the Installation to use the test server
545+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
546+
installer.ActualPublicIndex = server.URL() + "index.pidx"
547+
548+
// Create an existing index file
549+
assert.Nil(utils.TouchFile(installer.Installation.PublicIndex))
550+
551+
// Create an old update.cfg file (more than one day old)
552+
updateCfgPath := filepath.Join(installer.Installation.WebDir, "update.cfg")
553+
oldDate := time.Now().AddDate(0, 0, -2).Format("2-1-2006")
554+
updateCfgContent := "Date: " + oldDate + "\nAuto: true\n"
555+
assert.Nil(os.WriteFile(updateCfgPath, []byte(updateCfgContent), 0600))
556+
557+
// Call UpdatePublicIndexIfOnline - may fail depending on connection but should return nil
558+
err = installer.UpdatePublicIndexIfOnline()
559+
// May fail internally due to connection check, but always returns nil
560+
assert.Nil(err)
561+
})
562+
563+
t.Run("test with missing index file", func(t *testing.T) {
564+
localTestingDir := "test-update-missing-index"
565+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
566+
installer.UnlockPackRoot()
567+
defer removePackRoot(localTestingDir)
568+
569+
// Create a test server
570+
server := NewServer()
571+
defer server.httpsServer.Close()
572+
573+
// Create a public index file
574+
publicIndexContent, err := os.ReadFile(samplePublicIndex)
575+
assert.Nil(err)
576+
577+
// Add route for the public index
578+
server.AddRoute("index.pidx", publicIndexContent)
579+
580+
// Update the Installation to use the test server
581+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
582+
installer.ActualPublicIndex = server.URL() + "index.pidx"
583+
584+
// Ensure index file does not exist
585+
if utils.FileExists(installer.Installation.PublicIndex) {
586+
os.Remove(installer.Installation.PublicIndex)
587+
}
588+
589+
// Call UpdatePublicIndexIfOnline - should try to download
590+
err = installer.UpdatePublicIndexIfOnline()
591+
// Should always succeed
592+
assert.Nil(err)
593+
594+
// Verify that index file was created
595+
assert.True(utils.FileExists(installer.Installation.PublicIndex))
596+
597+
// Verify that update.cfg was created
598+
updateCfgPath := filepath.Join(installer.Installation.WebDir, "update.cfg")
599+
assert.True(utils.FileExists(updateCfgPath))
600+
})
601+
602+
t.Run("test with missing index and download failure", func(t *testing.T) {
603+
localTestingDir := "test-update-missing-index-download-failure"
604+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
605+
installer.UnlockPackRoot()
606+
defer removePackRoot(localTestingDir)
607+
608+
// Create a test server that returns 404
609+
server := NewServer()
610+
defer server.httpsServer.Close()
611+
612+
// Add route that returns nil (causes 404)
613+
server.AddRoute("index.pidx", nil)
614+
615+
// Update the Installation to use the test server
616+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
617+
installer.ActualPublicIndex = server.URL() + "index.pidx"
618+
619+
// Ensure index file does not exist
620+
if utils.FileExists(installer.Installation.PublicIndex) {
621+
os.Remove(installer.Installation.PublicIndex)
622+
}
623+
624+
// Call UpdatePublicIndexIfOnline
625+
err := installer.UpdatePublicIndexIfOnline()
626+
// Should not return error because WarningInsteadOfErrors is true
627+
assert.Nil(err)
628+
})
629+
630+
t.Run("test with corrupted update.cfg file", func(t *testing.T) {
631+
localTestingDir := "test-update-corrupted-updatecfg"
632+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
633+
installer.UnlockPackRoot()
634+
defer removePackRoot(localTestingDir)
635+
636+
// Create a test server
637+
server := NewServer()
638+
defer server.httpsServer.Close()
639+
640+
// Create a public index file
641+
publicIndexContent, err := os.ReadFile(samplePublicIndex)
642+
assert.Nil(err)
643+
644+
// Add route for the public index
645+
server.AddRoute("index.pidx", publicIndexContent)
646+
647+
// Update the Installation to use the test server
648+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
649+
installer.ActualPublicIndex = server.URL() + "index.pidx"
650+
651+
// Create an existing index file
652+
assert.Nil(utils.TouchFile(installer.Installation.PublicIndex))
653+
654+
// Create a corrupted update.cfg file (invalid date format)
655+
updateCfgPath := filepath.Join(installer.Installation.WebDir, "update.cfg")
656+
corruptedContent := "Date: invalid-date-format\nAuto: true\n"
657+
assert.Nil(os.WriteFile(updateCfgPath, []byte(corruptedContent), 0600))
658+
659+
// Call UpdatePublicIndexIfOnline - should handle corrupted file gracefully
660+
err = installer.UpdatePublicIndexIfOnline()
661+
// May fail internally due to connection check, but always returns nil
662+
assert.Nil(err)
663+
})
664+
665+
t.Run("test with missing update.cfg file", func(t *testing.T) {
666+
localTestingDir := "test-update-missing-updatecfg"
667+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
668+
installer.UnlockPackRoot()
669+
defer removePackRoot(localTestingDir)
670+
671+
// Create a test server
672+
server := NewServer()
673+
defer server.httpsServer.Close()
674+
675+
// Create a public index file
676+
publicIndexContent, err := os.ReadFile(samplePublicIndex)
677+
assert.Nil(err)
678+
679+
// Add route for the public index
680+
server.AddRoute("index.pidx", publicIndexContent)
681+
682+
// Update the Installation to use the test server
683+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
684+
installer.ActualPublicIndex = server.URL() + "index.pidx"
685+
686+
// Create an existing index file
687+
assert.Nil(utils.TouchFile(installer.Installation.PublicIndex))
688+
689+
// Ensure update.cfg does not exist
690+
updateCfgPath := filepath.Join(installer.Installation.WebDir, "update.cfg")
691+
if utils.FileExists(updateCfgPath) {
692+
os.Remove(updateCfgPath)
693+
}
694+
695+
// Call UpdatePublicIndexIfOnline - should try to update because update.cfg is missing
696+
err = installer.UpdatePublicIndexIfOnline()
697+
// May fail internally due to connection check, but always returns nil
698+
assert.Nil(err)
699+
})
700+
701+
t.Run("test with invalid XML response", func(t *testing.T) {
702+
localTestingDir := "test-update-invalid-xml"
703+
assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot))
704+
installer.UnlockPackRoot()
705+
defer removePackRoot(localTestingDir)
706+
707+
// Create a test server
708+
server := NewServer()
709+
defer server.httpsServer.Close()
710+
711+
// Create invalid XML content
712+
invalidIndexContent := []byte("This is not valid XML content")
713+
714+
// Add route for the public index
715+
server.AddRoute("index.pidx", invalidIndexContent)
716+
717+
// Update the Installation to use the test server
718+
installer.Installation.PublicIndexXML.URL = server.URL() + "index.pidx"
719+
installer.ActualPublicIndex = server.URL() + "index.pidx"
720+
721+
// Ensure index file does not exist
722+
if utils.FileExists(installer.Installation.PublicIndex) {
723+
os.Remove(installer.Installation.PublicIndex)
724+
}
725+
726+
// Call UpdatePublicIndexIfOnline
727+
err := installer.UpdatePublicIndexIfOnline()
728+
// Should handle gracefully with warning (WarningInsteadOfErrors is true)
729+
assert.Nil(err)
730+
})
731+
}
732+
473733
func TestUpdatePublicIndex(t *testing.T) {
474734

475735
assert := assert.New(t)

0 commit comments

Comments
 (0)