1#!./perl
2
3use strict;
4use warnings;
5BEGIN {
6    unless (-d 'blib') {
7        chdir 't' if -d 't';
8    }
9    require './test.pl';
10    set_up_inc('../lib');
11}
12use utf8;
13use open qw( :utf8 :std );
14
15plan(skip_all => "Your system has no SIGALRM") if !exists $SIG{ALRM};
16plan(tests => 8);
17
18=pod
19
20These are like the 010_complex_merge_classless test,
21but an infinite loop has been made in the heirarchy,
22to test that we can fail cleanly instead of going
23into an infinite loop
24
25=cut
26
27# initial setup, everything sane
28{
29    package ƙ;
30    our @ISA = qw/ᶨ ィ/;
31    package ᶨ;
32    our @ISA = qw/f/;
33    package ィ;
34    our @ISA = qw/ʰ f/;
35    package ʰ;
36    our @ISA = qw/ᶢ/;
37    package ᶢ;
38    our @ISA = qw/ᛞ/;
39    package f;
40    our @ISA = qw/ǝ/;
41    package ǝ;
42    our @ISA = qw/ᛞ/;
43    package ᛞ;
44    our @ISA = qw/Ạ B ʗ/;
45    package ʗ;
46    our @ISA = qw//;
47    package B;
48    our @ISA = qw//;
49    package Ạ;
50    our @ISA = qw//;
51}
52
53# A series of 8 aberations that would cause infinite loops,
54#  each one undoing the work of the previous
55my @loopies = (
56    sub { @ǝ::ISA = qw/f/ },
57    sub { @ǝ::ISA = qw/ᛞ/; @ʗ::ISA = qw/f/ },
58    sub { @ʗ::ISA = qw//; @Ạ::ISA = qw/ƙ/ },
59    sub { @Ạ::ISA = qw//; @ᶨ::ISA = qw/f ƙ/ },
60    sub { @ᶨ::ISA = qw/f/; @ʰ::ISA = qw/ƙ ᶢ/ },
61    sub { @ʰ::ISA = qw/ᶢ/; @B::ISA = qw/B/ },
62    sub { @B::ISA = qw//; @ƙ::ISA = qw/ƙ ᶨ ィ/ },
63    sub { @ƙ::ISA = qw/ᶨ ィ/; @ᛞ::ISA = qw/Ạ ʰ B ʗ/ },
64);
65
66foreach my $loopy (@loopies) {
67    eval {
68        local $SIG{ALRM} = sub { die "ALRMTimeout" };
69        alarm(3);
70        $loopy->();
71        mro::get_linear_isa('ƙ', 'dfs');
72    };
73
74    if(my $err = $@) {
75        if($err =~ /ALRMTimeout/) {
76            ok(0, "Loop terminated by SIGALRM");
77        }
78        elsif($err =~ /Recursive inheritance detected/) {
79            ok(1, "Graceful exception thrown");
80        }
81        else {
82            ok(0, "Unrecognized exception: $err");
83        }
84    }
85    else {
86        ok(0, "Infinite loop apparently succeeded???");
87    }
88}
89