<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloudpods –
Testing</title><link>/docs/en/tags/testing/</link><description>Recent content in Testing on Cloudpods</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><atom:link href="/docs/en/tags/testing/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: Login Test Cases</title><link>/docs/en/docs/web_ui/testcase/login/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/en/docs/web_ui/testcase/login/</guid><description>
&lt;h2 id="scope"&gt;Scope&lt;/h2&gt;
&lt;p&gt;Covers login, login security policies, logout, and session management of the OneCloud Web console. See the following product features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="../../../practice/login"&gt;Login page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../intro/usercenter/userinfor"&gt;User information&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../intro/usercenter/signout"&gt;Sign out&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../intro/ui/view"&gt;Switch view&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../auth-security/authentication/authentication-system/systemuser"&gt;User management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../auth-security/security/security-alert/securityalert"&gt;Security alert&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="environment-and-account"&gt;Environment and account&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;td&gt;&lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account&lt;/td&gt;
&lt;td&gt;cloudadmin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;cloudadmin@test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Login page elements (the actual UI prevails): the Account login / Mobile number login tabs, username input box, password input box, login button, image captcha (shown according to policy), Specify login domain entry, Forgot password, and third-party/CAS login entry.&lt;/p&gt;
&lt;h2 id="case-overview"&gt;Case overview&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;Case name&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-001&lt;/td&gt;
&lt;td&gt;Log in with the correct username and password&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-002&lt;/td&gt;
&lt;td&gt;Log in with a wrong password&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-003&lt;/td&gt;
&lt;td&gt;Log in with a non-existent username&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-004&lt;/td&gt;
&lt;td&gt;Submit with an empty username or password&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-005&lt;/td&gt;
&lt;td&gt;Log in with a specified login domain&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-006&lt;/td&gt;
&lt;td&gt;Login fails when the domain and user do not match&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-007&lt;/td&gt;
&lt;td&gt;An image captcha appears after repeated wrong passwords&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-008&lt;/td&gt;
&lt;td&gt;Exceeding the wrong-password limit locks the account and generates a security alert&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-009&lt;/td&gt;
&lt;td&gt;A user with &amp;ldquo;Console login&amp;rdquo; disabled cannot log in&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-010&lt;/td&gt;
&lt;td&gt;A disabled user cannot log in&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-011&lt;/td&gt;
&lt;td&gt;Log in as a user with MFA enabled&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-012&lt;/td&gt;
&lt;td&gt;A user with an expired password cannot log in&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-013&lt;/td&gt;
&lt;td&gt;The landing view after login is correct&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-014&lt;/td&gt;
&lt;td&gt;The session becomes invalid after logout&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-015&lt;/td&gt;
&lt;td&gt;Accessing an inner page without logging in redirects to the login page&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-016&lt;/td&gt;
&lt;td&gt;Switch the language of the login page&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-017&lt;/td&gt;
&lt;td&gt;Log in as an identity provider (LDAP) user&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-LOGIN-018&lt;/td&gt;
&lt;td&gt;Login session validity period&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-001-log-in-with-the-correct-username-and-password"&gt;TC-LOGIN-001 Log in with the correct username and password&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: The cloudadmin account is enabled and allowed to log in to the console.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt; in a browser.&lt;/li&gt;
&lt;li&gt;On the &amp;ldquo;Account login&amp;rdquo; tab, enter the username &lt;code&gt;cloudadmin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enter the password &lt;code&gt;cloudadmin@test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After submission, the UI shows a transitional state such as &amp;ldquo;Logging in, please wait&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Login succeeds and jumps to the dashboard page, with the current user shown in the upper right corner.&lt;/li&gt;
&lt;li&gt;The top area shows the view switch entry, and the current view is the &lt;strong&gt;Admin Console view&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A login credential (&lt;code&gt;yunionauth&lt;/code&gt;) and the &lt;code&gt;scope&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt;, &lt;code&gt;tenant&lt;/code&gt;, and other cookies are generated in the browser.&lt;/li&gt;
&lt;li&gt;Entering the address again to access the console does not require logging in again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Actual result&lt;/strong&gt;: Pass (verified at the API layer; see Appendix B).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-002-log-in-with-a-wrong-password"&gt;TC-LOGIN-002 Log in with a wrong password&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Same as TC-LOGIN-001.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page.&lt;/li&gt;
&lt;li&gt;Enter the username &lt;code&gt;cloudadmin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enter the wrong password &lt;code&gt;wrongpass123&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login fails and stays on the login page.&lt;/li&gt;
&lt;li&gt;The page prompts &amp;ldquo;Incorrect username or password&amp;rdquo; (the API returns &lt;code&gt;incorrect username or password&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The password input box is cleared or kept as masked text; no plaintext is echoed.&lt;/li&gt;
&lt;li&gt;No valid login credential is generated and the console cannot be entered.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Actual result&lt;/strong&gt;: Pass. The API returns HTTP 401 with the response body &lt;code&gt;{&amp;quot;class&amp;quot;:&amp;quot;IncorrectUsernameOrPassword&amp;quot;,&amp;quot;code&amp;quot;:401,&amp;quot;details&amp;quot;:&amp;quot;incorrect username or password&amp;quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-003-log-in-with-a-non-existent-username"&gt;TC-LOGIN-003 Log in with a non-existent username&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page.&lt;/li&gt;
&lt;li&gt;Enter the username &lt;code&gt;no_such_user_9999&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enter any password.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login fails.&lt;/li&gt;
&lt;li&gt;The message is &lt;strong&gt;identical&lt;/strong&gt; to TC-LOGIN-002 and does not distinguish &amp;ldquo;username does not exist&amp;rdquo; from &amp;ldquo;wrong password&amp;rdquo;, so that whether an account exists is not leaked.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-004-submit-with-an-empty-username-or-password"&gt;TC-LOGIN-004 Submit with an empty username or password&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page, leave both the username and password empty, and click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;Fill in only the username, leave the password empty, and click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;Fill in only the password, leave the username empty, and click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In all three cases no login request is sent and the page stays where it is.&lt;/li&gt;
&lt;li&gt;A validation message &amp;ldquo;Please enter the username&amp;rdquo; / &amp;ldquo;Please enter the password&amp;rdquo; appears below the corresponding input box.&lt;/li&gt;
&lt;li&gt;The input box is highlighted in red or clearly shows an error state.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-005-log-in-with-a-specified-login-domain"&gt;TC-LOGIN-005 Log in with a specified login domain&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A user that is enabled and allowed to log in to the console exists in the Default domain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page and click the &amp;ldquo;Specify login domain&amp;rdquo; entry.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Default&lt;/code&gt; in the domain list.&lt;/li&gt;
&lt;li&gt;Enter the username &lt;code&gt;cloudadmin&lt;/code&gt; and the password &lt;code&gt;cloudadmin@test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;In the user menu in the upper right corner of the console, reopen the login domain setting and click &amp;ldquo;Reset login domain&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After specifying the login domain, the UI shows &amp;ldquo;Current login domain: Default&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Login succeeds and the console opens.&lt;/li&gt;
&lt;li&gt;After resetting the login domain, the login page returns to platform-level login and does not preselect any domain.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-006-login-fails-when-the-domain-and-user-do-not-match"&gt;TC-LOGIN-006 Login fails when the domain and user do not match&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A domain that cloudadmin has not joined exists (for example a new domain &lt;code&gt;testdomain&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page, click &amp;ldquo;Specify login domain&amp;rdquo;, and select a domain that cloudadmin has not joined.&lt;/li&gt;
&lt;li&gt;Enter the username &lt;code&gt;cloudadmin&lt;/code&gt; and the password &lt;code&gt;cloudadmin@test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Login&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login fails and prompts that the username or password is incorrect.&lt;/li&gt;
&lt;li&gt;No cross-domain privilege escalation login occurs.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-007-an-image-captcha-appears-after-repeated-wrong-passwords"&gt;TC-LOGIN-007 An image captcha appears after repeated wrong passwords&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Confirm that a wrong-password threshold is configured on the platform (keystone service parameter &lt;code&gt;password_error_lock_count&lt;/code&gt;; the default 0 means no locking). &lt;strong&gt;This case consumes cloudadmin&amp;rsquo;s error count; confirm the threshold with the administrator before executing it to avoid locking the account.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in repeatedly with cloudadmin and a wrong password until the captcha input box appears in the UI.&lt;/li&gt;
&lt;li&gt;Record the number of failures required to trigger the captcha.&lt;/li&gt;
&lt;li&gt;Enter a wrong captcha in the captcha input box and click &amp;ldquo;Login&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Enter the correct captcha and submit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After the threshold is reached, an image captcha input box appears on the login page and the captcha image can be refreshed.&lt;/li&gt;
&lt;li&gt;When the captcha is wrong, it prompts &amp;ldquo;Please enter a valid captcha&amp;rdquo; / &amp;ldquo;Incorrect captcha&amp;rdquo; and the login is rejected.&lt;/li&gt;
&lt;li&gt;When the captcha is correct and the password is correct, login succeeds.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Remarks&lt;/strong&gt;: If the captcha policy is not enabled on the platform, mark this case as &amp;ldquo;Not applicable&amp;rdquo; and record the platform configuration value.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-008-exceeding-the-wrong-password-limit-locks-the-account-and-generates-a-security-alert"&gt;TC-LOGIN-008 Exceeding the wrong-password limit locks the account and generates a security alert&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: &lt;code&gt;password_error_lock_count&lt;/code&gt; is configured to a value greater than 0.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in repeatedly with cloudadmin and a wrong password, exceeding the configured threshold.&lt;/li&gt;
&lt;li&gt;Try to log in with the &lt;strong&gt;correct&lt;/strong&gt; password.&lt;/li&gt;
&lt;li&gt;Log in with an administrator account and view the security alert list.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After the threshold is exceeded, the account is locked; even the correct password cannot log in and a message says the account is locked.&lt;/li&gt;
&lt;li&gt;A &amp;ldquo;Login anomaly&amp;rdquo; alert record is generated on the security alert page.&lt;/li&gt;
&lt;li&gt;The alert is also sent to the locked user, the domain administrator of the user&amp;rsquo;s domain, and the system administrator.&lt;/li&gt;
&lt;li&gt;After the lock is released, the correct password can log in normally.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Remarks&lt;/strong&gt;: &lt;strong&gt;This case locks the cloudadmin account&lt;/strong&gt;. Do not execute it in a production or shared environment; confirm that it can be unlocked before executing.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-009-a-user-with-console-login-disabled-cannot-log-in"&gt;TC-LOGIN-009 A user with &amp;ldquo;Console login&amp;rdquo; disabled cannot log in&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Prepare a local user that is enabled but has &lt;strong&gt;&amp;ldquo;Login to console&amp;rdquo; turned off&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;As an administrator, create a user in user management and turn off &amp;ldquo;Login to console&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Log out of the current session and log in to the console with that user.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login is rejected, prompting that there is no console login permission or that the username or password is incorrect.&lt;/li&gt;
&lt;li&gt;The user can still access via the API and other means (if the platform allows it) but cannot log in to the console.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-010-a-disabled-user-cannot-log-in"&gt;TC-LOGIN-010 A disabled user cannot log in&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Prepare a user in the disabled state that is currently online.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to the console with that user and keep the session online.&lt;/li&gt;
&lt;li&gt;As an administrator, disable the user in user management.&lt;/li&gt;
&lt;li&gt;The user keeps operating on console pages.&lt;/li&gt;
&lt;li&gt;The user logs out and logs in again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The disable operation does &lt;strong&gt;not&lt;/strong&gt; force an online user to log out immediately.&lt;/li&gt;
&lt;li&gt;After the user logs out, logging in again fails and prompts that the user is disabled.&lt;/li&gt;
&lt;li&gt;Logging in with the correct password of the disabled user also fails.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-011-log-in-as-a-user-with-mfa-enabled"&gt;TC-LOGIN-011 Log in as a user with MFA enabled&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Two-factor authentication is enabled in the global configuration, and the target user has MFA enabled and has completed credential binding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in as a user with MFA enabled and enter the correct username and password.&lt;/li&gt;
&lt;li&gt;Enter the 6-digit security code on the login protection page that appears.&lt;/li&gt;
&lt;li&gt;Submit once with a wrong security code.&lt;/li&gt;
&lt;li&gt;Submit with the correct security code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After the password is verified, the console is not entered directly; instead a 6-digit security code is required.&lt;/li&gt;
&lt;li&gt;A wrong security code prompts &amp;ldquo;Incorrect security code, please re-enter&amp;rdquo; and the console cannot be entered.&lt;/li&gt;
&lt;li&gt;Submitting the correct security code enters the console successfully.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Remarks&lt;/strong&gt;: On test.yunion.io, MFA is currently &lt;strong&gt;not enabled&lt;/strong&gt; for cloudadmin (&lt;code&gt;totp_on=false&lt;/code&gt; in the login credential). Executing this case requires preparing a user with MFA enabled first; if global two-factor authentication is not enabled, the user-side MFA switch does not take effect.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-012-a-user-with-an-expired-password-cannot-log-in"&gt;TC-LOGIN-012 A user with an expired password cannot log in&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A user with an expired password exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in as a user whose password has expired.&lt;/li&gt;
&lt;li&gt;Log in as a user whose password expires in 7 days.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A user whose password has expired &lt;strong&gt;cannot&lt;/strong&gt; log in to the system.&lt;/li&gt;
&lt;li&gt;A user whose password expires in 7 days can log in normally, and after login is prompted that the password is about to expire and is advised to change it as soon as possible.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-013-the-landing-view-after-login-is-correct"&gt;TC-LOGIN-013 The landing view after login is correct&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: cloudadmin has the admin role of the system project in the Default domain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in as cloudadmin.&lt;/li&gt;
&lt;li&gt;Check the view switch entry in the top area.&lt;/li&gt;
&lt;li&gt;Switch to the Domain Admin Console view and the Project view in turn, then switch back to the Admin Console view.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Admin Console view&lt;/strong&gt; is the default landing view, where system-level resources can be seen.&lt;/li&gt;
&lt;li&gt;The view switch entry is displayed normally, and the left navigation menu changes with the view after switching.&lt;/li&gt;
&lt;li&gt;The Domain Admin Console view requires three-level permissions to be enabled on the platform; when not enabled, that view does not appear.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-014-the-session-becomes-invalid-after-logout"&gt;TC-LOGIN-014 The session becomes invalid after logout&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to the console and record the current address.&lt;/li&gt;
&lt;li&gt;Click the user icon in the upper right corner and select &amp;ldquo;Sign out&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Use the browser back button to return to the page from before the logout.&lt;/li&gt;
&lt;li&gt;Paste the inner page address from before the logout and access it directly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After logout, the page jumps to the login page.&lt;/li&gt;
&lt;li&gt;Going back or directly accessing the inner page is redirected to the login page and no business data is shown.&lt;/li&gt;
&lt;li&gt;The login credential in the browser is invalid.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;After a third-party identity provider (such as CAS) user logs out, if the session on the authentication server side is not destroyed, the user may be logged in again automatically. This is the behavior of the identity provider and needs to be confirmed separately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-015-accessing-an-inner-page-without-logging-in-redirects-to-the-login-page"&gt;TC-LOGIN-015 Accessing an inner page without logging in redirects to the login page&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clear the browser cookies or use an incognito window.&lt;/li&gt;
&lt;li&gt;Access an inner page address directly, such as a resource list address like &lt;code&gt;/vminstance&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The request is intercepted and redirects to the login page.&lt;/li&gt;
&lt;li&gt;After a successful login, the user is redirected back to the inner page address originally accessed (if the platform supports redirecting back).&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-016-switch-the-language-of-the-login-page"&gt;TC-LOGIN-016 Switch the language of the login page&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the login page and switch the UI language to English.&lt;/li&gt;
&lt;li&gt;Switch back to Simplified Chinese.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The login page text switches with the language; the login button, input box placeholders, and error messages are all in the target language.&lt;/li&gt;
&lt;li&gt;Switching the language does not affect the username and password already entered.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-017-log-in-as-an-identity-provider-ldap-user"&gt;TC-LOGIN-017 Log in as an identity provider (LDAP) user&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An LDAP identity provider is configured and enabled on the platform, and users have been synced.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the login page, select the corresponding identity provider (for example, select the domain corresponding to the identity provider in &amp;ldquo;Specify login domain&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;Enter the username and password of the LDAP user and log in.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identity provider users can log in to the console normally.&lt;/li&gt;
&lt;li&gt;Users marked as from an LDAP identity provider in user management do &lt;strong&gt;not&lt;/strong&gt; support resetting the password on the platform side.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-login-018-login-session-validity-period"&gt;TC-LOGIN-018 Login session validity period&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to the console and check the expiration time of the login credential cookie.&lt;/li&gt;
&lt;li&gt;After the page stays idle beyond the credential validity period, operate on the page or access an inner page again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The login credential validity period is 24 hours by default (&lt;code&gt;Max-Age=86399&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;After the credential expires, operating on the page or accessing an inner page redirects to the login page and requires logging in again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Actual result&lt;/strong&gt;: Pass. In the measured login response, the &lt;code&gt;Max-Age&lt;/code&gt; of the four cookies &lt;code&gt;yunionauth&lt;/code&gt;, &lt;code&gt;scope&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt;, and &lt;code&gt;tenant&lt;/code&gt; is 86399 seconds.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="appendix-a-api-layer-verification-script"&gt;Appendix A: API-layer verification script&lt;/h2&gt;
&lt;p&gt;Login-related UI behavior can be quickly regression tested with the login API. The following script performs API-level verification against &lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt; and can be copied and run directly (&lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;python3&lt;/code&gt; are required).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# verify_login.sh — login API regression verification&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://test.yunion.io&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cloudadmin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cloudadmin@test&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Default&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;== TC-LOGIN-001 Login with correct credentials ==&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -s -o /tmp/login_ok.txt -w &lt;span class="s2"&gt;&amp;#34;%{http_code}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c /tmp/login_cookie.txt &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -X POST -H &lt;span class="s1"&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;username\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;,\&amp;#34;password\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PASS&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;,\&amp;#34;domain\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/auth/login&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTTP &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;200&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS: login succeeded&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; grep -q yunionauth /tmp/login_cookie.txt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS: yunionauth credential issued&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;FAIL: expected 200, got &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;== TC-LOGIN-002 Login with wrong password ==&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -s -w &lt;span class="s2"&gt;&amp;#34;\n%{http_code}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -X POST -H &lt;span class="s1"&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;username\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;,\&amp;#34;password\&amp;#34;:\&amp;#34;wrongpass123\&amp;#34;,\&amp;#34;domain\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/auth/login&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; head -n -1&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tail -n 1&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTTP &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -q IncorrectUsernameOrPassword &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS: returned IncorrectUsernameOrPassword&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;FAIL: expected error class not returned&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;== TC-LOGIN-003 Login with non-existent user (message should match wrong password) ==&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -s -w &lt;span class="s2"&gt;&amp;#34;\n%{http_code}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -X POST -H &lt;span class="s1"&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;username\&amp;#34;:\&amp;#34;no_such_user_9999\&amp;#34;,\&amp;#34;password\&amp;#34;:\&amp;#34;whatever\&amp;#34;,\&amp;#34;domain\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/auth/login&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; head -n -1&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tail -n 1&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTTP &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -q IncorrectUsernameOrPassword &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS: same response as wrong password; account existence not leaked&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;FAIL: error class differs from wrong password&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;== TC-LOGIN-018 Session validity period ==&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;exp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -s -D - -o /dev/null &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -X POST -H &lt;span class="s1"&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;username\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;,\&amp;#34;password\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PASS&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;,\&amp;#34;domain\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;}&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/auth/login&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -i &lt;span class="s1"&gt;&amp;#39;^set-cookie: yunionauth&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -o &lt;span class="s1"&gt;&amp;#39;Max-Age=[0-9]*&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;yunionauth &lt;/span&gt;&lt;span class="nv"&gt;$exp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$exp&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Max-Age=86399&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS: validity period is 24 hours&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;WARN: validity period differs from expected 86399&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After a successful login, you can use the credential in &lt;code&gt;/tmp/login_cookie.txt&lt;/code&gt; to call other service APIs, for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s -b /tmp/login_cookie.txt &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/servers?limit=5&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="appendix-b-measured-records-for-this-environment"&gt;Appendix B: Measured records for this environment&lt;/h2&gt;
&lt;p&gt;The following API behavior was confirmed by measurement on &lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt; (2026-09-15) and can serve as the baseline for the expected results of the cases.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check item&lt;/th&gt;
&lt;th&gt;Measured result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Console reachability&lt;/td&gt;
&lt;td&gt;HTTP 200, HTTP/2, nginx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/auth/login&lt;/code&gt;, request body &lt;code&gt;{&amp;quot;username&amp;quot;,&amp;quot;password&amp;quot;,&amp;quot;domain&amp;quot;}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correct credentials&lt;/td&gt;
&lt;td&gt;HTTP 200, empty response body, issues &lt;code&gt;yunionauth&lt;/code&gt;/&lt;code&gt;scope&lt;/code&gt;/&lt;code&gt;domain&lt;/code&gt;/&lt;code&gt;tenant&lt;/code&gt; cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong password&lt;/td&gt;
&lt;td&gt;HTTP 401, &lt;code&gt;{&amp;quot;class&amp;quot;:&amp;quot;IncorrectUsernameOrPassword&amp;quot;,&amp;quot;details&amp;quot;:&amp;quot;incorrect username or password&amp;quot;}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cloudadmin default scope&lt;/td&gt;
&lt;td&gt;&lt;code&gt;system&lt;/code&gt; (Admin Console view)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cloudadmin default domain&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Default&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cloudadmin MFA status&lt;/td&gt;
&lt;td&gt;Not enabled (&lt;code&gt;totp_on=false&lt;/code&gt;, &lt;code&gt;totp_verified=false&lt;/code&gt; in the credential)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login credential validity period&lt;/td&gt;
&lt;td&gt;86399 seconds (24 hours)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image captcha API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/auth/captcha&lt;/code&gt;, returns &lt;code&gt;image/png&lt;/code&gt; and issues a &lt;code&gt;captcha&lt;/code&gt; cookie&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The above are API-layer measurement conclusions; cases that depend on UI interaction (such as when the captcha appears, MFA interaction, and password expiration prompts) still need to be executed step by step in a browser to confirm.&lt;/p&gt;</description></item><item><title>Docs: VM Creation Test Cases</title><link>/docs/en/docs/web_ui/testcase/vminstance-create/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/en/docs/web_ui/testcase/vminstance-create/</guid><description>
&lt;h2 id="scope"&gt;Scope&lt;/h2&gt;
&lt;p&gt;Covers the configuration of each parameter when creating a VM and the verification of the creation result. For parameter meanings, see &lt;a href="../../resource-mgmt/compute/server/vminstance/create"&gt;Create a VM&lt;/a&gt;; for operations after creation, see &lt;a href="../../resource-mgmt/compute/server/vminstance/lifecycle"&gt;Instance operations&lt;/a&gt; and &lt;a href="../../resource-mgmt/compute/server/vminstance/detail"&gt;View details&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Entry points&lt;/strong&gt; (see the &amp;ldquo;Entry points&amp;rdquo; section of the guide):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a Local IDC VM: On the VM instance page, click the &amp;ldquo;Create&amp;rdquo; button above the list;&lt;/li&gt;
&lt;li&gt;Create a private cloud VM: Click the &amp;ldquo;Private cloud&amp;rdquo; tab at the top, then click the &amp;ldquo;Create&amp;rdquo; button;&lt;/li&gt;
&lt;li&gt;Create a public cloud VM: Click the &amp;ldquo;Public cloud&amp;rdquo; tab at the top, then click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;On any VM creation page, you can use the &amp;ldquo;Local IDC&amp;rdquo;, &amp;ldquo;Private cloud&amp;rdquo;, and &amp;ldquo;Public cloud&amp;rdquo; tabs at the top to switch the platform to create on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="environment-check"&gt;Environment check&lt;/h2&gt;
&lt;p&gt;Before executing the cases, check each item in this section. If any item is not satisfied, the corresponding cases cannot pass (in that case record them as &amp;ldquo;Blocked&amp;rdquo; rather than &amp;ldquo;Failed&amp;rdquo;).&lt;/p&gt;
&lt;h3 id="local-idc"&gt;Local IDC&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;An OneCloud platform host in the &lt;strong&gt;enabled&lt;/strong&gt; and &lt;strong&gt;online&lt;/strong&gt; state exists in basic resources, or the cloud management platform is integrated with VMware and a VMware host in the enabled state exists;&lt;/li&gt;
&lt;li&gt;An available IP subnet with the &amp;ldquo;guest&amp;rdquo; attribute exists in the target zone;&lt;/li&gt;
&lt;li&gt;A public image or custom image in the &amp;ldquo;available&amp;rdquo; state exists in the system image list.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="private-cloud"&gt;Private cloud&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;The cloud management platform has imported the resources of an OpenStack, ZStack, ZettaCloud, or HCSO cloud account;&lt;/li&gt;
&lt;li&gt;A host in the enabled state belonging to one of the above platforms exists in basic resources;&lt;/li&gt;
&lt;li&gt;The corresponding platform has an available IP subnet.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="public-cloud"&gt;Public cloud&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;The cloud management platform has imported an Alibaba Cloud, AWS, Azure, Huawei Cloud, Tencent Cloud, or UCloud cloud account;&lt;/li&gt;
&lt;li&gt;The cloud account is enabled, healthy, and has sufficient balance;&lt;/li&gt;
&lt;li&gt;A VPC and IP subnet exist in the corresponding platform region.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;For the check results, refer to the measured data in &amp;ldquo;Appendix A: Measured snapshot of resources in this environment&amp;rdquo; of this document.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="case-overview"&gt;Case overview&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;Case name&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-001&lt;/td&gt;
&lt;td&gt;Create a Linux VM on Local IDC (minimum required parameters)&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-002&lt;/td&gt;
&lt;td&gt;Create multiple VMs in batch and name them by sequence number&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-003&lt;/td&gt;
&lt;td&gt;Use the ordered suffix placeholder # for naming&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-004&lt;/td&gt;
&lt;td&gt;Name with a hostname expression&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-005&lt;/td&gt;
&lt;td&gt;Specify an IP subnet and configure a static IP manually&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-006&lt;/td&gt;
&lt;td&gt;Administrator password generated randomly and viewed in the list&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-007&lt;/td&gt;
&lt;td&gt;Associate the administrator password with a key&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-008&lt;/td&gt;
&lt;td&gt;Add data disks&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-009&lt;/td&gt;
&lt;td&gt;Bind an elastic public IP in advanced configuration&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-010&lt;/td&gt;
&lt;td&gt;Bind a security group in advanced configuration&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-011&lt;/td&gt;
&lt;td&gt;Combination of remote console protocol and graphics card&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-012&lt;/td&gt;
&lt;td&gt;Create from a Windows image and connect remotely&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-013&lt;/td&gt;
&lt;td&gt;Create a VM by booting from ISO&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-014&lt;/td&gt;
&lt;td&gt;Custom data (cloud-init)&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-015&lt;/td&gt;
&lt;td&gt;Create a VM from an ARM architecture image&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Local IDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-016&lt;/td&gt;
&lt;td&gt;Create a VM on the ZStack platform&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Private cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-017&lt;/td&gt;
&lt;td&gt;Create a VM on the OpenStack platform&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Private cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-018&lt;/td&gt;
&lt;td&gt;Create a pay-as-you-go VM on Alibaba Cloud&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Public cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-019&lt;/td&gt;
&lt;td&gt;Public cloud subscription and expire-and-release&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Public cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-020&lt;/td&gt;
&lt;td&gt;Validation of required fields and invalid values&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-021&lt;/td&gt;
&lt;td&gt;Duplicate VM name&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-022&lt;/td&gt;
&lt;td&gt;Creation fails when no host or IP subnet is available&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-023&lt;/td&gt;
&lt;td&gt;Status transitions during creation&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC-VM-024&lt;/td&gt;
&lt;td&gt;Lifecycle operations and deletion after creation&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-001-create-a-linux-vm-on-local-idc-minimum-required-parameters"&gt;TC-VM-001 Create a Linux VM on Local IDC (minimum required parameters)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An online host and an available IP subnet exist in Local IDC, and an available Linux public image exists in the image list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in as cloudadmin and go to the &amp;ldquo;Resource Management/Compute/Instances/VM instance&amp;rdquo; page.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Local IDC&amp;rdquo; tab at the top, then click the &amp;ldquo;Create&amp;rdquo; button above the list.&lt;/li&gt;
&lt;li&gt;Basic configuration: Select the default region, and select a zone with an online host.&lt;/li&gt;
&lt;li&gt;Set the name, for example &lt;code&gt;tc-vm-001&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Instance configuration: Keep the quantity at &lt;code&gt;1&lt;/code&gt;, and select &amp;ldquo;OneCloud&amp;rdquo; as the platform.&lt;/li&gt;
&lt;li&gt;Spec configuration: Select &lt;code&gt;1&lt;/code&gt; CPU core and &lt;code&gt;1G&lt;/code&gt; memory (or select &amp;ldquo;Unlimited&amp;rdquo; and pick the smallest instance type).&lt;/li&gt;
&lt;li&gt;Image configuration: Select a Linux image from public images for the operating system, for example &lt;code&gt;openEuler-Linux-24.03 LTS SP4-x86_64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;System disk: Select the default disk type, with a size not lower than the image&amp;rsquo;s minimum disk requirement.&lt;/li&gt;
&lt;li&gt;Login configuration: Select &amp;ldquo;Random&amp;rdquo; for the administrator password.&lt;/li&gt;
&lt;li&gt;Network configuration: Select &amp;ldquo;Auto schedule&amp;rdquo; for the network or specify an available IP subnet.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After clicking &amp;ldquo;Create&amp;rdquo;, a creation success message appears and the page returns to the VM instance list.&lt;/li&gt;
&lt;li&gt;The newly created VM appears in the list with the name &lt;code&gt;tc-vm-001&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The VM status transitions from &amp;ldquo;Creating&amp;rdquo; to &amp;ldquo;Running&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;The region, zone, image, and spec of the VM are consistent with the submitted configuration.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-002-create-multiple-vms-in-batch-and-name-them-by-sequence-number"&gt;TC-VM-002 Create multiple VMs in batch and name them by sequence number&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Follow the steps of TC-VM-001 to open the create page, and set the name to &lt;code&gt;tc-batch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the quantity to &lt;code&gt;3&lt;/code&gt; in the instance configuration.&lt;/li&gt;
&lt;li&gt;Keep the other parameters the same as TC-VM-001 and click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After a successful creation, 3 VMs appear in the list.&lt;/li&gt;
&lt;li&gt;The first VM is named &lt;code&gt;tc-batch&lt;/code&gt; and the rest are &lt;code&gt;tc-batch-1&lt;/code&gt; and &lt;code&gt;tc-batch-2&lt;/code&gt; (when the quantity is greater than 1, all names except the first are expressed as &lt;code&gt;name-1~N&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;All 3 VMs transition to &amp;ldquo;Running&amp;rdquo; normally.&lt;/li&gt;
&lt;li&gt;The IP addresses allocated to the 3 VMs do not conflict with each other.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-003-use-the-ordered-suffix-placeholder--for-naming"&gt;TC-VM-003 Use the ordered suffix placeholder # for naming&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and set the name to &lt;code&gt;tc-host##&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the quantity to &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep the other parameters at their defaults and click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The created VMs are named &lt;code&gt;tc-host00&lt;/code&gt; and &lt;code&gt;tc-host01&lt;/code&gt; (each &lt;code&gt;#&lt;/code&gt; occupies one position).&lt;/li&gt;
&lt;li&gt;The sequence number is zero-padded according to the number of placeholder digits.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-004-name-with-a-hostname-expression"&gt;TC-VM-004 Name with a hostname expression&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and set the name to &lt;code&gt;${region}-${zone}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep the other parameters at their defaults and click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;Create another VM with the name &lt;code&gt;${host}&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The name is evaluated from the expression and displayed as &amp;ldquo;region name-zone name&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Variable names must be lowercase; when &lt;code&gt;${host}&lt;/code&gt; is used, it is displayed as the name of the host that creates the VM.&lt;/li&gt;
&lt;li&gt;Variables in the expression take values according to &amp;ldquo;Hostname expression examples&amp;rdquo; in the guide; unsupported variable names do not take effect or are output as-is.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-005-specify-an-ip-subnet-and-configure-a-static-ip-manually"&gt;TC-VM-005 Specify an IP subnet and configure a static IP manually&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An available IP subnet exists in the target zone and the subnet has unallocated IPs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and select &amp;ldquo;Specify IP subnet&amp;rdquo; in &amp;ldquo;Network configuration&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Select a VPC and an IP subnet.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Configure IP manually&amp;rdquo; button and fill in an unoccupied IP address within the subnet range.&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;OK&amp;rdquo; to save the IP configuration.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The IP filled in the &amp;ldquo;Configure IP manually&amp;rdquo; dialog is saved correctly and echoed back.&lt;/li&gt;
&lt;li&gt;After the VM is created successfully, its IP address is consistent with the manually specified address.&lt;/li&gt;
&lt;li&gt;When a second VM is created repeatedly with the same IP, creation fails or prompts that the IP is already in use.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-006-administrator-password-generated-randomly-and-viewed-in-the-list"&gt;TC-VM-006 Administrator password generated randomly and viewed in the list&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and select &amp;ldquo;Random&amp;rdquo; for the administrator password in &amp;ldquo;Login configuration&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, find the VM in the VM instance list and check the &amp;ldquo;Password&amp;rdquo; column.&lt;/li&gt;
&lt;li&gt;Copy the password and use it to log in to the VM via VNC or a remote connection.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;ldquo;Random&amp;rdquo; does not show the plaintext password; after creation, the administrator password can be viewed and copied in the Password column of the VM instance list.&lt;/li&gt;
&lt;li&gt;The administrator account is &lt;code&gt;root&lt;/code&gt; for Linux systems and &lt;code&gt;administrator&lt;/code&gt; for Windows systems.&lt;/li&gt;
&lt;li&gt;The copied password can be used to log in to the VM successfully.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-007-associate-the-administrator-password-with-a-key"&gt;TC-VM-007 Associate the administrator password with a key&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: At least one keypair already exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In &amp;ldquo;Login configuration&amp;rdquo;, select &amp;ldquo;Associate key&amp;rdquo; for the administrator password.&lt;/li&gt;
&lt;li&gt;Select an existing key.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, log in to the VM over SSH with the corresponding private key.&lt;/li&gt;
&lt;li&gt;When no key has been created, try to select &amp;ldquo;Associate key&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After a key is associated, the VM must be logged in to remotely with the private key, not with a password.&lt;/li&gt;
&lt;li&gt;The matching private key can be used to log in successfully.&lt;/li&gt;
&lt;li&gt;When no key has been created, &amp;ldquo;Associate key&amp;rdquo; cannot be selected or prompts that a key must be created first.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-008-add-data-disks"&gt;TC-VM-008 Add data disks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Confirm the disk type and size in the system disk area of &amp;ldquo;Disk configuration&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;In the &amp;ldquo;Data disks&amp;rdquo; area, click add and set the disk type, medium, and size.&lt;/li&gt;
&lt;li&gt;Add another data disk (optional).&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, view the disk information on the VM details page.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Data disks are optional and multiple disks can be added; the disk type is the same as the system disk.&lt;/li&gt;
&lt;li&gt;Only the first data disk supports selecting a disk type; the type of subsequently added data disks is the same as the first one.&lt;/li&gt;
&lt;li&gt;After a successful creation, the disk list on the details page contains all configured disks, with sizes consistent with the configuration.&lt;/li&gt;
&lt;li&gt;Data disks are attached to the VM but are &lt;strong&gt;not partitioned automatically&lt;/strong&gt;; they must be partitioned manually after logging in.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-009-bind-an-elastic-public-ip-in-advanced-configuration"&gt;TC-VM-009 Bind an elastic public IP in advanced configuration&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An available EIP line is configured on the platform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand &amp;ldquo;Advanced configuration&amp;rdquo; and select &amp;ldquo;Create&amp;rdquo; in &amp;ldquo;Elastic public IP&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Select the line type, select &amp;ldquo;By bandwidth&amp;rdquo; for the network billing method, and set the bandwidth (for example 1Mbps).&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, view the EIP information of the VM.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The EIP is created and bound successfully together with the VM.&lt;/li&gt;
&lt;li&gt;The bound EIP and bandwidth configuration can be seen in the VM details.&lt;/li&gt;
&lt;li&gt;With bandwidth billing, traffic exceeding the bandwidth is dropped (this can be verified with an actual transfer).&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-010-bind-a-security-group-in-advanced-configuration"&gt;TC-VM-010 Bind a security group in advanced configuration&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An available security group and its rules exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand &amp;ldquo;Advanced configuration&amp;rdquo; and select 1 security group in &amp;ldquo;Security group&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Try to select more than 5 security groups.&lt;/li&gt;
&lt;li&gt;After configuring the parameters (without exceeding the limit), click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Security groups can be bound to a VM, up to 5. Beyond that, selection cannot continue or a clear message is shown.&lt;/li&gt;
&lt;li&gt;After binding, the security group rules take effect: ports that are not allowed are inaccessible and allowed ports are accessible.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-011-combination-of-remote-console-protocol-and-graphics-card"&gt;TC-VM-011 Combination of remote console protocol and graphics card&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A OneCloud platform VM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand &amp;ldquo;Advanced configuration&amp;rdquo;, select &lt;code&gt;VNC&lt;/code&gt; for &amp;ldquo;Remote console protocol&amp;rdquo;, and try &lt;code&gt;Standard&lt;/code&gt; and &lt;code&gt;QXL&lt;/code&gt; for &amp;ldquo;Graphics card&amp;rdquo; in turn.&lt;/li&gt;
&lt;li&gt;Change &amp;ldquo;Remote console protocol&amp;rdquo; to &lt;code&gt;SPICE&lt;/code&gt; and observe the available options of &amp;ldquo;Graphics card&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Save and create the VM, then open the remote console of the VM.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;With the VNC protocol, the graphics card can be &lt;code&gt;Standard&lt;/code&gt; or &lt;code&gt;QXL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;With the SPICE protocol, the graphics card can only be &lt;code&gt;QXL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The remote console opens normally and displays the VM screen.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Remarks&lt;/strong&gt;: VNC has no audio or USB transfer and is not suitable for virtual desktops; SPICE performs better in color, audio, and USB and is suitable for virtual desktops.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-012-create-from-a-windows-image-and-connect-remotely"&gt;TC-VM-012 Create from a Windows image and connect remotely&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and select a Windows image for the operating system (for example &lt;code&gt;windows_server_2022_...qcow2&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set the system disk size to be not lower than the image&amp;rsquo;s minimum disk requirement.&lt;/li&gt;
&lt;li&gt;Select &amp;ldquo;Random&amp;rdquo; for the administrator password.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, copy the administrator password in the list and open the remote console connection.&lt;/li&gt;
&lt;li&gt;Log in with the &lt;code&gt;administrator&lt;/code&gt; account and the copied password.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The VM is created successfully and enters the &amp;ldquo;Running&amp;rdquo; state.&lt;/li&gt;
&lt;li&gt;The remote console can display the Windows login screen normally.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;administrator&lt;/code&gt; account and the copied password can be used to log in successfully.&lt;/li&gt;
&lt;li&gt;If Windows is installed by mounting an ISO, Virtio drivers need to be installed separately after installation (the drivers are available in Image Marketplace - ISO).&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-013-create-a-vm-by-booting-from-iso"&gt;TC-VM-013 Create a VM by booting from ISO&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An image in ISO format exists in the image list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page, select &amp;ldquo;Boot from ISO&amp;rdquo; for the operating system, and select an ISO image.&lt;/li&gt;
&lt;li&gt;Check the &amp;ldquo;Login configuration&amp;rdquo; area.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, open the remote console and install the operating system.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After &amp;ldquo;Boot from ISO&amp;rdquo; is selected, setting an administrator password is &lt;strong&gt;not supported&lt;/strong&gt;, and a message says it must be set while installing the operating system.&lt;/li&gt;
&lt;li&gt;All disk types are displayed as &amp;ldquo;data disk&amp;rdquo; (the display does not affect normal use).&lt;/li&gt;
&lt;li&gt;The remote console can enter the ISO boot installation interface.&lt;/li&gt;
&lt;li&gt;Only the OneCloud and VMware platforms support booting from ISO.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-014-custom-data-cloud-init"&gt;TC-VM-014 Custom data (cloud-init)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand &amp;ldquo;Advanced configuration&amp;rdquo; and enter a shell script (for example creating a file and writing the host name) as text in &amp;ldquo;Custom data&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;After configuring the parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;After a successful creation, log in to the VM and check the script execution result.&lt;/li&gt;
&lt;li&gt;Submit the configuration again using &amp;ldquo;Upload JSON file&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Both the text method and the uploaded JSON file method can submit the configuration.&lt;/li&gt;
&lt;li&gt;The OneCloud platform supports shell, python, and perl scripts; private cloud and public cloud platforms support shell and yaml scripts.&lt;/li&gt;
&lt;li&gt;The script is executed after the VM starts for the first time, and the check result matches the expectation of the script.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-015-create-a-vm-from-an-arm-architecture-image"&gt;TC-VM-015 Create a VM from an ARM architecture image&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An ARM architecture host and an ARM architecture image exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and select &lt;code&gt;ARM&lt;/code&gt; for &amp;ldquo;CPU architecture&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Check the operating system image list.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;UEFI&lt;/code&gt; for the boot mode and try to select &lt;code&gt;BIOS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;After configuring the parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Only the OneCloud platform supports the ARM architecture; this option is unavailable on other platforms.&lt;/li&gt;
&lt;li&gt;When the CPU architecture is ARM, the image list is filtered by architecture and shows only ARM architecture images.&lt;/li&gt;
&lt;li&gt;The ARM architecture supports the &lt;code&gt;UEFI&lt;/code&gt; boot mode only and BIOS cannot be selected.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-016-create-a-vm-on-the-zstack-platform"&gt;TC-VM-016 Create a VM on the ZStack platform&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: The cloud management platform has imported ZStack resources, and an online host and an available IP subnet exist in the ZStack region.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to the VM instance page and click the &amp;ldquo;Private cloud&amp;rdquo; tab at the top.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Create&amp;rdquo; button, then click the &amp;ldquo;Private cloud&amp;rdquo; tab at the top.&lt;/li&gt;
&lt;li&gt;Select the region and zone corresponding to ZStack (the region determines the platform the VM belongs to).&lt;/li&gt;
&lt;li&gt;Set the name, and select a spec and a ZStack platform image.&lt;/li&gt;
&lt;li&gt;Select an available IP subnet in the network configuration.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The VM is created successfully on the ZStack platform and enters the &amp;ldquo;Running&amp;rdquo; state.&lt;/li&gt;
&lt;li&gt;The platform displayed for the VM in the list is ZStack.&lt;/li&gt;
&lt;li&gt;The VM can be accessed normally through the remote console and SSH.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-017-create-a-vm-on-the-openstack-platform"&gt;TC-VM-017 Create a VM on the OpenStack platform&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: The cloud management platform has imported OpenStack resources, and an online host and an available IP subnet exist in the region.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Under the &amp;ldquo;Private cloud&amp;rdquo; tab, select the region and zone corresponding to OpenStack.&lt;/li&gt;
&lt;li&gt;Select an image as the system disk (OpenStack supports using an image as the system disk, with image storage as the system disk storage).&lt;/li&gt;
&lt;li&gt;After the system disk is configured, try to set the data disk type.&lt;/li&gt;
&lt;li&gt;After configuring the network and other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The VM is created successfully on the OpenStack platform and enters the &amp;ldquo;Running&amp;rdquo; state.&lt;/li&gt;
&lt;li&gt;When the system disk uses image storage, the data disk type can be set.&lt;/li&gt;
&lt;li&gt;The region, platform, and spec of the VM are consistent with the submitted configuration.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-018-create-a-pay-as-you-go-vm-on-alibaba-cloud"&gt;TC-VM-018 Create a pay-as-you-go VM on Alibaba Cloud&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: An available Alibaba Cloud cloud account with sufficient balance has been imported, and a VPC and IP subnet exist in the corresponding region.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to the VM instance page, click the &amp;ldquo;Public cloud&amp;rdquo; tab at the top, then click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;Select &amp;ldquo;Pay-as-you-go&amp;rdquo; for the billing method.&lt;/li&gt;
&lt;li&gt;Determine the available instance types by geography, platform, region, and zone, and select Alibaba Cloud and a nearby region.&lt;/li&gt;
&lt;li&gt;Select an image that already has a cached badge (to avoid a long image caching time).&lt;/li&gt;
&lt;li&gt;Select a VPC and IP subnet, and configure the other parameters.&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The VM is created successfully on Alibaba Cloud and synced to the cloud management platform, with the status &amp;ldquo;Running&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Charges are billed by actual usage.&lt;/li&gt;
&lt;li&gt;When an uncached image is used, creation takes longer; when a cached badge appears next to the image name, creation is faster.&lt;/li&gt;
&lt;li&gt;On public clouds, only pay-as-you-go VMs support &amp;ldquo;Expire and release&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-019-public-cloud-subscription-and-expire-and-release"&gt;TC-VM-019 Public cloud subscription and expire-and-release&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A domestic public cloud cloud account.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a VM under the &amp;ldquo;Public cloud&amp;rdquo; tab and select &amp;ldquo;Subscription&amp;rdquo; for the billing method.&lt;/li&gt;
&lt;li&gt;Check whether &amp;ldquo;Auto-renewal&amp;rdquo; can be selected, and set the purchase duration.&lt;/li&gt;
&lt;li&gt;Switch the billing method to &amp;ldquo;Pay-as-you-go&amp;rdquo; and set &amp;ldquo;Expire and release&amp;rdquo; to &amp;ldquo;1 hour&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;After configuring the parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Subscription is a prepaid mode and supports selecting auto-renewal.&lt;/li&gt;
&lt;li&gt;Only domestic public clouds support subscription; only Alibaba Cloud subscription supports purchasing one week, and when one week is selected the platform automatically selects Alibaba Cloud.&lt;/li&gt;
&lt;li&gt;For Alibaba Cloud weekly purchases, the renewal period is one week; monthly is one month and yearly is one year; the renewal period of other platforms is one month.&lt;/li&gt;
&lt;li&gt;Expire and release is supported only for pay-as-you-go VMs; when the time is exceeded, the VM is deleted and moved to the recycle bin.&lt;/li&gt;
&lt;li&gt;After being moved to the recycle bin, &lt;strong&gt;charges still apply&lt;/strong&gt;, and the VM must be purged from the recycle bin.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-020-validation-of-required-fields-and-invalid-values"&gt;TC-VM-020 Validation of required fields and invalid values&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the create page and click the &amp;ldquo;Create&amp;rdquo; button directly without filling in anything.&lt;/li&gt;
&lt;li&gt;Fill in the required items such as region, name, spec, image, and network one by one, and resubmit after each item is filled in to observe how the message changes.&lt;/li&gt;
&lt;li&gt;Fill in invalid characters in the name (such as spaces and special characters like &lt;code&gt;/&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Fill in a system disk size smaller than the image&amp;rsquo;s minimum disk size.&lt;/li&gt;
&lt;li&gt;Fill in CPU cores or memory that exceed the remaining resources of the host.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When required fields are missing, the submission is intercepted, the corresponding fields are highlighted in red, and a &amp;ldquo;Please enter/Please select xxx&amp;rdquo; message is shown.&lt;/li&gt;
&lt;li&gt;The submission cannot succeed until all required fields are filled in.&lt;/li&gt;
&lt;li&gt;An invalid name is intercepted with a clear message.&lt;/li&gt;
&lt;li&gt;When the system disk size is smaller than the image&amp;rsquo;s minimum disk requirement, the submission is not allowed or a message is shown.&lt;/li&gt;
&lt;li&gt;When the spec exceeds the available resources, the spec cannot be selected, or the submission fails with the reason given.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-021-duplicate-vm-name"&gt;TC-VM-021 Duplicate VM name&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: A VM named &lt;code&gt;tc-dup&lt;/code&gt; already exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a VM and fill in the name &lt;code&gt;tc-dup&lt;/code&gt;, which already exists.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The creation is rejected and prompts that the name already exists.&lt;/li&gt;
&lt;li&gt;VMs and Baremetals share a name namespace, so trying to create a VM with the name of an existing &lt;strong&gt;Baremetals&lt;/strong&gt; resource is likewise rejected.&lt;/li&gt;
&lt;li&gt;Names are unique in the system.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-022-creation-fails-when-no-host-or-ip-subnet-is-available"&gt;TC-VM-022 Creation fails when no host or IP subnet is available&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: Prepare a zone with no online host, or a subnet whose IPs are exhausted/unavailable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a VM and select a zone that has no online host.&lt;/li&gt;
&lt;li&gt;After configuring the other parameters, click the &amp;ldquo;Create&amp;rdquo; button.&lt;/li&gt;
&lt;li&gt;Then select a scenario where the host is online but the IP subnet does not meet the conditions and submit again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When no host is available, creation fails and prompts that no host is available or that scheduling failed.&lt;/li&gt;
&lt;li&gt;When no IP subnet is available, no subnet can be selected in the network configuration, or the submission fails with the reason given.&lt;/li&gt;
&lt;li&gt;If the host request workflow (ticket) is enabled on the platform, a ticket request is initiated after parameter validation passes, and automatic deployment starts only after approval; when it is not enabled, the VM is created directly.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-023-status-transitions-during-creation"&gt;TC-VM-023 Status transitions during creation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a VM and observe the status in the list immediately after clicking &amp;ldquo;Create&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Check the status count statistics in the upper right of the VM instance list.&lt;/li&gt;
&lt;li&gt;Keep observing until the status no longer changes.&lt;/li&gt;
&lt;li&gt;Open the details page of the VM and check each item of information.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After submission, the VM first appears in the list with the &amp;ldquo;Creating&amp;rdquo; status.&lt;/li&gt;
&lt;li&gt;After a successful creation, the status transitions to &amp;ldquo;Running&amp;rdquo;; when creation fails, it is &amp;ldquo;Operation failed&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;The upper right of the list shows the total number of VMs and the number of VMs in the running, stopped, operation failed, and unknown states, and updates in real time as the status changes.&lt;/li&gt;
&lt;li&gt;The name, region, zone, spec, image, IP, disk, and other information on the details page are consistent with the submitted configuration.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tc-vm-024-lifecycle-operations-and-deletion-after-creation"&gt;TC-VM-024 Lifecycle operations and deletion after creation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Priority&lt;/strong&gt;: P0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: TC-VM-001 has been completed and a VM in the &amp;ldquo;Running&amp;rdquo; state exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select the VM in the VM instance list and perform &amp;ldquo;Stop&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;After confirming the stop, perform &amp;ldquo;Start&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Perform &amp;ldquo;Restart&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Perform &amp;ldquo;Delete&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;After deletion, view it in the recycle bin and perform purge.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After the stop operation, the status becomes &amp;ldquo;Stopped&amp;rdquo;; after the start, it returns to &amp;ldquo;Running&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;The remote console connection is interrupted during the restart; if &amp;ldquo;Force restart&amp;rdquo; is selected, unsaved data in the VM will be lost.&lt;/li&gt;
&lt;li&gt;After deletion, the VM enters the recycle bin and is no longer shown in the list by default.&lt;/li&gt;
&lt;li&gt;The deleted VM can be seen in the recycle bin and is permanently deleted after purge.&lt;/li&gt;
&lt;li&gt;Public cloud VMs may still incur charges after being moved to the recycle bin, so purge them promptly when they are no longer used.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="appendix-a-measured-snapshot-of-resources-in-this-environment"&gt;Appendix A: Measured snapshot of resources in this environment&lt;/h2&gt;
&lt;p&gt;The following data was obtained by measurement on &lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt; (2026-09-15) and is used for checking the prerequisites of the cases and as a reference for parameter values. Resource names differ in other environments; when executing, replace them with the actual options in the drop-down lists.&lt;/p&gt;
&lt;h3 id="local-idc-1"&gt;Local IDC&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Measured value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;&lt;code&gt;default&lt;/code&gt; (Beijing OneCloud)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zone&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Wangjing&lt;/code&gt;, &lt;code&gt;yunion&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Online hosts (OneCloud/KVM)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;test-69-onecloud01&lt;/code&gt; (40C/257923MB), &lt;code&gt;test-66-onecloud02&lt;/code&gt; (40C/257755MB), &lt;code&gt;ampere-10-127-100-7-10-127-100-7&lt;/code&gt; (32C/65079MB), &lt;code&gt;test-d2000-01-10-127-100-8&lt;/code&gt; (8C/15929MB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Online hosts (VMware/ESXi)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10-127-40-2&lt;/code&gt; (48C/131008MB), &lt;code&gt;10-127-40-4&lt;/code&gt; (24C/98258MB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline hosts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;esxi2&lt;/code&gt;, &lt;code&gt;bm15&lt;/code&gt;, &lt;code&gt;vbm1&lt;/code&gt;, &lt;code&gt;vbm2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;guest IP subnets (examples)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;default-86&lt;/code&gt; (10.206.0.1 ~ 10.206.15.254, gateway 10.206.0.1), &lt;code&gt;default-85&lt;/code&gt;, &lt;code&gt;default-84&lt;/code&gt;, and so on, one per VPC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="private-cloud-1"&gt;Private cloud&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Region&lt;/th&gt;
&lt;th&gt;Zone&lt;/th&gt;
&lt;th&gt;Online host&lt;/th&gt;
&lt;th&gt;Available IP subnet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ZStack&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zs-test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ZONE-test&lt;/code&gt;, &lt;code&gt;zone2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Host-test&lt;/code&gt; (12C/11824MB)&lt;/td&gt;
&lt;td&gt;Yes (about 50 subnets per zone)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenStack&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ops-test-RegionOne&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nova&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;test-72-openstack01&lt;/code&gt; (40C/262050MB)&lt;/td&gt;
&lt;td&gt;Yes (about 50 subnets)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="available-images-examples"&gt;Available images (examples)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Image name&lt;/th&gt;
&lt;th&gt;Architecture&lt;/th&gt;
&lt;th&gt;Minimum disk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;openeuler-24.03-lts-sp4-x86_64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;40GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;openEuler-Linux-24.03 LTS SP2-x86_64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;40GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Kylin-Server-10-SP2-aarch64-Release-Build09-20231122.qcow2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;aarch64&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CentOS-Linux-7.9-x86_64-2009&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;8GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Debian-Linux-14 (Forky)-x86_64-latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;3GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;td&gt;&lt;code&gt;windows_server_2022_updated_july_2026_x86_64_20260820.qcow2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;td&gt;&lt;code&gt;windows_11_pro_26h1_x86_64_20260816.qcow2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;80GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Public images (&lt;code&gt;is_public=true&lt;/code&gt;) are shown in the &amp;ldquo;Public image&amp;rdquo; group of the drop-down list; the other items are mostly custom images or host images, selected by their actual groups.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="existing-vms"&gt;Existing VMs&lt;/h3&gt;
&lt;p&gt;VMs such as &lt;code&gt;qj-ubuntu-tmp&lt;/code&gt;, &lt;code&gt;qj-test-w22&lt;/code&gt;, &lt;code&gt;test-rocky&lt;/code&gt;, and &lt;code&gt;glb-test-4.0.4&lt;/code&gt; already exist in the environment; avoid these names when executing cases related to name uniqueness.&lt;/p&gt;
&lt;h2 id="appendix-b-api-layer-verification"&gt;Appendix B: API-layer verification&lt;/h2&gt;
&lt;p&gt;The resource status during creation can be checked quickly through the API. First run &lt;code&gt;verify_login.sh&lt;/code&gt; to obtain a login credential (see Appendix A of &lt;a href="../login"&gt;Login test cases&lt;/a&gt;), then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://test.yunion.io&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;COOKIE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/login_cookie.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# View the VM list and status&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s -b &lt;span class="nv"&gt;$COOKIE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/servers?limit=20&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; python3 -c &lt;span class="s2"&gt;&amp;#34;import sys,json;[print(s[&amp;#39;name&amp;#39;],s[&amp;#39;status&amp;#39;],s.get(&amp;#39;hypervisor&amp;#39;)) for s in json.load(sys.stdin)[&amp;#39;data&amp;#39;]]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# View online hosts (check of creation prerequisites)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s -b &lt;span class="nv"&gt;$COOKIE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/hosts?limit=50&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; python3 -c &lt;span class="s2"&gt;&amp;#34;import sys,json;[print(h[&amp;#39;name&amp;#39;],h[&amp;#39;host_type&amp;#39;],h[&amp;#39;host_status&amp;#39;]) for h in json.load(sys.stdin)[&amp;#39;data&amp;#39;]]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# View available IP subnets (check of creation prerequisites)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s -b &lt;span class="nv"&gt;$COOKIE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/networks?server_type=guest&amp;amp;limit=20&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; python3 -c &lt;span class="s2"&gt;&amp;#34;import sys,json;[print(n[&amp;#39;name&amp;#39;],n[&amp;#39;guest_ip_start&amp;#39;],n[&amp;#39;guest_ip_end&amp;#39;]) for n in json.load(sys.stdin)[&amp;#39;data&amp;#39;]]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# View the image list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s -b &lt;span class="nv"&gt;$COOKIE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/images?limit=20&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; python3 -c &lt;span class="s2"&gt;&amp;#34;import sys,json;[print(i[&amp;#39;name&amp;#39;],i.get(&amp;#39;os_arch&amp;#39;),i.get(&amp;#39;disk_format&amp;#39;)) for i in json.load(sys.stdin)[&amp;#39;data&amp;#39;]]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;The correspondence between the &lt;code&gt;status&lt;/code&gt; values in the API and the UI statuses: &lt;code&gt;running&lt;/code&gt; = Running, &lt;code&gt;ready&lt;/code&gt; = Stopped, &lt;code&gt;start_fail&lt;/code&gt;/&lt;code&gt;create_fail&lt;/code&gt; = Operation failed. The API layer is only used for quickly checking the environment and status; &lt;strong&gt;UI interaction, parameter validation messages, and the ticket workflow still need to be executed step by step in a browser according to the cases&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Docs: Test Cases</title><link>/docs/en/docs/web_ui/testcase/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/en/docs/web_ui/testcase/</guid><description>
&lt;p&gt;This directory maintains test cases for core features of the OneCloud Web console, used for feature verification and version regression. The cases are written based on the feature descriptions in the &lt;a href="../"&gt;Web Console Guide&lt;/a&gt;, and the steps and parameter meanings are consistent with the guide.&lt;/p&gt;
&lt;h2 id="test-environment"&gt;Test environment&lt;/h2&gt;
&lt;p&gt;Test cases are executed in the following environment by default. If you execute them in another environment, first adjust the parameters in the cases according to the &amp;ldquo;Environment differences&amp;rdquo; section below.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Console address&lt;/td&gt;
&lt;td&gt;&lt;a href="https://test.yunion.io" target="_blank" rel="noopener noreferrer"&gt;https://test.yunion.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrator account&lt;/td&gt;
&lt;td&gt;cloudadmin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrator password&lt;/td&gt;
&lt;td&gt;cloudadmin@test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default domain&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default view&lt;/td&gt;
&lt;td&gt;Admin Console view (cloudadmin is the admin of the system project in the Default domain)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local IDC region&lt;/td&gt;
&lt;td&gt;Default (Beijing OneCloud)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local IDC zones&lt;/td&gt;
&lt;td&gt;test, yunion, Wangjing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="case-numbering-rules"&gt;Case numbering rules&lt;/h2&gt;
&lt;p&gt;Case numbers use the format &lt;code&gt;TC-&amp;lt;module&amp;gt;-&amp;lt;sequence&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TC-LOGIN-xxx&lt;/code&gt;: Cases related to login and logout; see &lt;a href="login"&gt;Login&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TC-VM-xxx&lt;/code&gt;: Cases related to VM creation; see &lt;a href="vminstance-create"&gt;Create a VM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Priority descriptions:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Smoke cases; must be tested on every release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Main feature cases; must be tested in version regression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Boundary and combination scenarios; executed as needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="general-conventions"&gt;General conventions&lt;/h2&gt;
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;Before executing any case, the following must be satisfied:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The browser can access the console address and load the login page normally;&lt;/li&gt;
&lt;li&gt;The cloudadmin account can log in normally;&lt;/li&gt;
&lt;li&gt;A host in the &lt;strong&gt;online&lt;/strong&gt; state exists in the Local IDC region (otherwise the cases that create VMs cannot pass);&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;available&lt;/strong&gt; IP subnet exists in the Local IDC region (otherwise no network can be selected in the network configuration).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For how to check items 3 and 4, see the &amp;ldquo;Environment check&amp;rdquo; section of &lt;a href="vminstance-create"&gt;Create a VM&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="result-recording"&gt;Result recording&lt;/h3&gt;
&lt;p&gt;After each case is executed, record the following in &amp;ldquo;Actual result&amp;rdquo;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conclusion: Pass / Fail / Blocked;&lt;/li&gt;
&lt;li&gt;Actual behavior: when it differs from the expected result, record the original text of the interface message;&lt;/li&gt;
&lt;li&gt;Screenshot or API response: required for failed cases;&lt;/li&gt;
&lt;li&gt;Executor, execution time, and the version under test.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="environment-differences"&gt;Environment differences&lt;/h3&gt;
&lt;p&gt;The resource names in the cases (image name, IP subnet name, host name) are taken from the measured snapshot of test.yunion.io. These names are most likely different in other environments; when executing, replace them with the options actually available in the drop-down lists. &lt;strong&gt;This does not affect the acceptance criteria of the cases.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="case-list"&gt;Case list&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="login"&gt;Login&lt;/a&gt;: Login, login security, logout and session — 18 cases in total.&lt;/li&gt;
&lt;li&gt;&lt;a href="vminstance-create"&gt;Create a VM&lt;/a&gt;: Creating VMs on Local IDC, private cloud, and public cloud and various parameter combinations — 24 cases in total.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>