#!/usr/software/bin/perl # $Id: //depot/prod/test/main/storage/hdd/NADQ_SEA/NDATE_NVMe/NADQ02_NVMe_Compliance.thpl#1 $ # ## @summary Mode ## Disk Firmware Download in background/foreground mode # ## ## @description ## Verify that the drive can download disk firmware in foreground and background mode properly ## using the method available in the NetApp system. ## ## @Test Mode ## File system mode ## ## @Test bed setup ## FC : Cluster Fabric ## SATA : Cluster ## SAS : Cluster ## ## @usage ## The test can be run independently or with other tests as part of STEST. ## ## @dependencies ## Disk firmwares should be copied to ~/NDATE/FIRMWARE/DISKFW/HIGH folder for foreground ## ## @steps ## The test will execute steps mentioned below: ## ## ## @status Automated ######################################## ### Library functions ########################################## use strict; use Storage::NVMe_Common_Lib; use Storage::Tahiti_Common_Lib; use Storage::Common_Lib; use NACL::C::Statistics; use NACL::MTask::EventLogDetector; ######################################### ######################################### ### Initialization/declaration ######################################### ##### # Global parameters use vars qw( $FILER $MODE $FILER_CONN $TEST_CONFIG $TEST_SETUP $FILER_PROMPT $LOGDIR $EOE $TEST_WAIT_TIME $BOOT_MODE $BOOT_TYPE $SSD $EMAIL $MAIL_TO $MAIL_FROM $FILER_TYPE $FIRMWARE $RUNID $ARMADILLO ); my $params = NATE::ParamSet->new( global => 1 ); $FILER = $params->get( 'FILER', default => 'Filer' ); $TEST_CONFIG = $params->get( 'TEST_CONFIG', default => 'E' ); $TEST_WAIT_TIME = $params->get( 'TEST_WAIT_TIME', default => '3' ); $LOGDIR = $params->get( 'LOGDIR', default => undef ); $EOE = $params->get( 'EOE', default => 1 ); $EMAIL = $params->get( 'EMAIL', default => 'y' ); $MAIL_TO = $params->get( 'MAIL_TO', default => 'Email to' ); $MAIL_FROM = $params->get( 'MAIL_FROM', default => 'Email from' ); $TEST_SETUP = $params->get( 'TEST_SETUP', default => 'SAS' ); $BOOT_MODE = $params->get( 'BOOT_MODE', default => '1' ); $BOOT_TYPE = $params->get( 'BOOT_TYPE', default => 'A' ); $RUNID = $params->get( 'RUNID', default => undef ); $SSD = $params->get( 'SSD', default => 'no' ); $ARMADILLO = $params->get( 'ARMADILLO', default => '2' ); $FILER_TYPE = $params->get( 'FILER_TYPE', default => 'BR' ); $FIRMWARE = $params->get( 'FIRMWARE', default => 'Firmware file not entered' ); ################ # Testcase name ################ my $TC_name; $TC_name = "100_NADQ02_NVMe_Th_Compliance.thpl"; #Common variable declaration my ( $email_subject, $email_body ); my @Nodes; my $filer_names; my $Mode; my $test_status = 0; my %nodes_filer; my $firmware_hash = {}; my @firmware_list; my $cnt = 1; my $disk_show_v; my %test_details; my $Home = $ENV{HOME}; my $test_wait_time = 12 * 3600; #12 Hrs test if ( $TEST_WAIT_TIME == 1 ) { $test_wait_time = ( $test_wait_time / 10 ); } elsif ( $TEST_WAIT_TIME == 2 ) { $test_wait_time = ( $test_wait_time / 2 ); } elsif ( $TEST_WAIT_TIME == 4 ) { $test_wait_time = ( ($test_wait_time) * (.95) ); } ######################################### # Test case available for execution ######################################### my @Testcases = ( NVMe_Compliance => "NVMe Command Compliance script." ); &main(); sub main { # Debug break point $DB::single = 2; # Create Test Case Driver object $Test = new TCD( -testcases => [@Testcases] ); if ( $Test->error ) { $Test->log( $Test->errmsg ); $test_status = 1; $email_subject = "$TC_name : Test FAILED: FAIL"; $email_body = "Failed to instantiate Test object.\nLog Location : $LOGDIR\n"; send_message( mail_subject => $email_subject, mail_body => $email_body, MAIL_FROM => $MAIL_FROM, MAIL_TO => $MAIL_TO, EOE => $EOE, EMAIL => $EMAIL ); return $TCD::FAIL; } # Performs method callbacks $Test->run_test(); if ( $Test->error ) { $Test->log( $Test->errmsg ); return $TCD::FAIL; } exit(0); } ## end sub main ########## INIT ################################################### # This init subroutine will initialise the filer. #################################################################### sub init() { $Test->description(" Initialising all required variables and filer connections "); $filer_names = $Test->get_param("FILER"); # Capturing Filer names from the param(Test_Suite) ##Check for duplicate node object and push unique node object in Nodes array. my @temp_nodes = NACL::C::Node->find(); # Find Nodes/Filers used in the test, Based on FILER param. foreach my $Node (@temp_nodes) { my $FILER_C = $Node->name(); $nodes_filer{$FILER_C} = $Node; } @Nodes = values(%nodes_filer); # Contains Node object used for test execution. sort(@Nodes); $Mode = $Nodes[0]->mode(); logcomment("Checking for execution mode"); logcomment( "FILER- $filer_names : $TC_name : started, expected max completion time 30 Min : " . scalar( localtime() ) ); logcomment( "FILER- $filer_names : Log file for this test case: \n $LOGDIR/$TC_name" . ".log " . scalar( localtime() ) ); return $TCD::PASS; } ########## SETUP ################################################### # setup automatically called before executing tests #################################################################### sub setup() { $Test->description("Setup the environment for the test execution "); logcomment("Mode of filer $filer_names : $Mode"); my $node_ref = \@Nodes; version_test( node_present => $node_ref, tc_name => $TC_name ); ##################################################################### # Pre test proces : call for pre_n_post test process ##################################################################### nvme_pre_test( node_present => $node_ref, Test => $Test, change_state_to => "CLI", filer_mode => $Mode, Tahiti => "yes" ); foreach my $Node (@Nodes) { my $FILER_C = $Node->name; my $Api_Set_Obj = $Node->get_7m_or_nodescope_apiset( connid => 'console' ); my $Host = host($FILER_C); logcomment("disable autogiveback "); my $prompts_answers = [ 'Do you want to disable auto-giveback?' => 'y', 'Do you want to continue' => 'y' ]; $Api_Set_Obj->execute_raw_command( command => "storage failover modify -node * -auto-giveback false", 'connectrec-match_table' => $prompts_answers ); logcomment("Disable background firmwar update option"); $Api_Set_Obj->execute_raw_command( command => "run local options raid.background_disk_fw_update.enable off" ); logcomment("Stop firmware update command"); try { my $prompts = [ 'Are you sure you want to' => 'y' ]; $Api_Set_Obj->execute_raw_command( 'command' => "run local \"priv set -q test; disk_fw_update -S\"", 'connectrec-match_table' => $prompts); logcomment("Firmware Qualification download stopped "); } catch NACL::APISet::Exceptions::ResponseException with { logcomment("FW Download stop test Failed."); }; } return $TCD::PASS; } sub NVMe_Compliance { my @subtests; my $status = 0; logcomment( "Number of nodes are " . scalar @Nodes . " and the filer are $filer_names" ); foreach my $Node (@Nodes) { my $FILER_C = $Node->name(); push( @subtests, subtest( \&Compliance_cmd_exe, -runid, "Compliance_cmd_exe_$FILER_C", -bg, "--", $Node ) ); } Subtest::wait_finish( subtest => [@subtests] ); my $status = status_return( subtest_ref => [@subtests] ); logcomment("Total test status is : $status"); if ( $status == 0 ) { return $TCD::PASS; } else { return $TCD::FAIL; } } sub Compliance_cmd_exe { $Test->description("Executing Command Compliance Steps"); my ( @Nodes, %filer_nvol ); my $Home = $ENV{HOME}; my @NON_RT_AGG; my @NON_RT_VOLS; my $Api_Set_Obj_SS; my $drv_result = {}; my $tahiti_drvs = {}; my @nv_drv; my @tahiti_drv; my $Node = shift(@_); my $FILER_C = $Node->name(); my $Host = host($FILER_C); logcomment("Total Nodes - $Node"); logcomment( "Filer passed to the subtest :: " . $Node->name() ); #STEP 1 tahiti_eye_catcher( Test => $Test, string => "STEP 1 of 9: Set Privilage level to diag" ); my $Api_Set_Obj = $Node->get_7m_or_nodescope_apiset( connid => 'console' ); logcomment(" Privilage Level "); $Api_Set_Obj->execute_raw_command( 'command' => "set" ); logcomment("Set privilage level to diag"); my $prompts_answers = [ ".*Do you want to continue.*" => 'y' ]; $Api_Set_Obj->execute_raw_command( 'command' => "set diag", 'connectrec-match_table' => $prompts_answers ); logcomment("Privilage level diag set"); $Api_Set_Obj->execute_raw_command( 'command' => "set" ); #STEP 2 : tahiti_eye_catcher( Test => $Test, string => "STEP 2 of 9: Login into system shell" ); logcomment("Get password to login in system shell"); my $Passwd = $Host->default_password(); logcomment("Filer password : $Passwd"); my $prompts_answers = [ ".*Do you want to continue.*" => 'y' ]; $Api_Set_Obj_SS = NACL::APISet->new( hostobj => $Host, category => "Node", interface => "CLI", set => "Systemshell" ); logcomment("System shell API created, Proceeding with compliance commands"); #STEP 3 tahiti_eye_catcher( Test => $Test, string => "STEP 3 of 9: List all drives " ); my $ss_disk_list = $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol devlist" ); foreach my $line ( split( /\n/, $ss_disk_list ) ) { my ( $drv, $ns, $nsz ); if ( $line =~ /(\S+)\:\s+(\S+)/ ) { $drv = $1; if ( $drv =~ /nvmeof/ ) { $tahiti_drvs->{$drv}->{'PRDID'} = $2; } else { $drv_result->{$drv}->{'PRDID'} = $2; } } if ( $line =~ /(\S+)ns\d+/ ) { $drv = $1; if ( $line =~ /(\S+)\s+\((\S+)\)/ ) { $ns = $1; $nsz = $2; if ( $ns =~ /nvmeof/ ) { $tahiti_drvs->{$drv}->{'NAME_SP'} = $ns; $tahiti_drvs->{$drv}->{'NS_SIZE'} = $nsz; } else { $drv_result->{$drv}->{'NAME_SP'} = $ns; $drv_result->{$drv}->{'NS_SIZE'} = $nsz; } } } } @nv_drv = keys(%$drv_result); @tahiti_drv = keys(%$tahiti_drvs); logcomment(" Nvme System Shell Drive list "); foreach my $d (@nv_drv) { logcomment(" Nvme System Shell Drive : $d"); } logcomment(" Tahiti System Shell Drive list "); foreach my $d (@tahiti_drv) { logcomment(" Tahiti System Shell Drives(s) : $d"); } #STEP 4 tahiti_eye_catcher( Test => $Test, string => "STEP 4 of 9: Record Controller Information" ); foreach my $drv (@tahiti_drv) { logcomment("Recording controller infromation on $drv"); $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol identify $drv" ); logcomment("Recorded controller infromation on $drv"); } #STEP 5 tahiti_eye_catcher( Test => $Test, string => "STEP 5 of 9: Record Namespace Information" ); foreach my $drv (@tahiti_drv) { logcomment("Recording namespace information on $drv"); my $drvns = $tahiti_drvs->{$drv}->{'NAME_SP'}; $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol identify $drvns" ); logcomment("Recorded namespace information on $drv"); } #STEP 6 tahiti_eye_catcher( Test => $Test, string => "STEP 6 of 9: Verify that the device resets properly, does not hang loop" ); foreach my $drv (@tahiti_drv) { logcomment("Verifying $drv device resets properly, does not hang "); logcomment("Tahiti drive reset not yet stabilized, Skipping reset command - File a burt to enable this"); #my $vout = $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol reset $drv" ); logcomment("Verified $drv device resets "); } #STEP 7 tahiti_eye_catcher( Test => $Test, string => "STEP 7 of 9: Record Error Information log page data" ); my @err_drv; foreach my $drv (@tahiti_drv) { logcomment("Recording Error Information log page data for drive $drv "); my $lgpg = $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol logpage -p 1 $drv " ); if ( $lgpg =~ /No error entries found/ ) { logcomment("NO LOG PAGE 1 ENTRIES FOUND for drive $drv"); } else { logcomment("Error Entries Found for drive : $drv"); push( @err_drv, $drv ); } logcomment("Recorded Error Information log page data for drive $drv "); } if (@err_drv) { logcomment("**FAIL** : ERROR ENTRIES FOUND found for following drives : @err_drv"); logcomment("@err_drv"); $test_status = 1; } #STEP 8 tahiti_eye_catcher( Test => $Test, string => "STEP 8 of 9: Record SMART/Health log page data" ); foreach my $drv (@tahiti_drv) { logcomment("Recording SMART/Health log page data for drive $drv "); my $smlg = $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol logpage -p 2 $drv " ); logcomment("Recorded SMART/Health log page data for drive $drv "); } #STEP 9 tahiti_eye_catcher( Test => $Test, string => "STEP 9 of 9: Record Firmware log page data" ); foreach my $drv (@tahiti_drv) { logcomment("Recording Firmware log page data for drive $drv "); my $fwl = $Api_Set_Obj_SS->execute_raw_command( 'command' => "sudo peg_nvmecontrol logpage -p 3 $drv " ); logcomment("Recorded Firmware log page data for drive $drv "); } logcomment("$FILER_C : Basic Command Compliance command Completed "); logresult( "INFO", msg => $test_status ); } # End of sub_exe ##################################################################### # Cleanup - Post Process ##################################################################### sub cleanup() { $Test->nlog(" $filer_names - Clean up and post test process"); @Nodes = node_new_obj( node_array => [@Nodes] ); my $node_ref = \@Nodes; nvme_post_test( node_present => $node_ref, Test => $Test, change_state_to => "CLI", Tahiti => "yes", filer_mode => $Mode ); ########################################################################################### ## Delete/Reset test specific options and values ########################################################################################### foreach my $Node (@Nodes) { my $FILER_C = $Node->name; my $Api_Set_Obj = $Node->get_7m_or_nodescope_apiset( connid => 'console' ); my $Host = host($FILER_C); logcomment("disable autogiveback "); my $prompts_answers = [ 'Do you want to disable auto-giveback?' => 'y', 'Do you want to continue' => 'y' ]; $Api_Set_Obj->execute_raw_command( command => "storage failover modify -node * -auto-giveback false", 'connectrec-match_table' => $prompts_answers ); logcomment("Disable background firmwar update option"); $Api_Set_Obj->execute_raw_command( command => "run local options raid.background_disk_fw_update.enable off" ); logcomment("Stop firmware update command"); try { my $prompts = [ 'Are you sure you want to' => 'y' ]; $Api_Set_Obj->execute_raw_command( 'command' => "run local \"priv set -q test; disk_fw_update -S\"", 'connectrec-match_table' => $prompts); logcomment("Firmware Qualification download stopped "); } catch NACL::APISet::Exceptions::ResponseException with { logcomment("FW Download stop test Failed."); }; logcomment("$FILER_C : Turn off firmware dwbug messages"); $Api_Set_Obj->execute_raw_command( 'command' => "run local dbg level diskfw=0" ); logcomment("$FILER_C : Turn off the raid options"); $Api_Set_Obj->execute_raw_command( command => "run local options raid.media_scrub.enable off" ); $Api_Set_Obj->execute_raw_command( command => "run local options raid.media_scrub.spares.enable off" ); $Api_Set_Obj->execute_raw_command( command => "run local options raid.scrub.enable off" ); my $response = $Api_Set_Obj->hammer_status(); logcomment("Hammer Status - $response "); my $response = $Api_Set_Obj->hammer_abort(); logcomment("Hammer thread stopped "); } return $TCD::PASS; }