From eca09bc980b701717115b35e28cc9171d7dccca5 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Wed, 8 Dec 2021 13:31:34 -0500 Subject: [PATCH] Attempt to fix errors during test teardown --- t/View/TT.t | 20 ++---- t/evaluate-basic.t | 12 +--- t/lib/HydraTestContext.pm | 130 ++++++++++++++++++++++++++++++++++++++ t/lib/Setup.pm | 74 +++++----------------- 4 files changed, 156 insertions(+), 80 deletions(-) create mode 100644 t/lib/HydraTestContext.pm diff --git a/t/View/TT.t b/t/View/TT.t index 378bbbdb..a2401976 100644 --- a/t/View/TT.t +++ b/t/View/TT.t @@ -2,31 +2,25 @@ use feature 'unicode_strings'; use strict; use warnings; use Setup; - -my %ctx = test_init(); - -require Hydra::Schema; -require Hydra::Model::DB; - use Test2::V0; +my $ctx = test_context(); + require Hydra; # calls setup() - - -my $db = Hydra::Model::DB->new; -hydra_setup($db); - require Hydra::View::TT; +require Catalyst::Test; + +my $db = $ctx->db; + # The following lines are a cheap and hacky trick to get $c, # there is no other reason to call /. -require Catalyst::Test; Catalyst::Test->import('Hydra'); my ($_request, $c) = ctx_request('/'); my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"}); -my $jobset = createBaseJobset("example", "bogus.nix", $ctx{jobsdir}); +my $jobset = createBaseJobset("example", "bogus.nix", $ctx->jobsdir); my $job = "myjob"; diff --git a/t/evaluate-basic.t b/t/evaluate-basic.t index f4c6fde8..d3f21564 100644 --- a/t/evaluate-basic.t +++ b/t/evaluate-basic.t @@ -2,21 +2,15 @@ use feature 'unicode_strings'; use strict; use warnings; use Setup; - -my %ctx = test_init(); - -require Hydra::Schema; -require Hydra::Model::DB; - use Test2::V0; -my $db = Hydra::Model::DB->new; -hydra_setup($db); +my $ctx = test_context(); +my $db = $ctx->db; my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"}); # Most basic test case, no parameters -my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir}); +my $jobset = createBaseJobset("basic", "basic.nix", $ctx->jobsdir); ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0"); is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds"); diff --git a/t/lib/HydraTestContext.pm b/t/lib/HydraTestContext.pm new file mode 100644 index 00000000..3395f0a7 --- /dev/null +++ b/t/lib/HydraTestContext.pm @@ -0,0 +1,130 @@ +use strict; +use warnings; + +package HydraTestContext; +use File::Path qw(make_path); +use File::Basename; +use Cwd qw(abs_path getcwd); + +# Set up the environment for running tests. +# +# Hash Parameters: +# +# * hydra_config: configuration for the Hydra processes for your test. +# * nix_config: text to include in the test's nix.conf +# * use_external_destination_store: Boolean indicating whether hydra should +# use a destination store different from the evaluation store. +# True by default. +# +# This clears several environment variables and sets them to ephemeral +# values: a temporary database, temporary Nix store, temporary Hydra +# data directory, etc. +# +# Note: This function must run _very_ early, before nearly any Hydra +# libraries are loaded. To use this, you very likely need to `use Setup` +# and then run `test_init`, and then `require` the Hydra libraries you +# need. +# +# It returns a tuple: a handle to a temporary directory and a handle to +# the postgres service. If either of these variables go out of scope, +# those resources are released and the test environment becomes invalid. +# +# Look at the top of an existing `.t` file to see how this should be used +# in practice. +sub new { + my ($class, %opts) = @_; + + my $dir = File::Temp->newdir(); + + $ENV{'HYDRA_DATA'} = "$dir/hydra-data"; + mkdir $ENV{'HYDRA_DATA'}; + $ENV{'NIX_CONF_DIR'} = "$dir/nix/etc/nix"; + make_path($ENV{'NIX_CONF_DIR'}); + my $nixconf = "$ENV{'NIX_CONF_DIR'}/nix.conf"; + my $nix_config = "sandbox = false\n" . ($opts{'nix_config'} || ""); + write_file($nixconf, $nix_config); + $ENV{'HYDRA_CONFIG'} = "$dir/hydra.conf"; + + my $hydra_config = $opts{'hydra_config'} || ""; + if ($opts{'use_external_destination_store'} // 1) { + $hydra_config = "store_uri = file:$dir/nix/dest-store\n" . $hydra_config; + } + + write_file($ENV{'HYDRA_CONFIG'}, $hydra_config); + + $ENV{'NIX_LOG_DIR'} = "$dir/nix/var/log/nix"; + $ENV{'NIX_REMOTE_SYSTEMS'} = ''; + $ENV{'NIX_REMOTE'} = ''; + $ENV{'NIX_STATE_DIR'} = "$dir/nix/var/nix"; + $ENV{'NIX_STORE_DIR'} = "$dir/nix/store"; + + my $pgsql = Test::PostgreSQL->new( + extra_initdb_args => "--locale C.UTF-8" + ); + $ENV{'HYDRA_DBI'} = $pgsql->dsn; + system("hydra-init") == 0 or die; + + my $self = { + _db => undef, + db_handle => $pgsql, + tmpdir => $dir, + testdir => abs_path(dirname(__FILE__) . "/.."), + jobsdir => abs_path(dirname(__FILE__) . "/../jobs") + }; + + return bless $self, $class; +} + +sub db { + my ($self, $setup) = @_; + + + if (!defined $self->{_db}) { + require Hydra::Schema; + require Hydra::Model::DB; + $self->{_db} = Hydra::Model::DB->new(); + + if (!(defined $setup && $setup == 0)) { + $self->{_db}->resultset('Users')->create({ + username => "root", + emailaddress => 'root@invalid.org', + password => '' + }); + } + } + + return $self->{_db}; +} + +sub tmpdir { + my ($self) = @_; + + return $self->{tmpdir}; +} + +sub testdir { + my ($self) = @_; + + return $self->{testdir}; +} + +sub jobsdir { + my ($self) = @_; + + return $self->{jobsdir}; +} + +sub DESTROY +{ + my ($self) = @_; + $self->db(0)->schema->storage->disconnect(); +} + +sub write_file { + my ($path, $text) = @_; + open(my $fh, '>', $path) or die "Could not open file '$path' $!"; + print $fh $text || ""; + close $fh; +} + +1; diff --git a/t/lib/Setup.pm b/t/lib/Setup.pm index 983a8c56..3887784c 100644 --- a/t/lib/Setup.pm +++ b/t/lib/Setup.pm @@ -10,74 +10,32 @@ use File::Basename; use Cwd qw(abs_path getcwd); our @ISA = qw(Exporter); -our @EXPORT = qw(test_init hydra_setup write_file nrBuildsForJobset queuedBuildsForJobset +our @EXPORT = qw(test_context test_init hydra_setup write_file nrBuildsForJobset queuedBuildsForJobset nrQueuedBuildsForJobset createBaseJobset createJobsetWithOneInput evalSucceeds runBuild sendNotifications updateRepository captureStdoutStderr); # Set up the environment for running tests. # -# Hash Parameters: +# See HydraTestContext::new for documentation +sub test_context { + require HydraTestContext; + return HydraTestContext->new(@_); +} + +# Set up the environment for running tests. # -# * hydra_config: configuration for the Hydra processes for your test. -# * nix_config: text to include in the test's nix.conf -# * use_external_destination_store: Boolean indicating whether hydra should -# use a destination store different from the evaluation store. -# True by default. -# -# This clears several environment variables and sets them to ephemeral -# values: a temporary database, temporary Nix store, temporary Hydra -# data directory, etc. -# -# Note: This function must run _very_ early, before nearly any Hydra -# libraries are loaded. To use this, you very likely need to `use Setup` -# and then run `test_init`, and then `require` the Hydra libraries you -# need. -# -# It returns a tuple: a handle to a temporary directory and a handle to -# the postgres service. If either of these variables go out of scope, -# those resources are released and the test environment becomes invalid. -# -# Look at the top of an existing `.t` file to see how this should be used -# in practice. +# See HydraTestContext::new for documentation sub test_init { - my %opts = @_; + require HydraTestContext; + my $ctx = HydraTestContext->new(@_); - my $dir = File::Temp->newdir(); - - $ENV{'HYDRA_DATA'} = "$dir/hydra-data"; - mkdir $ENV{'HYDRA_DATA'}; - $ENV{'NIX_CONF_DIR'} = "$dir/nix/etc/nix"; - make_path($ENV{'NIX_CONF_DIR'}); - my $nixconf = "$ENV{'NIX_CONF_DIR'}/nix.conf"; - my $nix_config = "sandbox = false\n" . ($opts{'nix_config'} || ""); - write_file($nixconf, $nix_config); - $ENV{'HYDRA_CONFIG'} = "$dir/hydra.conf"; - - my $hydra_config = $opts{'hydra_config'} || ""; - if ($opts{'use_external_destination_store'} // 1) { - $hydra_config = "store_uri = file:$dir/nix/dest-store\n" . $hydra_config; - } - - write_file($ENV{'HYDRA_CONFIG'}, $hydra_config); - - $ENV{'NIX_LOG_DIR'} = "$dir/nix/var/log/nix"; - $ENV{'NIX_REMOTE_SYSTEMS'} = ''; - $ENV{'NIX_REMOTE'} = ''; - $ENV{'NIX_STATE_DIR'} = "$dir/nix/var/nix"; - $ENV{'NIX_STORE_DIR'} = "$dir/nix/store"; - - my $pgsql = Test::PostgreSQL->new( - extra_initdb_args => "--locale C.UTF-8" - ); - $ENV{'HYDRA_DBI'} = $pgsql->dsn; - system("hydra-init") == 0 or die; return ( - db => $pgsql, - tmpdir => $dir, - testdir => abs_path(dirname(__FILE__) . "/.."), - jobsdir => abs_path(dirname(__FILE__) . "/../jobs") - ); + context => $ctx, + tmpdir => $ctx->tmpdir, + testdir => $ctx->testdir, + jobsdir => $ctx->jobsdir + ) } sub write_file {