#!/usr/bin/env perl #------------------------------------------------------------------------------ # # This program turns the all tests under src/ into a TSV format that can be # copy/pasted into a Google sheet. # # It is called by `make export` which writes the TSV into `export.tsv`. # If you use `make run-tests export` it will run each test against each # supported parser and add any failure indicators to the TSV data. # #------------------------------------------------------------------------------ use strict; use warnings; use FindBin; use lib $FindBin::Bin; use base 'YAMLTestSuite'; use Capture::Tiny ':all'; use Cwd; use Encode; my $container_id; sub kill_docker_container { if ($container_id) { my ($out, $err, $rc) = capture { system("docker kill $container_id"); }; } exit; } END { kill_docker_container(); } BEGIN { `rm -fr /tmp/test`; mkdir "/tmp/test" or die; if ($ENV{YTS_TEST_RUNNER}) { my $cwd = getcwd; my ($out, $err, $rc) = capture { system( "docker run -d " . "-v $cwd:/host " . "-v /tmp/test:/tmp/test " . "yamlio/yaml-test-runtimes:$ENV{YAML_TEST_RUNTIMES_VERSION} " . "sleep 600"); }; die "docker run failed" unless $rc == 0; chomp $out; $container_id = $out; $SIG{INT} = \&kill_docker_container; system("docker exec $container_id apk add bash 2>&1 >/dev/null") == 0 or die; } } my @test_runners = (qw< yaml-test-parse-refparse yaml-test-parse-refhs yaml-test-parse-dotnet yaml-test-parse-goyaml yaml-test-parse-hsyaml yaml-test-parse-libfyaml yaml-test-parse-libyaml yaml-test-parse-luayaml yaml-test-parse-nimyaml yaml-test-parse-npmyaml yaml-test-parse-ppyaml yaml-test-parse-pyyaml yaml-test-parse-ruamel yaml-test-parse-rustyaml yaml-test-parse-snake yaml-test-parse-snakeeng >); my @tag_names = (qw< alias anchor binary comment complex-key directive double duplicate-key edge empty empty-key error explicit-key flow folded footer header indent literal local-tag mapping missing scalar sequence simple single spec tag unknown-tag whitespace >); main->new->run([@ARGV]); sub make { my ($self) = @_; my $id = $self->{ID}; my $data = $self->{data}; my $name = $data->{name}; my $skip = $data->{skip} ? 'X' : ''; my $yaml = $data->{yaml}; $yaml =~ s/"/""/g; $yaml = qq{"$yaml"}; my $tree = $data->{tree}; $tree =~ s/"/""/g; chomp $tree; $tree = qq{"$tree"}; $tree = 'ERROR' if $data->{fail}; my $play = $self->play_url($data->{yaml}); print STDERR "\r\e[K$id"; my @test = $self->run_tests($id, $data->{yaml}); my @tags = $self->get_tags($data->{tags}); my $tsv = encode_utf8 join("\t", ( $play, $id, $name, $yaml, $tree, @test, @tags, ) ) . "\n"; print $tsv; } sub run_tests { my ($self, $id, $yaml) = @_; $yaml = $self->unescape($yaml); if (not $ENV{YTS_TEST_RUNNER}) { return ('') x scalar(@test_runners); } my ($out, $err, $rc) = capture { open my $pipe, '|-', "docker exec -i " . "--env ID=$id " . "--env RUNNERS='@test_runners' " . "$container_id " . "/host/bin/run-all-parsers" or die; print $pipe encode_utf8($yaml); close $pipe; return 0; }; # warn "out>>$out<<"; # warn "err>>$err<<"; die "docker run failed:\nrc: $rc\nstdout:\n$out\nstderr:\n$err\n" unless $rc == 0; my @tests = split /\t/, $out, -1; return @tests; } sub get_tags { my ($self, $tags) = @_; $tags ||= ''; my @tags = split /\s+/, $tags; my @list; for my $tag (@tag_names) { if (grep {$_ eq $tag} @tags) { push @list, 'x'; } else { push @list, ''; } } return @list; } sub final { my ($self) = @_; print STDERR "\r\e[K\n\nWrote $self->{make} rows.\n"; }