the fusioninventory projectguillomovitch/presentations/fosdem2012.pdf · glpi php plugin...

Post on 16-May-2020

11 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ProjectCoding challengesTesting challenges

The FusionInventory projectA perl hacker perspective

Guillaume Rousse

FOSDEM 2012

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Outline

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Outline

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

GLPI

OverviewIT assets inventory solution

inventoryhelpdesk

ArchitecturePHP applicationmodular

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

GLPI

OverviewIT assets inventory solution

inventoryhelpdesk

ArchitecturePHP applicationmodular

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

OCS-NG

OverviewAutonomous IT assets inventory solution

inventorysoftware deployment

ArchitectureServer side:

Perl agent interfacePHP user application

Agent side:Windows C agentUnix Perl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

OCS-NG

OverviewAutonomous IT assets inventory solution

inventorysoftware deployment

ArchitectureServer side:

Perl agent interfacePHP user application

Agent side:Windows C agentUnix Perl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Tracker

OverviewGLPI extension to deal with agentless devices

device discoveryremote inventory

ArchitecturePHP GLPI pluginPerl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Tracker

OverviewGLPI extension to deal with agentless devices

device discoveryremote inventory

ArchitecturePHP GLPI pluginPerl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Yesterday

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

FusionInventory

OverviewGeneric GLPI extension

merge of Unix OCS agent with Tracker agentmodular design

ArchitectureGLPI PHP pluginmulti-platform Perl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

FusionInventory

OverviewGeneric GLPI extension

merge of Unix OCS agent with Tracker agentmodular design

ArchitectureGLPI PHP pluginmulti-platform Perl agent

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Today

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Presentation

Componentsenginetasks

Task sampleslocal inventorynetwork discoveryremote network inventoryremote vmware inventorywake on lansoftware deployment

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Presentation

Componentsenginetasks

Task sampleslocal inventorynetwork discoveryremote network inventoryremote vmware inventorywake on lansoftware deployment

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Local inventory task

Hardware componentsCPU, memory, etc...USB, PCI, SCSI busesconnected devices

Software componentsoperating systeminstalled software

Configuration

network configurationdisplay configurationenvironment variables

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Local inventory task

Hardware componentsCPU, memory, etc...USB, PCI, SCSI busesconnected devices

Software componentsoperating systeminstalled software

Configuration

network configurationdisplay configurationenvironment variables

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Local inventory task

Hardware componentsCPU, memory, etc...USB, PCI, SCSI busesconnected devices

Software componentsoperating systeminstalled software

Configuration

network configurationdisplay configurationenvironment variables

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Network discovery

Network scanSNMP scannmap scannetbios scan

Device identificationSNMP fingerprinting

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Network discovery

Network scanSNMP scannmap scannetbios scan

Device identificationSNMP fingerprinting

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Network inventory

Printersink levelpage counters

Networking deviceports listvlans listconnected devices

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Network inventory

Printersink levelpage counters

Networking deviceports listvlans listconnected devices

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Server communication

Legacy OCS protocol

HTTP POST requestsXML format

FusionInventory protocolHTTP GET requestsJSON format

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Server communication

Legacy OCS protocol

HTTP POST requestsXML format

FusionInventory protocolHTTP GET requestsJSON format

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Not just GLPI

Other management solutionsRudderUranosOTRSPulse2

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Timeline

Versions2.0.x initial release2.1.x windows support2.2.x refactoring

roadmapswitch from XML to JSONswitch to POEmemory footprint reduction

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

HistoryAgent

Timeline

Versions2.0.x initial release2.1.x windows support2.2.x refactoring

roadmapswitch from XML to JSONswitch to POEmemory footprint reduction

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Outline

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Sysadmin-style code

Look ’ma, I’m a shell guru

# HPUX sof tware l i s t e x t r a c t i o n@sof tL is t = ‘ s w l i s t | grep −v ’ ^ PH ’ | grep −v ’ ^# ’ | t r −s " \ t " " " | t r −s " " ‘

What’s this syslog thing anyway ?

set logsock ( ’ un ix ’ ) ;openlog ( " fus ion inven to ry−agent " , ’ cons , p id ’ , $ENV{ ’USER ’ } ) ;sys log ( ’ debug ’ , ’ sys log backend enabled ’ ) ;c lose log ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Sysadmin-style code

Look ’ma, I’m a shell guru

# HPUX sof tware l i s t e x t r a c t i o n@sof tL is t = ‘ s w l i s t | grep −v ’ ^ PH ’ | grep −v ’ ^# ’ | t r −s " \ t " " " | t r −s " " ‘

What’s this syslog thing anyway ?

set logsock ( ’ un ix ’ ) ;openlog ( " fus ion inven to ry−agent " , ’ cons , p id ’ , $ENV{ ’USER ’ } ) ;sys log ( ’ debug ’ , ’ sys log backend enabled ’ ) ;c lose log ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Creative hacks

Dynamic function export

my $backendSharedFuncs = {can_run => sub {

. . .} ,

} ;

foreach my $package ( @packages ) {foreach my $func ( keys %{$backendSharedFuncs } ) {

$package−>{$func } = $backendSharedFuncs−>{$func } ;}

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Portability concerns

Contextthe agent runs an HTTP listener threadit forks itself to perform its duty

Code

# h t t p server main thread codesub DESTROY {

$_[0]−>{ l i s t e n e r }−> k i l l ( ’ KILL ’ ) i f $_[0]−>{ l i s t e n e r } ;}

# h t t p server l i s t e n e r thread codethreads−>se t_ th read_ex i t_on l y ( 1 ) ;$SIG { ’ KILL ’ } = sub { threads−>ex i t ( ) } ;

Trapfork() is emulated on Windows: the listener thread is lost

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Portability concerns

Contextthe agent runs an HTTP listener threadit forks itself to perform its duty

Code

# h t t p server main thread codesub DESTROY {

$_[0]−>{ l i s t e n e r }−> k i l l ( ’ KILL ’ ) i f $_[0]−>{ l i s t e n e r } ;}

# h t t p server l i s t e n e r thread codethreads−>se t_ th read_ex i t_on l y ( 1 ) ;$SIG { ’ KILL ’ } = sub { threads−>ex i t ( ) } ;

Trapfork() is emulated on Windows: the listener thread is lost

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Portability concerns

Contextthe agent runs an HTTP listener threadit forks itself to perform its duty

Code

# h t t p server main thread codesub DESTROY {

$_[0]−>{ l i s t e n e r }−> k i l l ( ’ KILL ’ ) i f $_[0]−>{ l i s t e n e r } ;}

# h t t p server l i s t e n e r thread codethreads−>se t_ th read_ex i t_on l y ( 1 ) ;$SIG { ’ KILL ’ } = sub { threads−>ex i t ( ) } ;

Trapfork() is emulated on Windows: the listener thread is lost

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Underlying code concerns

Contextthe network discovery task is multithreadedeach thread reports its result to the GLPI server

TrapOpenSSL is not thread-safe: crash with HTTPS

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

Underlying code concerns

Contextthe network discovery task is multithreadedeach thread reports its result to the GLPI server

TrapOpenSSL is not thread-safe: crash with HTTPS

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

LWP HTTPS support

Multiple SSL socket implementationsNet::SSL: certification authorityIO::Socket::SSL: certification authority, server hostname

Multiple LWP versionsLWP 5.x: no server certificate checkingLWP 6.x: server certificate checkingLWP 5.x on fedora: LWP 6.x behaviour backport

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Legacy codeEndless code traps

LWP HTTPS support

Multiple SSL socket implementationsNet::SSL: certification authorityIO::Socket::SSL: certification authority, server hostname

Multiple LWP versionsLWP 5.x: no server certificate checkingLWP 6.x: server certificate checkingLWP 5.x on fedora: LWP 6.x behaviour backport

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Outline

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Overview

GoalTo test interactions with an HTTP server

Examplesproxy usageSSL usagecertificates checking

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Overview

GoalTo test interactions with an HTTP server

Examplesproxy usageSSL usagecertificates checking

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Using a real server

Prosall features available

Conslimited availabilitylimited variability

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Using a real server

Prosall features available

Conslimited availabilitylimited variability

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Running a test server

Prosfull availabilityfull variability

Conslimited features

Used modulesHTTP::Server::SimpleHTTP::Server::Simple::AuthenIO::Socket::SSLHTTP::Proxy

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Running a test server

Prosfull availabilityfull variability

Conslimited features

Used modulesHTTP::Server::SimpleHTTP::Server::Simple::AuthenIO::Socket::SSLHTTP::Proxy

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Running a test server

Prosfull availabilityfull variability

Conslimited features

Used modulesHTTP::Server::SimpleHTTP::Server::Simple::AuthenIO::Socket::SSLHTTP::Proxy

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking the user agent

Test::MockObjectNot tested

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Testing command output parsing

GoalTesting the code parsing some command output

Initial code

my @output = ‘command ‘ ;foreach my $ l i n e ( @output ) {

i f ( $ l i n e =~ / ^ foo : ( . ∗ ) / ) {$ inventory−>addItem ( $1 ) ;

}}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Testing command output parsing

GoalTesting the code parsing some command output

Initial code

my @output = ‘command ‘ ;foreach my $ l i n e ( @output ) {

i f ( $ l i n e =~ / ^ foo : ( . ∗ ) / ) {$ inventory−>addItem ( $1 ) ;

}}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Abstraction layer

getFileHandle

sub getF i leHandle {my %params = @_;

my $handle ;

SWITCH: {i f ( $params { f i l e } ) {

i f ( ! open $handle , ’ < ’ , $params { f i l e } ) {carp "Can ’ t open f i l e $params { f i l e } : $ERRNO" ;return ;

}l as t SWITCH;

}i f ( $params {command } ) {

i f ( ! open $handle , ’−| ’ , $params {command} . " 2 >/dev / n u l l " ) {carp "Can ’ t run command $params {command } : $ERRNO" ;return ;

}l as t SWITCH;

}die " n e i t h e r command nor f i l e parameter given " ;

}

return $handle ;}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Code adaptation

Intermediate code

$inventory−>addItems ( $_ ) foreach get I tems ( ) ;

sub get I tems {my @output = ‘command ‘ ;my @items ;foreach my $ l i n e ( @output ) {

push @items , $1 i f $ l i n e =~ / ^ foo : ( . ∗ ) / ;}return @items

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Code adaptation

Final code

$inventory−>addItems ( $_ ) foreach get I tems (command => ’command ’ ) ;

sub get I tems {my $handle = getF i leHandle (@_) ;while (my $ l i n e = <$handle >) {

push @items , $1 i f $ l i n e =~ / ^ foo : ( . ∗ ) / ;}close $handle ;return @items ;

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Result availability concerns

Exotic files and commandsAIX lsvpd

HPUX machinfo

Linux Alpha /proc/cpuinfo

Samples collecting campaingresources treeorganisational concerns (tracability, ...)

Windows issuesregistryWMI

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Result availability concerns

Exotic files and commandsAIX lsvpd

HPUX machinfo

Linux Alpha /proc/cpuinfo

Samples collecting campaingresources treeorganisational concerns (tracability, ...)

Windows issuesregistryWMI

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Result availability concerns

Exotic files and commandsAIX lsvpd

HPUX machinfo

Linux Alpha /proc/cpuinfo

Samples collecting campaingresources treeorganisational concerns (tracability, ...)

Windows issuesregistryWMI

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Testing environment adaptation

GoalTesting the code selecting the command to run

Initial code

my @packages =−x ’ / b in / rpm ’ ? getRPMPackagesList (command => ’ rpm −qa ’ ) :−x ’ / b in / dpkg ’ ? getDPKGPackagesList (command => ’ dpkg − l ’ ) :−x ’ / b in / equery ’ ? getEqueryPackagesList (command => ’ equery l i s t − i ’ ) :

( ) ;}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Testing environment adaptation

GoalTesting the code selecting the command to run

Initial code

my @packages =−x ’ / b in / rpm ’ ? getRPMPackagesList (command => ’ rpm −qa ’ ) :−x ’ / b in / dpkg ’ ? getDPKGPackagesList (command => ’ dpkg − l ’ ) :−x ’ / b in / equery ’ ? getEqueryPackagesList (command => ’ equery l i s t − i ’ ) :

( ) ;}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Abstraction layer

canRun

sub canRun {my ( $wanted ) = @_;

return −x $wanted ;}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Code adaptation

Final code

my @packages =canRun ( ’ / b in / rpm ’ ) ? getRPMPackagesList (command => ’ rpm −qa ’ ) :canRun ( ’ / b in / dpkg ’ ) ? getDPKGPackagesList (command => ’ dpkg − l ’ ) :canRun ( ’ / b in / equery ’ ) ? getEqueryPackagesList (command => ’ equery l i s t − i ’ ) :

( ) ;}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Function hijacking

mockGetRun

sub mockCanRun {my (%params ) = @_;

my $new = sub {my $wanted = $_ [ 0 ] ;return $params {commands}−>{$wanted } ;

} ;

no warnings ’ rede f i ne ’ ;∗Fus ionInventory : : Agent : : Tools : : canRun = $new ;

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Function hijacking

mockGetFileHandle

sub mockGetFileHandle {my (%params ) = @_;

my $old = \& Fus ionInventory : : Agent : : Tools : : ge tF i leHandle ;

my $new = sub {my (%opt ions ) = @_;

my $ f i l e = $params {commands}−>{$wanted } ;

i f ( $ f i l e ) {pr in t STDERR " f i l e ’ $ f i l e ’ de l i ve red \ n " ;return $old−>(@_, f i l e => $ f i l e ) ;

} else {pr in t STDERR " noth ing de l i ve red \ n " ;return ;

}} ;

no warnings ’ rede f i ne ’ ;∗Fus ionInventory : : Agent : : Tools : : ge tF i leHandle = $new ;

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking a full environment

Code

package Fus ionInventory : : Test : : MockSystem : : Debian ;

use Fus ionInventory : : Test : : MockSystem ;

mockSystem (commands => {

’ dpkg ’ => ’ resources / packaging / dpkg ’} ,f i l e s => {

’ / e tc / debian_vers ion ’ => ’ resources / re lease / debian ’}

) ;

Usage

$> p e r l −MFusionInventory : : Test : : MockSystem : : Debian f u s i o n i n v e n t o r y

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking a full environment

Code

package Fus ionInventory : : Test : : MockSystem : : Debian ;

use Fus ionInventory : : Test : : MockSystem ;

mockSystem (commands => {

’ dpkg ’ => ’ resources / packaging / dpkg ’} ,f i l e s => {

’ / e tc / debian_vers ion ’ => ’ resources / re lease / debian ’}

) ;

Usage

$> p e r l −MFusionInventory : : Test : : MockSystem : : Debian f u s i o n i n v e n t o r y

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Plan

1 ProjectHistoryAgent

2 Coding challengesLegacy codeEndless code traps

3 Testing challengesTesting HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Compilation test

Test::More

use Test : : More ;

use_ok ( ’Some : : Module ’ ) ;use_ok ( ’ Another : : Module ’ ) ;

Test::Compile

use Test : : Compile ;

a l l _pm_f i l es_ok ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Compilation test

Test::More

use Test : : More ;

use_ok ( ’Some : : Module ’ ) ;use_ok ( ’ Another : : Module ’ ) ;

Test::Compile

use Test : : Compile ;

a l l _pm_f i l es_ok ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Module availability issues

Unix

package Some : : Module ;

use Win32 : : T ieReg is t r y ;

Windows

package Another : : Module ;

use Sys : : Syslog ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Module availability issues

Unix

package Some : : Module ;

use Win32 : : T ieReg is t r y ;

Windows

package Another : : Module ;

use Sys : : Syslog ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Workaround

Filtering

use Test : : Compile ;

my @fi les = $OSNAME eq ’MSWin32 ’ ?grep { ! / Another / } a l l _ p m _ f i l e s ( ’ l i b ’ ) :grep { ! /Some/ } a l l _ p m _ f i l e s ( ’ l i b ’ ) ;

a l l _pm_f i l es_ok ( @f i les ) ;

Loading modules at runtime

use UNIVERSAL : : require ;

Win32 : : T ieReg is t ry−>require ( ) ;Win32 : : T ieReg is t ry−>import ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Workaround

Filtering

use Test : : Compile ;

my @fi les = $OSNAME eq ’MSWin32 ’ ?grep { ! / Another / } a l l _ p m _ f i l e s ( ’ l i b ’ ) :grep { ! /Some/ } a l l _ p m _ f i l e s ( ’ l i b ’ ) ;

a l l _pm_f i l es_ok ( @f i les ) ;

Loading modules at runtime

use UNIVERSAL : : require ;

Win32 : : T ieReg is t ry−>require ( ) ;Win32 : : T ieReg is t ry−>import ( ) ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking module, trivial case

No exported symbol

use Win32 : : OLE : : Const ;

Testing code

$INC { ’ Win32 /OLE/ Const .pm ’ } = 1 ;

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking module, moderate case

Simple export

use Win32 : : OLE qw( i n CP_UTF8 ) ;

Mock module

package Win32 : : OLE;

use base ’ Expor ter ’ ;

our @EXPORT = qw( i n CP_UTF8 ) ;

1

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Mocking module, complex case

Complex export

use Win32 : : T ieReg is t r y (D e l i m i t e r => ’ / ’ ,ArrayValues => 0 ,qw /KEY_READ/

) ;

Mock module

package Win32 : : T ieReg is t r y ;

our $Regis t ry ;

sub import {my $ca l lpkg = c a l l e r ( ) ;no s t r i c t ’ r e f s ’ ;

∗{ " $ca l lpkg \ : : Reg is t ry " } = \ $Regis t ry ;∗{ " $ca l lpkg \ : : KEY_READ" } = sub { } ;

}

1

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Using mock modules

Testing code

i f ($OSNAME eq ’MSWin32 ’ ) {push @INC, ’ t / fake / un ix ’ ;

} else {push @INC, ’ t / fake / windows ’ ;

}

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Conclusion

Contactswww.fusioninventory.org#fusioninventory on freenodefusioninventory-user@lists.alioth.debian.org

Questions ?

Guillaume Rousse The FusionInventory project

ProjectCoding challengesTesting challenges

Testing HTTP server interactionsTesting system interactionsTesting modules compilation everywhere

Conclusion

Contactswww.fusioninventory.org#fusioninventory on freenodefusioninventory-user@lists.alioth.debian.org

Questions ?

Guillaume Rousse The FusionInventory project

top related