SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
The $path to Knowlege:
What little it takes to test perl.
Steven Lembark
Workhorse Computing
lembark@wrkhors.com
Everyone wants to leave a legacy.
Makes sense: Leave your mark on history.
Everyone wants to leave a legacy.
Makes sense: Leave your mark on history.
What if your mark is history?
It never changes.
It never adapts.
Forever frozen in the wastelands of 5.8.
Growing beyond legacy.
Any number of companies have legacy Perl code.
Any number of reasons it isn’t upgraded.
Then you decide to upgrade, get current.
Now what?
First step: Triage
Obvious questions:
What’s working?
What’s broken?
What’s next?
First step: Triage
Obvious questions:
What’s working?
What’s broken?
What’s next?
A: Let’s find out.
Example
I’ve worked for multiple clients with v5.8 code.
Then they wanted to upgrade.
Say to 5.2X or later.
Undo a few decades of technical debt.
Only takes a few weeks, right?
So what? You test the code?
Next step is testing lots of files.
Repeating the same tests, over and over.
Rule 1: Avoid Red Flags.
Don’t copy, cut, or paste.
Use Lazyness.
Perl Somalier
<https://www.perl.com/pub/2000/04/raceinfo.html/>
The Repair Shop has aged well:
Nice bouquet, pleasant aftertaste.
All the things that make cleaning up code pleasing.
Step 1: use perl.
#!/usr/bin/env perl
not /usr/bin/perl.
Then check your path.
Step 2: Find the perly files
find lib -type f -name ‘*pm’;
Skip shell programs:
find bin scripts utils -type f |
xargs file |
grep ‘Perl’ |
cut -d’:’ -f1 ;
OK: unit test the files
OK, so you copy a red flag... er... template for each...
Define a datafile?
Write the YAML file from hell?
Create JSON from worse?
Nope.
Start with a path.
Q: What do we need in order to unit test one module?
A: Its path.
/my/sandbox/XYX/lib/Foo/Bar.pm
Start with a path.
Q: What do we need in order to unit test one module?
A: Its path.
/my/sandbox/XYX/lib/Foo/Bar.pm
Encoded in a symlink:
./t/01-pm/~my~sandbox~XYZ~lib~Foo~Bar.pm.t
Start with a path.
Q: What do we need in order to unit test one module?
A: Its path.
/my/sandbox/XYX/lib/Foo/Bar.pm
Along with its package:
./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t
Start with a path.
Q: What do we need in order to unit test one module?
A: Its path.
/my/sandbox/XYX/lib/Foo/Bar.pm
Along with its package:
./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t
~Foo~Bar
Start with a path.
Q: What do we need in order to unit test one module?
A: Its path.
/my/sandbox/XYX/lib/Foo/Bar.pm
Along with its package:
./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t
Foo::Bar
Start with a path.
use Test::More;
use File::Basename;
my $base0 = basename $0;
my $sep = substr $base0, 0, 1;
my $path = join '/' => split m{[$sep]}, $base0;
my ($pkg) = $path =~ m{// (.+?) [.]pm$}x;
my $pkg =~ s{W}{::}g;
require_ok $path
or skip "Failed require", 1;
can_ok $pkg, 'VERSION'
or skip "Missing packge: '$pkg' ($path)";
Given a path and a packge...
What else would you want to test?
How about exports?
Validating @EXPORT & @EXPORT_OK
Basic problem: Exporting what isn’t.
Undefined values in @EXPORT or @EXPORT_OK.
Botched names.
Validating @EXPORT & @EXPORT_OK
Both can easily be checked.
Symbol is your friend.
qualify_to_ref is your buddy.
Validating @EXPORT & @EXPORT_OK
Starting with $path and $pkg:
Require the path.
Check for @EXPORT, @EXPORT_OK.
Walk down whichever is defined.
Check that the contents are defined.
Validating @EXPORT & @EXPORT_OK
# basic sanity checks: configured for exporting.
require_ok $path or skip “oops...”, 1;
isa_ok $pkg, ‘Exporter’ or skip “$pkg is not Exporter”;
can_ok $path -> 'import'
or do
{
diag “Botched $pkg: Exporter lacks ‘import’”;
skip “$pkg cannot ‘import’”
};
# hold off calling import until we have some values.
# maybe a diag for can_ok
Validating @EXPORT & @EXPORT_OK
# second step: check the contents of EXPORT & _OK
# require_ok doesn’t call import: need it for @EXPORT.
for my $exp ( qw( EXPORT EXPORT_OK ) )
{
my $ref = qualify_to_ref $exp => $pkg;
my $found = *{$ref}{ARRAY} or next;
note "Validate: $pkg $expn", explain $found;
my @namz = @$found
or skip "$pkg has empty '$exp'";
$pkg->import( @namz );
Validating @EXPORT & @EXPORT_OK
for my $name ( @namz )
{
my $sigil
= $name =~ m{^w} ? '&' : substr $name, 0, 1, '' ;
if( ‘&’ eq $sigil )
{
# anything exported should exist in both places.
can_ok $pkg, $name;
can_ok __PACKAGE__, $name;
}
else
...
Validating @EXPORT & @EXPORT_OK
...
{
state $sig2type = [qw( @ ARRAY % HASH $ SCLALAR ...) ];
my $type = $sigil2type{ $sigil };
my $src = qualify_to_ref $name, $pkg;
my $dst = qualify_to_ref $name, __PACKGE__;
my $src_v = *{ $ref }{ $type }
or do { diag “$pkg lacks ‘$name’”; next };
my $dst_v = *{ $dst }{ $type };
is_deeply $src_v, $dst_v, “$name exported from $pkg”;
}
}
Ever get sick of typing “perl -wc”?
Lazyness is a virtue: Let perl type it for you.
All you need is the path, perl, and a version.
Ever get sick of typing “perl -wc”?
chomp ( my $perl = qx{ which perl } );
my $run_d = dirname $0;
my $path = ( basename $0, '.t' ) =~ tr{~}{/}r;
my $base = basename $path;
SKIP:
{
-e $perl or skip "Non-existant: 'perl'";
-x $perl or skip "Non-executable: '$perl'";
-e $path or skip "Non-existant: '$path'";
-r $path or skip "Non-readable: '$path'";
-s $path or skip "Zero-sized: '$path'";
# at this point the test is run-able
Ever get sick of typing “perl -wk”?
chomp ( my $perl = qx{ which perl } );
# $^V isn’t perfect, but it’s a start.
my $input = "(echo ‘use $^V’; cat $path)";
my $cmd = "$input | perl -wc -";
my $out = qx{ $cmd 2>&1 };
my $exit = $?;
ok 0 == $exit, "Compile: '$base'";
$out eq "- Syntax OKn"
or
diag "nPerl diagnostic: '$path'n$outn";
}
Ever get sick of typing “perl -wk”?
chomp ( my $perl = qx{ which perl } );
# $^V isn’t perfect, but it’s a start.
my $input = "(echo ‘use $^V’; cat $path)";
my $cmd = "$input | perl -wc -";
my $out = qx{ $cmd 2>&1 };
my $exit = $?;
ok 0 == $exit, "Compile: '$base'";
$out eq "- Syntax OKn"
or
diag "nPerl diagnostic: '$path'n$outn";
}
Prove is lazier than perl -wc for each file.
Ouptut is quite paste-able:
GitLab issue:
~~~perl
<paste test output here>
~~~
Cleaning up Exports
Life begings with Globals.pm
@EXPORT qw( … );
~1500 entries.
Can’t delete any: Nobody knows what’s used.
Gotta maintain them all.
Cleaning up Exports
Life begings with Globals.pm
@EXPORT qw( … );
~1500 entries.
Can’t delete any: Nobody knows what’s used.
Gotta maintain them all.
Not...
Cleaning up Exports
Tests give us @EXPORT* & diagnostics.
Step 1: @EXPORT_OK
Yes, this breaks all of the code.
Result: We know what is missing.
Cleaning up Exports
Step 2: Diagnostics list undefined variables.
Grep them out.
Generate “use Global qw( … )” lines.
Updates via perl -i -p.
Result: We know what is used.
Cleaning up Exports
Step 3: Start removing unused exports.
Look at what we added.
Comment the rest.
Test diag’s tell us when we go too far.
And when to stop.
Testing with Jenkins
As always: There’s more than one way.
One simple fix:
./devops/Jenkinsfile
./devops/run-tests
Testing with Jenkins
stage("Runtime Env")
{
steps
{
sh "uname -a"
sh "hostname"
sh "pwd -L"
sh "pwd -P"
sh "set"
}
}
Testing with Jenkins
stage("Run Tests")
{
environment
{
path = “${env.WORKSPACE_TMP + ‘/prove’}”
}
steps
{
sh "git submodule init"
sh "git submodule update"
sh "./devops/run-tests"
}
}
Testing with Jenkins
stage("Run Tests")
{
environment
{
path = “${env.WORKSPACE_TMP + ‘/prove’}”
}
steps
{
sh "git submodule init"
sh "git submodule update"
sh "./devops/run-tests"
}
}
Testing with Jenkins
#!/bin/bash -x
perl -V;
prove -V;
echo “Ouput: ‘$path’”;
cmd=”prove -r --jobs=4 --state=save --statefile=$path t”;
cd $(dirname $0)/../..;
./t/bin/install-test-symlinks;
$cmd 2>&1 | tee "$path.out";
How do we know which files to test?
Simple: Ask
*.pm files are easy.
Find #!perl files with
find lib scripts utils progs apps -type f |
xargs file |
grep 'Perl' |
cut -d':' -f1 |
xargs ./t/bin/install-symlinks $dir ;
Bits of Jenins
Put site_perl into a git submodule.
Advanced Options for Jenkins: Submodules.
Allows shallow copy & recurse submodules.
Maintain as a seprate repo:
cpanm --local-lib=. --self-contained ... ;
git add .;
git commit -m’update CPAN’;
Bits of Jenins
environment
{
PERL5LIB = "$WORKSPACE/site_perl/lib/perl5"
TEMPDIR = "$WORKSPACE_TMP"
}
Test & Package Perl with Jenkins
Distribute your own cpan via ./site_perl.
Nice place for a submodule.
Catch: How do you find it?
Bits of Jenins
environment
{
PERL5LIB = "$WORKSPACE/site_perl/lib/perl5"
TEMPDIR = "$WORKSPACE_TMP"
}
Test & Package Perl with Jenkins
Distribute your own cpan via ./site_perl.
Nice place for a submodule.
Catch: How do you find it?
Bits of Jenins
environment
{
PERL5LIB = "$WORKSPACE/site_perl/lib/perl5"
TEMPDIR = "$WORKSPACE_TMP"
}
Test & Package Perl with Jenkins
Tee results or store ‘artifacts’.
Net result: Paths can tell you a lot.
Easy to acquire.
Easy to use: basenames & require_ok.
Explore with Symbol.
Net result: Paths can tell you a lot.
Jenkins’ plays nicely with Perl.
Distribute tests from git.
Including CPAN modules.

Más contenido relacionado

La actualidad más candente

BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Workhorse Computing
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
Utility Modules That You Should Know About
Utility Modules That You Should Know AboutUtility Modules That You Should Know About
Utility Modules That You Should Know Aboutjoshua.mcadams
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationAttila Balazs
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojobpmedley
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model Perforce
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @SilexJeen Lee
 

La actualidad más candente (20)

Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Getting testy with Perl
Getting testy with PerlGetting testy with Perl
Getting testy with Perl
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Utility Modules That You Should Know About
Utility Modules That You Should Know AboutUtility Modules That You Should Know About
Utility Modules That You Should Know About
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Perl basics for Pentesters
Perl basics for PentestersPerl basics for Pentesters
Perl basics for Pentesters
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Troubleshooting Puppet
Troubleshooting PuppetTroubleshooting Puppet
Troubleshooting Puppet
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
 

Similar a The $path to knowledge: What little it take to unit-test Perl.

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...Rodolfo Carvalho
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it2shortplanks
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
A Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassA Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassCurtis Poe
 
How to Vim - for beginners
How to Vim - for beginnersHow to Vim - for beginners
How to Vim - for beginnersMarcin Rogacki
 
10 tips for making Bash a sane programming language
10 tips for making Bash a sane programming language10 tips for making Bash a sane programming language
10 tips for making Bash a sane programming languageYaroslav Tkachenko
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application frameworktechmemo
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 

Similar a The $path to knowledge: What little it take to unit-test Perl. (20)

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Perl Moderno
Perl ModernoPerl Moderno
Perl Moderno
 
Cleancode
CleancodeCleancode
Cleancode
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
IntroTestMore
IntroTestMoreIntroTestMore
IntroTestMore
 
IntroTestMore
IntroTestMoreIntroTestMore
IntroTestMore
 
A Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassA Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::Class
 
How to Vim - for beginners
How to Vim - for beginnersHow to Vim - for beginners
How to Vim - for beginners
 
10 tips for making Bash a sane programming language
10 tips for making Bash a sane programming language10 tips for making Bash a sane programming language
10 tips for making Bash a sane programming language
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application framework
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Laravel Day / Deploy
Laravel Day / DeployLaravel Day / Deploy
Laravel Day / Deploy
 
Git::Hooks
Git::HooksGit::Hooks
Git::Hooks
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 

Más de Workhorse Computing

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Workhorse Computing
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Workhorse Computing
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Workhorse Computing
 

Más de Workhorse Computing (18)

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.
 
Putting some "logic" in LVM.
Putting some "logic" in LVM.Putting some "logic" in LVM.
Putting some "logic" in LVM.
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Selenium sandwich-2
Selenium sandwich-2Selenium sandwich-2
Selenium sandwich-2
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium
 
Docker perl build
Docker perl buildDocker perl build
Docker perl build
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 

Último (20)

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 

The $path to knowledge: What little it take to unit-test Perl.

  • 1. The $path to Knowlege: What little it takes to test perl. Steven Lembark Workhorse Computing lembark@wrkhors.com
  • 2. Everyone wants to leave a legacy. Makes sense: Leave your mark on history.
  • 3. Everyone wants to leave a legacy. Makes sense: Leave your mark on history. What if your mark is history? It never changes. It never adapts. Forever frozen in the wastelands of 5.8.
  • 4. Growing beyond legacy. Any number of companies have legacy Perl code. Any number of reasons it isn’t upgraded. Then you decide to upgrade, get current. Now what?
  • 5. First step: Triage Obvious questions: What’s working? What’s broken? What’s next?
  • 6. First step: Triage Obvious questions: What’s working? What’s broken? What’s next? A: Let’s find out.
  • 7. Example I’ve worked for multiple clients with v5.8 code. Then they wanted to upgrade. Say to 5.2X or later. Undo a few decades of technical debt. Only takes a few weeks, right?
  • 8. So what? You test the code? Next step is testing lots of files. Repeating the same tests, over and over. Rule 1: Avoid Red Flags. Don’t copy, cut, or paste. Use Lazyness.
  • 9. Perl Somalier <https://www.perl.com/pub/2000/04/raceinfo.html/> The Repair Shop has aged well: Nice bouquet, pleasant aftertaste. All the things that make cleaning up code pleasing.
  • 10. Step 1: use perl. #!/usr/bin/env perl not /usr/bin/perl. Then check your path.
  • 11. Step 2: Find the perly files find lib -type f -name ‘*pm’; Skip shell programs: find bin scripts utils -type f | xargs file | grep ‘Perl’ | cut -d’:’ -f1 ;
  • 12. OK: unit test the files OK, so you copy a red flag... er... template for each... Define a datafile? Write the YAML file from hell? Create JSON from worse? Nope.
  • 13. Start with a path. Q: What do we need in order to unit test one module? A: Its path. /my/sandbox/XYX/lib/Foo/Bar.pm
  • 14. Start with a path. Q: What do we need in order to unit test one module? A: Its path. /my/sandbox/XYX/lib/Foo/Bar.pm Encoded in a symlink: ./t/01-pm/~my~sandbox~XYZ~lib~Foo~Bar.pm.t
  • 15. Start with a path. Q: What do we need in order to unit test one module? A: Its path. /my/sandbox/XYX/lib/Foo/Bar.pm Along with its package: ./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t
  • 16. Start with a path. Q: What do we need in order to unit test one module? A: Its path. /my/sandbox/XYX/lib/Foo/Bar.pm Along with its package: ./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t ~Foo~Bar
  • 17. Start with a path. Q: What do we need in order to unit test one module? A: Its path. /my/sandbox/XYX/lib/Foo/Bar.pm Along with its package: ./t/01-pm/~my~sandbox~XYZ~lib~~Foo~Bar.pm.t Foo::Bar
  • 18. Start with a path. use Test::More; use File::Basename; my $base0 = basename $0; my $sep = substr $base0, 0, 1; my $path = join '/' => split m{[$sep]}, $base0; my ($pkg) = $path =~ m{// (.+?) [.]pm$}x; my $pkg =~ s{W}{::}g; require_ok $path or skip "Failed require", 1; can_ok $pkg, 'VERSION' or skip "Missing packge: '$pkg' ($path)";
  • 19. Given a path and a packge... What else would you want to test? How about exports?
  • 20. Validating @EXPORT & @EXPORT_OK Basic problem: Exporting what isn’t. Undefined values in @EXPORT or @EXPORT_OK. Botched names.
  • 21. Validating @EXPORT & @EXPORT_OK Both can easily be checked. Symbol is your friend. qualify_to_ref is your buddy.
  • 22. Validating @EXPORT & @EXPORT_OK Starting with $path and $pkg: Require the path. Check for @EXPORT, @EXPORT_OK. Walk down whichever is defined. Check that the contents are defined.
  • 23. Validating @EXPORT & @EXPORT_OK # basic sanity checks: configured for exporting. require_ok $path or skip “oops...”, 1; isa_ok $pkg, ‘Exporter’ or skip “$pkg is not Exporter”; can_ok $path -> 'import' or do { diag “Botched $pkg: Exporter lacks ‘import’”; skip “$pkg cannot ‘import’” }; # hold off calling import until we have some values. # maybe a diag for can_ok
  • 24. Validating @EXPORT & @EXPORT_OK # second step: check the contents of EXPORT & _OK # require_ok doesn’t call import: need it for @EXPORT. for my $exp ( qw( EXPORT EXPORT_OK ) ) { my $ref = qualify_to_ref $exp => $pkg; my $found = *{$ref}{ARRAY} or next; note "Validate: $pkg $expn", explain $found; my @namz = @$found or skip "$pkg has empty '$exp'"; $pkg->import( @namz );
  • 25. Validating @EXPORT & @EXPORT_OK for my $name ( @namz ) { my $sigil = $name =~ m{^w} ? '&' : substr $name, 0, 1, '' ; if( ‘&’ eq $sigil ) { # anything exported should exist in both places. can_ok $pkg, $name; can_ok __PACKAGE__, $name; } else ...
  • 26. Validating @EXPORT & @EXPORT_OK ... { state $sig2type = [qw( @ ARRAY % HASH $ SCLALAR ...) ]; my $type = $sigil2type{ $sigil }; my $src = qualify_to_ref $name, $pkg; my $dst = qualify_to_ref $name, __PACKGE__; my $src_v = *{ $ref }{ $type } or do { diag “$pkg lacks ‘$name’”; next }; my $dst_v = *{ $dst }{ $type }; is_deeply $src_v, $dst_v, “$name exported from $pkg”; } }
  • 27. Ever get sick of typing “perl -wc”? Lazyness is a virtue: Let perl type it for you. All you need is the path, perl, and a version.
  • 28. Ever get sick of typing “perl -wc”? chomp ( my $perl = qx{ which perl } ); my $run_d = dirname $0; my $path = ( basename $0, '.t' ) =~ tr{~}{/}r; my $base = basename $path; SKIP: { -e $perl or skip "Non-existant: 'perl'"; -x $perl or skip "Non-executable: '$perl'"; -e $path or skip "Non-existant: '$path'"; -r $path or skip "Non-readable: '$path'"; -s $path or skip "Zero-sized: '$path'"; # at this point the test is run-able
  • 29. Ever get sick of typing “perl -wk”? chomp ( my $perl = qx{ which perl } ); # $^V isn’t perfect, but it’s a start. my $input = "(echo ‘use $^V’; cat $path)"; my $cmd = "$input | perl -wc -"; my $out = qx{ $cmd 2>&1 }; my $exit = $?; ok 0 == $exit, "Compile: '$base'"; $out eq "- Syntax OKn" or diag "nPerl diagnostic: '$path'n$outn"; }
  • 30. Ever get sick of typing “perl -wk”? chomp ( my $perl = qx{ which perl } ); # $^V isn’t perfect, but it’s a start. my $input = "(echo ‘use $^V’; cat $path)"; my $cmd = "$input | perl -wc -"; my $out = qx{ $cmd 2>&1 }; my $exit = $?; ok 0 == $exit, "Compile: '$base'"; $out eq "- Syntax OKn" or diag "nPerl diagnostic: '$path'n$outn"; }
  • 31. Prove is lazier than perl -wc for each file. Ouptut is quite paste-able: GitLab issue: ~~~perl <paste test output here> ~~~
  • 32. Cleaning up Exports Life begings with Globals.pm @EXPORT qw( … ); ~1500 entries. Can’t delete any: Nobody knows what’s used. Gotta maintain them all.
  • 33. Cleaning up Exports Life begings with Globals.pm @EXPORT qw( … ); ~1500 entries. Can’t delete any: Nobody knows what’s used. Gotta maintain them all. Not...
  • 34. Cleaning up Exports Tests give us @EXPORT* & diagnostics. Step 1: @EXPORT_OK Yes, this breaks all of the code. Result: We know what is missing.
  • 35. Cleaning up Exports Step 2: Diagnostics list undefined variables. Grep them out. Generate “use Global qw( … )” lines. Updates via perl -i -p. Result: We know what is used.
  • 36. Cleaning up Exports Step 3: Start removing unused exports. Look at what we added. Comment the rest. Test diag’s tell us when we go too far. And when to stop.
  • 37. Testing with Jenkins As always: There’s more than one way. One simple fix: ./devops/Jenkinsfile ./devops/run-tests
  • 38. Testing with Jenkins stage("Runtime Env") { steps { sh "uname -a" sh "hostname" sh "pwd -L" sh "pwd -P" sh "set" } }
  • 39. Testing with Jenkins stage("Run Tests") { environment { path = “${env.WORKSPACE_TMP + ‘/prove’}” } steps { sh "git submodule init" sh "git submodule update" sh "./devops/run-tests" } }
  • 40. Testing with Jenkins stage("Run Tests") { environment { path = “${env.WORKSPACE_TMP + ‘/prove’}” } steps { sh "git submodule init" sh "git submodule update" sh "./devops/run-tests" } }
  • 41. Testing with Jenkins #!/bin/bash -x perl -V; prove -V; echo “Ouput: ‘$path’”; cmd=”prove -r --jobs=4 --state=save --statefile=$path t”; cd $(dirname $0)/../..; ./t/bin/install-test-symlinks; $cmd 2>&1 | tee "$path.out";
  • 42. How do we know which files to test? Simple: Ask *.pm files are easy. Find #!perl files with find lib scripts utils progs apps -type f | xargs file | grep 'Perl' | cut -d':' -f1 | xargs ./t/bin/install-symlinks $dir ;
  • 43. Bits of Jenins Put site_perl into a git submodule. Advanced Options for Jenkins: Submodules. Allows shallow copy & recurse submodules. Maintain as a seprate repo: cpanm --local-lib=. --self-contained ... ; git add .; git commit -m’update CPAN’;
  • 44. Bits of Jenins environment { PERL5LIB = "$WORKSPACE/site_perl/lib/perl5" TEMPDIR = "$WORKSPACE_TMP" } Test & Package Perl with Jenkins Distribute your own cpan via ./site_perl. Nice place for a submodule. Catch: How do you find it?
  • 45. Bits of Jenins environment { PERL5LIB = "$WORKSPACE/site_perl/lib/perl5" TEMPDIR = "$WORKSPACE_TMP" } Test & Package Perl with Jenkins Distribute your own cpan via ./site_perl. Nice place for a submodule. Catch: How do you find it?
  • 46. Bits of Jenins environment { PERL5LIB = "$WORKSPACE/site_perl/lib/perl5" TEMPDIR = "$WORKSPACE_TMP" } Test & Package Perl with Jenkins Tee results or store ‘artifacts’.
  • 47. Net result: Paths can tell you a lot. Easy to acquire. Easy to use: basenames & require_ok. Explore with Symbol.
  • 48. Net result: Paths can tell you a lot. Jenkins’ plays nicely with Perl. Distribute tests from git. Including CPAN modules.