• No results found

Test Driven Deployment with (i)python and nosetest

N/A
N/A
Protected

Academic year: 2021

Share "Test Driven Deployment with (i)python and nosetest"

Copied!
23
0
0

Loading.... (view fulltext now)

Full text

(1)

Roberto Polli, Solutions Architect 18.04.2015

Test Driven Deployment with

(i)python and nosetest

(2)

Agenda

• Who? What? Why?

Who fears Continuous Delivery? • Test Driven Deployment

Case Study: the LDAP infrastructure • Writing tests

From test to setup

• Contributing to opensource

(3)

Who? What? Why?

• Roberto Polli - Solutions Architect @ par-tec.it. Loves writing in C, Java and Python. Red Hat Certified Engineer and Virtualization Administrator.

• Par-Tec – Proud sponsor of this talk ;) provides expertise in IT Infrastructure & Services and Business Intelligence solutions + Vertical Applications for the financial market. Contributes to various FLOSS.

• Implement a Test Driven Deployment strategy on big, legacy infrastructures: not an LDAP talk!

(4)

Who fears Continuous Delivery?

Legacy infrastructures:

Compliance to laws and regulations

"Old" software / libraries

resilient to new technologies ;)

Enterprise infrastructures

Slow release cycle

Eterogeneous environment

(5)

Who fears Continuous Delivery?

Legacy infrastructures:

Compliance to laws and regulations

"Old" software / libraries

resilient to new technologies ;)

Enterprise infrastructures

Slow release cycle

Eterogeneous environment

(6)

Who fears Continuous Delivery?

Why not add...

requiring...

and:

add external repositories →

Licenses, NOC

review upgrade policies SOC

modify network policies NOC

audit new services SOC

(7)

Who fears Continuous Delivery?

Switch to Continuous Delivery is hard:

customers are reluctant to distruptive changes;

operation teams must adapt to new technologies.

Use

Test Driven Deployment

and python:

testing is not disruptive;

ipython is easy to learn and use

shell compatibility

(8)

Test Driven Deployment

Write down infrastructural requirements

Create tests for each requirement

test configurations

test behavior

Setup/Update infrastructure

Run & Reuse tests for monitoring

(9)

Test Driven Deployment with python!

• Python is the way:

already installed on all Linux servers

– PSL: batteries included (POP, SMTP, IMAP, HTTP, Telnet, ...)

modules already in distribution repositories – further modules packaged as a zip file

interactive

• TL;DR

no external repositories – no policy changes

(10)

TDD Case Study: LDAP architecture

• Achievements

eliminate maintenance issues

– simplify major upgrades

identify issues and their effects on the platform – document with code

• Without reinventing the wheel!

python-ldap in all linux distros

– reused bugfix script from 389 Team

• Small footprint:

python already present on all nodes – further libs packed as one .zip file

(11)

TDD Case study: LDAP architecture

• How we applied TDD to this infrastructure:

~30 LDAP server

– replication and proxy topologies

(12)

TDD Strategy: Collect and Create

• Collect all LDAP-related platform requirements, eg:

passwords expire periodically; – fine-grained user ACL;

backend/frontend replication; – connectivity routes, ping, ...;

Create tests for every requirement

– failures explicits the symptoms on the platform eg. user can't change password

– human-readable configurations

(13)

Nose: Tests are easy

• Run every file and function starting with "test"

#nosetests ­v 

• Filter test files and functions with -m :

#nosetests ­v test_ldap.py ­m "replication" 

E

X

PL

IC

IT

N

A

M

ES

!

# test_ldap.py  # def test_password_policy_enabled():     ... def test_password_policy_admin():     ... def test_password_policy_user():

(14)

Writing tests: Document with code

• Describe the infrastructure with dicts, eg:

# # Specify slaves for each master # replication_t = {  'be5.foo.it': [ 'fe9.foo.it', 'fe10.foo.it'], 'be6.foo.it': [ 'fe9.foo.it', 'fe10.foo.it'], 'be7.foo.it': [ 'fe9.foo.it', 'fe10.foo.it'], ... }

(15)

Writing tests: for readability

• Keep test code simple!

Parametrize your tests with Nose yield feature

def test_replica():

    for master, slaves in replication_t.items():         for slave in slaves:

      # generate a single test case

      # for each master­slave agreement

      yield has_replica, master, slave # nosetests ­v ­m replica

test_replica('be1.foo.it', 'fe9.foo.it') ... ok

def has_replica(master, slave):

(16)

Writing tests: explicit is better than implicit

• Be verbose with hostnames and features

Goals

clarity versus operation teamavoid this:

'be{hostid}.foo.it'.format(hostid=hostid)

can use gethostname and getfqdn directly

backends_config = {  'be1.foo.it': [   {'name': 'userDb',     'cacheSize' : 1*GB, ..},   {'name': 'adminDb',     'cacheSize' : 1*MB, ..},  ],  ..} backends_config = {  '1': [     # name , cacheSize      ['user', (1<<30)],      ['admin', (1<<20)]  ], .. }

(17)

Writing tests: for usability

• Developed the first tests, iteratively improving the ldap library.

• The code evolved:

1- infrastructure tests code moved to the library => remove duplicate code, improved UX

(18)

Writing test: for usability

• Operation team learnt python via auto-completion and test code.

Code was focused for interactive use (eg. mnemonical names,

docstrings, ..) >>> from dsadmin import DSAdmin # verbose output via logs >>> logging.basicConfig(level=DEBUG) # connect to server using uris >>> cli = DSAdmin("ldaps://be1.foo.it") # get all databases on a server #  easier than bash #  ldapsearch … '(&(objectclass=nsBackendInstance)(..))' >>> cli.backend.list() 

(19)

From test to setup

● Write the setup code: next deployments will go unattended!

Use logging to produce an installation log.

Reuse infrastructure tests as functional tests for the setup code.Use the library with Ansible in new projects :D

def create_proxy_user():      ...   def create_backends():    my_backends = backends[getfqdn()]    for backend in my_backends:      ...create_backend with the given attributes...

(20)

Contribute to open source

• The open source model gave us the opportunity to contribute, widespread python...

(21)

Contribute to open source

• Give new life to a great part of your code, moving part of the tests to unit/functional tests of the library

(22)

Wrap up

• Continuous Delivery is not welcome everywhere

Test Driven Deployment in Python is a viable solution • Use iPython and Nose to introduce python to novices

Write tests starting from requirements • Then Update/Deploy servers

(23)

Thank you!

[email protected]

References

Related documents