package analyzer import ( "fmt" "testing" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) type getFile func(n string) ([]byte, error) func Test_cephStatus(t *testing.T) { tests := []struct { name string analyzer troubleshootv1beta2.CephStatusAnalyze expectResult *AnalyzeResult getFile getFile filePath, file string }{ { name: "pass case", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: &AnalyzeResult{ IsPass: true, IsWarn: false, IsFail: false, Title: "Ceph Status", Message: "Ceph is healthy", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_OK" }, "osdmap": { "osdmap": { "num_osds": 5, "num_up_osds": 5, "full": false, "nearfull": false } }, "pgmap": { "bytes_used": 10000, "bytes_total": 100000 } }`, }, { name: "warn case", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: &AnalyzeResult{ IsPass: false, IsWarn: true, IsFail: false, Title: "Ceph Status", Message: "Ceph status is HEALTH_WARN\n5/5 OSDs up\nOSD disk is nearly full\nPG storage usage is 85.0%", URI: "https://rook.io/docs/rook/v1.4/ceph-common-issues.html", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_WARN" }, "osdmap": { "osdmap": { "num_osds": 5, "num_up_osds": 5, "full": false, "nearfull": true } }, "pgmap": { "bytes_used": 85000, "bytes_total": 100000 } }`, }, { name: "fail case", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: &AnalyzeResult{ IsPass: false, IsWarn: false, IsFail: true, Title: "Ceph Status", Message: "Ceph status is HEALTH_ERR\n4/5 OSDs up\nOSD disk is full\nPG storage usage is 95.0%", URI: "https://rook.io/docs/rook/v1.4/ceph-common-issues.html", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_ERR" }, "osdmap": { "osdmap": { "num_osds": 5, "num_up_osds": 4, "full": true, "nearfull": true } }, "pgmap": { "bytes_used": 95000, "bytes_total": 100000 } }`, }, { name: "CollectorName and Namespace", analyzer: troubleshootv1beta2.CephStatusAnalyze{ CollectorName: "custom-namespace", Namespace: "namespace", }, expectResult: &AnalyzeResult{ IsPass: true, IsWarn: false, IsFail: false, Title: "Ceph Status", Message: "Ceph is healthy", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "custom-namespace/namespace/ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_OK" }, "osdmap": { "osdmap": { "full": false, "nearfull": false } }, "pgmap": { "bytes_used": 10000, "bytes_total": 100000 } }`, }, { name: "outcomes when", analyzer: troubleshootv1beta2.CephStatusAnalyze{ Outcomes: []*troubleshootv1beta2.Outcome{ { Fail: &troubleshootv1beta2.SingleOutcome{ When: "== HEALTH_OK", Message: "custom message OK", URI: "custom uri OK", }, }, { Fail: &troubleshootv1beta2.SingleOutcome{ When: "<= HEALTH_WARN", Message: "custom message WARN", URI: "custom uri WARN", }, }, }, }, expectResult: &AnalyzeResult{ IsPass: false, IsWarn: false, IsFail: true, Title: "Ceph Status", Message: "custom message WARN\n5/5 OSDs up\nOSD disk is nearly full\nPG storage usage is 85.0%", URI: "custom uri WARN", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_WARN" }, "osdmap": { "osdmap": { "num_osds": 5, "num_up_osds": 5, "full": false, "nearfull": true } }, "pgmap": { "bytes_used": 85000, "bytes_total": 100000 } }`, }, { name: "warn case with missing osd/pg data", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: &AnalyzeResult{ IsPass: false, IsWarn: true, IsFail: false, Title: "Ceph Status", Message: "Ceph status is HEALTH_WARN", URI: "https://rook.io/docs/rook/v1.4/ceph-common-issues.html", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_WARN" } }`, }, { name: "warn case with health status message and summary", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: &AnalyzeResult{ IsPass: false, IsWarn: true, IsFail: false, Title: "Ceph Status", Message: "Ceph status is HEALTH_WARN\nPOOL_NO_REDUNDANCY: 11 pool(s) have no replicas configured", URI: "https://rook.io/docs/rook/v1.4/ceph-common-issues.html", IconKey: "rook", IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", }, filePath: "ceph/status.json", file: `{ "fsid": "96a8178c-6aa2-4adf-a309-9e8869a79611", "health": { "status": "HEALTH_WARN", "checks": { "POOL_NO_REDUNDANCY": { "severity": "HEALTH_WARN", "summary": { "message": "11 pool(s) have no replicas configured", "count": 11 }, "muted": false } } } }`, }, { name: "pass case when get file returns not found error", analyzer: troubleshootv1beta2.CephStatusAnalyze{}, expectResult: nil, getFile: func(n string) ([]byte, error) { return nil, &types.NotFoundError{} }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { req := require.New(t) if test.getFile == nil { test.getFile = func(n string) ([]byte, error) { assert.Equal(t, n, test.filePath) return []byte(test.file), nil } } a := AnalyzeCephStatus{ analyzer: &test.analyzer, } actual, err := a.cephStatus(&test.analyzer, test.getFile) req.NoError(err) assert.Equal(t, test.expectResult, actual) }) } } func Test_compareCephStatus(t *testing.T) { tests := []struct { actual string when string want bool wantErr bool }{ { actual: "HEALTH_OK", when: "HEALTH_OK", want: true, }, { actual: "HEALTH_OK", when: "HEALTH_WARN", want: false, }, { actual: "HEALTH_OK", when: "<= HEALTH_WARN", want: false, }, { actual: "HEALTH_OK", when: ">= HEALTH_WARN", want: true, }, } for _, tt := range tests { t.Run(fmt.Sprintf("%s %s", tt.actual, tt.when), func(t *testing.T) { got, err := compareCephStatus(tt.actual, tt.when) if (err != nil) != tt.wantErr { t.Errorf("compareCephStatus() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { t.Errorf("compareCephStatus() = %v, want %v", got, tt.want) } }) } }