Reimplement (named) constituent jobs (+globbing) based on nix-eval-jobs
Depends on https://github.com/nix-community/nix-eval-jobs/pull/349 & #1421. Almost equivalent to #1425, but with a small change: when having e.g. an aggregate job with a glob that matches nothing, the jobset evaluation is failed now. This was the intended behavior before (hydra-eval-jobset fails hard if an aggregate is broken), the code-path was never reached however since the aggregate was never marked as broken in this case before.
This commit is contained in:
		@@ -6,27 +6,55 @@ use Hydra::Helper::Exec;
 | 
			
		||||
 | 
			
		||||
my $ctx = test_context();
 | 
			
		||||
 | 
			
		||||
my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
    expression => 'constituents-broken.nix',
 | 
			
		||||
);
 | 
			
		||||
my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
subtest "broken constituents expression" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-broken.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
    ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
);
 | 
			
		||||
isnt($res, 0, "hydra-eval-jobset exits non-zero");
 | 
			
		||||
ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
like(
 | 
			
		||||
    $stderr,
 | 
			
		||||
    qr/aggregate job ‘mixed_aggregate’ failed with the error: "constituentA": does not exist/,
 | 
			
		||||
    "The stderr record includes a relevant error message"
 | 
			
		||||
);
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
    isnt($res, 0, "hydra-eval-jobset exits non-zero");
 | 
			
		||||
    ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
    like(
 | 
			
		||||
        $stderr,
 | 
			
		||||
        qr/aggregate job 'mixed_aggregate' references non-existent job 'constituentA'/,
 | 
			
		||||
        "The stderr record includes a relevant error message"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
$jobset->discard_changes({ '+columns' => {'errormsg' => 'errormsg'} });  # refresh from DB
 | 
			
		||||
like(
 | 
			
		||||
    $jobset->errormsg,
 | 
			
		||||
    qr/aggregate job ‘mixed_aggregate’ failed with the error: "constituentA": does not exist/,
 | 
			
		||||
    "The jobset records a relevant error message"
 | 
			
		||||
);
 | 
			
		||||
    $jobset->discard_changes({ '+columns' => {'errormsg' => 'errormsg'} });  # refresh from DB
 | 
			
		||||
    like(
 | 
			
		||||
        $jobset->errormsg,
 | 
			
		||||
        qr/aggregate job ‘mixed_aggregate’ failed with the error: constituentA: does not exist/,
 | 
			
		||||
        "The jobset records a relevant error message"
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
subtest "no matches" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-no-matches.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
    isnt($res, 0, "hydra-eval-jobset exits non-zero");
 | 
			
		||||
    ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
    like(
 | 
			
		||||
        $stderr,
 | 
			
		||||
        qr/aggregate job 'non_match_aggregate' references constituent glob pattern 'tests\.\*' with no matches/,
 | 
			
		||||
        "The stderr record includes a relevant error message"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    $jobset->discard_changes({ '+columns' => {'errormsg' => 'errormsg'} });  # refresh from DB
 | 
			
		||||
    like(
 | 
			
		||||
        $jobset->errormsg,
 | 
			
		||||
        qr/aggregate job ‘non_match_aggregate’ failed with the error: tests\.\*: constituent glob pattern had no matches/,
 | 
			
		||||
        qr/in job ‘non_match_aggregate’:\ntests\.\*: constituent glob pattern had no matches/,
 | 
			
		||||
        "The jobset records a relevant error message"
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
done_testing;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										138
									
								
								t/evaluator/evaluate-constituents-globbing.t
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								t/evaluator/evaluate-constituents-globbing.t
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
use Setup;
 | 
			
		||||
use Test2::V0;
 | 
			
		||||
use Hydra::Helper::Exec;
 | 
			
		||||
use Data::Dumper;
 | 
			
		||||
 | 
			
		||||
my $ctx = test_context();
 | 
			
		||||
 | 
			
		||||
subtest "general glob testing" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-glob.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
    is($res, 0, "hydra-eval-jobset exits zero");
 | 
			
		||||
 | 
			
		||||
    my $builds = {};
 | 
			
		||||
    for my $build ($jobset->builds) {
 | 
			
		||||
        $builds->{$build->job} = $build;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    subtest "basic globbing works" => sub {
 | 
			
		||||
        ok(defined $builds->{"ok_aggregate"}, "'ok_aggregate' is part of the jobset evaluation");
 | 
			
		||||
        my @constituents = $builds->{"ok_aggregate"}->constituents->all;
 | 
			
		||||
        is(2, scalar @constituents, "'ok_aggregate' has two constituents");
 | 
			
		||||
 | 
			
		||||
        my @sortedConstituentNames = sort (map { $_->nixname } @constituents);
 | 
			
		||||
 | 
			
		||||
        is($sortedConstituentNames[0], "empty-dir-A", "first constituent of 'ok_aggregate' is 'empty-dir-A'");
 | 
			
		||||
        is($sortedConstituentNames[1], "empty-dir-B", "second constituent of 'ok_aggregate' is 'empty-dir-B'");
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    subtest "transitivity is OK" => sub {
 | 
			
		||||
        ok(defined $builds->{"indirect_aggregate"}, "'indirect_aggregate' is part of the jobset evaluation");
 | 
			
		||||
        my @constituents = $builds->{"indirect_aggregate"}->constituents->all;
 | 
			
		||||
        is(1, scalar @constituents, "'indirect_aggregate' has one constituent");
 | 
			
		||||
        is($constituents[0]->nixname, "direct_aggregate", "'indirect_aggregate' has 'direct_aggregate' as single constituent");
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
subtest "* selects all except current aggregate" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-glob-all.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    subtest "no eval errors" => sub {
 | 
			
		||||
        ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
        ok(
 | 
			
		||||
            $stderr !~ "aggregate job ‘ok_aggregate’ has a constituent .* that doesn't correspond to a Hydra build",
 | 
			
		||||
            "Catchall wildcard must not select itself as constituent"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $jobset->discard_changes;  # refresh from DB
 | 
			
		||||
        is(
 | 
			
		||||
            $jobset->errormsg,
 | 
			
		||||
            "",
 | 
			
		||||
            "eval-errors non-empty"
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    my $builds = {};
 | 
			
		||||
    for my $build ($jobset->builds) {
 | 
			
		||||
        $builds->{$build->job} = $build;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    subtest "two constituents" => sub {
 | 
			
		||||
        ok(defined $builds->{"ok_aggregate"}, "'ok_aggregate' is part of the jobset evaluation");
 | 
			
		||||
        my @constituents = $builds->{"ok_aggregate"}->constituents->all;
 | 
			
		||||
        is(2, scalar @constituents, "'ok_aggregate' has two constituents");
 | 
			
		||||
 | 
			
		||||
        my @sortedConstituentNames = sort (map { $_->nixname } @constituents);
 | 
			
		||||
 | 
			
		||||
        is($sortedConstituentNames[0], "empty-dir-A", "first constituent of 'ok_aggregate' is 'empty-dir-A'");
 | 
			
		||||
        is($sortedConstituentNames[1], "empty-dir-B", "second constituent of 'ok_aggregate' is 'empty-dir-B'");
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
subtest "trivial cycle check" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-cycle.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    ok(
 | 
			
		||||
        $stderr =~ "Found dependency cycle between jobs 'indirect_aggregate' and 'ok_aggregate'",
 | 
			
		||||
        "Dependency cycle error is on stderr"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
 | 
			
		||||
    $jobset->discard_changes;  # refresh from DB
 | 
			
		||||
    like(
 | 
			
		||||
        $jobset->errormsg,
 | 
			
		||||
        qr/Dependency cycle: indirect_aggregate <-> ok_aggregate/,
 | 
			
		||||
        "eval-errors non-empty"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    is(0, $jobset->builds->count, "No builds should be scheduled");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
subtest "cycle check with globbing" => sub {
 | 
			
		||||
    my $jobsetCtx = $ctx->makeJobset(
 | 
			
		||||
        expression => 'constituents-cycle-glob.nix',
 | 
			
		||||
    );
 | 
			
		||||
    my $jobset = $jobsetCtx->{"jobset"};
 | 
			
		||||
 | 
			
		||||
    my ($res, $stdout, $stderr) = captureStdoutStderr(60,
 | 
			
		||||
        ("hydra-eval-jobset", $jobsetCtx->{"project"}->name, $jobset->name)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    ok(utf8::decode($stderr), "Stderr output is UTF8-clean");
 | 
			
		||||
 | 
			
		||||
    $jobset->discard_changes;  # refresh from DB
 | 
			
		||||
    like(
 | 
			
		||||
        $jobset->errormsg,
 | 
			
		||||
        qr/aggregate job ‘indirect_aggregate’ failed with the error: Dependency cycle: indirect_aggregate <-> packages.constituentA/,
 | 
			
		||||
        "packages.constituentA error missing"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    # on this branch of Hydra, hydra-eval-jobset fails hard if an aggregate
 | 
			
		||||
    # job is broken.
 | 
			
		||||
    is(0, $jobset->builds->count, "Zero jobs are scheduled");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
done_testing;
 | 
			
		||||
							
								
								
									
										14
									
								
								t/jobs/config.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								t/jobs/config.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
rec {
 | 
			
		||||
  path = "/nix/store/l9mg93sgx50y88p5rr6x1vib6j1rjsds-coreutils-9.1/bin";
 | 
			
		||||
 | 
			
		||||
  mkDerivation = args:
 | 
			
		||||
    derivation ({
 | 
			
		||||
      system = builtins.currentSystem;
 | 
			
		||||
      PATH = path;
 | 
			
		||||
    } // args);
 | 
			
		||||
  mkContentAddressedDerivation = args: mkDerivation ({
 | 
			
		||||
    __contentAddressed = true;
 | 
			
		||||
    outputHashMode = "recursive";
 | 
			
		||||
    outputHashAlgo = "sha256";
 | 
			
		||||
  } // args);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								t/jobs/constituents-cycle-glob.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								t/jobs/constituents-cycle-glob.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
with import ./config.nix;
 | 
			
		||||
{
 | 
			
		||||
  packages.constituentA = mkDerivation {
 | 
			
		||||
    name = "empty-dir-A";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [ "*_aggregate" ];
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  packages.constituentB = mkDerivation {
 | 
			
		||||
    name = "empty-dir-B";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ok_aggregate = mkDerivation {
 | 
			
		||||
    name = "direct_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "packages.*"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  indirect_aggregate = mkDerivation {
 | 
			
		||||
    name = "indirect_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "ok_aggregate"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								t/jobs/constituents-cycle.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								t/jobs/constituents-cycle.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
with import ./config.nix;
 | 
			
		||||
{
 | 
			
		||||
  ok_aggregate = mkDerivation {
 | 
			
		||||
    name = "direct_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "indirect_aggregate"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  indirect_aggregate = mkDerivation {
 | 
			
		||||
    name = "indirect_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "ok_aggregate"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								t/jobs/constituents-glob-all.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								t/jobs/constituents-glob-all.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
with import ./config.nix;
 | 
			
		||||
{
 | 
			
		||||
  packages.constituentA = mkDerivation {
 | 
			
		||||
    name = "empty-dir-A";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  packages.constituentB = mkDerivation {
 | 
			
		||||
    name = "empty-dir-B";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ok_aggregate = mkDerivation {
 | 
			
		||||
    name = "direct_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "*"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								t/jobs/constituents-glob.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								t/jobs/constituents-glob.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
with import ./config.nix;
 | 
			
		||||
{
 | 
			
		||||
  packages.constituentA = mkDerivation {
 | 
			
		||||
    name = "empty-dir-A";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  packages.constituentB = mkDerivation {
 | 
			
		||||
    name = "empty-dir-B";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ok_aggregate = mkDerivation {
 | 
			
		||||
    name = "direct_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "packages.*"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  indirect_aggregate = mkDerivation {
 | 
			
		||||
    name = "indirect_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "ok_aggregate"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								t/jobs/constituents-no-matches.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								t/jobs/constituents-no-matches.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
with import ./config.nix;
 | 
			
		||||
{
 | 
			
		||||
  non_match_aggregate = mkDerivation {
 | 
			
		||||
    name = "mixed_aggregate";
 | 
			
		||||
    _hydraAggregate = true;
 | 
			
		||||
    _hydraGlobConstituents = true;
 | 
			
		||||
    constituents = [
 | 
			
		||||
      "tests.*"
 | 
			
		||||
    ];
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  # Without a second job no jobset is attempted to be created
 | 
			
		||||
  # (the only job would be broken)
 | 
			
		||||
  # and thus the constituent validation is never reached.
 | 
			
		||||
  dummy = mkDerivation {
 | 
			
		||||
    name = "dummy";
 | 
			
		||||
    builder = ./empty-dir-builder.sh;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								t/jobs/declarative/project.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								t/jobs/declarative/project.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
    "enabled": 1,
 | 
			
		||||
    "hidden": false,
 | 
			
		||||
    "description": "declarative-jobset-example",
 | 
			
		||||
    "nixexprinput": "src",
 | 
			
		||||
    "nixexprpath": "declarative/generator.nix",
 | 
			
		||||
    "checkinterval": 300,
 | 
			
		||||
    "schedulingshares": 100,
 | 
			
		||||
    "enableemail": false,
 | 
			
		||||
    "emailoverride": "",
 | 
			
		||||
    "keepnr": 3,
 | 
			
		||||
    "inputs": {
 | 
			
		||||
        "src": {
 | 
			
		||||
            "type": "path",
 | 
			
		||||
            "value": "/home/ma27/Projects/hydra-cppnix/t/jobs",
 | 
			
		||||
            "emailresponsible": false
 | 
			
		||||
        },
 | 
			
		||||
        "jobspath": {
 | 
			
		||||
            "type": "string",
 | 
			
		||||
            "value": "/home/ma27/Projects/hydra-cppnix/t/jobs",
 | 
			
		||||
            "emailresponsible": false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,11 +22,11 @@ is(nrQueuedBuildsForJobset($jobset), 0, "Evaluating jobs/broken-constituent.nix
 | 
			
		||||
 | 
			
		||||
like(
 | 
			
		||||
    $jobset->errormsg,
 | 
			
		||||
    qr/^"does-not-exist": does not exist$/m,
 | 
			
		||||
    qr/^does-not-exist: does not exist$/m,
 | 
			
		||||
    "Evaluating jobs/broken-constituent.nix should log an error for does-not-exist");
 | 
			
		||||
like(
 | 
			
		||||
    $jobset->errormsg,
 | 
			
		||||
    qr/^"does-not-evaluate": "error: assertion 'false' failed/m,
 | 
			
		||||
    qr/^does-not-evaluate: error: assertion 'false' failed/m,
 | 
			
		||||
    "Evaluating jobs/broken-constituent.nix should log an error for does-not-evaluate");
 | 
			
		||||
 | 
			
		||||
done_testing;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user