Skip to content

Commit

Permalink
Merge pull request #144 from angelabriel/master
Browse files Browse the repository at this point in the history
saptune 3.2 - jsc#TEAM-9204, jsc#SAPSOL-168, jsc#SAPSOL-209, bsc#1190508 and jsc#SAPSOL-236
  • Loading branch information
angelabriel authored Aug 20, 2024
2 parents 206ec18 + 6af7493 commit 7d0a1cb
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 21 deletions.
18 changes: 15 additions & 3 deletions actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,21 @@ func SelectAction(writer io.Writer, stApp *app.App, saptuneVers string) {
StagingAction(system.CliArg(2), system.CliArgs(3), stApp)
case "status":
ServiceAction(writer, "status", saptuneVers, stApp)
case "verify":
VerifyAction(writer, system.CliArg(2), stApp)
default:
PrintHelpAndExit(writer, 1)
}
}

// VerifyAction verifies all applied Notes
func VerifyAction(writer io.Writer, actionName string, tuneApp *app.App) {
if actionName != "applied" {
PrintHelpAndExit(writer, 1)
}
VerifyAllParameters(writer, tuneApp)
}

// RevertAction Revert all notes and solutions
func RevertAction(writer io.Writer, actionName string, tuneApp *app.App) {
if actionName != "all" {
Expand Down Expand Up @@ -291,20 +301,22 @@ Daemon control:
saptune [--format FORMAT] [--force-color] daemon ( start | stop | status [--non-compliance-check] ) ATTENTION: deprecated
saptune [--format FORMAT] [--force-color] service ( start | stop | restart | takeover | enable | disable | enablestart | disablestop | status [--non-compliance-check] )
Tune system according to SAP and SUSE notes:
saptune [--format FORMAT] [--force-color] note ( list | revertall | enabled | applied )
saptune [--format FORMAT] [--force-color] note ( list | verify | revertall | enabled | applied )
saptune [--format FORMAT] [--force-color] note ( apply | simulate | customise | create | edit | revert | show | delete ) NOTEID
saptune [--format FORMAT] [--force-color] note verify [--colorscheme SCHEME] [--show-non-compliant] [NOTEID]
saptune [--format FORMAT] [--force-color] [--fun] note verify [--colorscheme SCHEME] [--show-non-compliant] [NOTEID|applied]
saptune [--format FORMAT] [--force-color] note rename NOTEID NEWNOTEID
Tune system for all notes applicable to your SAP solution:
saptune [--format FORMAT] [--force-color] solution ( list | verify | enabled | applied )
saptune [--format FORMAT] [--force-color] solution ( apply | simulate | customise | create | edit | revert | show | delete ) SOLUTIONNAME
saptune [--format FORMAT] [--force-color] solution change [--force] SOLUTIONNAME
saptune [--format FORMAT] [--force-color] solution verify [--colorscheme SCHEME] [--show-non-compliant] [SOLUTIONNAME]
saptune [--format FORMAT] [--force-color] [--fun] solution verify [--colorscheme SCHEME] [--show-non-compliant] [SOLUTIONNAME]
saptune [--format FORMAT] [--force-color] solution rename SOLUTIONNAME NEWSOLUTIONNAME
Staging control:
saptune [--format FORMAT] [--force-color] staging ( status | enable | disable | is-enabled | list )
saptune [--format FORMAT] [--force-color] staging ( analysis | diff ) [ ( NOTEID | SOLUTIONNAME )... | all ]
saptune [--format FORMAT] [--force-color] staging release [--force|--dry-run] [ ( NOTEID | SOLUTIONNAME )... | all ]
Verify all applied Notes:
saptune [--format FORMAT] [--force-color] verify applied
Revert all parameters tuned by the SAP notes or solutions:
saptune [--format FORMAT] [--force-color] revert all
Remove the pending lock file from a former saptune call
Expand Down
29 changes: 27 additions & 2 deletions actions/actionsMatchtxt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,42 @@ staged Notes:
staged Solutions:
sapconf.service: not available
tuned.service: disabled/active (profile: '%s')
tuned.service: disabled/active (profile: 'balanced')
systemd system state: running
virtualization: %s
tuning: not tuned
Remember: if you wish to automatically activate the note's and solution's tuning options after a reboot, you must enable saptune.service by running:
'saptune service enable'.
`, "balanced", system.GetVirtStatus())
`, system.GetVirtStatus())

var saptuneStatMatchText = fmt.Sprintf(`
saptune.service: disabled/active
saptune package: 'undef'
configured version: '3'
enabled Solution: sol1 (simpleNote)
applied Solution:
additional enabled Notes: 900929
enabled Notes: 900929
applied Notes:
orphaned Overrides:
staging: disabled
staged Notes:
staged Solutions:
sapconf.service: not available
tuned.service: disabled/active (profile: '')
systemd system state: running
virtualization: %s
tuning: not tuned
Remember: if you wish to automatically activate the note's and solution's tuning options after a reboot, you must enable saptune.service by running:
'saptune service enable'.
`, system.GetVirtStatus())

var saptuneStat2MatchText = fmt.Sprintf(`
saptune.service: disabled/inactive
saptune package: 'undef'
configured version: '3'
Expand Down
41 changes: 41 additions & 0 deletions actions/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,47 @@ var tearDown = func(t *testing.T) {
}
}

func TestVerifyAction(t *testing.T) {
// test setup
setUp(t)

var verifyMatchText = `No notes or solutions enabled, nothing to verify.
`
buffer := bytes.Buffer{}
VerifyAction(&buffer, "applied", tApp)
txt := buffer.String()
checkOut(t, txt, verifyMatchText)

// test for PrintHelpAndExit
oldOSExit := system.OSExit
defer func() { system.OSExit = oldOSExit }()
system.OSExit = tstosExit
oldErrorExitOut := system.ErrorExitOut
defer func() { system.ErrorExitOut = oldErrorExitOut }()
system.ErrorExitOut = tstErrorExitOut

// this errExitMatchText differs from the 'real' text by the last 2 lines
// because of test situation, the 'exit 1' in PrintHelpAndExit is not
// executed (as designed for testing)
errExitMatchText := PrintHelpAndExitMatchText + `No notes or solutions enabled, nothing to verify.
`
buffer.Reset()
errExitbuffer := bytes.Buffer{}
tstwriter = &errExitbuffer
VerifyAction(&buffer, "NotApplied", tApp)
txt = buffer.String()
checkOut(t, txt, errExitMatchText)
if tstRetErrorExit != 1 {
t.Errorf("error exit should be '1' and NOT '%v'\n", tstRetErrorExit)
}
errExOut := errExitbuffer.String()
if errExOut != "" {
t.Errorf("wrong text returned by ErrorExit: '%v' instead of ''\n", errExOut)
}
// reset tApp variables, which were deleted by 'revert all'
tearDown(t)
}

func TestRevertAction(t *testing.T) {
var revertMatchText = `Reverting all notes and solutions, this may take some time...
Parameters tuned by the notes and solutions have been successfully reverted.
Expand Down
2 changes: 1 addition & 1 deletion actions/noteacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func setupNoteListFormat(noteID string, solutionNoteIDs []string, tuneApp *app.A
// NoteActionVerify compares all parameter settings from a Note definition
// against the system settings
func NoteActionVerify(writer io.Writer, noteID string, tuneApp *app.App) {
if noteID == "" {
if noteID == "" || noteID == "applied" {
VerifyAllParameters(writer, tuneApp)
} else {
result := system.JPNotes{
Expand Down
26 changes: 26 additions & 0 deletions actions/noteacts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,32 @@ current order of enabled notes is: simpleNote
checkOut(t, txt, verifyMatchText)
})

// Test NoteActionVerifyApplied
t.Run("NoteActionVerifyApplied", func(t *testing.T) {
var verifyMatchText = `
SAPNote, Version | Parameter | Expected | Override | Actual | Compliant
--------------------+------------------------------+-------------+-----------+-------------+-----------
simpleNote, 1 | net.ipv4.ip_local_port_range | 31768 61999 | | 31768 61999 | yes
Attention for SAP Note simpleNote:
Hints or values not yet handled by saptune. So please read carefully, check and set manually, if needed:
# Text to ignore for apply but to display.
# Everything the customer should know about this note, especially
# which parameters are NOT handled and the reason.

current order of enabled notes is: simpleNote
The running system is currently well-tuned according to all of the enabled notes.
`
buffer := bytes.Buffer{}
nID := "applied"
NoteActionVerify(&buffer, nID, tApp)
txt := buffer.String()
checkOut(t, txt, verifyMatchText)
})

// Test NoteActionEnabled
t.Run("NoteActionEnabled", func(t *testing.T) {
enabledMatchText := "simpleNote"
Expand Down
60 changes: 58 additions & 2 deletions actions/serviceacts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,56 @@ func TestServiceActions(t *testing.T) {
})
// Test ServiceActionEnable
t.Run("ServiceActionEnable", func(t *testing.T) {
oldOSExit := system.OSExit
defer func() { system.OSExit = oldOSExit }()
system.OSExit = tstosExit
oldErrorExitOut := system.ErrorExitOut
defer func() { system.ErrorExitOut = oldErrorExitOut }()
system.ErrorExitOut = tstErrorExitOut

errExitbuffer := bytes.Buffer{}
tstwriter = &errExitbuffer

ServiceActionEnable()
if tstRetErrorExit != 0 {
t.Logf("error exit should be '0' and NOT '%v'\n", tstRetErrorExit)
}
errExOut := errExitbuffer.String()
if errExOut != "" {
t.Logf("wrong text returned by ErrorExit: '%v' instead of ''\n", errExOut)
}

enabled, _ := system.SystemctlIsEnabled(testService)
if !enabled {
t.Errorf("'%s' not enabled", testService)
}
})
// Test ServiceActionDisable
t.Run("ServiceActionDisable", func(t *testing.T) {
oldOSExit := system.OSExit
defer func() { system.OSExit = oldOSExit }()
system.OSExit = tstosExit
oldErrorExitOut := system.ErrorExitOut
defer func() { system.ErrorExitOut = oldErrorExitOut }()
system.ErrorExitOut = tstErrorExitOut

errExitbuffer := bytes.Buffer{}
tstwriter = &errExitbuffer

ServiceActionDisable()
if tstRetErrorExit != 0 {
t.Logf("error exit should be '0' and NOT '%v'\n", tstRetErrorExit)
}
errExOut := errExitbuffer.String()
if errExOut != "" {
t.Logf("wrong text returned by ErrorExit: '%v' instead of ''\n", errExOut)
}

enabled, _ := system.SystemctlIsEnabled(testService)
if enabled {
t.Errorf("'%s' not disabled", testService)
}
})

// Test ServiceActionApply
t.Run("ServiceActionApply", func(t *testing.T) {
oldOSExit := system.OSExit
Expand All @@ -186,7 +221,24 @@ func TestServiceActions(t *testing.T) {
})
// Test ServiceActionRevert
t.Run("ServiceActionRevert", func(t *testing.T) {
oldOSExit := system.OSExit
defer func() { system.OSExit = oldOSExit }()
system.OSExit = tstosExit
oldErrorExitOut := system.ErrorExitOut
defer func() { system.ErrorExitOut = oldErrorExitOut }()
system.ErrorExitOut = tstErrorExitOut

errExitbuffer := bytes.Buffer{}
tstwriter = &errExitbuffer

ServiceActionRevert(sApp)
if tstRetErrorExit != 0 {
t.Logf("error exit should be '0' and NOT '%v'\n", tstRetErrorExit)
}
errExOut := errExitbuffer.String()
if errExOut != "" {
t.Logf("wrong text returned by ErrorExit: '%v' instead of ''\n", errExOut)
}
})

// Test ServiceActionStatus
Expand All @@ -204,7 +256,11 @@ func TestServiceActions(t *testing.T) {
tstwriter = &errExitbuffer
ServiceActionStatus(&buffer, sApp, saptuneVersion)
txt := buffer.String()
checkOut(t, txt, saptuneStatusMatchText)
if txt != saptuneStatusMatchText {
checkOut(t, txt, saptuneStatMatchText)
} else {
checkOut(t, txt, saptuneStatusMatchText)
}
errExOut := errExitbuffer.String()
if errExOut != "" {
t.Errorf("wrong text returned by ErrorExit: '%v' instead of ''\n", errExOut)
Expand Down
26 changes: 24 additions & 2 deletions actions/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ import (
"strings"
)

// define smiley for 'yes' and 'no' in 'verify'
var smileYes = '\U0001F60E'
var smileNo = '\U0001F61F'
var smileDash = '\U0001F611'

// define max column width
var fmtmax = 30

// number of lines printed for 'verify'
var lineCnt = 0

Expand Down Expand Up @@ -443,6 +449,9 @@ func colorPrint(format, compliant, colorScheme string) (string, string) {
if colCompl == "" {
colCompl = compliant
}
if system.IsFlagSet("fun") {
colCompl = funPrint(colCompl)
}
return colFormat, colCompl
}

Expand All @@ -469,6 +478,17 @@ func colorFormating(colCmpl, colNonCmpl, txt, compliant string) string {
return colFormat
}

// funPrint prints emojis instead of text in the 'compliant' column of 'verify'
func funPrint(txt string) string {
if strings.Contains(txt, "yes") {
txt = strings.Replace(txt, "yes", " "+string(smileYes), 1)
}
if strings.Contains(txt, "no") {
txt = strings.Replace(txt, "no ", " "+string(smileNo), 1)
}
return txt
}

// printTableRow prints one row of the table
// If needed the lines of the override column, the expected column and the
// actual column will be wrapped after 'fmtmax' characters
Expand Down Expand Up @@ -545,12 +565,13 @@ func printWrappedRow(writer io.Writer, wrappedElem map[string][]string, rowEleme
// printRow prints now the row of the table
func printRow(writer io.Writer, twist bool, cols []string, rowElements map[string]string) {
if rowElements["type"] == "verify" {
printVerifiedRow(twist, writer, rowElements, cols)
printVerifyRow(twist, writer, rowElements, cols)
} else {
printSimulateRow(twist, writer, rowElements, cols)
}
}

// printSimulateRow prints the 'simulate' row
func printSimulateRow(twist bool, writer io.Writer, rowElements map[string]string, cols []string) {
if twist {
fmt.Fprintf(writer, rowElements["colFormat"], rowElements["parameter"], cols[0], cols[1], cols[2], rowElements["comment"])
Expand All @@ -559,7 +580,8 @@ func printSimulateRow(twist bool, writer io.Writer, rowElements map[string]strin
}
}

func printVerifiedRow(twist bool, writer io.Writer, rowElements map[string]string, cols []string) {
// printVerifyRow prints the 'verify' row
func printVerifyRow(twist bool, writer io.Writer, rowElements map[string]string, cols []string) {
if twist {
fmt.Fprintf(writer, rowElements["colFormat"], rowElements["note"], rowElements["parameter"], cols[1], cols[2], cols[0], rowElements["compliant"])
} else {
Expand Down
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func main() {
case "2", "3":
break
default:
system.ErrorExit("Wrong saptune version in file '/etc/sysconfig/saptune': %s", SaptuneVersion)
system.ErrorExit("Wrong saptune version in file '/etc/sysconfig/saptune': %s", SaptuneVersion, 128)
}

solutionSelector := system.GetSolutionSelector()
Expand Down Expand Up @@ -243,6 +243,7 @@ func checkSaptuneConfigFile(writer io.Writer, saptuneConf string, lswitch map[st

// set values read from the config file
saptuneVers := sconf.GetString("SAPTUNE_VERSION", "")

// Switch Debug on ("on") or off ("off" - default)
// Switch verbose mode on ("on" - default) or off ("off")
// Switch error mode on ("on" - default) or off ("off")
Expand Down
Loading

0 comments on commit 7d0a1cb

Please sign in to comment.