diff --git a/.travis.yml b/.travis.yml index 14781c9d5..2be32504e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,11 @@ -# This file was adapted from work by Keith James (keithj) + +# This file was adapted from work by Keith James (keithj). The original source +# can be found as part of the wtsi-npg/data_handling project here: +# +# https://github.com/wtsi-npg/data_handling +# +# iRODS setup added by Iain Bancarz (ib5), adapted from baton: +# https://github.com/wtsi-npg/baton sudo: required @@ -8,17 +15,35 @@ perl: - "5.16" - "5.22-shrplib" +addons: + postgresql: "9.3" + env: global: + - secure: cDfB188ECmloGfScZQezqwiFef7l+gXgn2RiTOxINriy9wYS6RmZxuZBHGuR36u7QV3QEJtMdihyQ+XBN2eQPf5jULQXV15t7gArXEVPzzF8i+f8MTgVHugU3TqmPLQkY94wBBbpzvRD9xCAC/uNiQcLLwuD2SjPfTXkqgqqtd0= + - PGVERSION="9.3" + - DISPOSABLE_IRODS_VERSION="1.2" + - JANSSON_VERSION="2.7" + - BATON_VERSION="0.17.0" + - TRAVIS_NODE_VERSION="4.5.0" + - RENCI_URL=ftp://ftp.renci.org - WTSI_NPG_GITHUB_URL=https://github.com/wtsi-npg + matrix: - - TRAVIS_NODE_VERSION="4.5.0" + - IRODS_VERSION=3.3.1 IRODS_RIP_DIR=/usr/local/irods + - IRODS_VERSION=4.1.10 PG_PLUGIN_VERSION=1.10 PLATFORM=ubuntu12 before_install: - - ./.travis/before_install_mysql57.sh - - ./.travis/before_install.sh + - ./.travis/before_install_mysql57.sh + - ./.travis/before_install.sh + install: - - ./.travis/install.sh + - ./.travis/install.sh + script: - - ./.travis/script.sh + - export PATH=$IRODS_RIP_DIR/iRODS/clients/icommands/bin:$PATH + - ienv + - ils + - ilsresc -l + - ./.travis/script.sh diff --git a/.travis/install.sh b/.travis/install.sh index 4a6d17992..8d2b72193 100755 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -4,9 +4,16 @@ # can be found as part of the wtsi-npg/data_handling project here: # # https://github.com/wtsi-npg/data_handling +# +# iRODS setup added by Iain Bancarz (ib5), adapted from baton: +# https://github.com/wtsi-npg/baton set -e -x +# The default build branch for all repositories. This defaults to +# TRAVIS_BRANCH unless set in the Travis build environment. +WTSI_NPG_BUILD_BRANCH=${WTSI_NPG_BUILD_BRANCH:=$TRAVIS_BRANCH} + sudo apt-get install libgd2-xpm-dev # For npg_tracking sudo apt-get install liblzma-dev # For npg_qc sudo apt-get install --yes nodejs @@ -17,24 +24,59 @@ cpanm --quiet --notest --reinstall ExtUtils::ParseXS cpanm --quiet --notest --reinstall MooseX::Role::Parameterized cpanm --quiet --notest Alien::Tidyp -# Git branch to merge to or custom branch -WTSI_NPG_BUILD_BRANCH=${WTSI_NPG_BUILD_BRANCH:=$TRAVIS_BRANCH} +# iRODS +wget -q https://github.com/wtsi-npg/disposable-irods/releases/download/${DISPOSABLE_IRODS_VERSION}/disposable-irods-${DISPOSABLE_IRODS_VERSION}.tar.gz -O /tmp/disposable-irods-${DISPOSABLE_IRODS_VERSION}.tar.gz +tar xfz /tmp/disposable-irods-${DISPOSABLE_IRODS_VERSION}.tar.gz -C /tmp +cd /tmp/disposable-irods-${DISPOSABLE_IRODS_VERSION} +./scripts/download_and_verify_irods.sh +./scripts/install_irods.sh +./scripts/configure_irods.sh + +# Jansson +wget -q https://github.com/akheron/jansson/archive/v${JANSSON_VERSION}.tar.gz -O /tmp/jansson-${JANSSON_VERSION}.tar.gz +tar xfz /tmp/jansson-${JANSSON_VERSION}.tar.gz -C /tmp +cd /tmp/jansson-${JANSSON_VERSION} +autoreconf -fi +./configure ; make ; sudo make install +sudo ldconfig + +# baton +wget -q https://github.com/wtsi-npg/baton/releases/download/${BATON_VERSION}/baton-${BATON_VERSION}.tar.gz -O /tmp/baton-${BATON_VERSION}.tar.gz +tar xfz /tmp/baton-${BATON_VERSION}.tar.gz -C /tmp +cd /tmp/baton-${BATON_VERSION} + +IRODS_HOME= +baton_irods_conf="--with-irods" + +if [ -n "$IRODS_RIP_DIR" ] +then + export IRODS_HOME="$IRODS_RIP_DIR/iRODS" + baton_irods_conf="--with-irods=$IRODS_HOME" +fi + +./configure ${baton_irods_conf} ; make ; sudo make install +sudo ldconfig + # WTSI NPG Perl repo dependencies -repos="perl-dnap-utilities ml_warehouse npg_tracking npg_seq_common" +for repo in perl-dnap-utilities ml_warehouse npg_tracking npg_seq_common perl-irods-wrap; do + cd /tmp + # Always clone master when using depth 1 to get current tag + git clone --branch master --depth 1 ${WTSI_NPG_GITHUB_URL}/${repo}.git ${repo}.git + cd /tmp/${repo}.git + # Shift off master to appropriate branch (if possible) + git ls-remote --heads --exit-code origin ${WTSI_NPG_BUILD_BRANCH} && git pull origin ${WTSI_NPG_BUILD_BRANCH} && echo "Switched to branch ${WTSI_NPG_BUILD_BRANCH}" + repos=$repos" /tmp/${repo}.git" +done + +# Finally, bring any common dependencies up to the latest version and +# install for repo in $repos do - # Logic of keeping branch consistent was taken from @dkj - # contribution to https://github.com/wtsi-npg/npg_irods - cd /tmp - # Always clone master when using depth 1 to get current tag - git clone --branch master --depth 1 ${WTSI_NPG_GITHUB_URL}/${repo}.git ${repo}.git - cd /tmp/${repo}.git - # Shift off master to appropriate branch (if possible) - git ls-remote --heads --exit-code origin ${WTSI_NPG_BUILD_BRANCH} && git pull origin ${WTSI_NPG_BUILD_BRANCH} && echo "Switched to branch ${WTSI_NPG_BUILD_BRANCH}" - cpanm --quiet --notest --installdeps . || find /home/travis/.cpanm/work -cmin -1 -name '*.log' -exec tail -n20 {} \; - perl Build.PL - ./Build - ./Build install + cd $repo + cpanm --quiet --notest --installdeps . || find /home/travis/.cpanm/work -cmin -1 -name '*.log' -exec tail -n20 {} \; + perl Build.PL + ./Build + ./Build install done -cd "$TRAVIS_BUILD_DIR" +cd $TRAVIS_BUILD_DIR diff --git a/.travis/script.sh b/.travis/script.sh index 790b4ef30..0a306574e 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -5,6 +5,10 @@ set -e -x unset PERL5LIB export PATH=/home/travis/.nvm/versions/node/v${TRAVIS_NODE_VERSION}/bin:$PATH +export TEST_AUTHOR=1 +export WTSI_NPG_iRODS_Test_irodsEnvFile=$HOME/.irods/.irodsEnv +export WTSI_NPG_iRODS_Test_IRODS_ENVIRONMENT_FILE=$HOME/.irods/irods_environment.json +export WTSI_NPG_iRODS_Test_Resource=testResc cpanm --notest --installdeps . || find /home/travis/.cpanm/work -cmin -1 -name '*.log' -exec tail -n20 {} \; perl Build.PL diff --git a/MANIFEST b/MANIFEST index ba6763db4..a79558926 100644 --- a/MANIFEST +++ b/MANIFEST @@ -291,7 +291,6 @@ lib/npg_qc/Schema/ResultSet.pm lib/npg_qc/Schema/ResultSet/MqcOutcomeEnt.pm lib/npg_qc/util.pm lib/npg_qc/utils/bam_genotype.pm -lib/npg_qc/utils/iRODS.pm lib/npg_qc/view/analysis.pm lib/npg_qc/view/cache_query.pm lib/npg_qc/view/create_xml.pm diff --git a/lib/npg_qc/autoqc/checks/genotype.pm b/lib/npg_qc/autoqc/checks/genotype.pm index dd27a9786..8ace8a991 100644 --- a/lib/npg_qc/autoqc/checks/genotype.pm +++ b/lib/npg_qc/autoqc/checks/genotype.pm @@ -9,10 +9,11 @@ use List::MoreUtils qw { any }; use File::Slurp; use JSON; use npg_qc::utils::bam_genotype; -use npg_qc::utils::iRODS; use npg_qc::autoqc::types; use Readonly; use FindBin qw($Bin); +use Try::Tiny; +use WTSI::NPG::iRODS::DataObject; extends qw(npg_qc::autoqc::checks::check); with qw(npg_tracking::data::reference::find @@ -21,6 +22,14 @@ with qw(npg_tracking::data::reference::find our $VERSION = '0'; +has 'irods' => + (is => 'ro', + isa => 'WTSI::NPG::iRODS', + required => 1, + default => sub { + return WTSI::NPG::iRODS->new; + },); + Readonly::Scalar our $HUMAN_REFERENCES_DIR => q[Homo_sapiens]; Readonly::Scalar my $GENOTYPE_DATA => 'sgd'; Readonly::Scalar my $SAMTOOLS_NAME => q[samtools_irods]; @@ -331,40 +340,44 @@ has 'input_files_md5' => ( lazy_build => 1, ); sub _build_input_files_md5 { - my ($self) = @_; - my $md5 = q{}; - Readonly::Scalar my $IRODS_PREFIX_LEN_IS_THIS_READABLE_ENOUGH => 6; - - my @md5_vals = (); - for my $input_file (@{$self->input_files}) { - if($input_file =~ /^irods:/smx) { - my $irods_filename = substr $input_file, $IRODS_PREFIX_LEN_IS_THIS_READABLE_ENOUGH; # strip leading "irods:" - - $md5 = npg_qc::utils::iRODS->new->get_file_md5($irods_filename); - - $md5 ||= '0000000000000000'; - - push @md5_vals, $md5; - } - else { - my $md5_file = "${input_file}.md5"; - - $md5 = q{}; - if(-r $md5_file) { - open my $f, '<', $md5_file or croak "$md5_file readable, but open fails"; - - $md5 = <$f>; - - close $f or croak "Failed to close $md5_file"; - - } - $md5 ||= '0000000000000000'; - push @md5_vals, $md5; - } - - } + my ($self) = @_; + my $md5; + Readonly::Scalar my $IRODS_PREFIX_LEN_IS_THIS_READABLE_ENOUGH => 6; + + my @md5_vals = (); + for my $input_file (@{$self->input_files}) { + $md5 = q{}; + if ($input_file =~ /^irods:/smx) { + my $irods_filename = substr $input_file, $IRODS_PREFIX_LEN_IS_THIS_READABLE_ENOUGH; # strip leading "irods:" + try { + my $data_obj = WTSI::NPG::iRODS::DataObject->new( + $self->irods, $irods_filename + ); + $md5 = $data_obj->checksum; + } catch { + my $msg = 'Unable to find md5 checksum for '. + "iRODS file '$irods_filename': $_"; + carp($msg); + $md5 = '0000000000000000'; + } + } else { + my $md5_file = "${input_file}.md5"; + if(-r $md5_file) { + open my $f, '<', $md5_file or croak "$md5_file readable, but open fails"; + $md5 = <$f>; + chomp $md5; + close $f or croak "Failed to close $md5_file"; + } + if (! $md5) { + my $msg = "Unable to read md5 checksum from file '$md5_file'"; + carp($msg); + $md5 = '0000000000000000'; + } + } + push @md5_vals, $md5; + } - return join q[;], @md5_vals; + return join q[;], @md5_vals; } ##################################################################################################################### diff --git a/lib/npg_qc/autoqc/checks/tags_reporters.pm b/lib/npg_qc/autoqc/checks/tags_reporters.pm index 7e7dc7a1e..cef0e8abc 100644 --- a/lib/npg_qc/autoqc/checks/tags_reporters.pm +++ b/lib/npg_qc/autoqc/checks/tags_reporters.pm @@ -8,7 +8,6 @@ use File::Slurp; use File::Spec::Functions qw(catfile catdir); use List::MoreUtils qw(any); use JSON; -use npg_qc::utils::iRODS; use npg_qc::autoqc::types; use Readonly; diff --git a/lib/npg_qc/autoqc/checks/upstream_tags.pm b/lib/npg_qc/autoqc/checks/upstream_tags.pm index 158364b5f..aca5f92ba 100644 --- a/lib/npg_qc/autoqc/checks/upstream_tags.pm +++ b/lib/npg_qc/autoqc/checks/upstream_tags.pm @@ -14,7 +14,6 @@ use FindBin qw($Bin); use npg_qc::autoqc::checks::tag_metrics; use npg_qc::autoqc::qc_store; -use npg_qc::utils::iRODS; use npg_qc::autoqc::types; extends qw(npg_qc::autoqc::checks::check); diff --git a/lib/npg_qc/utils/iRODS.pm b/lib/npg_qc/utils/iRODS.pm deleted file mode 100755 index ac8992851..000000000 --- a/lib/npg_qc/utils/iRODS.pm +++ /dev/null @@ -1,324 +0,0 @@ -##no critic - -=head1 NAME - -npg_qc::utils::iRODS - -=head1 SYNOPSIS - -use npg_qc::utils::iRODS; - -=head1 DESCRIPTION - -Wrapper for iRODS (Integrated Rule Oriented Data Systems) icommands. -New sequencing data is written into the NPG iRODS system, and this module -provides a perl-friendly way to query, view, and retrieve those data. - -=head1 AUTHOR - -Jim Stalker jws@sanger.ac.uk - -Kevin Lewis kl2@sanger.ac.uk (adapted for use by vips) - -=cut - -package npg_qc::utils::iRODS; - -use strict; -use warnings; - -our $VERSION = '0'; - -# you need to install your .irodsEnv + .irodsA file on the server side in a -# given path . then in your code, you can set up the env variables -# "irodsEnvFile" and "irodsAuthFileName" with the function putenv where you -# give the full path name of the 2 connexion files. once you have that, please -# note that the "iinit" step is not required anymore. - -my %defaults = - ( - 'irodsEnvFile' => '~/.irods/.irodsEnv', -### 'irodsAuthFileName' => '/lustre/scratch102/conf/irodsA', - 'default_dest' => '/tmp', - 'ignore_errors' => 0, - ); - - -=head2 new - - Args [...] : key/value pairs allowing specific settings of instance variables. Currently these are: - 'irodsEnvFile' - the iRODS environment file [default: '~/.irods/.irodsEnv'] - 'default_dest' - where iget will put files [default: '/tmp'] - 'ignore_errors' - if non-zero, errors from ils commands will be ignored [[default: 0] - Example : my $irods = vips::iRODS->new('irodsEnvFile'=>'~/.irods/.irodsEnv'); - Returntype : vips::iRODS object - -=cut - -sub new { - my ($class, @args) = @_; - my $self = { %defaults, @args }; - bless($self,$class); - # set up iRODS environment? - - return $self; -} - -=head2 ipwd - - Returns current iRODS "working directory" - Args [0] : None - Example : my $pwd = $irods->ipwd; - Returntype : String - -=cut - -sub ipwd { - my ($self) = @_; - my $cmd = 'ipwd'; - my $out = `$cmd`; - - chomp $out; - - return $out; -} - -=head2 ils - - List file(s) - Arg [...] : optional directories or file names - Example : my @a = $irods->ils('/seq/5600', '/seq/620/620_1.bam'); - Returntype : array ref - -=cut - -sub ils { - my ($self, @targets) = @_; - my $cmd = 'ils'; - my @ret; - my @errvec = (); - - $cmd = join(' ', ($cmd, @targets)) if(@targets); - - open my $data, "$cmd 2>&1 |" or return [ "Error processing $cmd" ]; - my @a = <$data>; - close $data; - - chomp @a; - @a = map { s/^\s*//; s/\s*$//; $_; } @a; - my $dir = ''; - for my $item (@a) { - if($item =~ /^ERROR:/) { - push @errvec, $item; - } - elsif($item =~ /^(.*):$/) { # directory name - $dir = $1 . '/'; - } - else { - if($item =~ /^\//) { # file name already fully-qualified? - $dir = ''; - } - push @ret, "${dir}${item}"; - } - } - - die (@errvec) if(!$self->{ignore_errors} and @errvec); - - return \@ret; -} - -=head2 ils_wildcard - - List file(s) - either the "file_name" or (optional) "collection" parameters may contain - SQL-style wildcards. If "collection" is unspecified, the value specified by ipwd will - be used. - Arg [2] : filename, [collection] - Example : my @a = $irods->ils_wildcard('5630_%.ba%', '/seq/5630'); - Returntype : array ref - -=cut - -sub ils_wildcard { - my ($self, $file_pat, $coll_pat) = @_; - my @errvec = (); - - die "No file pattern specified" unless($file_pat); - - if(!$coll_pat) { $coll_pat = $self->ipwd }; - - my $cmd = qq(iquest "%s/%s" "select COLL_NAME, DATA_NAME where COLL_NAME like '$coll_pat' and DATA_NAME like '$file_pat'"); - - open my $data, "$cmd 2>&1 |" or return [ "Error processing $cmd" ]; - my @ret = <$data>; - close $data; - - chomp @ret; - @errvec = grep { /^ERROR: / } @ret; - die (@errvec) if(!$self->{ignore_errors} and @errvec); - - return \@ret; -} - -=head2 find_files_by_run_lane - - List file(s) - return the filename(s) specified by "run", (optionally) "lane and "tag_index" - only looks for sequence files (e.g. bams) and only the ones we want downstream - e.g. _phix or _human not included - Args [3] : run, lane, [tag_index] - Example : my @a = $irods->find_files_by_run_lane('5630_%.ba%', '/seq/5630'); - Returntype : array ref - -=cut - -sub find_files_by_run_lane { - my ($self, $run, $lane, $tag_index) = @_; - unless ($run){ - $self->throw("Missing parameter: run.\n"); - } - my $cmd = "imeta -z seq qu -d id_run = $run"; - $cmd .= " and lane = $lane" if ($lane); - $cmd .= " and tag_index = $tag_index" if ($tag_index); - - $cmd .= " and target = 1 "; ## 20/04/11 force choice to only the downstream files ! - - open(my $irods, "$cmd |"); - - my @out; - my $path = ''; - while (<$irods>) { - # output looks like: - #collection: /seq/5253 - #dataObj: 5253_1.bam - #---- - #collection: /seq/5253 - #dataObj: 5253_2.bam - # or - # No rows found - - if (/^collection: (.+)$/){ - $path = $1; - } - if (/^dataObj: (.+)$/){ - push @out, "$path/$1"; - } - } - close $irods; - return \@out; -} - -=head2 get_file_md5 - - List file(s) - return the md5 checksum for the specified file - Args [1] : filename - Example : my $md5 = $irods->get_file_md5('/seq/5630/5600_8.bam'); - Returntype : string - -=cut - -sub get_file_md5 { - my ($self, $file) = @_; - my $cmd = "ichksum $file"; - - my @md5 = `$cmd`; - chomp @md5; - $md5[0] =~s/.*\s//; - return $md5[0]; -} - - -=head2 get_file_size - - List file(s) - return the size of the specified file - Args [1] : filename - Example : my $size = $irods->get_file_size('/seq/5630/5600_8.bam'); - Returntype : number - -=cut - -sub get_file_size { - my ($self, $file) = @_; - my $cmd = "ils -l $file"; - - open(my $irods, "$cmd |"); - my $line = <$irods>; - # srpipe 0 res-g2 17084186273 2010-10-20.19:13 & 5330_1.bam - my @fields = split ' ', $line; - return $fields[3]; -} - -=head2 get_file - - List file(s) - fetch the specified file (to the optionally-specfied destination) - Args [2] : filename [, destination] - Example : my $size = $irods->get_file('/seq/5630/5600_8.bam', '~/bam_files'); - Returntype : exit status of iget command - -=cut - -sub get_file { - - my ($self, $file, $dest) = @_; - - $dest ||= $self->{default_dest}; - - die "Destination doesn't exist or is not directory: $dest" unless(-d $dest); - die "Destination not writeable: $dest" unless(-w $dest); - - my $cmd = "iget"; - my @args = ($cmd, "-K", "-f", $file, $dest); - ##my @args = ($cmd, "-K", "-Q", "-f", $file, $dest); - - return system(@args); -} - - -=head2 get_imeta_for_file - - Args [1] : filename - Example : my $atts = $irods->get_imeta_for_file('/seq/5630/5600_8.bam'); - Returntype : ref to hash - -=cut - -sub get_imeta_for_file{ - - my($self,$file) = @_; - - my $cmd = "imeta ls -d $file"; - - - my($at,$va,$un,); - my $atts = {}; - - if(open(my $irods, "$cmd |")){ - while(<$irods>){ - if(/attribute\:\s+(\S+)/){ - $at = $1; - } - if(/value\:\s+(\S+)/){ - $va = $1; - } - if(/units\:\s+(\S+)/){ - $un = $1; - } - if(/^----/ && $at =~ /\S/){ - $atts->{$at}->{'value'} = $va; - $atts->{$at}->{'units'} = $un if defined $un && $un =~ /\S/; - ($at,$va,$un) = ('','',''); - } - } - close $irods; - }else{ - die "cant run $cmd\n"; - } - - if($at =~ /\S/){ - $atts->{$at}->{'value'} = $va; - $atts->{$at}->{'units'} = $un if defined $un && $un =~ /\S/; - } - - return($atts); - -} - -1; diff --git a/t/60-autoqc-checks-genotype.t b/t/60-autoqc-checks-genotype.t index 3aefd0786..cdd03302c 100644 --- a/t/60-autoqc-checks-genotype.t +++ b/t/60-autoqc-checks-genotype.t @@ -2,12 +2,15 @@ use strict; use warnings; use Cwd; use File::Temp qw/ tempdir /; -use Test::More tests => 8; +use Test::More tests => 10; use Test::Exception; +use WTSI::NPG::iRODS; use_ok ('npg_qc::autoqc::checks::genotype'); my $ref_repos = cwd . '/t/data/autoqc'; +my $expected_md5 = q[a4790111996a3f1c0247d65f4998e492]; + my $dir = tempdir(CLEANUP => 1); my $st = join q[/], $dir, q[samtools_irods]; `touch $st`; @@ -16,22 +19,56 @@ my $bt = join q[/], $dir, q[bcftools1]; `touch $bt`; `chmod +x $bt`; local $ENV{PATH} = join q[:], $dir, $ENV{PATH}; +my $data_dir = $dir."/data"; +mkdir($data_dir); +`cp t/data/autoqc/alignment.bam $data_dir/2_1_1.bam`; +`echo -n $expected_md5 > $data_dir/2_1_1.bam.md5`; + +# create and populate a temporary iRODS collection +my $irods = WTSI::NPG::iRODS->new; +my $irods_tmp_coll; +my $irods_data_coll; +my $pid = $$; +$irods_tmp_coll = $irods->add_collection("GenotypeTest.$pid"); +$irods->put_collection($data_dir, $irods_tmp_coll); +$irods_data_coll = $irods_tmp_coll."/data"; { - - my $r = npg_qc::autoqc::checks::genotype->new( - repository => $ref_repos, id_run => 2, path => q[t], position => 1); + my $r; + + $r = npg_qc::autoqc::checks::genotype->new( + id_run => 2, + path => $data_dir, + position => 1, + repository => $ref_repos, + ); isa_ok ($r, 'npg_qc::autoqc::checks::genotype'); lives_ok { $r->result; } 'No error creating result object'; lives_ok {$r->samtools } 'No error calling "samtools" accessor'; is($r->samtools, $st, 'correct samtools path'); lives_ok {$r->bcftools } 'No error calling "bcftools" accessor'; is($r->bcftools, $bt, 'correct bcftools path'); + is($r->input_files_md5, $expected_md5, + "Local MD5 string matches expected value"); lives_ok {npg_qc::autoqc::checks::genotype->new( repository => $ref_repos, rpt_list => '2:1', path => q[t]); } 'object via the rpt_list'; + + my $irods_path = "irods:".$irods_data_coll."/2_1_1.bam"; + $r = npg_qc::autoqc::checks::genotype->new( + id_run => 2, + input_files => [$irods_path, ], + position => 1, + repository => $ref_repos, + ); + is($r->input_files_md5, $expected_md5, + "iRODS MD5 string matches expected value"); + } +# remove temporary iRODS collection +$irods->remove_collection($irods_tmp_coll); + 1;