perl syntax to access the constant variable in cgi script - perl

recently I was debugging a piece of code and found the following usage in the template tool kit usage in the template.
#Constants.pm
# Bugzilla version
use constant BUGZILLA_VERSION => "4.0.11";
#template file index.html.tmpl
[% PROCESS global/header.html.tmpl
header_addl_info = "version $constants.BUGZILLA_VERSION"
style_urls = [ 'skins/standard/index.css' ]
%]
#index.cgi
use Bugzilla::Constants;
.......
print "buzilla version : $constants.BUGZILLA_VERSION <br/>";
When I am using the same syntax in the main cgi script , giving error 500

print "buzilla version : ".Bugzilla::Constants::BUGZILLA_VERSION." <br/>";

'.' probably means something different in Template::Toolkit.
In Perl you just use BUGZILLA_VERSION:
$ perl -E 'use constant BUGZILLA_VERSION=>"4.0.11"; say BUGZILLA_VERSION'
4.0.11
$

Related

Perl and Selenium::Remote::Driver

EDITED AGAIN
I have a server on AWS somewhere in Northern Virginia and this is my monitoring server. I ssh into this Ubuntu server from another State to do system administration. I want to do web automation tests on this server which will test a web application on the Internet hitting a URL and verify that I can selenium test a login and authenticate successfully. This server is on an AWS cloud I'm not quite sure which Perl module to use since I'm accessing it remotely.
There are two CPAN modules: Selenium::Remote::Driver and WWW::Selenium. I have tried both and they are giving me issues. And I really don't know which is appropriate for my scenario. When I use Selenium::Remote::Driver, I get the following error:
Selenium server did not return proper status at /usr/local/share/perl/5.18.2/Selenium/Remote/Driver.pm line 401.
When I use WWW::Selenium, I get this error:
Failed to start new browser session: org.openqa.selenium.server.RemoteCommandException: Error while launching browser
I was able to launch firefox manually from the AWS monitoring server by exporting the DISPLAY but it was really slow. I have heard that I can use a headless browser but I would have to export the DISPLAY by:
export DISPLAY=:5
But remember, I'm sshing into this AWS/Selenium server from my desktop so I'm assuming I use the above command on the AWS/Selenium Server while I'm ssh into it from my desktop? Actually, at this point, I'm not sure I'm doing here. Can somebody help?
The problem in this type of questions is that the variety of configurations and binaries in your setup might be so broad that the it is hard to actually provide a straight and correct answer for YOUR SETUP.
This answer has the following assumptions:
you have downloaded the selenium-server-standalone.jar into /usr/lib/
you have jdk 1.8 ( run the java -version in the shell
you have installed and configured the xvfb-run ( it is a fight on it's own )
So :
```
# ssh to your server , obs the -X !
ssh -X user-name#server-name
# start the selenium-server-standalone on the server
xvfb-run -e /dev/stdout java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/lib/selenium-server-standalone.jar &
# one liner test - this is one veery long one
perl -e 'use strict ; use warnings ; use Data::Printer ; my $host="127.0.0.1"; use Selenium::Remote::Driver;my $driver = Selenium::Remote::Driver->new( "browser_name" =>"chrome", "error_handler" => sub { print $_[1]; croak 'goodbye'; }, "remote_server_addr" => "$host","port"=> "4444");$driver->debug_on();$driver->get("http://www.google.com"); print $driver->get_title();$driver->quit();' &
```
Here is the code in the one-liner as a perl script
#!/usr/bin/env perl
use strict ;
use warnings ;
use Carp ;
use Data::Printer ;
use Selenium::Remote::Driver;
my $host="127.0.0.1";
my $driver = Selenium::Remote::Driver->new(
"browser_name" =>"chrome"
, "error_handler" => sub { print $_[1]; croak 'goodbye' ; }
, "remote_server_addr" => "$host"
, "port"=> "4444") ;
$driver->debug_on() ;
$driver->get("http://www.google.com");
print $driver->get_title();
$driver->quit();
The output should look something like:
```
Prepping get
Executing get
REQ: POST, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/url, {"url":"http://www.google.com"}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
Prepping getTitle
Executing getTitle
REQ: GET, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/title, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":"Google"}
GooglePrepping quit
Executing quit
REQ: DELETE, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
```
Try running the below code:
#!/usr/bin/perl
use warnings;
use strict;
use Selenium::Remote::Driver;
my $host = "10.10.1.1"; //Enter your server IP in this place
my $driver = new Selenium::Remote::Driver('remote_server_addr' => $host,
'port' => '4444',
'auto_close' => 0);
$driver->get('http://www.google.com');

Using __END__ and DATA in Chef recipes (to run legacy shell scripts)

I'm migrating some shell scripts to Chef recipes. Some of these scripts are fairly involved, so just to make life easier in the short term and to avoid introducing bugs in rewriting everything in Chef/Ruby, I'd like to just run some of them as-is. They're all well-written and idempotent, so honestly there's no rush, but of course, the eventual goal is to rewrite them.
One cool feature of Ruby is its __END__ keyword/method: Lines below __END__ will not be executed. Those lines will be available via the special filehandle DATA.
It would be cool to ship the shell scripts as-is inside the the recipe after __END__, maybe something like the following, which I placed in chef-repo/cookbooks/ruby-data-test/recipes/default.rb:
file = Tempfile.new(File.basename(__FILE__))
file << DATA.read
bash file.path
file.unlink
__END__
echo "Hello, world"
However when I run this (with chef-solo -c solo.rb --override-runlist 'recipe[ruby-data-test]'), I get the following error:
[2014-10-03T17:14:56+00:00] ERROR: uninitialized constant Chef::Recipe::DATA
I'm pretty new to Chef, but I'm guessing the above is something about Chef wrapping my recipe in a class, and there's something simple preventing me from accessing DATA. Since it's "global" (?) I tried putting a dollar sign ($DATA) in front of it but that failed with:
NoMethodError
-------------
undefined method `read' for nil:NilClass
So the question is: How do I access DATA in my Chef recipe? Thanks!
It appears you don't have access to DATA, but you can fake it by reading in the current file yourself and splitting on __END__, like Sinatra does.
I ended up making a Chef LWRP for reuse. I don't know if I'll actually end up using this, but I wanted to figure it out. Like I said, I'm a Chef/Ruby noob, so any better ideas or suggestions welcome!
ruby_data_test/recipes/default.rb:
ruby_data_test_execute_ruby_data __FILE__
__END__
#!/bin/bash
set -o errexit
date
echo "Hello, world"
ruby_data_test/resources/execute_ruby_data.rb:
actions :execute_ruby_data
default_action :execute_ruby_data
attribute :source, :name_attribute => true, :required => true
attribute :args, :kind_of => Array
attribute :ignore_errors, :kind_of => [TrueClass, FalseClass], :default => false
ruby_data_test/providers/execute_ruby_data.rb:
def whyrun_supported?
true
end
use_inline_resources
action :execute_ruby_data do
converge_by("Executing #{#new_resource}") do
Chef::Log.info("Executing #{#new_resource}")
file_who_called_me = #new_resource.source
io = ::IO.respond_to?(:binread) ? ::IO.binread(file_who_called_me) : ::IO.read(file_who_called_me)
app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
data.lstrip!
file = Tempfile.new('execute_ruby_data')
file << data
file.chmod(0755)
file.close
exit_status = ::Open3.popen2e(file.path, *#new_resource.args) do |stdin, stdout_and_stderr, wait_thr|
stdout_and_stderr.each { |line| puts line }
wait_thr.value # exit status
end
if exit_status != 0 && !#new_resource.ignore_errors
throw RuntimeError
end
end
end
Here's the output:
$ chef-solo -c solo.rb --override-runlist 'recipe[ruby_data_test]'
Starting Chef Client, version 11.12.4
[2014-10-03T21:50:29+00:00] WARN: Run List override has been provided.
[2014-10-03T21:50:29+00:00] WARN: Original Run List: []
[2014-10-03T21:50:29+00:00] WARN: Overridden Run List: [recipe[ruby_data_test]]
Compiling Cookbooks...
Converging 1 resources
Recipe: ruby_data_test::default
* ruby_data_test_execute_ruby_data[/root/chef/chef-repo/cookbooks/ruby_data_test/recipes/default.rb] action execute_ruby_dataFri Oct 3 21:50:29 UTC 2014
Hello, world
- Executing ruby_data_test_execute_ruby_data[/root/chef/chef-repo/cookbooks/ruby_data_test/recipes/default.rb]
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 1.387608 seconds

Open2 Api failure while installing Mead software

I am running into some issues trying to install a software called MEAD . I would appreciate if someone could have alook .
I get the following error while installing
/mead/bin # ./mead.pl GA3
Using system rc-file: /home/karosh/mead/bin/../.meadrc
Warning: Can't find user rc-file
Cluster: /home/karosh/mead/bin/../data/GA3/GA3.cluster
open2: exec of /home/karosh/mead/bin/driver.pl failed at ./mead.pl line 230
THe mead software is not written by me so I have not changed any of the perl scrips . I line 230 in the driver.pl file is
sub run_mead {
my %options = #_;
my $reader = FileHandle->new();
my $writer = FileHandle->new();
unless ( open2($reader, $writer, "$FindBin::Bin/driver.pl") ) {
die "Unable to run MEAD.\n";
}
...
...
}
Does this error mean that open2 was not found . The mead folks have put the following line in the file:
use strict;
use File::Spec;
use FileHandle;
use IPC::Open2;
Or does it mean that i need to install the rpm that contains the API . I see that this API is a part of the core perl bundle http://perldoc.perl.org/IPC/Open2.html. So why was it not installed ? Do i need to install perl again .
Someone has earlier faced this problem - http://www.summarization.com/~radev/mead/email/0160.html but the solution is not working for me . I find no Perl files with the incorrect perl directives . The mead team has been dissolved and there is no one to ask questions but I need to use this software.
I think if some one can explain me the meaning of the error than I can do deeper. Anyone?
It probably means that .../driver.pl doesn't have execute permission. Change the file permissions or call it like
open2($reader, $writer, "perl $FindBin::Bin/driver.pl")
open2($reader, $writer, "$^X $FindBin::Bin/driver.pl")

Perl Rover v3 pass environment variable to in the Rulesets

I am using perl Rover module version 3 to login to the Linux/Unix server and run the script. In the ruleset if I add the full path name it copies the script to the remote server, not able to substitute the environment variable.
eg.
This works:
copy:{
put_file "/home/u1/find.sh" "/tmp/"
};
This didn't work:
copy:{
put_file "$HOME/find.sh" "/tmp/"
};
used $ENV{'HOME'}, this also didn't work.
How can I pass the environment variable?
Rover module document.
http://rover.sourceforge.net/QuickStart/Rover-QuickStart-3.html#ss3.2
http://rover.sourceforge.net/
After reviewing the source code for rover, which I never used, I determined it was not possible from the existing code.
I created a new extension for you, that has that functionality, it supports the ~ and ${HOME} syntax, (which are bash extensions and not part of the OS directly, that is why perl does not support them).
code is here:
https://github.com/h4ck3rm1k3/perl-rover/commit/2c78aefb97e819956bb665b04056763f8df1b242
I have had a hard time testing it because I never used rover before, and rover does not seem to support scp.(I read it is supported,but could not test it yet.) Anyway, let me know if you like it. I will put more work into it if reasonably requested.
Update
Here is my example ruleset :
example ruleset
[rulesets]
test:
{
put_file_from_home put_file "~/find2.sh" "/tmp/"
put_file_from_home put_file "${HOME}/find3.sh" "/tmp/"
}, ;
example output
Here is the example output, I cannot get rover to work. See the test case below.
Test output
perl -I lib t/example2.t
Local was ~/find2.sh and home was /home/mdupont at lib/Rover/CoreExtension.pm line 19.
Local now /home/mdupont/find2.sh at lib/Rover/CoreExtension.pm line 22.
Local was ${HOME}/find3.sh and home was /home/mdupont at lib/Rover/CoreExtension.pm line 19.
Local now /home/mdupont/find3.sh at lib//Rover/CoreExtension.pm line 22.
new config option for the new sshport option
[hosts]
someexample:{
os linux
username myusername
description 'myhost'
sshport 12345
ftp_method_used sftp
};
update2
Dont use quotes around the name, use a comma between the args,
To git#github.com:h4ck3rm1k3/perl-rover.git
2207417..7637741 CoreExtension -> CoreExtension
[rulesets]
test: { put_file_from_home ~/find2.sh,/tmp/ }, ;
[hosts]
localhost:{
os linux
username mdupont
description 'localhost'
ftp_methods sftp
ftp_method_used sftp };
mike
Old question but new answer, since your using Rover v3 you can just extend the Rover::Core modules by overloading it.
Add this to your ~/.rover/contrib directory:
CoreVariables.pm:
package CoreVariables;
use strict;
use Exporter;
our #ISA = qw( Exporter );
our #EXPORT = qw( put_file );
sub put_file {
my ($self, $host, $command) = #_;
$command =~ s/(\$[\w{}]+)/$1/eeg;
return Rover::Core::put_file($self, $host, $command);
}
And add the following to your ~/.rover/config [modules] section (must be after Rover::Core):
CoreVariables:{
};
And then you can store environment variables in your rover config when using put_file. Add other routines if you wish, this only extends put_file.
And since this is such an easy task I will add it to the requested feature list and include it in the next release (I am the Rover author).
The better place to ask Rover questions is on the sourceforge website of course: http://sourceforge.net/projects/rover/

Why does my Perl unit test fail in EPIC but work in the debugger?

Has anyone ever experienced a unit test that fails and when they tried to debug it to find out where the failure was occurring, the unit test succeeds when running the code in the debugger?
I'm using Eclipse 3.5.1 with EPIC 0.6.35 and ActiveState ActivePerl 5.10.0. I wrote module A and module B both with multiple routines. A routine in module B calls a bunch of routines from module A. I'm adding mock objects to my module B unit test file to try to get more complete code coverage on module B where the code in module B tests to see if all the calls to module As routines fail or succeed. So I added some mock objects to my unit test to force some of the module A routines to return failures, but I was not getting the failures as expected. When I debugged my unit test file, the calls to the module A routine did fail as expected (and my unit test succeeds). When I run the unit test file as normal without debugging, the call to the mocked Module A routine does not fail as expected (and my unit test fails).
What could be going on here? I'll try to post a working example of my problem if I can get it to fail using a small set of simple code.
ADDENDUM: I got my code whittled down to a bare minimum set that demonstrates my problem. Details and a working example of the problem follows:
My Eclipse project contains a "lib" directory with two modules ... MainModule.pm and UtilityModule.pm. My Eclipse project also contains at the top level a unit test file named MainModuleTest.t and a text file called input_file.txt which just contains some garbage text.
EclipseProject/
MainModuleTest.t
input_file.txt
lib/
MainModule.pm
UtilityModule.pm
Contents of the MainModuleTest.t file:
use Test::More qw(no_plan);
use Test::MockModule;
use MainModule qw( mainModuleRoutine );
$testName = "force the Utility Module call to fail";
# set up mock utility routine that fails
my $mocked = new Test::MockModule('UtilityModule');
$mocked->mock( 'slurpFile', undef );
# call the routine under test
my $return_value = mainModuleRoutine( 'input_file.txt' );
if ( defined($return_value) ) {
# failure; actually expected undefined return value
fail($testName);
}
else {
# this is what we expect to occur
pass($testName);
}
Contents of the MainModule.pm file:
package MainModule;
use strict;
use warnings;
use Exporter;
use base qw(Exporter);
use UtilityModule qw( slurpFile );
our #EXPORT_OK = qw( mainModuleRoutine );
sub mainModuleRoutine {
my ( $file_name ) = #_;
my $file_contents = slurpFile($file_name);
if( !defined($file_contents) ) {
# failure
print STDERR "slurpFile() encountered a problem!\n";
return;
}
print "slurpFile() was successful!\n";
return $file_contents;
}
1;
Contents of the UtilityModule.pm file:
package UtilityModule;
use strict;
use warnings;
use Exporter;
use base qw(Exporter);
our #EXPORT_OK = qw( slurpFile );
sub slurpFile {
my ( $file_name ) = #_;
my $filehandle;
my $file_contents = "";
if ( open( $filehandle, '<', $file_name ) ) {
local $/=undef;
$file_contents = <$filehandle>;
local $/='\n';
close( $filehandle );
}
else {
print STDERR "Unable to open $file_name for read: $!";
return;
}
return $file_contents;
}
1;
When I right-click on MainModuleTest.t in Eclipse and select Run As | Perl Local, it gives me the following output:
slurpFile() was successful!
not ok 1 - force the Utility Module call to fail
1..1
# Failed test 'force the Utility Module call to fail'
# at D:/Documents and Settings/[SNIP]/MainModuleTest.t line 13.
# Looks like you failed 1 test of 1.
When I right click on the same unit test file and select Debug As | Perl Local, it gives me the following output:
slurpFile() encountered a problem!
ok 1 - force the Utility Module call to fail
1..1
So, this is obviously a problem. Run As and Debug As should give the same results, right?!?!?
Both Exporter and Test::MockModule work by manipulating the symbol table. Things that do that don't always play nicely together. In this case, Test::MockModule is installing the mocked version of slurpFile into UtilityModule after Exporter has already exported it to MainModule. The alias that MainModule is using still points to the original version.
To fix it, change MainModule to use the fully qualified subroutine name:
my $file_contents = UtilityModule::slurpFile($file_name);
The reason this works in the debugger is that the debugger also uses symbol table manipulation to install hooks. Those hooks must be getting installed in the right way and at the right time to avoid the mismatch that occurs normally.
It's arguable that it's a bug (in the debugger) any time the code behaves differently there than it does when run outside the debugger, but when you have three modules all mucking with the symbol table it's not surprising that things might behave oddly.
Does your mocking manipulate the symbol table? I've seen a bug in the debugger that interferes with symbol table munging. Although in my case the problem was reversed; the code broke under the debugger but worked when run normally.