File: check-repos

package info (click to toggle)
extrepo-data 1.0.5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,748 kB
  • sloc: perl: 777; makefile: 5
file content (154 lines) | stat: -rwxr-xr-x 5,171 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/perl -w

use strict;
use warnings;

use File::Basename;
use YAML::XS qw/LoadFile/;
use XML::Writer;
use DateTime::HiRes;

use lib join("/", dirname($0), "lib");

use ExtRepoData;

use v5.36;

my @testcases;
my $tests = 0;
my $failures = 0;

my $full_start = DateTime::HiRes->now;

my $repos = {};

sub repotest($condition, $message) {
        $tests++;
	if($condition) {
		return { result => 1 };
	} else {
		say STDERR $message;
		$failures++;
		return { result => 0, message => $message };
	}
}

while(defined($ARGV[0])) {
	my $filedata = LoadFile(shift);
	foreach my $key(keys %$filedata) {
		next if $key =~ /^\./;
		die "duplicate repository name $key" if exists($repos->{$key});
		$repos->{$key} = $filedata->{$key};
	}
}

my %keys = (
	description => { ref => "", req => 1 },
	source => { ref => "HASH", req => 1 },
	suites => { ref => "ARRAY", req => 1 },
	components => { ref => "ARRAY", req => 0 },
	policies => { ref => "HASH", req => 0 },
	policy => { ref => "", req => 0 },
	contact => { ref => "", req => 0 },
	bugs => { ref => "", req => 0 },
	"gpg-key" => { ref => "", req => 1 },
	"onion-URIs" => { ref => "", req => 0 },
	Disabled => { ref => "", req => 0 },
	"post-enable-commands" => { ref => "ARRAY", req => 0 },
);

# These options mess with secure apt, and MUST NOT be used.
# Signed-By is added because it is managed by extrepo, and will be
# overridden if used.
my %forbidden = (
	"allow-insecure" => 1,
	"allow-weak" => 1,
	"allow-downgrade-to-insecure" => 1,
	"check-valid-until" => 1,
	"check-date" => 1,
	"trusted" => 1,
	"signed-by" => 1,
);

foreach my $repo(sort(keys %$repos)) {
	my $result = {
		starttime => DateTime::HiRes->now,
		name => "Check of repository $repo",
                id => "checkrepos.repository.$repo",
                tests => {},
	};
	my @component_keys = ( "components" );
	print STDERR "Checking repository $repo...\n";
	$result->{tests}{"repository name passes syntax check"} = repotest($repo =~ /^[a-z0-9_.-]+$/, "Invalid repository name $repo!");
	tie my(%hash), 'ExtRepoData', $repos->{$repo};
	$repos->{$repo} = \%hash;
	my $have_components = 0;
	foreach my $topkey(keys %{$repos->{$repo}}) {
		if($topkey =~ /suite-[^-]+-components/) {
			$have_components = 1;
			push @component_keys, $topkey;
			next;
		}
		$result->{tests}{"valid toplevel key $topkey"} = repotest(exists($keys{$topkey}), "invalid key $topkey");
		$result->{tests}{"type correct for toplevel key $topkey"} = repotest(ref($repos->{$repo}{$topkey}) eq $keys{$topkey}{ref}, "invalid type of key $topkey");
	}
	if($have_components || exists($repos->{$repo}{components})) {
		$have_components = 1;
		$keys{policies}{req} = 1;
		$keys{policy}{req} = 0;
	} else {
		$keys{policies}{req} = 0;
		$keys{policy}{req} = 1;
	}
	foreach my $reqd(keys %keys) {
		next unless $keys{$reqd}{req};
		$result->{tests}{"required toplevel key $reqd exists"} = repotest(exists($repos->{$repo}{$reqd}), "missing required key $reqd");
	}
	if($have_components) {
		foreach my $comp_key(@component_keys) {
			foreach my $component(@{$repos->{$repo}{$comp_key}}) {
				$result->{tests}{"policy for component $component is present"} = repotest(exists($repos->{$repo}{policies}{$component}), "no policy found for component $component");
			}
		}
	}
	my $types_found = 0;
	foreach my $src(keys %{$repos->{$repo}{source}}) {
		my $srcl = lc($src);
		if($srcl =~ /suite-[^-]*-(.*)/) {
			$srcl = $1;
		}
		$result->{tests}{"Deb822 field $src not forbidden"} = repotest(!exists($forbidden{$srcl}), "forbidden source option $src found");
		$result->{tests}{"Deb822 field $src is a scalar"} = repotest(ref($repos->{$repo}{source}{$src}) eq "", "source option $src is not a scalar");
		if ($srcl eq "types") {
			$types_found = 1;
			my $types_val = $repos->{$repo}{source}{$src};
			$result->{tests}{"types Deb822 field format is acceptable"} = repotest(($types_val eq "deb" || $types_val eq "deb deb-src"), "wrong value for source Types option: $types_val");
		}
	}
	$result->{tests}{"types Deb822 field present"} = repotest($types_found, "source Types option is missing");
	$result->{"time"} = DateTime::HiRes->now->hires_epoch - $result->{"starttime"}->hires_epoch;
        $result->{"timestamp"} = $result->{"starttime"}->iso8601;
	delete $result->{starttime};
	push @testcases, $result;
}

open my $junitfile, ">", "check-results-junit.xml";

my $junit = XML::Writer->new(OUTPUT => $junitfile);

$junit->startTag("testsuites", time => (DateTime::HiRes->now->hires_epoch - $full_start->hires_epoch), tests => $tests, failures => $failures);
foreach my $testcase(@testcases) {
	$junit->startTag("testsuite", name => $testcase->{name}, tests => scalar(keys %{$testcase->{tests}}), time => $testcase->{time}, timestamp => $testcase->{timestamp}, id => $testcase->{id});
	foreach my $testkey(keys %{$testcase->{tests}}) {
		$junit->startTag("testcase", name => $testkey);
		if(!$testcase->{tests}{$testkey}{result}) {
			$junit->startTag("failure", message => $testcase->{tests}{$testkey}{message});
			$junit->endTag("failure");
		}
		$junit->endTag("testcase");
	}
	$junit->endTag("testsuite");
}
$junit->endTag("testsuites");
$junit->end();
close $junitfile;