88 "context"
99 "crypto/tls"
1010 "fmt"
11+ "net/http"
12+ "net/http/httptest"
1113 "os"
1214 "path/filepath"
1315 "runtime"
@@ -26,6 +28,7 @@ import (
2628 "github.com/elastic/elastic-agent-libs/transport/tlscommon"
2729 "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
2830 "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
31+ upgradeErrors "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact/download/errors"
2932 "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details"
3033 "github.com/elastic/elastic-agent/internal/pkg/agent/errors"
3134 "github.com/elastic/elastic-agent/internal/pkg/config"
@@ -38,6 +41,7 @@ import (
3841 "github.com/elastic/elastic-agent/pkg/core/logger"
3942 "github.com/elastic/elastic-agent/pkg/core/logger/loggertest"
4043 agtversion "github.com/elastic/elastic-agent/pkg/version"
44+ "github.com/elastic/elastic-agent/testing/mocks/internal_/pkg/agent/application/info"
4145 mocks "github.com/elastic/elastic-agent/testing/mocks/pkg/control/v2/client"
4246)
4347
@@ -1365,3 +1369,117 @@ func createArchive(t *testing.T, archiveName string, archiveFiles []files) (stri
13651369 }
13661370 return createTarArchive (t , archiveName , archiveFiles )
13671371}
1372+
1373+ func TestUpgradeMarkUpgradeError (t * testing.T ) {
1374+ log , _ := loggertest .New ("test" )
1375+
1376+ tempConfig := & artifact.Config {} // used only to get os and arch, runtime.GOARCH returns amd64 which is not a valid arch when used in GetArtifactName
1377+
1378+ initialVersion := agtversion .NewParsedSemVer (1 , 2 , 3 , "SNAPSHOT" , "" )
1379+ initialArchiveName , initialArchiveFiles := buildArchiveFiles (t , archiveFilesWithMoreComponents , initialVersion , "abcdef" )
1380+
1381+ targetVersion := agtversion .NewParsedSemVer (3 , 4 , 5 , "SNAPSHOT" , "" )
1382+ targetArchiveName , targetArchiveFiles := buildArchiveFiles (t , archiveFilesWithMoreComponents , targetVersion , "ghijkl" )
1383+
1384+ mockAgentInfo := info .NewAgent (t )
1385+ mockAgentInfo .On ("Version" ).Return (targetVersion .String ())
1386+
1387+ upgradeDetails := details .NewDetails (targetVersion .String (), details .StateRequested , "test" )
1388+
1389+ tempUnpacker , err := NewUpgrader (log , tempConfig , mockAgentInfo ) // used only to unpack the initial archive
1390+ require .NoError (t , err )
1391+
1392+ type testCase struct {
1393+ markUpgradeError error
1394+ expectedError error
1395+ }
1396+
1397+ genericError := errors .New ("test mark upgrade error" )
1398+
1399+ testCases := map [string ]testCase {
1400+ "should return generic error if mark upgrade fails" : {
1401+ markUpgradeError : genericError ,
1402+ expectedError : genericError ,
1403+ },
1404+ }
1405+ for _ , te := range upgradeErrors .OS_DiskSpaceErrors {
1406+ testCases [fmt .Sprintf ("should return disk space error if mark upgrade fails with disk space error: %v" , te )] = testCase {
1407+ markUpgradeError : te ,
1408+ expectedError : upgradeErrors .ErrInsufficientDiskSpace ,
1409+ }
1410+ }
1411+
1412+ for name , tc := range testCases {
1413+ t .Run (name , func (t * testing.T ) {
1414+ baseDir := t .TempDir ()
1415+ paths .SetTop (baseDir )
1416+ paths .SetDownloads (filepath .Join (baseDir , "downloads" ))
1417+
1418+ initialArchive , err := createArchive (t , initialArchiveName , initialArchiveFiles )
1419+ require .NoError (t , err )
1420+
1421+ t .Logf ("Created archive: %s" , initialArchive )
1422+
1423+ _ , err = tempUnpacker .unpack (initialVersion .String (), initialArchive , paths .Data (), "" )
1424+ require .NoError (t , err )
1425+
1426+ // The archive file list does not contain the action store files, so we need to
1427+ // create them
1428+ actionStorePaths := []string {paths .AgentActionStoreFile (), paths .AgentStateStoreYmlFile (), paths .AgentStateStoreFile ()}
1429+ for _ , path := range actionStorePaths {
1430+ err := os .MkdirAll (filepath .Dir (path ), 0o700 )
1431+ require .NoError (t , err , "error creating directory %s" , filepath .Dir (path ))
1432+
1433+ err = os .WriteFile (path , []byte (fmt .Sprintf ("initial agent %s content" , filepath .Base (path ))), 0o600 )
1434+ require .NoError (t , err , "error writing to %s" , path )
1435+ }
1436+
1437+ // Create several files in the initial run path and save their paths in an array.
1438+ initialRunPath := paths .Run ()
1439+ require .NoError (t , os .MkdirAll (initialRunPath , 0o755 ))
1440+
1441+ for i := 0 ; i < 3 ; i ++ {
1442+ filePath := filepath .Join (initialRunPath , fmt .Sprintf ("file%d.txt" , i ))
1443+ err := os .WriteFile (filePath , []byte (fmt .Sprintf ("content for file %d" , i )), 0o600 )
1444+ require .NoError (t , err )
1445+ }
1446+
1447+ targetArchive , err := createArchive (t , targetArchiveName , targetArchiveFiles )
1448+ require .NoError (t , err )
1449+
1450+ t .Logf ("Created archive: %s" , targetArchive )
1451+
1452+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1453+ http .ServeFile (w , r , targetArchive )
1454+ }))
1455+ t .Cleanup (server .Close )
1456+
1457+ config := artifact.Config {
1458+ TargetDirectory : paths .Downloads (),
1459+ SourceURI : server .URL ,
1460+ RetrySleepInitDuration : 1 * time .Second ,
1461+ HTTPTransportSettings : httpcommon.HTTPTransportSettings {
1462+ Timeout : 1 * time .Second ,
1463+ },
1464+ }
1465+
1466+ tmpMarkUpgradeFunc := markUpgradeFunc
1467+ t .Cleanup (func () {
1468+ markUpgradeFunc = tmpMarkUpgradeFunc
1469+ })
1470+
1471+ mockCalled := false // this is used to assert that the mock was called
1472+ markUpgradeFunc = func (log * logger.Logger , dataDirPath string , agent agentInstall , previousAgent agentInstall , action * fleetapi.ActionUpgrade , upgradeDetails * details.Details , desiredOutcome UpgradeOutcome ) error {
1473+ mockCalled = true
1474+ return tc .markUpgradeError
1475+ }
1476+
1477+ upgrader , err := NewUpgrader (log , & config , mockAgentInfo )
1478+ require .NoError (t , err )
1479+
1480+ _ , err = upgrader .Upgrade (context .Background (), targetVersion .String (), server .URL , nil , upgradeDetails , true , true )
1481+ require .True (t , mockCalled , "markUpgradeFunc was not called" )
1482+ require .ErrorIs (t , err , tc .expectedError , "expected error mismatch" )
1483+ })
1484+ }
1485+ }
0 commit comments