Developer-Dashboard

 view release on metacpan or  search on metacpan

t/13-integration-assets.t  view on Meta::CPAN

    like( $qemu, qr/WINDOWS_SKIP_CPANM_TESTS/, 'Windows QEMU launcher supports a Windows-specific cpanm test policy toggle' );
    like( $qemu, qr/WINDOWS_USE_INSTALL_BOOTSTRAP/, 'Windows QEMU launcher supports exercising install.ps1 inside the Windows guest' );
    like( $qemu, qr/reusing existing Dockur Windows container/, 'Windows QEMU launcher can reuse an existing Dockur container instead of always recreating it' );
    like( $qemu, qr/prepare_strawberry_installer/, 'Windows QEMU launcher stages the Strawberry Perl installer from the host ahead of guest bootstrap' );
    like( $qemu, qr/strawberry-perl-installer\.msi/, 'Windows QEMU launcher caches the Strawberry Perl MSI in the OEM folder' );
    like( $qemu, qr/LWP::UserAgent/, 'Windows QEMU launcher downloads the Strawberry Perl installer with LWP::UserAgent on the host' );
    like( $qemu, qr/locate-tarball/, 'Windows QEMU launcher bootstrap publishes the locate-tarball phase for long-running guest setup' );
    like( $qemu, qr/install-strawberry-perl/, 'Windows QEMU launcher bootstrap publishes the install-strawberry-perl phase for long-running guest setup' );
    like( $qemu, qr/UseInstallBootstrap|BootstrapScript/, 'Windows QEMU launcher can pass install.ps1 into the in-guest smoke' );
    like( $qemu, qr/\$smokeArgs = \@\(/, 'Windows QEMU launcher builds an explicit argument array for the in-guest PowerShell command' );
    unlike( $qemu, qr/\& "C:\\\\OEM\\\\run-strawberry-smoke\.ps1" \@\(.*UseInstallBootstrap/s, 'Windows QEMU launcher does not pass bootstrap parameters directly to the script through a positional array' );
    like( $qemu, qr/powershell\.exe/, 'Windows QEMU launcher bootstrap re-enters PowerShell explicitly for the in-guest smoke script' );
    like( $qemu, qr/'-File', 'C:\\\\OEM\\\\run-strawberry-smoke\.ps1'/, 'Windows QEMU launcher bootstrap invokes the in-guest smoke script through powershell.exe -File' );
    unlike( $qemu, qr/\& "C:\\\\OEM\\\\run-strawberry-smoke\.ps1" \@smokeArgs/, 'Windows QEMU launcher bootstrap avoids direct script splatting for the in-guest smoke script' );
    like( $qemu, qr/run-strawberry-smoke/, 'Windows QEMU launcher bootstrap publishes the run-strawberry-smoke phase before invoking the in-guest smoke script' );
    like( $qemu, qr/\$smokeArgs \+= '-SkipCpanmTests'/, 'Windows QEMU launcher bootstrap forwards the Windows cpanm skip-tests switch into the guest smoke when requested' );
    unlike( $qemu, qr/Invoke-WebRequest -UseBasicParsing -Uri "\$WINDOWS_STRAWBERRY_URL"/, 'Windows QEMU launcher bootstrap no longer downloads Strawberry Perl inside the Windows guest' );
    like( $qemu, qr/-p "\$\{WINDOWS_DOCKUR_WEB_PORT\}:8006"/, 'Windows QEMU launcher maps the configurable host web port to Dockur port 8006' );
    like( $qemu, qr/-p "\$\{WINDOWS_DOCKUR_RDP_PORT\}:3389\/tcp"/, 'Windows QEMU launcher maps the configurable host RDP TCP port to Dockur port 3389' );
    like( $qemu, qr/-p "\$\{WINDOWS_DOCKUR_RDP_PORT\}:3389\/udp"/, 'Windows QEMU launcher maps the configurable host RDP UDP port to Dockur port 3389' );
    like( $qemu, qr/windows-qemu\.env|WINDOWS_QEMU_ENV_FILE/, 'Windows QEMU launcher supports a reusable environment file' );
    like( $qemu, qr/\/dev\/kvm|enable-kvm/, 'Windows QEMU launcher manages KVM availability explicitly' );
    like( $qemu, qr/__END__/, 'Windows QEMU launcher carries POD trailer' );
    unlike( $qemu, qr/Developer-Dashboard-1\.\d+\.tar\.gz/, 'Windows QEMU launcher POD avoids hard-coded release tarball versions' );

    open my $windows_host_fh, '<', 'integration/windows/run-host-windows-smoke.sh' or die $!;
    my $windows_host = do { local $/; <$windows_host_fh> };
    close $windows_host_fh;
    like( $windows_host, qr/dzil build/, 'Windows host rerun helper builds a fresh tarball when needed' );
    like( $windows_host, qr/run-qemu-windows-smoke\.sh/, 'Windows host rerun helper delegates to the QEMU launcher' );
    like( $windows_host, qr/windows-qemu\.env|WINDOWS_QEMU_ENV_FILE/, 'Windows host rerun helper supports the reusable environment file' );
    like( $windows_host, qr/Developer-Dashboard-\*\.tar\.gz|\*\.tar\.gz/, 'Windows host rerun helper uses version-agnostic tarball discovery' );
    like( $windows_host, qr/__END__/, 'Windows host rerun helper carries POD trailer' );
    unlike( $windows_host, qr/Developer-Dashboard-1\.\d+\.tar\.gz/, 'Windows host rerun helper POD avoids hard-coded release tarball versions' );

    open my $timeout_e2e_fh, '<', 'integration/windows/run-collector-timeout-e2e.ps1' or die $!;
    my $timeout_e2e = do { local $/; <$timeout_e2e_fh> };
    close $timeout_e2e_fh;
    like( $timeout_e2e, qr/\[guid\]::NewGuid/, 'Windows timeout E2E script generates a unique per-run marker so persistent-guest reruns cannot collide' );
    like( $timeout_e2e, qr/dd-timeout-e2e-/, 'Windows timeout E2E script namespaces its marker so stray-process matching stays scoped to this harness' );
    like( $timeout_e2e, qr/Stop-StrayDashboardProcesses/, 'Windows timeout E2E script applies the clean-slate rule and kills stray dashboard processes before the run' );
    like( $timeout_e2e, qr/Get-CimInstance Win32_Process/, 'Windows timeout E2E script observes real guest process state through CIM instead of trusting exit codes' );
    like( $timeout_e2e, qr/Where-Object/, 'Windows timeout E2E script filters process rows with Where-Object' );
    unlike( $timeout_e2e, qr/Get-CimInstance[^\r\n]*-Filter/, 'Windows timeout E2E script avoids WQL -Filter string quoting pitfalls when matching processes' );
    like( $timeout_e2e, qr/\$env:USERPROFILE = \$homeRoot/, 'Windows timeout E2E script isolates the run under a hermetic temporary Windows home' );
    like( $timeout_e2e, qr/\$env:DD_STATE_ROOT_USER/, 'Windows timeout E2E script pins the state-root user seam so a non-interactive Windows session never reaches the unimplemented getpwuid fallback' );
    like( $timeout_e2e, qr/timeout\s*=\s*\$TimeoutSeconds/, 'Windows timeout E2E script configures the collector with an explicit short timeout' );
    like( $timeout_e2e, qr/system\( 1, \$\^X/, 'Windows timeout E2E blocker spawns an asynchronous descendant so subtree termination is really exercised' );
    like( $timeout_e2e, qr/descendant-/, 'Windows timeout E2E blocker tags its descendant command line with the run marker' );
    like( $timeout_e2e, qr/sleep 1 for 1 \.\. 3600/, 'Windows timeout E2E blocker blocks far longer than the configured timeout so an interrupt is the only passing path' );
    like( $timeout_e2e, qr/collector", "run"/, 'Windows timeout E2E script triggers the blocking collector through dashboard collector run' );
    like( $timeout_e2e, qr/ConvertFrom-Json/, 'Windows timeout E2E script parses the structured collector run result' );
    like( $timeout_e2e, qr/timed_out/, 'Windows timeout E2E script asserts the timed_out flag on the collector result' );
    like( $timeout_e2e, qr/\b124\b/, 'Windows timeout E2E script asserts the canonical timeout exit code 124' );
    like( $timeout_e2e, qr/collector", "status"/, 'Windows timeout E2E script verifies the cached collector status after the timeout' );
    like( $timeout_e2e, qr/last_exit_code/, 'Windows timeout E2E script asserts the persisted last_exit_code reflects the timeout' );
    like( $timeout_e2e, qr/\[System\.Diagnostics\.Stopwatch\]::StartNew/, 'Windows timeout E2E script measures elapsed wall-clock time to prove the blocking command was interrupted' );
    like( $timeout_e2e, qr/Assert-MarkerProcessesGone/, 'Windows timeout E2E script asserts the blocker and its descendant are both really gone after the timeout' );
    like( $timeout_e2e, qr/\@\(\s*Get-ProcessesMatching/, 'Windows timeout E2E script forces array semantics on process queries so the zero-survivor success path cannot trip strict mode' );
    unlike( $timeout_e2e, qr/\$survivors\s*=\s*Get-ProcessesMatching/, 'Windows timeout E2E script never assigns a process query straight to a variable it then counts' );
    like( $timeout_e2e, qr/agent-alive-ok/, 'Windows timeout E2E script proves the collector agent survives the timeout by running a healthy collector afterwards' );
    like( $timeout_e2e, qr/__END__/, 'Windows timeout E2E script carries POD trailer' );
    unlike( $timeout_e2e, qr/Developer-Dashboard-\d+\.\d+\.tar\.gz/, 'Windows timeout E2E script avoids hard-coded release tarball versions' );

    open my $dockur_fh, '<', 'integration/windows/run-dockur-collector-timeout-e2e.sh' or die $!;
    my $dockur = do { local $/; <$dockur_fh> };
    close $dockur_fh;
    like( $dockur, qr/^#!/, 'Dockur timeout E2E driver carries a shebang' );
    like( $dockur, qr/set -euo pipefail/, 'Dockur timeout E2E driver fails fast instead of continuing past a broken step' );
    like( $dockur, qr/run-collector-timeout-e2e\.ps1/, 'Dockur timeout E2E driver ships the in-guest harness into the guest' );
    like( $dockur, qr/ddagent-alive\.txt/, 'Dockur timeout E2E driver verifies the in-guest job agent is alive before submitting work' );
    like( $dockur, qr/ddjob-/, 'Dockur timeout E2E driver submits work through the shared-folder job protocol' );
    like( $dockur, qr/Developer-Dashboard-\*\.tar\.gz|\*\.tar\.gz/, 'Dockur timeout E2E driver uses version-agnostic tarball discovery' );
    like( $dockur, qr/cpanm/, 'Dockur timeout E2E driver installs the built tarball in the guest before running the E2E' );
    like( $dockur, qr/_await_windows_command|DD_E2E_REQUIRE_SYMBOL|require_symbol/, 'Dockur timeout E2E driver proves the installed guest product carries the Windows timeout implementation' );
    like( $dockur, qr/DD_STATE_ROOT_USER|HOME/, 'Dockur timeout E2E driver gives the guest install the environment a non-interactive Windows session lacks' );
    like( $dockur, qr/exit:/, 'Dockur timeout E2E driver reads the job status file the guest agent writes' );
    like( $dockur, qr/tr -d/, 'Dockur timeout E2E driver strips the guest CRLF from the status file before reading the exit code' );
    like( $dockur, qr/git-common-dir/, 'Dockur timeout E2E driver finds the shared folder in the main checkout when it runs from a ticket worktree' );
    like( $dockur, qr/\[A-Za-z0-9\._-\]\+/, 'Dockur timeout E2E driver validates the job namespace before interpolating it into the generated guest script' );
    like( $dockur, qr/__END__/, 'Dockur timeout E2E driver carries POD trailer' );
    unlike( $dockur, qr/Developer-Dashboard-\d+\.\d+\.tar\.gz/, 'Dockur timeout E2E driver avoids hard-coded release tarball versions' );
}
else {
    ok( -d 'integration', 'release tarball keeps integration assets for shipped install-time verification' );
    ok( -f 'doc/integration-test-plan.md', 'release tarball keeps the integration test plan document for shipped verification guidance' );
    ok( -f 'doc/testing.md', 'release tarball keeps the general testing workflow document for shipped verification guidance' );
    ok( -f 'doc/windows-testing.md', 'release tarball keeps the Windows testing guide for shipped verification guidance' );
}

if ( -f 'dist.ini' ) {
    open my $dist_fh, '<', 'dist.ini' or die $!;
    my $dist = do { local $/; <$dist_fh> };
    close $dist_fh;
    unlike( $dist, qr/exclude_filename = Makefile\.PL/, 'dist.ini keeps the checked-in Makefile.PL so dzil ships the checkout install hooks' );
    unlike( $dist, qr/^\[MakeMaker\]$/m, 'dist.ini does not regenerate Makefile.PL over the checked-in checkout install hooks' );
    like( $dist, qr/\[AutoPrereqs\]/, 'dist.ini includes AutoPrereqs for built distribution dependencies' );
    like( $dist, qr/^JSON::XS = 4\.04$/m, 'dist.ini pins JSON::XS at its secure minimum for built distribution runtime metadata' );
}
else {
    ok( !-f 'dist.ini', 'release tarball excludes dist.ini from shipped assets' );
    open my $meta_fh, '<', 'META.json' or die $!;
    my $meta = json_decode( do { local $/; <$meta_fh> } );
    close $meta_fh;
    ok( exists $meta->{prereqs}, 'META.json ships generated prerequisite metadata in the tarball' );
    ok( exists $meta->{prereqs}{runtime}, 'META.json keeps runtime prerequisite sections in the tarball' );
    ok( exists $meta->{prereqs}{runtime}{requires}{'JSON::XS'}, 'META.json keeps JSON::XS in shipped runtime prerequisites' );
}

done_testing;

sub _path_is_git_tracked {
    my ($path) = @_;
    return 0 if !defined $path || $path eq '';
    my ( $stdout, $stderr, $status ) = capture {
        system( 'git', 'ls-files', '--error-unmatch', '--', $path );
    };
    return $status == 0 ? 1 : 0;
}

__END__

=head1 NAME

13-integration-assets.t - verify blank-environment integration assets exist

=head1 DESCRIPTION

This test verifies that the blank-environment Docker integration plan and
runner assets are present and cover the intended install and smoke flow.



( run in 1.185 second using v1.01-cache-2.11-cpan-14f38c9f855 )