Victor Vogelpoel

Excellence is in the details

SharePoint (2007) deployments controleren met PowerShell test framework

Leave a comment


Dit artikel is 3 oktober 2013 ook verschenen op de site van de Nederlandse SharePoint community SPCNL.nl.

De volgende technieken zijn ook heel goed bruikbaar bij de recentere SharePoint versies; de tests en scripts hieronder zijn oorspronkelijk geschreven voor SharePoint 2007.

De scripts uit dit artikel kun je vinden in het bijgesloten ZIP 20130923Test-PortalDeployment.zip.

De afgelopen jaren is elke drie jaar een nieuwe versie van SharePoint verschenen, maar overstappen naar een nieuwere versie is helemaal niet zo vanzelfsprekend. Soms blijft een klant nog even hangen bij die versie die het op dat moment goed genoeg doet. En met SharePoint 2007 krijg je meteen een uitdaging om deployment van componenten robuust te regelen, zeker als er sprake is van twee ontwikkelstraten met tussen de 1 en 5 servers in elke omgeving.

Omdat er veel herhaalde handelingen zitten in een deployment, is het scripten van deze handelingen echt een noodzaak. Niet alleen omdat je menselijke uitvoeringsfouten uitsluit, maar ook voor volledig geautomatiseerde uitrol. Een nachtelijke build moet de volgende ochtend klaar staan op een ‘development integration’ omgeving voor intake door de testers, waarbij de vorige build eerst netjes wordt verwijderd en vervolgens de verse build wordt geïnstalleerd. Na wat initieel gepeuter met CMD/BAT files en STSADM kwam ik in aanraking met PowerShell en ontdekte al snel dat ook SharePoint 2007 heel goed te manipuleren is met deze ‘task automation framework’ van Microsoft, maar ook om een deployment van een SharePoint oplossing goed is te controleren, in combinatie met een testing framework PSaint.

PowerShell en SharePoint

PowerShell is een commandline-shell en een scripting taal, gebouwd op het .NET framework en dat maakt PowerShell meteen de beste nieuwe vriend van elke automatiseerder die een Microsoft product wil manipuleren dat gebouwd is met .NET. Elk Microsoft product komt uit met een bijbehorende PowerShell module. Voor SharePoint is dat niet anders, maar SharePoint 2007 kent geen native PowerShell ondersteuning. Toch kun je het modernere PowerShell erg goed gebruiken met het oudje.

Even een SharePoint – PowerShell overzicht:

  • SharePoint 2013 is gebouwd op .NET 4. De SharePoint ‘snapin’ voor PowerShell v3 is de enige manier om deze SharePoint versie administratief te beheren (naast natuurlijk de administratieve web gui). PowerShell v4 komt binnenkort uit.
  • SharePoint 2010 kent nog stsadm.exe voor administratief beheer, maar deze SharePoint bevat al een een eerste versie van de officiële Microsoft SharePoint snapin voor PowerShell. SP2010 is gebouwd in .NET 3.5 en PowerShell versie 2 gebruik je om deze SharePoint versie te beheren via de commandline.
  • SharePoint 2007 kent alleen stsadm.exe voor beheerstaken. SP2007 is gebouwd op .NET 2; via C# (of VB.Net) kun je SharePoint via het object model manipuleren, maar dat kun je ook prima met PowerShell versie 1 of 2. Alleen: er is geen officiële snapin van Microsoft, maar slechts een handvol PowerShell script snippets op internet te vinden van een beperkt aantal enthousiastelingen. En daar zie je ook vaak het onbegrip van het juist disposen van SPSite, SPWeb objecten weer terugkomen, terwijl dat zo’n impact kan hebben op je SharePoint omgeving…
    De PowerShell ondersteuning voor SharePoint 2007 moet je dus voornamelijk zelf schrijven tegen het SP object model; ben je een SharePoint ontwikkelaar, dan heb je een stapje voor met het schrijven van scripts.

Deployments verifieren

Ik wilde oorspronkelijk een artikel schrijven over het deployen van SharePoint 2007 WSP solutions met behulp van PowerShell, maar daar kun je al legio artikelen en script code voor vinden. In dit artikel wil ik je laten zien dat PowerShell scripts wel heel fijn zijn om tegen SharePoint 2007 te praten en er deployments mee te controleren (naast het uitvoeren van de deployment).
Voor een klant heb ik ruim 500 PowerShell commando’s geschreven die de artefacts van twee SharePoint 2007 Portals & web services helpen bouwen, installeren, de-installeren en testen voor twee ontwikkelstraten met omgevingen die variëren van een single server farm tot een load balanced tripple-front-end SharePoint farm met load balanced dual-front-end WCF web services farm die praten tegen enterprise services en SAP/Integration. Het zijn niet alleen SharePoint gerelateerde commando’s, maar ook commando’s om te babbelen met de TFS Build- en Source Control server en algemenere commando’s om bijvoorbeeld web service bestanden te deployen of te controleren of de PowerShell sessie niet in 32-bit modus is gestart terwijl SharePoint in 64 bit modus werkt.

Nu kwam het wel eens voor dat na ‘onderhoud’, vervangen van een config file of een hotfix in de farm de portal niet helemaal lekker meer liep. En het vinden van het probleem was dan best uitdagend werk, met name als de farm niet onder mijn beheer stond, maar onder dat van de beheer afdeling. Ik wilde een instrument hebben om een omgeving op elk moment te (laten) kunnen controleren op verwachte staat; dus niet de functionele kant van de applicatie, maar of alle onderdelen van de applicatie geïnstalleerd staan waar ik verwacht dat ze zijn. Dat instrument moet mij eenvoudig kunnen laten zien of een artefact in de gewenste staat is of niet. PowerShell is ook hier een fijne vriend om die staat te controleren en inzichtelijk te maken. Denk daarbij aan:

  • Staan de verwachte WSP solutions wel in de SharePoint solution store?
  • Zijn de WSPs wel deployed naar de juiste web application?
  • Zijn de WSPs voor de ene portal juist niet gedeployed naar de web application van de andere portal?
  • Zijn de URL rewriting configuratie bestanden gelijk op elke front-end server?
  • Zijn de URL rewriting configuratie bestanden op elke front-end gelijk aan die in het deployment package?
  • En zo nog veel meer…

Ik heb een keer meegemaakt in de acceptatie omgeving dat een WSP voor de ene portal was deployed naar de web application van de andere portal en dat was niet de bedoeling; uiteraard had “niemand” dat gedaan en de deployment scripts zeker niet. Of dat een aanpassing in een url-rewriting configuratie bestand naar de ene front-end was gekopieerd, maar niet naar de andere, waardoor er in gemiddeld helft van de gevallen de portal niet reageerde op de URL zoals verwacht…

Dit soort verwachtingen zijn prima in PowerShell scripts te verwoorden en uit te voeren. Eigenlijk zijn het gewoon een soort niet-functionele systeemtesten. Deze testen zijn op elk moment weer te herhalen om direct een beeld te krijgen van de staat-van-deployment van de portals in de omgeving. En laten deze testen nu onderdeel zijn van het deployment package van de portal; op het moment dat de portal is gedeployed, zijn de testen ook beschikbaar.

PowerShell test framework PSaint

Er is een aantal test frameworks voor PowerShell; ik koos voor JayKul’s (Joel Bennett) PSaint. Joel Bennett is heel bedreven in PowerShell en beheert onder ander de PowerShell script code site POSHCODE.org.
Met PSaint is niet alleen makkelijk om een Arrange-Act-Assert tests op te stellen, maar PSaint was ook het enige framework waarbij elke test een TestResult object oplevert, wat je weer mooi kunt gebruiken in een pipeline om te filteren. Het TestResult object bevat members Name, Result en Category.

Test-Code "New-Guid outputs a Guid" {
  act {
    $guid = New-Guid
  }
  assert {
    $guid -is [string]
	New-Object Guid $guid
  }
}

Deze test zal een TestResult object teruggeven, die zo in de output wordt weergegeven op scherm:

Result Name                          Category
------ ----                          --------
Pass   New-Guid outputs a Guid

Op JayKul’s site kun je meer meer informatie vinden over PSaint: http://huddledmasses.org/arrange-act-assert-intuitive-testing/.
Ik heb wel een uitbreiding gemaakt: om de gebruiker ook te vertellen wát er is misgegaan in een gefaalde test, heb ik “FailMessage” toegevoegd aan de TestResult. Deze uitbreiding heb ik ook teruggekoppeld naar JayKul. Hij verwachtte eigenlijk niet dat iemand het ooit zou gebruiken…

Tests voor deployment verwachtingen schrijven

Elke deployment verwachting is nu in PSaint tests te beschrijven:

  • Wanneer een verwachting klopt, dan geeft de test “PASS
  • Wanneer een verwachting niet klopt, dan geeft de test “FAIL”.
    De FailMessage geeft aan wát er mis is met de verwachting.
  • Testen kunnen ook even uitgeschakeld worden: “SKIPPED

Als voorbeeld schrijf ik twee verwachtingen uit:

  1. Bestaat WSP solution met naam “framework_v1.0.0.0.WSP” in de solution store en is deze gedeployed? En eigenlijk wil ik dat deze test niet afhankelijk is van het versienummer in de naam van de WSP, dus ik gebruik een wildcard in de test bij mijn SP2007 Get-SPSolution script (dat met wildcards kan omgaan).
  2. Is de feature “Error Page control adapter” geactiveerd op web scope op de portal? Via mijn SP2007 Get-SPFeature script haal ik de SPFeature object op uit SharePoint en voer controles daarop uit.

De PSaint module bevat een aantal commando’s, waaronder Test-Code. Met Test-Code ga ik in het onderstaande voorbeeld controleren of een SharePoint feature is geïnstalleerd en geactiveerd op web application scope (Test-PortalDeployment.ps1). Het Test-Code commando levert een TestResult object op met het resultaat van de test. (Noot: Get-SPSolution en Get-SPFeature zijn custom script commands, die ik heb geschreven voor SharePoint 2007)

Test-Code "Solution framework_v*.WSP is installed in solution store" {
  arrange {
    $solutionName = "framework_v*.WSP"
  }
  act {
    $solution = Get-SPSolution $solutionName    # NOTE: mijn Get-SPSolution voor SharePoint 2007 ondersteunt wildcards!
  }
  assert {
    Assert-That { $solution –ne $null }   -FailMessage "Solution `"$solutionName`" not found in solution store"
    Assert-That { $solution.Deployed }    -FailMessage “Solution `"$solutionName`" is not deployed"
  }
}

Test-Code "Feature `"Error Page control adapter`" is activated (at web application scope)" {
  arrange {
    $webAppUrl                      = "http://portal.nl"
    $featureIdentity                = "Feature-ErrorPageControlAdapter"
    $featureIsInstalled             = $false
    $webAppScopedFeatureIsActivated = $false
  }
  act {
    # Get the feature from the list of all installed features in the server farm
    $feature            = Get-SPFeature -Identity $featureIdentity
    $featureIsInstalled = ($feature -ne $null -and $feature.Status -eq "Online")
    if ($featureIsInstalled)
    {
	  $webAppScopedFeatureIsActivated = ((Get-SPFeature -Identity $featureIdentity -WebAppUrl $webAppUrl) -ne $null)
    }
  }
  assert {
    Assert-That { $featureIsInstalled }             -FailMessage "Feature `"$featureIdentity`" is not installed in the farm."
    Assert-That { $webAppScopedFeatureIsActivated } -FailMessage "Feature `"$featureIdentity`" is not activated at webapplication `"$webAppUrl`"."
  }
}

Stel dat de solution en feature niet zijn geïnstalleerd, dan is dit het resultaat van de test:

Result Name                                                                          FailMessage
------ ----                                                                          --------
Fail   Solution framework_v*.WSP is installed in solution store                      Solution "framework_v*.WSP" not found in solution store
Fail   Feature "Error Page control adapter" is activated (at web application scope)  Feature "Feature-ErrorPageControlAdapter" is not installed in the farm.

En als feature wel is geïnstalleerd én geactiveerd op de “http://portal.nl” web application, maar de solution nog niet is geïnstalleerd:

Result Name                                                                          FailMessage
------ ----                                                                          --------
Fail   Solution framework_v*.WSP is installed in solution store                      Solution "framework_v*.WSP" not found in solution store
Pass   Feature "Error Page control adapter" is activated (at web application scope)

Afijn, je snapt wel dat je heel veel van dit soort testen kunt bedenken en schrijven.

Het Get-SPFeature commando heb ik zelf moeten schrijven voor SharePoint 2007; ook hier weer is het SharePoint 2007 object model gebruikt om de features te ontsluiten. In het source code bestand bij dit artikel vind je de script source code. Dit is de inhoud van het ZIP bestand:

  • /Modules/PSaint/PSaint.psm1 (en andere bestanden)
  • /Modules/Reflection/Reflection.psm1 (en andere bestanden)
  • Test-PortalDeployment.ps1

Bestand “Test-PortalDeployment.ps1” bevat alle script code om bovenstaande tests te doen: het SharePoint 2007 object model laden, de module PSaint importeren en script functions Get-SPSolution en Get-SPFeature voor SharePoint 2007. Als BONUS heb ik ook functions toegevoegd voor het installeren, deployen, retracten en verwijderen van WSP solutions op SharePoint 2007 te regelen:

  • Add-SPSolution,
  • Wait-SPSolutionJob,
  • Install-SPSolution,
  • Remove-SPSolution,
  • Uninstall-SPSolution,
  • ondersteunende functions Get-SPWebApplication, Get-SPWebApplicationCollection, New-GenericObject2

De script source code (excl PSaint module) vind je ook op mijn github account als gist.

Overige toepassingen van een PowerShell test framework

Er zijn nog veel meer gebieden waar je een PowerShell test framework kunt toepassen (naast testen van de deployment een SharePoint portal); denk daarbij eens aan:

Script quality tests

  • Unit testen voor commando’s: doet een command script wat je verwacht in alle variaties van parameters en parametersets? Werkt het commando ook goed in een pipeline?
  • Is voor elk commando een help topic geschreven?
  • Zijn er geen TODOs meer in de script definition van een commando? Ik zet namelijk vaak TODOs in de function definition van een script commando om me te helpen herinneren om later nog iets op te pakken; met deze tests controleer of ik alle TODOs heb verwerkt.
  • Zijn er geen TODOs meer in de conceptuele help topics?

Deployment package tests

  • Is het deployment package compleet? WSPs, content files, scripts, installatie handleiding, config bestanden, SPDisposeCheck reports en overige bestanden?
  • Zijn gegenereerde XML bestanden wel echt XML?
  • Zijn voor elke omgeving specifieke settings aanwezig?

Quality gate tests

  • Bevat SPDisposeCheck levert geen (nieuwe) issues aan in de SharePoint code?
  • Zijn de DLLs in het deployment package zijn RELEASE build (en niet DEBUG build)?
  • Bevat het deployment package alle benodigde files zoals release notes en een installatie handleiding?

Server Infrastucture tests

  • Is de server goed ingericht: zijn bijvoorbeeld SQLAliases geconfigureerd zoals verwacht?
  • Zijn rechten op specifieke directories juist ingesteld?
  • Zijn de web applications voor de portals aanwezig?

SmokeTests

  • Start de portal op na deployment?
  • Werkt URL-rewriting?
  • Zit die ene gemelde bug nog in die pagina?

Functionele tests

  • Staan de SharePoint site, groep, gebruikersrechten nog zoals verwacht?
  • Test scenario’s via Selenium scripts naspelen

BugTests

  • Zit die ene gemelde bug nog in die pagina?

Ik ben een fan van SharePoint en ik ben een fan van PowerShell. Mijn naam is Victor Vogelpoel en ik werk voor Macaw als een SharePoint Technical Specialist.
Heb ik je nu op leuke ideeën gebracht? Meldt het in het commentaar of neem contact met mij op.. Je kunt me bereiken op victor.vogelpoel@macaw.nl of twitter @victorvogelpoel.

Resources: Jaykul’s PSaint: http://huddledmasses.org/arrange-act-assert-intuitive-testing/

Advertisements

Author: Victor Vogelpoel

Dad, SharePoint technical specialist, PowerShell architect, photographer and just a guy whose life happens while trying planning it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s