Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TeamCity: Managing deployment dependencies for acceptance tests?

I'm trying to configure a set of build configurations in TeamCity 6 and am trying to model a specific requirement in the cleanest possible manner way enabled by TeamCity.

I have a set of acceptance tests (around 4-8 suites of tests grouped by the functional area of the system they pertain to) that I wish to run in parallel (I'll model them as build configurations so they can be distributed across a set of agents).

From my initial research, it seems that having a AcceptanceTests meta-build config that pulls in the set of individual Acceptance test configs via Snapshot dependencies should do the trick. Then all I have to do is say that my Commit build config should trigger AcceptanceTests and they'll all get pulled in. So, lets say I also have AcceptanceSuiteA, AcceptanceSuiteB and AcceptanceSuiteC

So far, so good (I know I could also turn it around the other way and cause the Commit config to trigger AcceptanceSuiteA, AcceptanceSuiteB and AcceptanceSuiteC - problem there is I need to manually aggregate the results to determine the overall success of the acceptance tests as a whole).

The complicating bit is that while AcceptanceSuiteC just needs some Commit artifacts and can then live on it's own, AcceptanceSuiteA and AcceptanceSuiteB need to:

  • DeploySite (lets say it takes 2 minutes and I cant afford to spin up a completely isolated one just for this run)
  • Run tests against the deployed site

The problem is that I need to be able to ensure that:

  • the website only gets configured once
  • The website does not get clobbered while the two suites are running

If I set up DeploySite as a build config and have AcceptanceSuiteA and AcceptanceSuiteB pull it in as a snapshot dependency, AFAICT:

  • a subsequent or parallel run of AcceptanceSuiteB could trigger another DeploySite which would clobber the deployment that AcceptanceSuiteA and/or AcceptanceSuiteB are in the middle of using.

While I can say Limit the number of simultaneously running builds to force only one to happen at a time, I need to have one at a time and not while the dependent pieces are still running.

Is there a way in TeamCity to model such a hierarchy?

EDIT: Ideas:-

A crap solution is that DeploySite could set a 'in use flag' marker and then have the AcceptanceTests config clear that flag [after AcceptanceSuiteA and AcceptanceSuiteB have completed]. The problem then becomes one of having the next DeploySite down the pipeline wait until said gate has been opened again (Doing a blocking wait within the build, doesnt feel right - I want it to be flagged as 'not yet started' rather than looking like it's taking a long time to do something). However this sort of stuff a flag over here and have this bit check it is the sort of mutable state / flakiness smell I'm trying to get away from.

EDIT 2: if I could programmatically alter the agent configuration, I could set Agent Requirements to require InUse=false and then set the flag when a deploy starts and clear it after the tests have run

like image 654
Ruben Bartelink Avatar asked Apr 11 '11 10:04

Ruben Bartelink


1 Answers

Seems you go look on the Jetbrains Devnet and YouTrack tracker first and remember to use the magic word clobber in your search.

Then you install groovy-plug and use the StartBuildPrecondition facility

To use the feature, add system.locks.readLock. or system.locks.writeLock. property to the build configuration. The build with writeLock will only start when there are no builds running with read or write locks of the same name. The build with readLock will only start when there are no builds running with write lock of the same name.

therein to manage the fact that the dependent configs 'read' and the DeploySite config 'writes' the shared item.

(This is not a full productised solution hence the tracker item remains open)

EDIT: And I still dont know whether the lock should be under Build Parameters|System Properties and what the exact name format should be, is it locks.writeLock.MYLOCKNAME (i.e., show up in config with reference syntax %system.locks.writeLock.MYLOCKNAME%) ?

Other puzzlers are: how does one manage giving builds triggered by build completion of a writeLock task read access - does the lock get dropped until the next one picks up (which would allow another writer in) - or is it necessary to have something queue up the parent and child dependency at the same time ?

like image 99
Ruben Bartelink Avatar answered Nov 03 '22 00:11

Ruben Bartelink