openbmc / openbmc-test-automation

Apache License 2.0
104 stars 92 forks source link

refactoring ipmi/test_ipmi_user.robot to remove some limitations #2187

Closed generatz closed 2 years ago

generatz commented 2 years ago

At run time, along with the root user there may be other users with ADMINISTRATOR privilege, and there is no guarantee that root will be assigned user ID 1. But the test cases are hard-coded to expect root at UID 1 and to have no other UIDs with ADMINISTRATOR privilege. Consequently, when those conditions are not met, there are several fails.

To address these issues I created the keyword Set Admin User ID List and apply it as the Suite Setup. It dynamically determines the UID for root and generates a list of UIDs that have ADMINISTRATOR privilege. It then sets those values into suite variables ${root_userid} and ${admin_ids}, respectively. With that addition the correct root UID is always available. And whenever a new UID is needed by a test case, the UIDs in ${admin_ids} are correctly avoided using the added Find Available User Id.

Here is my git patch for this change (it corrporates the changes I recommended for issue #2151):

diff --git a/ipmi/test_ipmi_user.robot b/ipmi/test_ipmi_user.robot
index a9d1857d..5149058f 100644
--- a/ipmi/test_ipmi_user.robot
+++ b/ipmi/test_ipmi_user.robot
@@ -1,10 +1,12 @@
 *** Settings ***
-Documentation       Test suite for OpenBMC IPMI user management.
+Documentation       Test suite for OpenBMC IPMI user management;
+                    ...  this suite will delete all non-administrative users.

 Resource            ../lib/ipmi_client.robot
 Resource            ../lib/openbmc_ffdc.robot
 Resource            ../lib/bmc_network_utils.robot
 Library             ../lib/ipmi_utils.py
+Suite Setup         Set Admin User ID List
 Test Setup          Printn

 Test Teardown       Test Teardown Execution
@@ -14,7 +16,6 @@ Test Teardown       Test Teardown Execution
 ${invalid_username}     user%
 ${invalid_password}     abc123
 ${new_username}         newuser
-${root_userid}          1
 ${operator_level_priv}  0x3
 ${user_priv}            2
 ${operator_priv}        3
@@ -26,6 +27,8 @@ ${ipmi_setaccess_cmd}   channel setaccess
 &{password_values}      16=0penBmc10penBmc2  17=0penBmc10penBmc2B
               ...       20=0penBmc10penBmc2Bmc3  21=0penBmc10penBmc2Bmc34
               ...       7=0penBmc  8=0penBmc0
+${expected_max_ids}     15
+${root_pattern}         ^.*\\sroot\\s.*ADMINISTRATOR.*$

 # User defined count.
 ${USER_LOOP_COUNT}      20
@@ -34,26 +37,28 @@ ${USER_LOOP_COUNT}      20

 Verify IPMI User Summary
     [Documentation]  Verify IPMI maximum supported IPMI user ID and
-    ...  enabled user form user summary
+    ...  enabled user from user summary.
     [Tags]  Verify_IPMI_User_Summary
     [Teardown]  Run Keywords  FFDC On Test Case Fail  AND
     ...  Delete Created User  ${random_userid}
-    # Delete all non-root IPMI (i.e. except userid 1)
+
+    # Delete all non-administrative users
     Delete All Non Root IPMI User
+    ${admin_user_count}  ${maximum_ids}=  Get Enabled User Count
+    Run Keyword If  ${admin_user_count} == ${expected_max_ids}
+    ...  Fail  msg= ${admin_user_count} admin users is unexpected!

     ${random_userid}  ${random_username}=  Create Random IPMI User
     Set Test Variable  ${random_userid}
     Run IPMI Standard Command  user enable ${random_userid}

-    # Verify maximum user count IPMI local user can have. Also verify
-    # currently enabled users.
-    ${resp}=  Wait Until Keyword Succeeds  15 sec  5 sec  Run IPMI Standard Command
-    ...  user summary ${CHANNEL_NUMBER}
-    ${enabled_user_count}=
-    ...  Get Lines Containing String  ${resp}  Enabled User Count
-    ${maximum_ids}=  Get Lines Containing String  ${resp}  Maximum IDs
-    Should Contain  ${enabled_user_count}  2
-    Should Contain  ${maximum_ids}  15
+    # Verify number of currently enabled users.
+    ${current_user_count}  ${maximum_ids}=  Get Enabled User Count
+    ${calculated_count}=  Evaluate  ${admin_user_count} + 1
+    Should Be Equal As Integers  ${current_user_count}   ${calculated_count}
+
+    # Verify maximum user count IPMI local user can have.
+    Should Be Equal As Integers  ${maximum_ids}  ${expected_max_ids}

 Verify IPMI User List
@@ -98,10 +103,10 @@ Verify IPMI User Creation With Valid Name And ID

 Verify IPMI User Creation With Invalid Name
     [Documentation]  Verify error while creating IPMI user with invalid
-    ...  name(e.g. user name with special characters).
+    ...  name (e.g. user name with special characters).
     [Tags]  Verify_IPMI_User_Creation_With_Invalid_Name

-    ${random_userid}=  Evaluate  random.randint(2, 15)  modules=random
+    ${random_userid}=  Find Available User Id
     ${msg}=  Run Keyword And Expect Error  *  Run IPMI Standard Command
     ...  user set name ${random_userid} ${invalid_username}
     Should Contain  ${msg}  Invalid data
@@ -109,7 +114,7 @@ Verify IPMI User Creation With Invalid Name

 Verify IPMI User Creation With Invalid ID
     [Documentation]  Verify error while creating IPMI user with invalid
-    ...  ID(i.e. any number greater than 15 or 0).
+    ...  ID (i.e. zero or any number greater than 15).
     [Tags]  Verify_IPMI_User_Creation_With_Invalid_ID

     @{id_list}=  Create List
@@ -202,14 +207,14 @@ Verify IPMI User Creation With Same Name
     [Documentation]  Verify error while creating two IPMI user with same name.
     [Tags]  Verify_IPMI_User_Creation_With_Same_Name
     [Teardown]  Run Keywords  FFDC On Test Case Fail  AND
-    ...  Delete Created User  2
+    ...  Delete Created User  ${random_userid}

-    ${random_username}=  Generate Random String  8  [LETTERS]
-    IPMI Create User  2  ${random_username}
+    ${random_userid}  ${random_username}=  Create Random IPMI User

     # Set same username for another IPMI user.
+    ${rand_userid_two}=  Find Available User Id
     ${msg}=  Run Keyword And Expect Error  *  Run IPMI Standard Command
-    ...  user set name 3 ${random_username}
+    ...  user set name ${rand_userid_two} ${random_username}
     Should Contain  ${msg}  Invalid data field in request

@@ -279,7 +284,7 @@ Test IPMI Administrator Privilege Level

 Test IPMI No Access Privilege Level
-    [Documentation]  Verify IPMI user with no access privilege can not run only any level command.
+    [Documentation]  Verify IPMI user with no access privilege can not run any level command.
     [Tags]  Test_IPMI_No_Access_Privilege_Level
     [Template]  Test IPMI User Privilege
     [Teardown]  Run Keywords  FFDC On Test Case Fail  AND
@@ -513,14 +518,87 @@ Modify IPMI User

 *** Keywords ***

+Set Admin User ID List
+    [Documentation]  Generates list of User IDs that have ADMINISTRATOR privileges
+    ...  and determines which one is root; sets generated values as suite variables.
+
+    ${resp}=  Wait Until Keyword Succeeds  15 sec  5 sec  Run IPMI Standard Command
+    ...  user list
+    @{lines}=  Split To Lines  ${resp}
+
+    ${root_userid}=  Set Variable  ${-1}
+    ${id_index}=     Set Variable  ${1}
+    ${count}=        Set Variable  ${0}
+    ${admin_ids}=  Create List
+    FOR  ${line}  IN  @{lines}
+        ${admin}=  Get Lines Containing String  ${line}  ADMINISTRATOR
+        ${count}=  Set Variable If  '${admin}' != '${EMPTY}'
+        ...  ${count+1}
+        ...  ${count}
+        Run Keyword If  '${admin}' != '${EMPTY}'
+        ...  Collections.Append To List  ${admin_ids}  ${id_index}
+
+        ${root_found}=  Get Lines Matching Regexp  ${line}  ${root_pattern}
+        ${root_userid}=  Set Variable If  '${root_found}' != '${EMPTY}'
+        ...  ${id_index}
+        ...  ${root_userid}
+
+        ${hdr_found}=  Get Lines Containing String  ${line}  Channel Priv Limit
+        ${id_index}=  Set Variable If  '${hdr_found}' == '${EMPTY}'
+        ...  ${id_index+1}
+        ...  ${id_index}
+    END
+    ${num_admins}=  Set Variable  ${count}
+    Set Suite Variable  ${num_admins}
+    Set Suite Variable  ${admin_ids}
+    Set Suite Variable  ${root_userid}
+
+    Log To Console  There are ${num_admins} administrative IPMI user IDs.
+    Log To Console  There list of administrative user IDs: ${admin_ids}.
+    Log To Console  The root user ID is ${root_userid}.
+    Run Keyword If  ${root_userid} < ${1}  Fail  msg= Did not identify root user ID.
+    Run Keyword If  ${num_admins} < ${1}   Fail  msg= Did not identify administrator user ID.
+
+
+Get Enabled User Count
+    [Documentation]  Return as integers: current number of enabled users and
+    ...  Maximum number of Ids.
+
+    # Isolate 'Enabled User Count' value and convert to integer
+    ${resp}=  Wait Until Keyword Succeeds  15 sec  5 sec  Run IPMI Standard Command
+    ...  user summary ${CHANNEL_NUMBER}
+    ${user_count_line}=  Get Lines Containing String  ${resp}  Enabled User Count
+    ${count}=  Fetch From Right  ${user_count_line}  \:
+    ${int_user_count}=  Convert To Integer  ${count}
+
+    # Isolate 'Maximum IDs' value and convert to integer
+    ${maximum_ids}=  Get Lines Containing String  ${resp}  Maximum IDs
+    ${max_ids}=  Fetch From Right  ${maximum_ids}  \:
+    ${int_maximum_ids_count}=  Convert To Integer  ${max_ids}
+
+    [Return]  ${int_user_count}  ${int_maximum_ids_count}
+
 Create Random IPMI User
     [Documentation]  Create IPMI user with random username and userid and return those fields.

     ${random_username}=  Generate Random String  8  [LETTERS]
-    ${random_userid}=  Evaluate  random.randint(2, 15)  modules=random
+
+    ${random_userid}=  Find Available User Id
+
     IPMI Create User  ${random_userid}  ${random_username}
     [Return]  ${random_userid}  ${random_username}

+Find Available User Id
+    [Documentation]  Find a userid that does not conflict with existing administrative userid
+    FOR    ${jj}    IN RANGE    300
+        ${random_userid}=  Evaluate  random.randint(1, ${expected_max_ids})  modules=random
+        ${is_id_unique}=  Run Keyword And Return Status  List Should Not Contain Value
+        ...  ${admin_ids}  ${random_userid}
+        Exit For Loop If  ${is_id_unique} == ${True}
+    END
+    Run Keyword If  ${is_id_unique} == ${False}  Fail  msg= Could not find free user_ID.
+    [Return]  ${random_userid}
+

 Enable IPMI User And Verify
     [Documentation]  Enable the userid and verify that it has been enabled.
@@ -561,7 +639,7 @@ Test IPMI User Privilege

     # Create IPMI user and set valid password.
     ${random_username}=  Generate Random String  8  [LETTERS]
-    ${random_userid}=  Evaluate  random.randint(2, 15)  modules=random
+    ${random_userid}=  Find Available User Id
     IPMI Create User  ${random_userid}  ${random_username}
     Set Test Variable  ${random_userid}
     Run IPMI Standard Command
gkeishin commented 2 years ago

Fix https://gerrit.openbmc-project.xyz/c/openbmc/openbmc-test-automation/+/53531

gkeishin commented 2 years ago

Merged