added additional tests from #187.
Detected that the frontend was incorrectly classifying Scrutiny Failures as Warnings. Fixed.
This commit is contained in:
@@ -93,6 +93,8 @@ func (sa *SmartAtaAttribute) PopulateAttributeStatus() *SmartAtaAttribute {
|
|||||||
//this attribute has previously failed
|
//this attribute has previously failed
|
||||||
sa.Status = pkg.SmartAttributeStatusFailed
|
sa.Status = pkg.SmartAttributeStatusFailed
|
||||||
sa.StatusReason = "Attribute is failing manufacturer SMART threshold"
|
sa.StatusReason = "Attribute is failing manufacturer SMART threshold"
|
||||||
|
//if the Smart Status is failed, we should exit early, no need to look at thresholds.
|
||||||
|
return sa
|
||||||
|
|
||||||
} else if strings.ToUpper(sa.WhenFailed) == pkg.SmartWhenFailedInThePast {
|
} else if strings.ToUpper(sa.WhenFailed) == pkg.SmartWhenFailedInThePast {
|
||||||
sa.Status = pkg.SmartAttributeStatusWarning
|
sa.Status = pkg.SmartAttributeStatusWarning
|
||||||
|
|||||||
@@ -381,6 +381,70 @@ func TestFromCollectorSmartInfo_Fail_ScrutinySmart(t *testing.T) {
|
|||||||
require.Equal(t, 17, len(smartMdl.Attributes))
|
require.Equal(t, 17, len(smartMdl.Attributes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFromCollectorSmartInfo_Fail_ScrutinyNonCriticalFailed(t *testing.T) {
|
||||||
|
//setup
|
||||||
|
smartDataFile, err := os.Open("../testdata/smart-ata-failed-scrutiny.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer smartDataFile.Close()
|
||||||
|
|
||||||
|
var smartJson collector.SmartInfo
|
||||||
|
|
||||||
|
smartDataBytes, err := ioutil.ReadAll(smartDataFile)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = json.Unmarshal(smartDataBytes, &smartJson)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
//test
|
||||||
|
smartMdl := measurements.Smart{}
|
||||||
|
err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson)
|
||||||
|
|
||||||
|
//assert
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "WWN-test", smartMdl.DeviceWWN)
|
||||||
|
require.Equal(t, pkg.DeviceStatusFailedScrutiny, smartMdl.Status)
|
||||||
|
require.Equal(t, int64(pkg.SmartAttributeStatusFailed), smartMdl.Attributes["199"].GetStatus(),
|
||||||
|
"scrutiny should detect that %d failed (status: %d, %s)",
|
||||||
|
smartMdl.Attributes["199"].(*measurements.SmartAtaAttribute).AttributeId,
|
||||||
|
smartMdl.Attributes["199"].GetStatus(), smartMdl.Attributes["199"].(*measurements.SmartAtaAttribute).StatusReason,
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Equal(t, 14, len(smartMdl.Attributes))
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Scrutiny Warn
|
||||||
|
//TODO: Smart + Scrutiny Warn
|
||||||
|
|
||||||
|
func TestFromCollectorSmartInfo_NVMe_Fail_Scrutiny(t *testing.T) {
|
||||||
|
//setup
|
||||||
|
smartDataFile, err := os.Open("../testdata/smart-nvme-failed.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer smartDataFile.Close()
|
||||||
|
|
||||||
|
var smartJson collector.SmartInfo
|
||||||
|
|
||||||
|
smartDataBytes, err := ioutil.ReadAll(smartDataFile)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = json.Unmarshal(smartDataBytes, &smartJson)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
//test
|
||||||
|
smartMdl := measurements.Smart{}
|
||||||
|
err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson)
|
||||||
|
|
||||||
|
//assert
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "WWN-test", smartMdl.DeviceWWN)
|
||||||
|
require.Equal(t, pkg.DeviceStatusFailedScrutiny, smartMdl.Status)
|
||||||
|
require.Equal(t, int64(pkg.SmartAttributeStatusFailed), smartMdl.Attributes["media_errors"].GetStatus(),
|
||||||
|
"scrutiny should detect that %s failed (status: %d, %s)",
|
||||||
|
smartMdl.Attributes["media_errors"].(*measurements.SmartNvmeAttribute).AttributeId,
|
||||||
|
smartMdl.Attributes["media_errors"].GetStatus(),
|
||||||
|
smartMdl.Attributes["media_errors"].(*measurements.SmartNvmeAttribute).StatusReason,
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Equal(t, 16, len(smartMdl.Attributes))
|
||||||
|
}
|
||||||
|
|
||||||
func TestFromCollectorSmartInfo_Nvme(t *testing.T) {
|
func TestFromCollectorSmartInfo_Nvme(t *testing.T) {
|
||||||
//setup
|
//setup
|
||||||
smartDataFile, err := os.Open("../testdata/smart-nvme.json")
|
smartDataFile, err := os.Open("../testdata/smart-nvme.json")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
|||||||
|
{
|
||||||
|
"json_format_version": [
|
||||||
|
1,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"smartctl": {
|
||||||
|
"version": [
|
||||||
|
7,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"svn_revision": "4883",
|
||||||
|
"platform_info": "x86_64-linux-5.13.0-40-generic",
|
||||||
|
"build_info": "(local build)",
|
||||||
|
"argv": [
|
||||||
|
"smartctl",
|
||||||
|
"-x",
|
||||||
|
"-j",
|
||||||
|
"/dev/nvme0"
|
||||||
|
],
|
||||||
|
"exit_status": 0
|
||||||
|
},
|
||||||
|
"device": {
|
||||||
|
"name": "/dev/nvme0",
|
||||||
|
"info_name": "/dev/nvme0",
|
||||||
|
"type": "nvme",
|
||||||
|
"protocol": "NVMe"
|
||||||
|
},
|
||||||
|
"model_name": "Samsung SSD 970 EVO 500GB",
|
||||||
|
"serial_number": "S466NX0M776250H",
|
||||||
|
"firmware_version": "2B2QEXE7",
|
||||||
|
"nvme_pci_vendor": {
|
||||||
|
"id": 5197,
|
||||||
|
"subsystem_id": 5197
|
||||||
|
},
|
||||||
|
"nvme_ieee_oui_identifier": 9528,
|
||||||
|
"nvme_total_capacity": 500107862016,
|
||||||
|
"nvme_unallocated_capacity": 0,
|
||||||
|
"nvme_controller_id": 4,
|
||||||
|
"nvme_number_of_namespaces": 1,
|
||||||
|
"nvme_namespaces": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"size": {
|
||||||
|
"blocks": 976773168,
|
||||||
|
"bytes": 500107862016
|
||||||
|
},
|
||||||
|
"capacity": {
|
||||||
|
"blocks": 976773168,
|
||||||
|
"bytes": 500107862016
|
||||||
|
},
|
||||||
|
"utilization": {
|
||||||
|
"blocks": 327275384,
|
||||||
|
"bytes": 167564996608
|
||||||
|
},
|
||||||
|
"formatted_lba_size": 512,
|
||||||
|
"eui64": {
|
||||||
|
"oui": 9528,
|
||||||
|
"ext_id": 376106710327
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"user_capacity": {
|
||||||
|
"blocks": 976773168,
|
||||||
|
"bytes": 500107862016
|
||||||
|
},
|
||||||
|
"logical_block_size": 512,
|
||||||
|
"local_time": {
|
||||||
|
"time_t": 1652220188,
|
||||||
|
"asctime": "Tue May 10 22:03:08 2022 UTC"
|
||||||
|
},
|
||||||
|
"smart_status": {
|
||||||
|
"passed": true,
|
||||||
|
"nvme": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nvme_smart_health_information_log": {
|
||||||
|
"critical_warning": 0,
|
||||||
|
"temperature": 35,
|
||||||
|
"available_spare": 99,
|
||||||
|
"available_spare_threshold": 10,
|
||||||
|
"percentage_used": 3,
|
||||||
|
"data_units_read": 17176794,
|
||||||
|
"data_units_written": 65602088,
|
||||||
|
"host_reads": 118020838,
|
||||||
|
"host_writes": 874050000,
|
||||||
|
"controller_busy_time": 7601,
|
||||||
|
"power_cycles": 25,
|
||||||
|
"power_on_hours": 12798,
|
||||||
|
"unsafe_shutdowns": 10,
|
||||||
|
"media_errors": 7,
|
||||||
|
"num_err_log_entries": 62,
|
||||||
|
"warning_temp_time": 0,
|
||||||
|
"critical_comp_time": 0,
|
||||||
|
"temperature_sensors": [
|
||||||
|
35,
|
||||||
|
39
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"current": 35
|
||||||
|
},
|
||||||
|
"power_cycle_count": 25,
|
||||||
|
"power_on_time": {
|
||||||
|
"hours": 12798
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -111,9 +111,9 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
if(attribute_status == 0){
|
if(attribute_status == 0){
|
||||||
return "passed"
|
return "passed"
|
||||||
} else if (attribute_status == 1){
|
} else if (attribute_status == 1){
|
||||||
return "warn"
|
|
||||||
} else if (attribute_status == 2){
|
|
||||||
return "failed"
|
return "failed"
|
||||||
|
} else if (attribute_status == 2){
|
||||||
|
return "warn"
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user