Where during my expect script is is it timing out? - timeout

Within my expect script expect_after to catch the timeout coming from BadPromptPassword, however how do I return that this was the place that my expect script timed out? I've played with expect_out and it doesnt give me what I need... Any help appreciated. Thanks
spawn telnet 172.27.228.239
expect {
timeout { puts "Timed out waiting for response from telnet ('172.27.228.230',)."; exit 1}
"Password:" { send "lab\r"; }
"\[>#\]"
};
send "en\r"
expect_after {
timeout {
puts "a default timeout clause for all subsequent expect commands ";
exit 1
}
}
expect "#>"
send "admin"
expect "BadPromptPassword:"
send "lab\r"
close
wait

Here's a quick hack
expect_after {
timeout {
puts "timed-out expecting $pattern";
exit 1
}
}
set pattern "#>"
expect $pattern
send "admin"
set pattern "BadPromptPassword:"
expect $pattern
send "lab\r"

Related

Cypress visit and wait timeouts ignored

I created a test where I setup a route, try to visit a page which makes an API request to the route and then wait for the route response:
cy
.server()
.route('GET', '/api/testing')
.as('testing');
cy.visit('/index.html', { timeout: 60000 });
cy.wait('#testing', { timeout: 60000 });
This only waits for the Cypress global default responseTimeout of 30 seconds and then fails the API request.
Here's the error message logged by Cypress in the console:
Cypress errored attempting to make an http request to this url:
https://localhost:4200/api/testing
The error was:
ESOCKETTIMEDOUT
The stack trace was:
Error: ESOCKETTIMEDOUT
at ClientRequest. (…\node_modules\cypress\dist\Cypress\resources\app\packages\server\node_modules\request\request.js:778:19)
at Object.onceWrapper (events.js:314:30)
at emitNone (events.js:105:13)
at ClientRequest.emit (events.js:207:7)
at TLSSocket.emitTimeout (_http_client.js:722:34)
at Object.onceWrapper (events.js:314:30)
at emitNone (events.js:105:13)
at TLSSocket.emit (events.js:207:7)
at TLSSocket.Socket._onTimeout (net.js:402:8)
at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)
Adding a responseTimeout to the global config of Cypress will increase the timeout, but why isn't the timeout for either the visit or the wait occurring?
See the code example on this page commands - wait - Alias
// Wait for the route aliased as 'getAccount' to respond
// without changing or stubbing its response
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('#getAccount').then((xhr) => {
// we can now access the low level xhr
// that contains the request body,
// response body, status, etc
})
I would add the then((xhr) => to your code and see what response is coming through.
Logic says that if a bogus route waits the full timeout, but a 'failed legitimate route' does not, then a response with failure code is being sent back from the server within the timeout period.
The block of code in request.js where the error comes from has an interesting comment.
self.req.on('socket', function(socket) {
var setReqTimeout = function() {
// This timeout sets the amount of time to wait *between* bytes sent
// from the server once connected.
//
// In particular, it's useful for erroring if the server fails to send
// data halfway through streaming a response.
self.req.setTimeout(timeout, function () {
if (self.req) {
self.abort()
var e = new Error('ESOCKETTIMEDOUT') <-- LINE 778 REFERENCED IN MESSAGE
e.code = 'ESOCKETTIMEDOUT'
e.connect = false
self.emit('error', e)
}
})
}
This may be a condition you want to test for (i.e connection broken mid-response).
Unfortunately, there seems to be no syntax cy.wait().catch(), see Commands-Are-Not-Promises
You cannot add a .catch error handler to a failed command.
You may want to try stubbing the route instead of setting the breakpoint on the server, but I'm not sure what form the fake response should take. (Ref route with stubbing)
.vist() and .wait() didn't work for me, error logs on cypress suggested using .request() instead which works fine.
cy.server();
cy.request('/api/path').then((xhr) => {
console.log(xhr.body)
})

Rails - How to stub a certain response time for a stubbed / fake http or ajax response

I want to test a feature that in my app sends the usera custom message when a Rails UJS/ajax times-out.
The code to timeout the Rails UJS request is itself on the app:
$.rails.ajax = function(options) {
if (!options.timeout) {
options.timeout = 10000;
}
return $.ajax(options);
};
When observing on chrome dev tools what happened when it timed out on my local dev mode, I notice the code status is strangely 200 but as it "times out", my message is indeed displayed to the user.
on('ajax:error',function(event,xhr, status, error){
// display message in modal for users
if(status == "timeout") {
console.log( ' ajax request timed out');
var msg;
msg = Messenger().post({
hideAfter: 8,
message: "Too long, the app timed out"
});
}
}
});
Below is my current test (using puffing bill gem). I managed to stub the http response for my ajax request but I don't know how to tell rspec to "wait" and timeout like take 11 seconds and still not send any response to the xhr call:) (xhr max timeout is set to 10 000 milliseconds above so 10 sec<11sec, it should time out inside the rspec test)
it " displays correct modal message appears correctly when xhr call timeout" do
visit deal_page_path(deal)
proxy.stub("http://127.0.0.1:59533/deals/dealname/ajaxrequest").and_return(:code => 200)
first('a.button').click
wait_for_ajax
within('ul.messenger') do
expect(page).to have_content('Too long, the app timed out')
end
end
If you really want it to just wait for the timeout I believe you can use the Proc version of and_return and sleep for as long as you want the request to take
proxy.stub("http://127.0.0.1:59533/deals/dealname/ajaxrequest").and_return(
Proc.new { |params, headers, body|
sleep 11
{code: 200}
} )
also - rather than wait_for_ajax just pass the amount of time you expect the element to take to appear to the within call
within('ul.messenger', wait: 11) do ...

EXPECT SCRIPT:procedure being ran before actual code

I'm creating an expect script to let me use macros in my managing of cisco devices.
after all the connections are done, my script waits for the "#" so I know the user is ready for input. if I define my procedure AFTER interact, script works fine, but obviously it hasn't been declared yet so the script fails. if I define it BEFORE interact, I time out like it's actually "expecting"
why would this procedure "run" without even being called?
proc portSec {port} {
send "show port interface $int\r"
expect {
-nocase -re "(invalid)|(ambig}" {
puts "\nInvalid Interface\n"
return
}
-nocase -re "(\[0-9\]+.\[^ \]+.\[^ \]+):\[^ \]" {
set mac $expect_out(1,string)
}
}
~~~~expect "#" ~~~~~~
send "show port address \| i $mac\r"
expect "#"
}
interact {
"!p" {
send_user "\nWelcome to macro mode!\nWhich interface would you like to clear port security?: "
stty echo
expect_user -re "(.*)\r" {
set port $expect_out(1,string)
}
stty -echo
portSec $port
send "\r"
}
}
Here is the debug
expect: does " \r\nYour password will expire in 1 week, 5 days, 3 hours,
44 minutes and 56 seconds
\r\r\n\r\nHOSTNAME line 1 \r\n\r\nHOSTNAME#" (spawn_id exp4)
match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " \r\nYour password will expire in 1 week,
5 days, 3 hours, 44 minutes and 56 seconds\r\r\n\r\nHOSTNAME line 1
n\r\nHOSTNAME#"
expect: does "" (spawn_id exp4) match glob pattern "#"? no
expect: timed out
can't read "mac": no such variable
while executing
"send "show port address \| i $mac\r""
(file "./ios.exp" line 78)
stepping through the debugger, I tilded "~~~" the line where it's expecting
Oh!!! Poor me. How come I missed this mistake!!! :-D
After banging my head for a lot, found that you have used close braces by mistake in the expect statement.
-nocase -re "(invalid)|(ambig}" {
Changing it to bracket, solves this issue. :-)
proc portSec {port} {
send "show port interface $int\r"
expect {
-nocase -re "(invalid)|(ambig)" {
puts "\nInvalid Interface\n"
return
}
-nocase -re {\[0-9\]+.\[^ \]+.\[^ \]+):\[^ \]} {
set mac $expect_out(1,string)
}
}
expect "#";#
send "show port address \| i $mac\r"
expect "#"
}
It all makes sense now. But, why Expect didn't throw any error as such? Then Why it has to accept the remaining part of braces as correct one ?
Well, Because of the misplaced close brace, Expect assumes that the it closes the first expect statement. The code segment remaining are
# two code segments enclosed in braces
# 'Expect' assumes these two as pattern-action pair
# which is why no errors thrown for these blocks.
{
puts "\nInvalid Interface\n"
return
}
-nocase -re "(\[0-9\]+.\[^ \]+.\[^ \]+):\[^ \]" {
set mac $expect_out(1,string)
}
};# This one closes the proc 'portSec'
####### Below code is now in global scope #########3
expect "#"; # Now, wait for '#'
# Send this command now, but wait...
# I don't know about the variable 'mac'
send "show port address \| i $mac\r"
expect "#"
Thereby throwing the error message as can't read "mac": no such variable.
Final product:
#port security clear feature
proc clearPortSec {} {
send_user "\n=====\nWelcome to the Port Security Macro!!!!!\nWhich interface would you like to clear port security?: "
#interact seems to turn of user echoing... turn it back on so the user can make changes
stty echo
expect_user -re "(.*)\r" {
set port $expect_out(1,string)
}
stty -echo
#send ctrl+u to clear the line, and send ctrl+z so we know we are in enable mode
send "\025\032\r"
expect "#"
#verify it is explicitly an access port, if not we don't do the operations to prevent trunks from being shut
send "sho run int $port \| i switchport mode access\r"
expect {
-nocase -re "\r\n\[ \]*switchport mode access\[ \]*\r\n.*#" {
send "\rshow port interface $port\r"
expect {
#grabs offending mac address on this port
-nocase -re "(\[0-9\]+.\[^ \]+.\[^ \]+):\[^ \]" {
set mac $expect_out(1,string)
expect "#"
#finds where switch learned the offending mac
send "show port address \| i $mac\r"
expect {
#case where switch learned mac from another interface
-nocase -re "sticky +(\[^ \]+)" {
set offendport $expect_out(1,string)
puts "\n=====\nMac was found on interface $offendport. Clearing $offendport\n====="
#clear port mac was found on
expect "#"
send "\rconf t\r"; expect "#"
send "interface $offendport\r"; expect "#"
send "no switchport port-security mac-address sticky\r"; expect "#"
send "switchport port-security mac-address sticky\r"; expect "#"
send "shut\r"; expect "#"
send "no shut\r;" expect "#"
#switch to original port
send "interface $port\r"; expect "#"
send "no switchport port-security mac-address sticky\r"; expect "#"
send "switchport port-security mac-address sticky\r"; expect "#"
send "shut\r"; expect "#"
send "no shut\r"; expect "#"
#end all operation and print status of each port
send "end\r"; expect "#"
send "wr\r"; expect "#"
puts "\n=====\nSleeping a few seconds..\nPrevious port will NOT be shut. Please shut if necessary\n====="
send "show int $offendport status\r"; expect "#"
send "show int $port status\r"; expect "#"
}
#case where switch never learned mac
"#" {
puts "\n=====\nMac is no where else on the switch, clearing existing sticky mac from $port\n====="
send "\rconf t\r"; expect "#"
send "interface $port\r"; expect "#"
send "no switchport port-security mac-address sticky\r"; expect "#"
send "switchport port-security mac-address sticky\r"; expect "#"
send "shut\r"; expect "#"
send "no shut\r"; expect "#"
send "end\r"; expect "#"
send "wr\r"; expect "#"
puts "\n=====\nSleeping a few seconds..\n====="
sleep 3
send "show int $port status\r"
}
}
}
}
}
#if we get back '%' - input error, if we get back '#' switchport mode access doesn't exist
-re "\[%#\]" {
puts "\n=====\nInvalid Interface\nThis script ignores all interfaces that don't have \"Switchport mode access\"\n====="
send "\r"
}
}
}
# Don't check keys
spawn ssh -o StrictHostKeyChecking=no $username\#$hostname
expect {
"assword:" {
interact -o -re "\[#>\]" return {
puts "\nLog in Complete"
}
}
timeout {
puts "=====\n$hostname timeout\n====="
exit 1
}
eof {
exit 1
}
}
send "\n"
expect "#"
set timeout -1
interact {
-re "!\[Hh\]" {
puts "\n=====\nMacro list\n=====\nPort Security: !p\n\n"
send "\r"
expect "#"
}
"!p" { clearPortSec }
}

Tcl script breaks out of foreach loop

I have a tcl script to log into devices and print SUCCESS. This is the script:
The file: (the first IP is valid, and can be logged into, the next 3 are fake).
192.38.133.145
178.18.34.48
183.24.56.3
145.234.67.145
The script:
#!/bin/expect
package require Expect
set file [open "hosts" r]
set f_data [read $file]
set data [split $f_data "\n"]
foreach host $data {
set timeout 8
if {$host > 0} {
## GETS THE HOST IP##
set host_ip $host
##LOGS INTO THE DEVICE##
spawn ssh test#$host_ip
expect {
"password:" {
puts "SUCCESS"
} timeout {
puts "Could not connect to host: ${host_ip}"
#break
}
}
send "password\r"
expect ">"
send "en\r"
}
}
If I do not include the break, I get the message could not connect to host, but instead of looping to the next host, it sends "en\r".
when I do include the break, it gives the message that it cannot reach the host (the second IP, which is expected) and the script ends there (it does not process the 3rd IP). How do I cannot seem to get it to process the 3rd and 4th IPs.
I used the method suggested by potrzebie in this thread: TCL: loops How to get out of inner most loop to outside?
and still cannot get it to work
break should work. The expect man page has this to say in the documentation for the expect command:
Actions such as break and continue cause control structures (i.e., for, proc) to behave in the usual way.
I'd write your loop like this:
foreach host $data {
# very basic data validation: an ipv4 address contains some dots
if {[string match {*.*.*.*} $host]} {
spawn ssh test#$host
expect {
"password:" {
puts "SUCCESS"
send "password\r"
exp_continue
}
timeout {
puts "Could not connect to host: $host"
continue
}
">" {
# I see a prompt. Fall out of this "expect loop"
}
}
send "en\r"
expect ">"
# do something to close the connection
send "exit\r"
expect eof
}
}

Stuck messages in ZeroMQ

I'm having a strange problem with ZeroMQ, in which some messages get stuck, and just get unstuck when new messages arrive. It's like the new messages push the stuck messages on the door (terrible comparison, i know).
My code is quite simple:
rep.php
$context = new ZMQContext;
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver->connect("tcp://localhost:8022");
$receiver2 = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver2->connect("tcp://localhost:8024");
for (;;) {
echo $receiver->recv() . PHP_EOL;
echo $receiver2->recv() . PHP_EOL;
}
cnt.php and cnt2.php (same code, different ports)
$context = new ZMQContext;
$work = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
$work->bind('tcp://*:8022');
$work->send('Hello World');
cnt.php sends to 8022 and cnt2.php to 8024. They get executed from time to time and send messages to rep.php. However, some messages get stuck. If i sent 4 messages from cnt.php, nothing is received, but when i send 1 from cnt2.php, i get 5 messages at once. Any ideas?
I am no PHP expert here but guessing the syntax and functionality. Please correct me if I am wrong
echo $receiver->recv() . ' - ' . $receiver2->recv();
recv() should be a blocking call.
$receiver->recv() blocks until some message is received.
But echo does not echo the message immediately
You are again blocked on $receiver2->recv()
Only when you send message from the other file does echo work because it is waiting on $receiver2->recv()
Since you want to process the socket recv() independently, you should use polling or event based asynchronous I/O.
[Attempted solution]
$poll = new ZMQPoll();
$poll->add($receiver, ZMQ::POLL_IN);
$poll->add($receiver2, ZMQ::POLL_IN);
$readable = $writeable = array();
while(true) {
$events = $poll->poll($readable, $writeable);
foreach($readable as $socket) {
$message = $socket->recv();
echo $message, PHP_EOL;
}
}
Adapted from : http://zguide.zeromq.org/php:rrbroker

Resources