map strict flag to analyze result (#551)

* add util functions

* rename func HasStrictAnalyzersFailed

* map strict flag to analyze err result
This commit is contained in:
Pavan Sokke Nagaraj
2022-03-22 20:47:50 -04:00
committed by GitHub
parent ca0b3c31c1
commit 7bfb54360c
3 changed files with 410 additions and 0 deletions

View File

@@ -77,8 +77,10 @@ func doAnalyze(allCollectedData map[string][]byte, analyzers []*troubleshootv1be
for _, analyzer := range analyzers {
analyzeResult, err := analyze.Analyze(analyzer, getCollectedFileContents, getChildCollectedFileContents)
if err != nil {
strict, _ := HasStrictAnalyzer(analyzer)
analyzeResult = []*analyze.AnalyzeResult{
{
Strict: strict,
IsFail: true,
Title: "Analyzer Failed",
Message: err.Error(),

80
pkg/preflight/util.go Normal file
View File

@@ -0,0 +1,80 @@
package preflight
import (
"encoding/json"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
)
// HasStrictAnalyzers - checks and returns true if a preflight's analyzer has strict:true, else false
func HasStrictAnalyzers(preflight *troubleshootv1beta2.Preflight) (bool, error) {
if preflight == nil {
return false, nil
}
marshalledAnalyzers, err := json.Marshal(preflight.Spec.Analyzers) // marshall and remove nil Analyzers eg result: "[{\"clusterVersion\":{\"exclude\":\"\",\"strict\":\"false\",\"outcomes\":null}}]"
if err != nil {
return false, errors.Wrap(err, "failed to marshal analyzers")
}
analyzersMap := []map[string]interface{}{}
err = json.Unmarshal(marshalledAnalyzers, &analyzersMap) // Unmarshall again so we can loop over non nil analyzers
if err != nil {
return false, errors.Wrap(err, "failed to unmarshal analyzers")
}
// analyzerMap will ignore empty Analyzers and loop around Analyzer with data
for _, analyzers := range analyzersMap { // for each analyzer: map["clusterVersion": map[string]interface{} ["exclude": "", "strict": "true", "outcomes": nil]
return hasStrictAnalyzer(analyzers)
}
return false, nil
}
// HasStrictAnalyzers - checks and returns true if a preflight's analyzer has strict:true, else false
func HasStrictAnalyzer(analyzer *troubleshootv1beta2.Analyze) (bool, error) {
marshalledAnalyzer, err := json.Marshal(analyzer)
if err != nil {
return false, errors.Wrap(err, "error while marshalling analyzer")
}
analyzerMap := make(map[string]interface{})
err = json.Unmarshal(marshalledAnalyzer, &analyzerMap) // Unmarshall again so we can loop over non nil analyzers
if err != nil {
return false, errors.Wrap(err, "failed to unmarshal analyzers")
}
return hasStrictAnalyzer(analyzerMap)
}
func hasStrictAnalyzer(analyzerMap map[string]interface{}) (bool, error) {
for _, analyzer := range analyzerMap { // for each analyzerMeta: map[string]interface{} ["exclude": "", "strict": "true", "outcomes": nil]
marshalledAnalyzer, err := json.Marshal(analyzer)
if err != nil {
return false, errors.Wrap(err, "error while marshalling analyzer")
}
// return Analyzer.Strict which can be extracted from AnalyzeMeta
analyzeMeta := troubleshootv1beta2.AnalyzeMeta{}
err = json.Unmarshal(marshalledAnalyzer, &analyzeMeta)
if err != nil {
return false, errors.Wrap(err, "error while un-marshalling marshalledAnalyzers")
}
return analyzeMeta.Strict.BoolOrDefaultFalse(), nil
}
return false, nil
}
// HasStrictAnalyzersFailed - checks if preflight analyzer's result is strict:true and isFail:true, then returns true else false
func HasStrictAnalyzersFailed(preflightResult *UploadPreflightResults) bool {
hasStrictAnalyzersFailed := false
// if results are empty, treat as failure
if preflightResult == nil || len(preflightResult.Results) == 0 {
hasStrictAnalyzersFailed = true
} else {
for _, result := range preflightResult.Results {
if result.IsFail && result.Strict {
hasStrictAnalyzersFailed = true
}
}
}
return hasStrictAnalyzersFailed
}

328
pkg/preflight/util_test.go Normal file
View File

@@ -0,0 +1,328 @@
package preflight
import (
"testing"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/multitype"
)
var (
analyzeMetaStrictFalseStr = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
StrVal: "false",
},
}
analyzeMetaStrictInvalidStr = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
StrVal: "invalid",
},
}
analyzeMetaStrictTrueStr = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
StrVal: "true",
},
}
analyzeMetaStrictFalseBool = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
Type: multitype.Bool,
BoolVal: false,
},
}
analyzeMetaStrictTrueBool = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
Type: multitype.Bool,
BoolVal: true,
},
}
analyzeMetaStrictFalseInt = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
StrVal: "0",
},
}
analyzeMetaStrictTrueInt = troubleshootv1beta2.AnalyzeMeta{
Strict: multitype.BoolOrString{
Type: multitype.String,
StrVal: "1",
},
}
)
func TestHasStrictAnalyzers(t *testing.T) {
tests := []struct {
name string
preflight *troubleshootv1beta2.Preflight
want bool
wantErr bool
}{
{
name: "expect false when preflight is nil",
preflight: nil,
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec is empty",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzers is nil",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: nil,
},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzers is empty",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{},
},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzer has nil analyzer",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: nil,
},
},
},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzer has analyzer with strict str: false",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictFalseStr},
},
},
},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzer has analyzer with strict bool: false",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictFalseBool},
},
},
},
},
want: false,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzer has analyzer with strict str: invalid",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictInvalidStr},
},
},
},
},
want: false,
wantErr: false,
}, {
name: "expect true when preflight spec's analyzer has analyzer with strict str: true",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictTrueStr},
},
},
},
},
want: true,
wantErr: false,
}, {
name: "expect true when preflight spec's analyzer has analyzer with strict bool: true",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictTrueBool},
},
},
},
},
want: true,
wantErr: false,
}, {
name: "expect true when preflight spec's analyzer has analyzer with strict int: 1",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictTrueInt},
},
},
},
},
want: true,
wantErr: false,
}, {
name: "expect false when preflight spec's analyzer has analyzer with strict int: 0",
preflight: &troubleshootv1beta2.Preflight{
Spec: troubleshootv1beta2.PreflightSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictFalseInt},
},
},
},
},
want: false,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := HasStrictAnalyzers(tt.preflight)
if (err != nil) != tt.wantErr {
t.Errorf("HasStrictAnalyzers error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("HasStrictAnalyzers() = %v, want %v", got, tt.want)
}
})
}
}
func TestHasStrictAnalyzerFailed(t *testing.T) {
tests := []struct {
name string
preflightResult *UploadPreflightResults
want bool
}{
{
name: "expect true when preflightResult is nil",
preflightResult: nil,
want: true,
}, {
name: "expect true when preflightResult.Results is nil",
preflightResult: &UploadPreflightResults{
Results: nil,
},
want: true,
}, {
name: "expect true when preflightResult.Results is empty",
preflightResult: &UploadPreflightResults{
Results: []*UploadPreflightResult{},
},
want: true,
}, {
name: "expect false when preflightResult.Results has result with strict false, IsFail false",
preflightResult: &UploadPreflightResults{
Results: []*UploadPreflightResult{
{Strict: false, IsFail: false},
},
},
want: false,
}, {
name: "expect false when preflightResult.Results has result with strict false, IsFail true",
preflightResult: &UploadPreflightResults{
Results: []*UploadPreflightResult{
{Strict: false, IsFail: true},
},
},
want: false,
}, {
name: "expect true when preflightResult.Results has result with strict true, IsFail true",
preflightResult: &UploadPreflightResults{
Results: []*UploadPreflightResult{
{Strict: true, IsFail: true},
},
},
want: true,
}, {
name: "expect true when preflightResult.Results has multiple results where atleast result has strict true, IsFail true",
preflightResult: &UploadPreflightResults{
Results: []*UploadPreflightResult{
{Strict: true, IsFail: true},
{Strict: false, IsFail: true},
{Strict: true, IsFail: false},
},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := HasStrictAnalyzersFailed(tt.preflightResult); got != tt.want {
t.Errorf("HasStrictAnalyzersFailed() = %v, want %v", got, tt.want)
}
})
}
}
func TestHasStrictAnalyzer(t *testing.T) {
tests := []struct {
name string
analyzer *troubleshootv1beta2.Analyze
want bool
wantErr bool
}{
{
name: "expect strict=false, err=nil when analyzer is nil",
analyzer: nil,
want: false,
wantErr: false,
}, {
name: "expect strict=false, err=nil when analyzer is empty",
analyzer: &troubleshootv1beta2.Analyze{},
want: false,
wantErr: false,
}, {
name: "expect strict=false, err=nil when ClusterVersion analyzer has strict=1",
analyzer: &troubleshootv1beta2.Analyze{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictFalseInt},
},
want: false,
wantErr: false,
}, {
name: "expect strict=false, err=nil when ClusterVersion analyzer has strict=true",
analyzer: &troubleshootv1beta2.Analyze{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{AnalyzeMeta: analyzeMetaStrictTrueInt},
},
want: true,
wantErr: false,
}, {
name: "expect strict=false, err=nil when ClusterVersion analyzer is nil",
analyzer: &troubleshootv1beta2.Analyze{
ClusterVersion: nil,
},
want: false,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := HasStrictAnalyzer(tt.analyzer)
if (err != nil) != tt.wantErr {
t.Errorf("HasStrictAnalyzer() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("HasStrictAnalyzer() = %v, want %v", got, tt.want)
}
})
}
}