PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/bin/runtests

https://bitbucket.org/wez/mtrack/
Perl | 367 lines | 339 code | 19 blank | 9 comment | 29 complexity | b927bb61114dd7d7434670773ce6709c MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. #!/usr/bin/env perl
  2. # vim:ts=2:sw=2:et:ft=perl:
  3. # For copyright and licensing terms, see the file named LICENSE
  4. #
  5. # This is still in early development; makes assumptions about wez's dev env.
  6. # if you're truly interested in this aspect of mtrack, discuss it with wez!
  7. use strict;
  8. use Cwd qw(abs_path getcwd);
  9. use Getopt::Long;
  10. use Data::Dumper;
  11. use Sys::Hostname;
  12. use File::Basename;
  13. use IO::File;
  14. eval "use LWP::UserAgent;";
  15. my $root = abs_path(getcwd());
  16. my $http_port = 8081;
  17. my $ssh_port = 8082;
  18. my $solr_port = 8083;
  19. my $use_solr = 0;
  20. my $use_selenium = 0;
  21. my $use_sshd = 0;
  22. my $use_pg = 0;
  23. # System detection
  24. my $apache_server_root;
  25. my $httpd;
  26. my $coverage = 0;
  27. my $nocrap = '/Users/wez/src/nocrap/nocrap';
  28. GetOptions(
  29. "coverage" => \$coverage,
  30. "nocrap=s" => \$nocrap,
  31. "solr" => \$use_solr,
  32. "selenium" => \$use_selenium,
  33. "pg|postgres" => \$use_pg,
  34. "sshd" => \$use_sshd,
  35. );
  36. $ENV{INCUB_MIME_TYPES_FILE} = "";
  37. if ($^O eq 'darwin') {
  38. $apache_server_root = '/usr/libexec/apache2';
  39. $httpd = '/usr/sbin/httpd';
  40. } elsif ($^O eq 'solaris') {
  41. $httpd = '/opt/apache22/bin/i386/httpd';
  42. $apache_server_root = "/opt/apache22/libexec/i386";
  43. $ENV{INCUB_MIME_TYPES_FILE} = "TypesConfig /opt/apache22/conf/mime.types";
  44. $ENV{PATH} = "/opt/php5/bin/i386:" . $ENV{PATH};
  45. $ENV{INCUB_PHP_RUNNER} = "/opt/msys/3rdParty/bin/php53";
  46. } else {
  47. die("Don't know how to find required test bits for $^O\n");
  48. }
  49. my $selenium_url = 'http://selenium.googlecode.com/files/selenium-server-standalone-2.13.0.jar';
  50. my $solr_url = 'http://www.gtlib.gatech.edu/pub/apache//lucene/solr/3.4.0/apache-solr-3.4.0.tgz';
  51. $ENV{INCUB_HOSTNAME} = hostname();
  52. $ENV{INCUB_ROOT} = $root;
  53. $ENV{INCUB_APACHE_SERVER_ROOT} = $apache_server_root;
  54. $ENV{INCUB_APACHE_PORT} = $http_port;
  55. $ENV{INCUB_SSH_PORT} = $ssh_port;
  56. if ($use_selenium =~ m/^http/) {
  57. $ENV{INCUB_WEBDRIVER} = $use_selenium;
  58. } elsif ($use_selenium) {
  59. $ENV{INCUB_WEBDRIVER} = "http://$ENV{INCUB_HOSTNAME}:4444/wd/hub";
  60. }
  61. if ($coverage) {
  62. # you need "nocrap" for coverage data
  63. # https://bitbucket.org/wez/nocrap/
  64. $ENV{INCUB_COVERAGE} = $nocrap;
  65. system($nocrap, 'init');
  66. }
  67. my $selenium_pid;
  68. sub stop_selenium {
  69. if ($selenium_pid) {
  70. print("# Stopping selenium $selenium_pid\n");
  71. kill 'TERM', $selenium_pid;
  72. }
  73. }
  74. sub start_selenium {
  75. if (! -f "build/" . basename($selenium_url)) {
  76. chdir("build");
  77. system('wget', $selenium_url);
  78. chdir('..');
  79. }
  80. $selenium_pid = fork();
  81. if ($selenium_pid == 0) {
  82. open STDOUT, ">build/selenium.log";
  83. open STDERR, ">&STDOUT";
  84. exec('java', '-jar', "build/" . basename($selenium_url),
  85. '-host', $ENV{INCUB_HOSTNAME});
  86. exit(0);
  87. }
  88. }
  89. END {
  90. stop_selenium();
  91. }
  92. my $solr_pid;
  93. sub stop_solr {
  94. if ($solr_pid) {
  95. print("# Stopping solr $solr_pid\n");
  96. kill 'TERM', $solr_pid;
  97. }
  98. }
  99. sub start_solr {
  100. $ENV{INCUB_SOLR_PORT} = $solr_port;
  101. if (! -f "build/" . basename($solr_url)) {
  102. chdir("build");
  103. system('wget', $solr_url);
  104. chdir('..');
  105. }
  106. if (! -d "build/solr/run") {
  107. system("build/solr/extract-solr", "build/" . basename($solr_url));
  108. }
  109. $solr_pid = fork();
  110. if ($solr_pid == 0) {
  111. open STDOUT, ">build/solr.log";
  112. open STDERR, ">&STDOUT";
  113. system("rm", "-rf", "$root/build/solr/run/data");
  114. mkdir("$root/build/solr/run/data");
  115. exec('java',
  116. "-Dsolr.solr.home=$root/build/solr/run",
  117. "-Djetty.port=$solr_port",
  118. "-Djetty.home=$root/build/solr/run",
  119. "-Djetty.logs=$root/build/solr/run/logs",
  120. "-Dsolr.data.dir=$root/build/solr/run/data",
  121. "-jar", "$root/build/solr/run/start.jar");
  122. exit(1);
  123. }
  124. }
  125. END {
  126. stop_solr();
  127. }
  128. sub start_apache {
  129. if (-f "build/httpd/apache.pid") {
  130. print("# Stopping lingering apache\n");
  131. system($httpd, '-f', "$root/build/httpd/apache.conf", '-k', 'stop');
  132. sleep(5);
  133. }
  134. print("# Starting apache\n");
  135. system($httpd, '-f', "$root/build/httpd/apache.conf", '-k', 'start');
  136. }
  137. sub stop_apache {
  138. print("# Stopping apache\n");
  139. system($httpd, '-f', "$root/build/httpd/apache.conf", '-k', 'stop');
  140. }
  141. my $sshd_pid;
  142. sub start_sshd {
  143. print("# Starting sshd\n");
  144. $sshd_pid = fork();
  145. if ($sshd_pid eq 0) {
  146. mkdir("$root/build/ssh");
  147. open STDOUT, ">build/ssh/sshd.log";
  148. open STDERR, ">&STDOUT";
  149. if (! -f "$root/build/ssh/host_key") {
  150. system("ssh-keygen", "-f", "$root/build/ssh/host_key",
  151. "-q", "-t", "rsa", "-C", "", '-N', '');
  152. }
  153. exec('/usr/sbin/sshd', '-D', '-e', '-h', "$root/build/ssh/host_key",
  154. "-p", $ssh_port, "-o", "AuthorizedKeysFile=$root/build/ssh/keys",
  155. "-o", "PidFile=$root/build/ssh/pid"
  156. );
  157. exit(1);
  158. }
  159. }
  160. sub stop_sshd {
  161. if ($sshd_pid) {
  162. print("# Stopping sshd\n");
  163. kill 'TERM', $sshd_pid;
  164. }
  165. }
  166. END {
  167. stop_sshd();
  168. }
  169. my $pg_started = 0;
  170. sub start_pg {
  171. $ENV{INCUB_PG_PORT} = 8084;
  172. $ENV{INCUB_DSN} = "pgsql:dbname=mtrack;host=127.0.0.1";
  173. $ENV{PGPORT} = 8084;
  174. if (-d "$root/build/pgdata") {
  175. system("rm -rf $root/build/pgdata");
  176. }
  177. $pg_started = 1;
  178. system("pg_ctl initdb -D $root/build/pgdata >$root/build/pg.log 2>&1");
  179. my $fh = IO::File->new(">>$root/build/pgdata/postgresql.conf");
  180. print $fh "\nport = 8084\n";
  181. $fh->close();
  182. system("pg_ctl start -D $root/build/pgdata -l $root/build/pg.log");
  183. wait_for_port($ENV{INCUB_PG_PORT}, "Waiting for postgres to come up");
  184. system("createdb -p $ENV{INCUB_PG_PORT} -E=UTF-8 mtrack");
  185. }
  186. sub stop_pg {
  187. if ($pg_started) {
  188. system("pg_ctl stop -D $root/build/pgdata -m immediate");
  189. }
  190. }
  191. END {
  192. stop_pg();
  193. }
  194. sub cleanup {
  195. # remove server side coverage data from prior run
  196. foreach my $cov (<build/.covdata/*>) {
  197. unlink($cov);
  198. }
  199. }
  200. start_selenium() if $use_selenium;
  201. start_solr() if $use_solr;
  202. start_sshd() if $use_sshd;
  203. start_pg() if $use_pg;
  204. cleanup();
  205. sub init_instance {
  206. my $vardir = "$root/build/var";
  207. system("rm -rf $vardir");
  208. mkdir($vardir);
  209. $ENV{MTRACK_CONFIG_FILE} = "$vardir/config.ini";
  210. my $dsn = '';
  211. if ($ENV{INCUB_DSN}) {
  212. $dsn = " --dsn '$ENV{INCUB_DSN}'";
  213. }
  214. system("./bin/setup $dsn --vardir $vardir --config-file $vardir/config.ini --http-user-pass admin admin >$vardir/init.log 2>&1");
  215. if ($?) {
  216. print STDERR "Failed to init\n";
  217. system("cat $vardir/init.log");
  218. exit(1);
  219. }
  220. my $search_engine = $use_solr ?
  221. 'MTrackSearchEngineSolr' : 'MTrackSearchEngineLucene';
  222. # we have to put this in runtime.config because php's parse_ini_file
  223. # routine will clobber prior values when it encounters a second [section]
  224. # in an ini file...
  225. my $fh = IO::File->new(">>$vardir/runtime.config");
  226. print $fh <<INI;
  227. [core]
  228. weburl="http://$ENV{INCUB_HOSTNAME}:$http_port/"
  229. search_engine = $search_engine
  230. admin_party = false
  231. [repos]
  232. serverurl="$ENV{INCUB_HOSTNAME}:$ssh_port"
  233. authorized_keys2="$root/build/ssh/keys"
  234. [solr]
  235. url = "http://$ENV{INCUB_HOSTNAME}:$solr_port/solr"
  236. INI
  237. $fh->close();
  238. undef($fh);
  239. }
  240. init_instance();
  241. start_apache();
  242. sub wait_for_port {
  243. my ($port, $msg) = @_;
  244. use IO::Socket::INET;
  245. for my $i (1..15) {
  246. my $sock = IO::Socket::INET->new(
  247. PeerAddr => '127.0.0.1',
  248. PeerPort => $port,
  249. Proto => 'tcp');
  250. return if $sock;
  251. if ($i eq 1) {
  252. print("# $msg\n");
  253. }
  254. sleep(2);
  255. }
  256. die("Timed out waiting for port $port");
  257. }
  258. sub wait_for_url {
  259. my ($url, $msg) = @_;
  260. my $ua;
  261. eval {
  262. $ua = LWP::UserAgent->new;
  263. $ua->timeout(10);
  264. };
  265. for my $i (1..6) {
  266. if (!defined($ua)) {
  267. system("curl -s --retry-delay 2 --retry 6 --retry-max-time 15 $url >/dev/null");
  268. if ($? == 0) {
  269. return;
  270. }
  271. } else {
  272. my $r = $ua->get($url);
  273. return if $r->is_success;
  274. }
  275. if ($i eq 1) {
  276. print("# $msg\n");
  277. }
  278. sleep(2);
  279. }
  280. die("Timed out waiting for a response from $url");
  281. }
  282. wait_for_url($ENV{INCUB_WEBDRIVER} . "/status",
  283. "Waiting for Selenium to come up") if $selenium_pid;
  284. wait_for_url("http://$ENV{INCUB_HOSTNAME}:$http_port/mtrack.css",
  285. "Waiting for Apache to be ready");
  286. wait_for_url("http://$ENV{INCUB_HOSTNAME}:$solr_port/solr/admin/ping",
  287. "Waiting for Solr to be ready") if $solr_pid;
  288. if (@ARGV eq 0) {
  289. push @ARGV, 't';
  290. }
  291. if ($^O eq 'solaris') {
  292. use File::Find;
  293. my @tests;
  294. sub collect_tests {
  295. my ($t) = @_;
  296. if (-d $t) {
  297. find({
  298. wanted => sub {
  299. if (-f $File::Find::name) {
  300. collect_tests($File::Find::name);
  301. }
  302. },
  303. no_chdir => 1
  304. }, $t);
  305. } else {
  306. if ($t =~ m/\.php$/) {
  307. push @tests, $t;
  308. }
  309. }
  310. }
  311. for (@ARGV) {
  312. collect_tests($_);
  313. }
  314. for (@tests) {
  315. system("bin/prove-php", $_);
  316. }
  317. } else {
  318. system("prove", "-e", "bin/prove-php", '--ext', '.php', '-v', '-r', @ARGV);
  319. }
  320. stop_apache();
  321. if ($coverage) {
  322. system($nocrap, 'compute');
  323. }