I use SSHLibrary to connect to the computer to run test cases. As follows:
*** Test Cases ***
Check CPU Temperature
Check that the CPU temperature is less than ? °C ${CPU tem}
Check CPU Usage
Check if any application is using CPU more than ? percent ${CPU usage percent}
Check TCP transmission
Check TCP transmission > ? MBytes ${tcp transmission}
*** Keywords ***
Open Connection & Login
Open Connection ${HOST}
Login ${ACCOUNT} ${PASSWORD}
#(The following is omitted)
I would like to ask how can I do if I want to use the same Test cases to test the second computer?
Well, that depends how much you want to change the structure of your current file/tests. Since you have single variables ${HOST}, ${ACCOUNT}, and ${PASSWORD} and it doesn't seem from your question that you iterate over some data structure where you store different login information for several different hosts, then the more straightforward way of running this is just to run several commands:
$ robot --variable HOST:host1 --variable ACCOUNT:a --variable PASSWORD:secret * && robot --variable HOST:host2 --variable ACCOUNT:a --variable PASSWORD *
EDIT: As I have been correctly reminded in the comments, executing the second command from the previous example will overwrite the outputs created by the first command, so a better way to go about it (to preserve logs from both executions) is something like this:
$ robot --timestampoutput --output host1 --log host1 --report host1 --variable HOST:host1 --variable ACCOUNT:a --variable PASSWORD:secret * && robot --timestampoutput --output host2 --log host2 --report host2 --variable HOST:host2 --variable ACCOUNT:a --variable PASSWORD:secret *
That will create separate outputs for each command in the following format: host{n}-{date}-{time}.
Since this is already a long command, it's better to use argument file that contains all these command-line options, you can later reference just this file from the command like: $ robot --argumentfile <path_to_argument_file>. More on that here.
This approach requires no change in your test/keyword files, but it doesn't scale very well if you have a lot of machines to run these tests on.
I'd most likely go for the following approach:
create a resource file with login information to all the machines I want to run these tests. If could be something like this:
Resources/machines.py
MACHINES = [
{
"host": "host1",
"account" "a",
"password": "secret"
},
{
"host": "host2",
"account" "b",
"password": "secret"
}
]
I'd iterate over this test data in each test case, calling the keywords with these values, something like:
*** Test Cases ***
Check Temperature
FOR ${machine} IN #{MACHINES}
# you would need to assing values from the dict into ${host}, ${account},
# and ${pwd} here, you want to check Collections library for this
Check CPU Temperature ${host} ${account} ${pwd}
END
Then you would be able to issue just one command with no need to specify any variables on the command line. It scales better if you have a lot of test data.
Another way of doing this would be a data driven approach:
*** Test Cases ***
Check Temperature
[Template] Check CPU Temperature
host1 a secret
host2 a secret
host3 a secret
and similarly for other test cases. You'd also need to change your keywords such as Check CPU Temperature so they accept parameters for a host, account, and login.
This approach is perhaps a little bit straighforward than the previous one, but you keep test data hard-coded in your test (.robot) files, which I personally don't like.
Related
I have a simple test, using the SSHLibrary which I'd like to start and run in parallel on multiple hosts. Now I have statically set 'host1'. How would I run this on host1, host2 and host3 at the same time?
*** Settings ***
Documentation Demo
Library SSHLibrary
Suite Setup Open Connection And Log In
Suite Teardown Close All Connections
*** Variables ***
${HOST} host1
${USERNAME} user
*** Test Cases ***
Evaluate command status
[Documentation] Demo
${output} Execute Command net show version
Should Be True $output
*** Keywords ***
Open Connection And Log In
Open Connection ${HOST}
Login With Public Key ${USERNAME} /home/user/.ssh/id_rsa
You can set the variable on the command line with the --variable or -V option:
robot --variable host:host1
robot --variable host:host2
For more information see Setting variables in command line in the robot framework user guide.
Robot iteself doesn't provide any features to run tests in parallel. To run them in parallel you could write a script that runs robot in the background for each host, and then combine the reports from each run into a single unified report.
*** Settings ***
Documentation Transfer a file from OCU to PC
Library SSHLibrary
Suite Setup Open Connection and Login With Public Key
Suite Teardown Close All Connections
*** Variables ***
${REMOTE HOST} 192.168.x.xxx
${USER} xxx
*** Keywords ***
Open Connection and Login With Public Key
Open Connection ${REMOTE HOST}
Login With Public Key ${USER} /home/bhushan/.ssh/id_rsa
*** Test Cases ***
Run the given command on the console
${pwd}= Execute Command pwd
Should Be Equal ${pwd} /home/root
${output}= Execute Command ls
${output}= Execute Command scp /home/root/myfile.txt bhushan#192.168.x.xxx:/home/bhushan/vdr-reports/
Log ${output}
I have Dropbear of the latest version installed on my target. I am trying to run the above SSH Library Robot framework keyword based test case which defines to transfer a file from remote to the local host. The execute command keyword works in the beginning i.e. ${output}= Execute Command ls, but i am getting an error while using the same keyword in copying the files, i.e i can't see anything happening on the console. It is hanging and i waited for long time to see the output but haven't seen anything. But this works when i copy the files to my local machine manually. Can anyone here try to help me in fixing this error.
KEYWORD ${output} = SSHLibrary . Execute Command scp
/home/root/myfile.txt bhushan#192.168.x.xxx:/home/bhushan/vdr-reports/
Documentation: Executes command on the remote machine and returns
its outputs. Start / End / Elapsed: 20170829 10:26:23.897 / 20170829
10:26:50.148 / 00:00:26.251 10:26:23.898 INFO Executing command 'scp
/home/root/myfile.txt
bhushan#192.168.x.xxx:/home/bhushan/vdr-reports/'...................>
This is what i see in the log
Trying to run this piece of code, but a "Prompt is not set" error keeps occurring at the Execute Command line.
*** Settings ***
Library Telnet
Library Telnet ${out}
Library Collections
Library Collections ${y}
Library Collections ${x}
*** Variables ***
${ip} 0.0.0.0
${port} 0
*** Test Cases ***
telnet to server
Open Connection ${ip} ${port}
verify something
${out}= Execute Command ls
${y}= Get From List ${out} 0
Should Match Regexp ${y} /^ID$/
Exit Test
Close All Connections
I have also tried deleting "Library Telnet ${out}" and replacing the " ${out}=
Execute Command ls" line with the following, but receive the same error.
Write ls
Set Prompt ${out}
${out}= Read Until Prompt
Is there a problem with the syntax? Or, is the usage of the "prompt" completely wrong? (if so, how can i fix this?)
(note: this is a first attempt at robot framework, so please feel free to comment on any other problems!)
Everything is in the Telnet docs. I use RED Robot Editor which can show me docs for Telnet and Telnet KW by hover over Telnet entry in editor, this can also be generated via command line:
python -m robot.libdoc Telnet show
There is a part about Prompt:
== Prompt ==
Often the easiest way to read the output of a command is reading all
the output until the next prompt with `Read Until Prompt`. It also makes
it easier, and faster, to verify did `Login` succeed.
Prompt can be specified either as a normal string or a regular expression.
The latter is especially useful if the prompt changes as a result of
the executed commands. Prompt can be set to be a regular expression
by giving ``prompt_is_regexp`` argument a true value (see `Boolean
arguments`).
Examples:
| `Open Connection` | lolcathost | prompt=$ |
| `Set Prompt` | (> |# ) | prompt_is_regexp=true |
Check Telnet docs for more help and examples.
ps. I don't see reason to import Telnet with parameter:
Library Telnet ${out}
Although I am too late to answer, I did not see the exact expected answer hence answering this now.
You need to set 2 things in Open Connection.
prompt_is_regexp=yes
prompt=#{Your expected prompt}
I am using Robot Framework SSH Library for my automation.
I need to establish SSH Tunnel to a remote machine using Robot Framework and then execute set of tests on the remote machine.
Looks like RF SSH Library do not have support for this.
Can someone point me to any other options available?
Thank you!
You could use Robot Framework to open SSH connection, copy test files, run them and copy results back.
You will need two files, first one is ssh.txt
*** Settings ***
Library SSHLibrary
Suite Setup Open Connection And Log In
Suite Teardown Copy And Delete Files And Close Connections
*** Variables ***
${HOST} your.server.here
${USERNAME} username
${PASSWORD} password
*** Testcases ***
Run Tests on remote server
Put File real-test.txt
Run Test In Server real-test.txt
Sleep 1s
*** Keywords ***
Open Connection And Log In
Open Connection ${HOST}
Login ${USERNAME} ${PASSWORD}
Copy And Delete Files And Close Connections
Copy Results From Server
Clean Up Server real-text.txt
Close All Connections
Run Test In Server
[Arguments] ${filename}
${rc}= Execute Command pybot ${filename} return_stdout=False return_rc=True
Should Be Equal As Numbers ${rc} 0
Copy Results From Server
GetFile log.html
GetFile output.xml
GetFile report.html
Clean Up Server
[Arguments] ${filename}
Write rm log.html
Write rm output.xml
Write rm report.html
Write rm ${filename}
the 2nd file is where real tests are, real-test.txt:
*** Settings ***
Library OperatingSystem
*** Testcases ***
Test 1
FileShouldExist real-test.txt
run this by specifying output files to avoid filename collisions when log files are copied back from server:
pybot -o conn.xml -r conn.html -l connlog.html ssh.txt
I recently did something like this but created the functionality in Python which I then imported to Robot as a keyword.
The jist of it was:
in SSHTunnel.py:
from sshtunnel import SSHTunnelForwarder
(other imports)
class SSHTunnel:
def create_ssh_tunnel(self):
ssh_server = SSHTunnelForwarder(
(host, int(port)),
ssh_username=username,
ssh_password=pass,
remote_bind_address=(remote_bind_host, int(remote_bind_port))
)
ssh_server.start()
def stop_ssh_tunnel(self):
ssh_server.stop()
Now you add the SSHTunnel.py file to the Robot Library and call the keyword Create SSH Tunnel in the beginning of the testcase (can also be in Test Setup or Suite Setup) and Stop SSH Tunnel at the end.
Hope that helps.
Library SSHLibrary
Open Connection host_server
Login With Public Key test /test.pem test12345
Create Local SSH Tunnel 9191 remote_host remote_port bind_address=127.0.0.1
#Once the connection is made you can directly access the resources in remote_host, for eg : i am trying to connect mysql db in remote host
Connect To Database Using Custom Params pymysql database='testDb', user='testuser', password='test123', host='127.0.0.1', port=9191
You can achieve this with the help of 'local port forwarding' feature.
Ref: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding.
Use this command on the test server(where the robot is running) in an instance:
ssh -4 -L <listening_port/forwarding_port>:<destination_ip>:destination_port> username#jump_box.com
eg)
ssh -4 -L 50025:10.122.56.45:23 anishg#jumpbox.teski.com
Use the following command in another instance to work in the destination server:
telnet localhost <listening port>
eg)
telnet localhost 50025
Here you can execute the commands as like you are working on the destination server, as the session is opened.
In Robot, this can be achieved by this way also:
The Step (1) - Port forwarding is done in a shell script and this shell script is called in your robot framework.
Do Telnet/other in localhost with port specified
sample.sh:
ssh -4 -L 50025:10.122.56.45:23 anishg#jumpbox.teski.com
Robot Code:
*** Test Cases ***
Port Forwarding
Start Process ./sample.sh shell=True #Port is opened
Log To Console SHELL IS Executing
Telnet.Open Connection localhost port=50025 #Normal op as in destn server
Note: I used jump_box as I dont have access to destination server from my test instance.
Within robot framework, I can use a for loop in each test case to Start an SSH connection to each host within a list, and then run commands on that host.
But it seems that the ssh setup happens in every test case which takes a considerable amount of time.
Is there some way in which I can make the connection persistent for every test case in a test suite?
Example Code:
*** Settings ***
Variables sys_variables.py
Resource ${RESOURCES}/common.robot
*** Test Cases ***
Ping :FOR ${HOST} IN #{REACHABLE}
\ SSH to ${HOST} ${USER} ${PASS}
\ ${result} = Run and Log ${PING_GOOGLE_DNS}
\ Should Be Equal As Integers ${result} 0
\ log ${result}
This works, but I'd like to not have to run it in every testcase.
Just put the tests in a single suite and make the connections in the suite setup. The suite setup is executed one time, before the actual test executions.
Consider the following example code:
*** Settings ***
Suite Setup SuiteSetup
*** Test Cases ***
Test1
Log This is the test 1
Test2
Log This is the Test 2
*** Keywords ***
SuiteSetup
Log This is the single setup
Put your connection cycle inside the SuiteSetup keyword and you're done.