Merge branch 'master' into issues/162-impl-manual-promotion
Conflicts: features/api/webhook/multipleWebhooks.feature src/test/groovy/deploydb/WorkFlowSpec.groovy
This commit is contained in:
commit
2a51a4492e
|
@ -61,8 +61,10 @@ dependencies {
|
|||
|
||||
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
|
||||
testCompile 'cglib:cglib-nodep:2.2.+'
|
||||
testCompile project(':dropwizard-integtest')
|
||||
|
||||
cucumberCompile 'info.cukes:cucumber-groovy:1.2.+'
|
||||
cucumberCompile project(':dropwizard-integtest')
|
||||
|
||||
/* Include unboundid sdk for in-memory ldap test server */
|
||||
cucumberCompile 'com.unboundid:unboundid-ldapsdk:2.3.8'
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
database:
|
||||
driverClass: org.h2.Driver
|
||||
user: nobody
|
||||
url: "jdbc:h2:mem:cucumber"
|
||||
|
||||
# DeployDB base configuration directory (cannonical path)
|
||||
# YAML configuration files for models - services, environments, pipelines,
|
||||
# webhooks and promotions - should be stored in respective sub-directories
|
||||
#configDirectory: config
|
||||
|
||||
whoas:
|
||||
queue:
|
||||
type: "com.github.lookout.whoas.InMemoryQueue"
|
||||
runnerType: "com.github.lookout.whoas.SequentialHookRunner"
|
||||
|
||||
logging:
|
||||
level: INFO
|
||||
loggers:
|
||||
org.hibernate.SQL: ALL
|
||||
appenders:
|
||||
- type: file
|
||||
currentLogFilename: ./logs/deploydb-spock.log
|
||||
threshold: ALL
|
||||
archive: false
|
||||
timeZone: UTC
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,43 @@
|
|||
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'groovy'
|
||||
|
||||
version = '0.1'
|
||||
group = 'com.github.lookout.dropwizard.integtest'
|
||||
description = 'common deploydb test library to be used by both cukes and spock'
|
||||
|
||||
project.targetCompatibility = 1.7
|
||||
|
||||
dependencies {
|
||||
compile ('org.codehaus.groovy:groovy-all:2.4.0+')
|
||||
|
||||
[
|
||||
'dropwizard-core',
|
||||
'dropwizard-assets',
|
||||
'dropwizard-jersey',
|
||||
'dropwizard-hibernate',
|
||||
'dropwizard-views-mustache',
|
||||
'dropwizard-testing',
|
||||
].each {
|
||||
compile ("io.dropwizard:${it}:0.8.1")
|
||||
}
|
||||
|
||||
/* Used instead of the default HTTP connector for the Jersey client to
|
||||
* allow us to make PATCH requests
|
||||
*/
|
||||
compile ('org.glassfish.jersey.connectors:jersey-apache-connector:2.+')
|
||||
/* Used for managing migrations */
|
||||
compile ('io.dropwizard.modules:dropwizard-flyway:0.7.0-1')
|
||||
|
||||
compile ('joda-time:joda-time:2.6+')
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
|
||||
maven { url 'http://dl.bintray.com/lookout/systems' }
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package deploydb.cucumber
|
||||
package dropwizardintegtest
|
||||
|
||||
import com.google.common.base.Strings
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import deploydb.WebhookManager
|
||||
import deploydb.WorkFlow
|
||||
import io.dropwizard.Application
|
||||
import io.dropwizard.Configuration
|
||||
import io.dropwizard.cli.ServerCommand
|
||||
|
@ -33,8 +31,6 @@ public class StubAppRunner<C extends Configuration> {
|
|||
private Environment environment
|
||||
private Server jettyServer
|
||||
private SessionFactory sessionFactory
|
||||
private WorkFlow workFlow
|
||||
private WebhookManager webhookManager
|
||||
|
||||
public StubAppRunner(Class<? extends Application<C>> applicationClass,
|
||||
@Nullable String configPath,
|
||||
|
@ -78,30 +74,25 @@ public class StubAppRunner<C extends Configuration> {
|
|||
* it's up and running
|
||||
*/
|
||||
sessionFactory = application.sessionFactory
|
||||
webhookManager = application.webhooksManager
|
||||
|
||||
/**
|
||||
* Save workflow object
|
||||
*/
|
||||
workFlow = application.workFlow
|
||||
|
||||
/**
|
||||
* Setup config checksum for tests
|
||||
*/
|
||||
application.configChecksum = "0xdead"
|
||||
|
||||
/* We're running the DB migrations here to make sure we're running
|
||||
* them in the same classloader environment as the DeployDB
|
||||
* application, otherwise the Hibernate code running inside of
|
||||
* DeployDB won't be able to "see" the in-memory DB
|
||||
*/
|
||||
Flyway flyway = configuration.flyway.build(
|
||||
configuration.database.build(metricRegistry, "Flyway"))
|
||||
flyway.clean()
|
||||
flyway.migrate()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Setup config checksum for tests
|
||||
*/
|
||||
application.configChecksum = "0xdead"
|
||||
|
||||
/* We're running the DB migrations here to make sure we're running
|
||||
* them in the same classloader environment as the DeployDB
|
||||
* application, otherwise the Hibernate code running inside of
|
||||
* DeployDB won't be able to "see" the in-memory DB
|
||||
*/
|
||||
Flyway flyway = configuration.flyway.build(
|
||||
configuration.database.build(metricRegistry, "Flyway"))
|
||||
flyway.clean()
|
||||
flyway.migrate()
|
||||
|
||||
StubAppRunner.this.configuration = configuration
|
||||
StubAppRunner.this.environment = environment
|
||||
super.run(configuration, environment)
|
|
@ -1,4 +1,4 @@
|
|||
package deploydb.cucumber
|
||||
package dropwizardintegtest
|
||||
|
||||
import com.google.common.base.Strings
|
||||
import com.google.common.collect.ImmutableMap
|
||||
|
@ -12,8 +12,6 @@ import io.dropwizard.testing.ConfigOverride
|
|||
import net.sourceforge.argparse4j.inf.Namespace
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.server.ServerConnector
|
||||
import webhookTestServer.models.RequestWebhookObject
|
||||
import webhookTestServer.models.ResponseWebhookObject
|
||||
|
||||
import javax.annotation.Nullable
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package webhookTestServer.health
|
||||
package dropwizardintegtest
|
||||
|
||||
|
||||
import com.codahale.metrics.health.HealthCheck
|
|
@ -1,4 +1,4 @@
|
|||
package webhookTestServer.models
|
||||
package dropwizardintegtest
|
||||
|
||||
import com.google.common.collect.HashMultimap
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package webhookTestServer.models
|
||||
package dropwizardintegtest
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package webhookTestServer.resources
|
||||
package dropwizardintegtest
|
||||
|
||||
import com.codahale.metrics.annotation.Timed
|
||||
import com.google.common.base.Charsets
|
|
@ -1,10 +1,8 @@
|
|||
package webhookTestServer.resources
|
||||
package dropwizardintegtest
|
||||
|
||||
import io.dropwizard.hibernate.UnitOfWork
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import webhookTestServer.models.RequestWebhookObject
|
||||
import webhookTestServer.models.ResponseWebhookObject
|
||||
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.ws.rs.POST
|
|
@ -1,9 +1,6 @@
|
|||
package webhookTestServer
|
||||
package dropwizardintegtest
|
||||
|
||||
import io.dropwizard.setup.Bootstrap
|
||||
import webhookTestServer.models.RequestWebhookObject
|
||||
import webhookTestServer.models.ResponseWebhookObject
|
||||
import webhookTestServer.health.webhookTestServerHealthCheck
|
||||
|
||||
import io.dropwizard.Application
|
||||
import io.dropwizard.setup.Environment
|
||||
|
@ -43,8 +40,8 @@ class webhookTestServerApp extends Application<webhookTestServerConfiguration>{
|
|||
responseWebhookObject.responseCode = "201"
|
||||
responseWebhookObject.delayBeforeResponseInSecs = 0
|
||||
|
||||
environment.jersey().register(new resources.RootResource())
|
||||
environment.jersey().register(new resources.TestCallBackobjectResource(requestWebhookObject,
|
||||
environment.jersey().register(new RootResource())
|
||||
environment.jersey().register(new TestCallBackobjectResource(requestWebhookObject,
|
||||
responseWebhookObject))
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package webhookTestServer
|
||||
package dropwizardintegtest
|
||||
|
||||
import io.dropwizard.Configuration
|
||||
|
|
@ -2,6 +2,6 @@ description: "Basic Environment"
|
|||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://jenkins.example.com/job/basicEnv-deploy-created/build
|
||||
- http://localhost:10000/job/basicEnv-deploy-created/build
|
||||
completed:
|
||||
- http://jenkins.example.com/job/basicEnv-deploy-completed/build
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed/build
|
||||
|
|
|
@ -49,613 +49,4 @@ Feature: Webhook invocation when deployment is created with multiple webhooks
|
|||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Multiple environment webhooks should be invoked when artifacts are created
|
||||
Given an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created/build
|
||||
- http://localhost:10000/job/another-notify-deployment-created/build
|
||||
"""
|
||||
And promotions are configured
|
||||
And a pipeline is configured
|
||||
And a service is configured
|
||||
When I POST to "/api/artifacts" with an artifact
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Global webhook and environment webhook should be invoked when artifacts are created
|
||||
Given a deployment webhook "created" configuration:
|
||||
"""
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created/build
|
||||
"""
|
||||
And an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/another-notify-deployment-created/build
|
||||
"""
|
||||
And promotions are configured
|
||||
And a pipeline is configured
|
||||
And a service is configured
|
||||
When I POST to "/api/artifacts" with an artifact
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Both global and environment webhooks should be invoked when promotion is completed with success
|
||||
Given a promotion webhook "completed" configuration:
|
||||
"""
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
"""
|
||||
And an promotion environment webhook "completed" configuration named "pre-prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/another-notify-promotion-completed/build
|
||||
"""
|
||||
And there is a deployment in "COMPLETED" state
|
||||
And promotions are configured
|
||||
When I POST to "/api/deployments/1/promotions" with:
|
||||
"""
|
||||
{
|
||||
"name" : "jenkins-smoke",
|
||||
"status" : "SUCCESS",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results"
|
||||
}
|
||||
"""
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Only Global webhook should be invoked when environment webhooks doesn't contain deployment created event
|
||||
Given a deployment webhook "created" configuration:
|
||||
"""
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/notify-deployment-created/build
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
"""
|
||||
And an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
"""
|
||||
And promotions are configured
|
||||
And a pipeline is configured
|
||||
And a service is configured
|
||||
When I POST to "/api/artifacts" with an artifact
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Only environment webhooks should be invoked when global webhooks doesn't contain deployment created event
|
||||
Given a deployment webhook "created" configuration:
|
||||
"""
|
||||
deployment:
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
"""
|
||||
And an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/notify-deployment-created/build
|
||||
- http://localhost:10000/another-notify-deployment-created/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
"""
|
||||
And promotions are configured
|
||||
And a pipeline is configured
|
||||
And a service is configured
|
||||
When I POST to "/api/artifacts" with an artifact
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Only global webhooks should be invoked when environment webhooks doesn't contain deployment started event
|
||||
Given a deployment webhook "started" configuration:
|
||||
"""
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created/build
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
- http://localhost:10000/job/another-notify-deployment-started/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
- http://localhost:10000/job/another-notify-deployment-completed/build
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-completed-completed/build
|
||||
"""
|
||||
And an deployment environment webhook "started" configuration named "pre-prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/notify-deployment-created/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
"""
|
||||
And there is a deployment in "CREATED" state
|
||||
When I PATCH "/api/deployments/1" with:
|
||||
"""
|
||||
{
|
||||
"status" : "STARTED"
|
||||
}
|
||||
"""
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "STARTED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "STARTED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Global webhooks should be invoked when environment webhook doesn't contain promotion event for promotion success
|
||||
Given a promotion webhook "completed" configuration:
|
||||
"""
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
- http://localhost:10000/job/another-notify-promotion-completed/build
|
||||
"""
|
||||
And an promotion environment webhook "completed" configuration named "pre-prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
"""
|
||||
And there is a deployment in "COMPLETED" state
|
||||
And promotions are configured
|
||||
When I POST to "/api/deployments/1/promotions" with:
|
||||
"""
|
||||
{
|
||||
"name" : "jenkins-smoke",
|
||||
"status" : "SUCCESS",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results"
|
||||
}
|
||||
"""
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: Environment webhooks should be invoked when global webhook doesn't contain promotion event for promotion success
|
||||
Given a promotion webhook "completed" configuration:
|
||||
"""
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
- http://localhost:10000/job/another-notify-deployment-completed/build
|
||||
"""
|
||||
And an promotion environment webhook "completed" configuration named "pre-prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
- http://localhost:10000/job/another-notify-promotion-completed/build
|
||||
|
||||
"""
|
||||
And there is a deployment in "COMPLETED" state
|
||||
And promotions are configured
|
||||
When I POST to "/api/deployments/1/promotions" with:
|
||||
"""
|
||||
{
|
||||
"name" : "jenkins-smoke",
|
||||
"status" : "SUCCESS",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results"
|
||||
}
|
||||
"""
|
||||
Then the webhook 1 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
And the webhook 2 should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "VERIFIED",
|
||||
"service" : "faas",
|
||||
"environment" : "pre-prod",
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotionResult":{
|
||||
"id" : 1,
|
||||
"createdAt" : "{{created_timestamp}}",
|
||||
"promotion": "jenkins-smoke",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results",
|
||||
"status" : "SUCCESS"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: webhooks should be invoked for first environment in a pipeline
|
||||
Given an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
"""
|
||||
And an deployment environment webhook "created" configuration named "prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/prod-notify-deployment-started/build
|
||||
"""
|
||||
And promotions are configured
|
||||
And a multi environment pipeline is configured
|
||||
And a service is configured
|
||||
When I POST to "/api/artifacts" with an artifact
|
||||
Then the webhook should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 1,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cukes",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "integ",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
||||
|
||||
@freezetime @webhook
|
||||
Scenario: webhooks should be invoked for second environment in a pipeline
|
||||
Given an deployment environment webhook "created" configuration named "integ":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
"""
|
||||
And an deployment environment webhook "created" configuration named "prod":
|
||||
"""
|
||||
description: "DeployDB Primary Integration"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/prod-notify-deployment-started/build
|
||||
"""
|
||||
And the first deployments is in "COMPLETED" state
|
||||
And promotions are configured
|
||||
When I POST to "/api/deployments/1/promotions" with:
|
||||
"""
|
||||
{
|
||||
"name" : "status-check",
|
||||
"status" : "SUCCESS",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results"
|
||||
}
|
||||
"""
|
||||
Then the webhook should be invoked with the JSON:
|
||||
"""
|
||||
{
|
||||
"id" : 2,
|
||||
"artifact" : {
|
||||
"id" : 1,
|
||||
"group" : "com.example.cucumber",
|
||||
"name" : "cucumber-artifact",
|
||||
"version" : "1.0.1",
|
||||
"sourceUrl" : "http://example.com/maven/com.example.cucumber/cucumber-artifact/1.0.1/cucumber-artifact-1.0.1.jar",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
},
|
||||
"status" : "CREATED",
|
||||
"service" : "faas",
|
||||
"environment" : "prod",
|
||||
"createdAt" : "{{created_timestamp}}"
|
||||
}
|
||||
"""
|
|
@ -0,0 +1 @@
|
|||
include "dropwizard-integtest"
|
|
@ -1,24 +1,28 @@
|
|||
package deploydb.cucumber
|
||||
|
||||
import deploydb.models.Webhook.Webhook
|
||||
import deploydb.ModelLoader
|
||||
import deploydb.DeployDBApp
|
||||
import com.github.mustachejava.DefaultMustacheFactory
|
||||
import com.github.mustachejava.Mustache
|
||||
import deploydb.DeployDBApp
|
||||
import deploydb.ModelLoader
|
||||
import deploydb.models.Webhook.Webhook
|
||||
|
||||
import io.dropwizard.auth.basic.BasicCredentials
|
||||
import javax.ws.rs.core.Response
|
||||
|
||||
import org.glassfish.jersey.client.ClientConfig
|
||||
import javax.ws.rs.client.Client
|
||||
import javax.ws.rs.client.ClientBuilder
|
||||
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider
|
||||
import org.glassfish.jersey.client.JerseyInvocation
|
||||
import javax.ws.rs.core.Response
|
||||
import javax.ws.rs.client.Entity
|
||||
|
||||
import org.hibernate.Session
|
||||
import org.hibernate.SessionFactory
|
||||
import org.hibernate.context.internal.ManagedSessionContext
|
||||
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider
|
||||
import org.glassfish.jersey.client.ClientConfig
|
||||
import org.glassfish.jersey.client.JerseyInvocation
|
||||
import dropwizardintegtest.StubAppRunner
|
||||
import dropwizardintegtest.WebhookTestServerAppRunner
|
||||
import dropwizardintegtest.webhookTestServerApp
|
||||
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature
|
||||
import webhookTestServer.webhookTestServerApp
|
||||
|
||||
|
||||
class AppHelper {
|
||||
private StubAppRunner runner = null
|
||||
|
@ -53,7 +57,7 @@ class AppHelper {
|
|||
* @param c (required) Closure to execute
|
||||
*/
|
||||
void withServiceRegistry(Closure c) {
|
||||
c.call(this.runner.workFlow.serviceRegistry)
|
||||
c.call(this.runner.getApplication().workFlow.serviceRegistry)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +66,7 @@ class AppHelper {
|
|||
* @param c (required) Closure to execute
|
||||
*/
|
||||
void withEnvironmentRegistry(Closure c) {
|
||||
c.call(this.runner.workFlow.environmentRegistry)
|
||||
c.call(this.runner.getApplication().workFlow.environmentRegistry)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +75,7 @@ class AppHelper {
|
|||
* @param c (required) Closure to execute
|
||||
*/
|
||||
void withPromotionRegistry(Closure c) {
|
||||
c.call(this.runner.workFlow.promotionRegistry)
|
||||
c.call(this.runner.getApplication().workFlow.promotionRegistry)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,7 +84,7 @@ class AppHelper {
|
|||
* @param c (required) Closure to execute
|
||||
*/
|
||||
void withPipelineRegistry(Closure c) {
|
||||
c.call(this.runner.workFlow.pipelineRegistry)
|
||||
c.call(this.runner.getApplication().workFlow.pipelineRegistry)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,11 +93,11 @@ class AppHelper {
|
|||
* @param c (required) Closure to execute
|
||||
*/
|
||||
void withWorkFlow(Closure c) {
|
||||
c.call(this.runner.workFlow)
|
||||
c.call(this.runner.getApplication().workFlow)
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the {@link Closure} with a proper WebhookManager
|
||||
* Execute the {@link Closure} with a proper TestWebhookServer
|
||||
*
|
||||
* @param c (required) Closure to execute
|
||||
*/
|
||||
|
@ -224,14 +228,16 @@ class AppHelper {
|
|||
* For a valid webhook configuration, deployment and promotion are valid objects
|
||||
*/
|
||||
if (webhook != null && webhook.deployment != null) {
|
||||
eventUrlList = this.runner.webhookManager.getMemberOfObject(webhook.deployment, eventType)
|
||||
eventUrlList = this.runner.getApplication().webhooksManager.getMemberOfObject(
|
||||
webhook.deployment, eventType)
|
||||
}
|
||||
if (webhook != null && webhook.promotion != null) {
|
||||
/*
|
||||
* Only event type valid for promotion is "completed", ignore all other types
|
||||
*/
|
||||
if (eventType == "completed") {
|
||||
eventUrlList += this.runner.webhookManager.getMemberOfObject(webhook.promotion, eventType)
|
||||
eventUrlList += this.runner.getApplication().webhooksManager.getMemberOfObject(
|
||||
webhook.promotion, eventType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ import deploydb.models.Webhook.Webhook
|
|||
import deploydb.registry.ModelRegistry
|
||||
import org.joda.time.DateTime
|
||||
import cucumber.api.DataTable
|
||||
import webhookTestServer.models.RequestWebhookObject
|
||||
|
||||
import dropwizardintegtest.RequestWebhookObject
|
||||
|
||||
Given(~/^a (.*?) webhook "(.*?)" configuration:$/) { String webhookType,
|
||||
String eventType, String configBody ->
|
||||
|
|
|
@ -147,15 +147,7 @@ class DeployDBApp extends Application<DeployDBConfiguration> {
|
|||
* Load configuration models
|
||||
*/
|
||||
this.configDirectory = configuration.configDirectory
|
||||
withHibernateSession() {
|
||||
try {
|
||||
workFlow.loadConfigModels()
|
||||
} catch (Exception e) {
|
||||
logger.error("failed to read config from directory: " +
|
||||
"${configDirectory} with an exception: ", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
loadModelConfiguration()
|
||||
|
||||
/**
|
||||
* webhooksManager
|
||||
|
@ -211,4 +203,20 @@ class DeployDBApp extends Application<DeployDBConfiguration> {
|
|||
ManagedSessionContext.unbind(this.getSessionFactory())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will load configuration with hibernate session.
|
||||
*/
|
||||
void loadModelConfiguration(){
|
||||
withHibernateSession() {
|
||||
try {
|
||||
workFlow.loadConfigModels()
|
||||
} catch (Exception e) {
|
||||
logger.error("failed to read config from directory: " +
|
||||
"${configDirectory} with an exception: ", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
package deploydb
|
||||
|
||||
import spock.lang.*
|
||||
|
||||
class DeploymentCompletedNotificationsSpec extends Specification {
|
||||
|
||||
IntegrationTestAppHelper integAppHelper = new IntegrationTestAppHelper()
|
||||
IntegrationModelHelper integModelHelper = new IntegrationModelHelper(integAppHelper)
|
||||
private WebhooksModelConfigHelper mcfgHelper = new WebhooksModelConfigHelper()
|
||||
|
||||
def setup() {
|
||||
mcfgHelper.setup()
|
||||
integAppHelper.startAppWithConfiguration('deploydb.spock.yml')
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
integAppHelper.runner.getApplication().configDirectory = mcfgHelper.baseCfgDirName
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentcompleted.v1+json"
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
integAppHelper.stopApp()
|
||||
integAppHelper.stopWebhookTestServerApp()
|
||||
mcfgHelper.cleanup()
|
||||
}
|
||||
|
||||
def "no webhook should be called when you receive deployment completed trigger if there is no webhook config" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 0
|
||||
}
|
||||
|
||||
def "webhook should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentCompletedWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-completed/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "environment webhook should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentCompletedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-completed/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "both global and environment webhooks should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentCompletedWebhookConfigFile()
|
||||
mcfgHelper.createDeploymentCompletedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-completed/build","/job/basicEnv-deploy-completed/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple webhooks should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentCompletedWebhooksConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-completed-1/build", "/job/notify-deployment-completed-2/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple environments webhook should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentCompletedEnvironmentWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-completed-1/build","/job/basicEnv-deploy-completed-2/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "both multiple global and environment webhooks should be called when you receive deployment completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentCompletedWebhooksConfigFile()
|
||||
mcfgHelper.createMultipleDeploymentCompletedEnvironmentWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-completed-1/build", "/job/notify-deployment-completed-2/build",
|
||||
"/job/basicEnv-deploy-completed-1/build", "/job/basicEnv-deploy-completed-2/build"]
|
||||
|
||||
// setup the deployment for completed trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 4
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
package deploydb
|
||||
|
||||
import spock.lang.*
|
||||
|
||||
class DeploymentCreatedNotificationsSpec extends Specification {
|
||||
|
||||
IntegrationTestAppHelper integAppHelper = new IntegrationTestAppHelper()
|
||||
IntegrationModelHelper integModelHelper = new IntegrationModelHelper(integAppHelper)
|
||||
private WebhooksModelConfigHelper mcfgHelper = new WebhooksModelConfigHelper()
|
||||
|
||||
def setup() {
|
||||
mcfgHelper.setup()
|
||||
integAppHelper.startAppWithConfiguration('deploydb.spock.yml')
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentcreated.v1+json"
|
||||
integAppHelper.runner.getApplication().configDirectory = mcfgHelper.baseCfgDirName
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
integAppHelper.stopApp()
|
||||
integAppHelper.stopWebhookTestServerApp()
|
||||
mcfgHelper.cleanup()
|
||||
}
|
||||
|
||||
def "no webhook should be called when you create an artifact with no webhook configuration" () {
|
||||
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 0
|
||||
}
|
||||
|
||||
|
||||
def "webhook should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-created/build"]
|
||||
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "environment webhook should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createEnvironmentConfigFile()
|
||||
|
||||
// load up the config
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-created/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "both global and environment webhooks should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentConfigFile()
|
||||
|
||||
// load up the config
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-created/build", "/job/basicEnv-deploy-created/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple webhook should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleWebhooksConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-created-1/build", "/job/notify-deployment-created-2/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple environment webhook should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleWebhooksEnvironmentConfigFile()
|
||||
|
||||
// load up the config
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-created-1/build", "/job/basicEnv-deploy-created-2/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "both multiple global and multiple environment webhooks should be called when you create an artifact" () {
|
||||
|
||||
given:
|
||||
// create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleWebhooksConfigFile()
|
||||
mcfgHelper.createMultipleWebhooksEnvironmentConfigFile()
|
||||
|
||||
// load up the config
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-created-1/build", "/job/notify-deployment-created-2/build",
|
||||
"/job/basicEnv-deploy-created-1/build", "/job/basicEnv-deploy-created-2/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 4
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
package deploydb
|
||||
|
||||
import spock.lang.*
|
||||
|
||||
class DeploymentStartedNotificationsSpec extends Specification {
|
||||
|
||||
IntegrationTestAppHelper integAppHelper = new IntegrationTestAppHelper()
|
||||
IntegrationModelHelper integModelHelper = new IntegrationModelHelper(integAppHelper)
|
||||
private WebhooksModelConfigHelper mcfgHelper = new WebhooksModelConfigHelper()
|
||||
|
||||
def setup() {
|
||||
mcfgHelper.setup()
|
||||
integAppHelper.startAppWithConfiguration('deploydb.spock.yml')
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
integAppHelper.runner.getApplication().configDirectory = mcfgHelper.baseCfgDirName
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentstarted.v1+json"
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
integAppHelper.stopApp()
|
||||
integAppHelper.stopWebhookTestServerApp()
|
||||
mcfgHelper.cleanup()
|
||||
}
|
||||
|
||||
def "no webhook should be called when you receive deployment started trigger if there is no webhook config" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 0
|
||||
}
|
||||
|
||||
def "webhook should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentStartedWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-started/build"]
|
||||
|
||||
// setup the deployment for started trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "environment webhook should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentStartedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-started/build"]
|
||||
|
||||
// setup the deployment for started trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "both global and environment webhooks should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createDeploymentStartedWebhookConfigFile()
|
||||
mcfgHelper.createDeploymentStartedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-started/build","/job/basicEnv-deploy-started/build"]
|
||||
|
||||
// setup the deployment for started trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple webhooks should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentStartedWebhooksConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-started-1/build", "/job/notify-deployment-started-2/build"]
|
||||
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple environments webhook should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentStartedEnvironmentWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-started-1/build", "/job/basicEnv-deploy-started-2/build"]
|
||||
|
||||
|
||||
// setup the deployment for started trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "both multiple global and environment webhooks should be called when you receive deployment started trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultipleDeploymentStartedWebhooksConfigFile()
|
||||
mcfgHelper.createMultipleDeploymentStartedEnvironmentWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-deployment-started-1/build", "/job/notify-deployment-started-2/build",
|
||||
"/job/basicEnv-deploy-started-1/build", "/job/basicEnv-deploy-started-2/build"]
|
||||
|
||||
// setup the deployment for started trigger
|
||||
integModelHelper.sendCreateArtifact()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendDeploymentStartedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 4
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package deploydb
|
||||
|
||||
import deploydb.models.Artifact
|
||||
import javax.ws.rs.core.Response
|
||||
|
||||
class IntegrationModelHelper {
|
||||
|
||||
private IntegrationTestAppHelper integrationTestAppHelper = null
|
||||
IntegrationModelHelper(IntegrationTestAppHelper integTestAppHelper) {
|
||||
integrationTestAppHelper = integTestAppHelper
|
||||
}
|
||||
boolean sendCreateArtifact() {
|
||||
String path = "/api/artifacts"
|
||||
String messageBody = """
|
||||
{
|
||||
"group" : "basic.group.1",
|
||||
"name" : "bg1",
|
||||
"version" : "1.2.345",
|
||||
"sourceUrl" : "http://example.com/cucumber.jar"
|
||||
}
|
||||
"""
|
||||
return (integrationTestAppHelper.postJsonToPath(path, messageBody, false)).status == 201
|
||||
|
||||
}
|
||||
|
||||
boolean sendDeploymentStartedTrigger() {
|
||||
String path = "/api/deployments/1"
|
||||
String messageBody = """
|
||||
{
|
||||
"status" : "STARTED"
|
||||
}
|
||||
"""
|
||||
Response response = integrationTestAppHelper.patchJsonToPath(path, messageBody)
|
||||
response.close()
|
||||
return response.status == 200
|
||||
}
|
||||
|
||||
boolean sendDeploymentCompletedTrigger() {
|
||||
String path = "/api/deployments/1"
|
||||
String messageBody = """
|
||||
{
|
||||
"status" : "COMPLETED"
|
||||
}
|
||||
"""
|
||||
Response response = integrationTestAppHelper.patchJsonToPath(path, messageBody)
|
||||
response.close()
|
||||
return response.status == 200
|
||||
}
|
||||
|
||||
boolean sendPromotionCompletedTrigger() {
|
||||
String path = "/api/deployments/1/promotions"
|
||||
String messageBody = """
|
||||
{
|
||||
"name" : "basicPromo",
|
||||
"status" : "SUCCESS",
|
||||
"infoUrl" : "http://local.lookout.com/jenkins/job-id/2/results"
|
||||
}
|
||||
"""
|
||||
Response response = integrationTestAppHelper.postJsonToPath(path, messageBody, false)
|
||||
response.close()
|
||||
return response.status == 201
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package deploydb
|
||||
|
||||
import deploydb.models.Webhook.Webhook
|
||||
import com.github.mustachejava.DefaultMustacheFactory
|
||||
import com.github.mustachejava.Mustache
|
||||
|
||||
import org.glassfish.jersey.client.ClientConfig
|
||||
import javax.ws.rs.client.Client
|
||||
import javax.ws.rs.client.ClientBuilder
|
||||
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider
|
||||
import org.glassfish.jersey.client.JerseyInvocation
|
||||
import javax.ws.rs.core.Response
|
||||
import javax.ws.rs.client.Entity
|
||||
|
||||
import org.hibernate.Session
|
||||
import org.hibernate.SessionFactory
|
||||
import org.hibernate.context.internal.ManagedSessionContext
|
||||
import dropwizardintegtest.StubAppRunner
|
||||
import dropwizardintegtest.WebhookTestServerAppRunner
|
||||
import dropwizardintegtest.webhookTestServerApp
|
||||
|
||||
|
||||
class IntegrationTestAppHelper {
|
||||
private StubAppRunner runner = null
|
||||
private Client jerseyClient = null
|
||||
private WebhookTestServerAppRunner webhookRunner = null
|
||||
|
||||
SessionFactory getSessionFactory() {
|
||||
return this.runner.sessionFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the {@link Closure} with a properly set up
|
||||
* {@link org.hibernate.Session}
|
||||
*
|
||||
* @param c (required) Closure to execute with a session
|
||||
*/
|
||||
void withSession(Closure c) {
|
||||
final Session session = sessionFactory.openSession()
|
||||
try {
|
||||
ManagedSessionContext.bind(session)
|
||||
c.call()
|
||||
}
|
||||
finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String processTemplate(String buffer, Map scope) {
|
||||
DefaultMustacheFactory mf = new DefaultMustacheFactory()
|
||||
StringWriter writer = new StringWriter()
|
||||
Mustache m = mf.compile(new StringReader(buffer),
|
||||
'cuke-stash-compiler')
|
||||
m.execute(writer, scope)
|
||||
|
||||
return writer.toString()
|
||||
}
|
||||
|
||||
Client getClient() {
|
||||
if (this.jerseyClient == null) {
|
||||
ClientConfig clientConfig = new ClientConfig()
|
||||
clientConfig.connectorProvider(new ApacheConnectorProvider())
|
||||
this.jerseyClient = ClientBuilder.newClient(clientConfig)
|
||||
}
|
||||
return this.jerseyClient
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the proper full URL for our running app with the given path.
|
||||
*
|
||||
* If this is an admin request, we'll hit the admin port correctly
|
||||
*/
|
||||
String urlWithPort(String path, Boolean isAdmin) {
|
||||
int port = isAdmin ? runner.adminPort : runner.localPort
|
||||
return String.format("http://localhost:%d${path}", port)
|
||||
}
|
||||
|
||||
|
||||
JerseyInvocation makeRequestToPath(String path, String method, Entity entity) {
|
||||
return this.makeRequestToPath(path, method, entity, false)
|
||||
}
|
||||
|
||||
JerseyInvocation makeRequestToPath(String path, String method, Entity entity, Boolean isAdmin) {
|
||||
return client.target(urlWithPort(path, isAdmin))
|
||||
.request()
|
||||
.build(method, entity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a POST to the test server for step definitions
|
||||
*/
|
||||
Response postJsonToPath(String path, String requestBody, Boolean isAdmin) {
|
||||
return this.makeRequestToPath(path, 'POST', Entity.json(requestBody), isAdmin).invoke()
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a PATCH to the test server for step definitions
|
||||
*/
|
||||
Response patchJsonToPath(String path, String requestBody) {
|
||||
return this.makeRequestToPath(path, 'PATCH', Entity.json(requestBody)).invoke()
|
||||
}
|
||||
|
||||
Response deleteFromPath(String path) {
|
||||
return this.makeRequestToPath(path, 'DELETE', null).invoke()
|
||||
}
|
||||
|
||||
/*
|
||||
* Get url path from webhook config body
|
||||
*/
|
||||
List<String> getUrlPathFromWebhookConfigBody(String configBody, String eventType) {
|
||||
ModelLoader<Webhook> webhookLoader = new
|
||||
ModelLoader<Webhook>(Webhook.class)
|
||||
Webhook webhook = webhookLoader.loadFromString(configBody)
|
||||
return getUrlPathFromWebhook(webhook, configBody, eventType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Minor convenience method to make sure we're dispatching GET requests to the
|
||||
* right port in our test application
|
||||
*/
|
||||
Response getFromPath(String path, boolean isAdmin) {
|
||||
return this.makeRequestToPath(path, 'GET', null , isAdmin).invoke()
|
||||
}
|
||||
|
||||
/** Set config directory */
|
||||
void setConfigDirectory(String configDirectory) {
|
||||
this.runner.setConfigDirectory(configDirectory)
|
||||
}
|
||||
|
||||
void startAppWithConfiguration(String config) {
|
||||
if (this.runner != null) {
|
||||
return
|
||||
}
|
||||
println("start application with config ${config}")
|
||||
this.runner = new StubAppRunner(DeployDBApp.class, config)
|
||||
this.runner.start()
|
||||
}
|
||||
|
||||
|
||||
void stopApp() {
|
||||
if (this.runner != null) {
|
||||
this.runner.stop()
|
||||
}
|
||||
}
|
||||
|
||||
void startWebhookTestServerWithConfiguration(String config) {
|
||||
if (this.webhookRunner != null) {
|
||||
return
|
||||
}
|
||||
println("start webhook test server with config ${config}")
|
||||
this.webhookRunner = new WebhookTestServerAppRunner(webhookTestServerApp.class, config)
|
||||
this.webhookRunner.start()
|
||||
}
|
||||
|
||||
|
||||
void stopWebhookTestServerApp() {
|
||||
if (this.webhookRunner != null) {
|
||||
this.webhookRunner.stop()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
package deploydb
|
||||
|
||||
|
||||
class ModelConfigHelper {
|
||||
String baseCfgDirName = "./build/tmp/config"
|
||||
|
||||
def setup() {
|
||||
File baseCfgDir = new File(baseCfgDirName)
|
||||
if (baseCfgDir.exists()) {
|
||||
baseCfgDir.deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
File baseCfgDir = new File(baseCfgDirName)
|
||||
if (baseCfgDir.exists()) {
|
||||
baseCfgDir.deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def createEnvironmentWebhookConfigFile(String fileContents, String name) {
|
||||
/* Create temp file */
|
||||
File environmentsDir = new File("${baseCfgDirName}/environments")
|
||||
if (!environmentsDir.exists()) {
|
||||
environmentsDir.mkdirs()
|
||||
}
|
||||
|
||||
File environmentFile = new File(environmentsDir, "${name}.yml")
|
||||
environmentFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createBasicWebhookConfigFile(String fileContents) {
|
||||
/* Create temp file */
|
||||
File webhookDir = new File("${baseCfgDirName}/webhook")
|
||||
if (!webhookDir.exists()) {
|
||||
webhookDir.mkdirs()
|
||||
}
|
||||
|
||||
File webhookFile = new File(webhookDir, "basicWebhook.yml")
|
||||
webhookFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createPromotionConfigFile() {
|
||||
String fileContents = """
|
||||
type: deploydb.models.promotion.BasicPromotionImpl
|
||||
description: "Basic Smoke test for the Basic Service"
|
||||
"""
|
||||
/* Create temp file */
|
||||
File promotionsDir = new File("${baseCfgDirName}/promotions")
|
||||
if (!promotionsDir.exists()) {
|
||||
promotionsDir.mkdirs()
|
||||
}
|
||||
|
||||
File promotionFile = new File(promotionsDir, "basicPromo.yml")
|
||||
promotionFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createAnotherPromotionConfigFile() {
|
||||
String fileContents = """
|
||||
type: deploydb.models.promotion.ManualLDAPPromotionImpl
|
||||
description: "Advanced Smoke test for the Basic Service"
|
||||
"""
|
||||
/* Create temp file */
|
||||
File promotionsDir = new File("${baseCfgDirName}/promotions")
|
||||
if (!promotionsDir.exists()) {
|
||||
promotionsDir.mkdirs()
|
||||
}
|
||||
|
||||
File promotionFile = new File(promotionsDir, "advancedPromo.yml")
|
||||
promotionFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createEnvironmentConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/basicEnv-deploy-created/build
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createEnvironmentNoWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
|
||||
def createPipelineConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic pipeline"
|
||||
environments:
|
||||
basicEnv:
|
||||
promotions:
|
||||
- basicPromo
|
||||
"""
|
||||
/* Create temp file */
|
||||
File pipelinesDir = new File("${baseCfgDirName}/pipelines")
|
||||
if (!pipelinesDir.exists()) {
|
||||
pipelinesDir.mkdirs()
|
||||
}
|
||||
|
||||
File pipelineFile = new File(pipelinesDir, "basicPipe.yml")
|
||||
pipelineFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created/build
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createServiceConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Service"
|
||||
artifacts:
|
||||
- basic.group.1:bg1
|
||||
- basic.group.2:bg2
|
||||
pipelines:
|
||||
- basicPipe
|
||||
promotions:
|
||||
- basicPromo
|
||||
"""
|
||||
/* Create temp file */
|
||||
File servicesDir = new File("${baseCfgDirName}/services")
|
||||
if (!servicesDir.exists()) {
|
||||
servicesDir.mkdirs()
|
||||
}
|
||||
|
||||
File serviceFile = new File(servicesDir, "basicServ.yml")
|
||||
serviceFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createProdEnvironmentConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Production Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/prodEnv-deploy-created/build
|
||||
completed:
|
||||
- http://localhost:10000/job/prodEnv-deploy-completed/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "prodEnv")
|
||||
}
|
||||
|
||||
def createBasicProdPipelineConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic pipeline"
|
||||
environments:
|
||||
basicEnv:
|
||||
promotions:
|
||||
- basicPromo
|
||||
prodEnv:
|
||||
promotions:
|
||||
- basicPromo
|
||||
"""
|
||||
/* Create temp file */
|
||||
File pipelinesDir = new File("${baseCfgDirName}/pipelines")
|
||||
if (!pipelinesDir.exists()) {
|
||||
pipelinesDir.mkdirs()
|
||||
}
|
||||
|
||||
File pipelineFile = new File(pipelinesDir, "basicPipe.yml")
|
||||
pipelineFile.write(fileContents)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WebhooksModelConfigHelper extends deploydb.ModelConfigHelper {
|
||||
|
||||
|
||||
def createMultipleWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created-1/build
|
||||
- http://localhost:10000/job/notify-deployment-created-2/build
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started-1/build
|
||||
- http://localhost:10000/job/notify-deployment-started-2/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed-1/build
|
||||
- http://localhost:10000/job/notify-deployment-completed-2/build
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed-1/build
|
||||
- http://localhost:10000/job/notify-promotion-completed-2/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createMultipleWebhooksEnvironmentConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/basicEnv-deploy-created-1/build
|
||||
- http://localhost:10000/job/basicEnv-deploy-created-2/build
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createDeploymentStartedWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createDeploymentStartedEnvironmentWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
started:
|
||||
- http://localhost:10000/job/basicEnv-deploy-started/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createMultipleDeploymentStartedWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started-1/build
|
||||
- http://localhost:10000/job/notify-deployment-started-2/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createMultipleDeploymentStartedEnvironmentWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
started:
|
||||
- http://localhost:10000/job/basicEnv-deploy-started-1/build
|
||||
- http://localhost:10000/job/basicEnv-deploy-started-2/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createDeploymentCompletedWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createDeploymentCompletedEnvironmentWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createMultipleDeploymentCompletedWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed-1/build
|
||||
- http://localhost:10000/job/notify-deployment-completed-2/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createMultipleDeploymentCompletedEnvironmentWebhooksConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed-1/build
|
||||
- http://localhost:10000/job/basicEnv-deploy-completed-2/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createPromotionCompletedWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createPromotionCompletedEnvironmentWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-promotion-completed/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createMultiplePromotionCompletedWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed-1/build
|
||||
- http://localhost:10000/job/notify-promotion-completed-2/build
|
||||
"""
|
||||
createBasicWebhookConfigFile(fileContents)
|
||||
}
|
||||
|
||||
def createMultiplePromotionCompletedEnvironmentWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/basicEnv-promotion-completed-1/build
|
||||
- http://localhost:10000/job/basicEnv-promotion-completed-2/build
|
||||
"""
|
||||
createEnvironmentWebhookConfigFile(fileContents, "basicEnv")
|
||||
}
|
||||
|
||||
def createServicePromoitionPipelineModelsConfigFiles() {
|
||||
createPromotionConfigFile()
|
||||
createPipelineConfigFile()
|
||||
createServiceConfigFile()
|
||||
}
|
||||
|
||||
def createBasicProdServicePromoitionPipelineModelsConfigFiles() {
|
||||
createEnvironmentConfigFile()
|
||||
createProdEnvironmentConfigFile()
|
||||
createPromotionConfigFile()
|
||||
createBasicProdPipelineConfigFile()
|
||||
createServiceConfigFile()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package deploydb
|
||||
|
||||
import spock.lang.*
|
||||
|
||||
class MultipleEnvironmentsNotificationsSpec extends Specification {
|
||||
|
||||
IntegrationTestAppHelper integAppHelper = new IntegrationTestAppHelper()
|
||||
IntegrationModelHelper integModelHelper = new IntegrationModelHelper(integAppHelper)
|
||||
private WebhooksModelConfigHelper mcfgHelper = new WebhooksModelConfigHelper()
|
||||
|
||||
def setup() {
|
||||
mcfgHelper.setup()
|
||||
integAppHelper.startAppWithConfiguration('deploydb.spock.yml')
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
integAppHelper.runner.getApplication().configDirectory = mcfgHelper.baseCfgDirName
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentcreated.v1+json"
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
integAppHelper.stopApp()
|
||||
integAppHelper.stopWebhookTestServerApp()
|
||||
mcfgHelper.cleanup()
|
||||
}
|
||||
|
||||
/**
|
||||
* This integration tests end-to-end scenario when multiple environment are configured in
|
||||
* pipeline. In this scenario multiple deployments are created and once a given deployment
|
||||
* is verified with promotion result, then we transition to next deployment.
|
||||
*
|
||||
*/
|
||||
def "multiple notifications should be called when configured with multiple environment pipeline" () {
|
||||
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createBasicProdServicePromoitionPipelineModelsConfigFiles()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-created/build"]
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendCreateArtifact()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
|
||||
when:
|
||||
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentcompleted.v1+json"
|
||||
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-created/build", "/job/basicEnv-deploy-completed/build"]
|
||||
|
||||
success = integModelHelper.sendDeploymentCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
|
||||
when:
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.deploymentcreated.v1+json"
|
||||
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-deploy-created/build", "/job/basicEnv-deploy-completed/build",
|
||||
"/job/prodEnv-deploy-created/build"]
|
||||
|
||||
success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 3
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
package deploydb
|
||||
|
||||
import spock.lang.*
|
||||
|
||||
class PromotionCompletedNotificationsSpec extends Specification {
|
||||
|
||||
IntegrationTestAppHelper integAppHelper = new IntegrationTestAppHelper()
|
||||
IntegrationModelHelper integModelHelper = new IntegrationModelHelper(integAppHelper)
|
||||
private WebhooksModelConfigHelper mcfgHelper = new WebhooksModelConfigHelper()
|
||||
|
||||
def setup() {
|
||||
mcfgHelper.setup()
|
||||
integAppHelper.startAppWithConfiguration('deploydb.spock.yml')
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().configDirectory = mcfgHelper.baseCfgDirName
|
||||
|
||||
integAppHelper.webhookRunner.requestWebhookObject.contentTypeParam =
|
||||
"application/vnd.deploydb.promotioncompleted.v1+json"
|
||||
integAppHelper.startWebhookTestServerWithConfiguration('webhookTestServer.example.yml')
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
integAppHelper.stopApp()
|
||||
integAppHelper.stopWebhookTestServerApp()
|
||||
mcfgHelper.cleanup()
|
||||
}
|
||||
|
||||
def setupDeploymentForPromotionTrigger(){
|
||||
|
||||
|
||||
integModelHelper.sendCreateArtifact()
|
||||
integModelHelper.sendDeploymentStartedTrigger()
|
||||
integModelHelper.sendDeploymentCompletedTrigger()
|
||||
}
|
||||
|
||||
def "no webhook should be called when you receive promotion completed trigger if there is no webhook config" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
// setup the deployment for promotion trigger
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 0
|
||||
}
|
||||
|
||||
def "webhook should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createPromotionCompletedWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-promotion-completed/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "environment webhook should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createPromotionCompletedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-promotion-completed/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 1
|
||||
}
|
||||
|
||||
def "both global and environment webhooks should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createPromotionCompletedWebhookConfigFile()
|
||||
mcfgHelper.createPromotionCompletedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-promotion-completed/build","/job/basicEnv-promotion-completed/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple webhooks should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultiplePromotionCompletedWebhookConfigFile()
|
||||
mcfgHelper.createEnvironmentNoWebhooksConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-promotion-completed-1/build", "/job/notify-promotion-completed-2/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "multiple environment webhooks should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultiplePromotionCompletedEnvironmentWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/basicEnv-promotion-completed-1/build", "/job/basicEnv-promotion-completed-2/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 2
|
||||
}
|
||||
|
||||
def "both multiple global and environment webhooks should be called when you receive promotion completed trigger" () {
|
||||
given:
|
||||
// Create the required config
|
||||
mcfgHelper.createServicePromoitionPipelineModelsConfigFiles()
|
||||
mcfgHelper.createMultiplePromotionCompletedEnvironmentWebhookConfigFile()
|
||||
mcfgHelper.createMultiplePromotionCompletedWebhookConfigFile()
|
||||
|
||||
// load up the configuration
|
||||
integAppHelper.runner.getApplication().loadModelConfiguration()
|
||||
|
||||
/* set the webhookTestServer's requestWebhookObject. This data will be compare once deploydb
|
||||
* sends the webhook to the webhookTestServer
|
||||
*/
|
||||
integAppHelper.webhookRunner.requestWebhookObject.configuredUriPaths =
|
||||
["/job/notify-promotion-completed-1/build", "/job/notify-promotion-completed-2/build",
|
||||
"/job/basicEnv-promotion-completed-1/build", "/job/basicEnv-promotion-completed-2/build"]
|
||||
|
||||
setupDeploymentForPromotionTrigger()
|
||||
|
||||
when:
|
||||
boolean success = integModelHelper.sendPromotionCompletedTrigger()
|
||||
|
||||
then:
|
||||
success == true
|
||||
sleep(1000)
|
||||
integAppHelper.webhookRunner.requestWebhookObject.requestMessageBodies.size() == 4
|
||||
}
|
||||
}
|
|
@ -18,14 +18,15 @@ class WorkFlowSpec extends Specification {
|
|||
}
|
||||
|
||||
class workFlowWithArgsSpec extends Specification {
|
||||
private String baseCfgDirName = "./build/tmp/config"
|
||||
private ModelConfigHelper modelConfigHelper = new ModelConfigHelper()
|
||||
private DeployDBApp app = new DeployDBApp()
|
||||
private WorkFlow workFlow
|
||||
private FlowDAO fdao = Mock(FlowDAO)
|
||||
private ModelConfigDAO mdao = Mock(ModelConfigDAO)
|
||||
|
||||
def setup() {
|
||||
app.configDirectory = baseCfgDirName
|
||||
modelConfigHelper.setup()
|
||||
app.configDirectory = modelConfigHelper.baseCfgDirName
|
||||
app.configChecksum = null
|
||||
workFlow = new WorkFlow(app)
|
||||
workFlow.initializeRegistry()
|
||||
|
@ -34,132 +35,16 @@ class workFlowWithArgsSpec extends Specification {
|
|||
}
|
||||
|
||||
def cleanup() {
|
||||
File baseCfgDir = new File(baseCfgDirName)
|
||||
if (baseCfgDir.exists()) {
|
||||
baseCfgDir.deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def createPromotionConfigFile() {
|
||||
String fileContents = """
|
||||
type: deploydb.models.promotion.BasicPromotionImpl
|
||||
description: "Basic Smoke test for the Basic Service"
|
||||
"""
|
||||
/* Create temp file */
|
||||
File promotionsDir = new File("${baseCfgDirName}/promotions")
|
||||
if (!promotionsDir.exists()) {
|
||||
promotionsDir.mkdirs()
|
||||
}
|
||||
|
||||
File promotionFile = new File(promotionsDir, "basicPromo.yml")
|
||||
promotionFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createAnotherPromotionConfigFile() {
|
||||
String fileContents = """
|
||||
type: deploydb.models.promotion.ManualLDAPPromotionImpl
|
||||
description: "Manual LDAP Promotion"
|
||||
"""
|
||||
/* Create temp file */
|
||||
File promotionsDir = new File("${baseCfgDirName}/promotions")
|
||||
if (!promotionsDir.exists()) {
|
||||
promotionsDir.mkdirs()
|
||||
}
|
||||
|
||||
File promotionFile = new File(promotionsDir, "advancedPromo.yml")
|
||||
promotionFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createEnvironmentConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Environment"
|
||||
webhook:
|
||||
deployment:
|
||||
created:
|
||||
- http://jenkins.example.com/job/basicEnv-deploy-created/build
|
||||
completed:
|
||||
- http://jenkins.example.com/job/basicEnv-deploy-completed/build
|
||||
"""
|
||||
/* Create temp file */
|
||||
File environmentsDir = new File("${baseCfgDirName}/environments")
|
||||
if (!environmentsDir.exists()) {
|
||||
environmentsDir.mkdirs()
|
||||
}
|
||||
|
||||
File environmentFile = new File(environmentsDir, "basicEnv.yml")
|
||||
environmentFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createPipelineConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic pipeline"
|
||||
environments:
|
||||
basicEnv:
|
||||
promotions:
|
||||
- basicPromo
|
||||
"""
|
||||
/* Create temp file */
|
||||
File pipelinesDir = new File("${baseCfgDirName}/pipelines")
|
||||
if (!pipelinesDir.exists()) {
|
||||
pipelinesDir.mkdirs()
|
||||
}
|
||||
|
||||
File pipelineFile = new File(pipelinesDir, "basicPipe.yml")
|
||||
pipelineFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createServiceConfigFile() {
|
||||
String fileContents = """
|
||||
description: "Basic Service"
|
||||
artifacts:
|
||||
- basic.group.1:bg1
|
||||
- basic.group.2:bg2
|
||||
pipelines:
|
||||
- basicPipe
|
||||
promotions:
|
||||
- basicPromo
|
||||
"""
|
||||
/* Create temp file */
|
||||
File servicesDir = new File("${baseCfgDirName}/services")
|
||||
if (!servicesDir.exists()) {
|
||||
servicesDir.mkdirs()
|
||||
}
|
||||
|
||||
File serviceFile = new File(servicesDir, "basicServ.yml")
|
||||
serviceFile.write(fileContents)
|
||||
}
|
||||
|
||||
def createWebhookConfigFile() {
|
||||
String fileContents = """
|
||||
deployment:
|
||||
created:
|
||||
- http://localhost:10000/job/notify-deployment-created/build
|
||||
started:
|
||||
- http://localhost:10000/job/notify-deployment-started/build
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-deployment-completed1/build
|
||||
- http://localhost:10000/job/notify-deployment-completed2/build
|
||||
promotion:
|
||||
completed:
|
||||
- http://localhost:10000/job/notify-promotion-completed/build
|
||||
"""
|
||||
/* Create temp file */
|
||||
File webhookDir = new File("${baseCfgDirName}/webhook")
|
||||
if (!webhookDir.exists()) {
|
||||
webhookDir.mkdirs()
|
||||
}
|
||||
|
||||
File webhookFile = new File(webhookDir, "basicWebhook.yml")
|
||||
webhookFile.write(fileContents)
|
||||
modelConfigHelper.cleanup()
|
||||
}
|
||||
|
||||
def "Load entire config from a directory and make sure it passes"() {
|
||||
given:
|
||||
createPromotionConfigFile()
|
||||
createEnvironmentConfigFile()
|
||||
createPipelineConfigFile()
|
||||
createServiceConfigFile()
|
||||
createWebhookConfigFile()
|
||||
modelConfigHelper.createPromotionConfigFile()
|
||||
modelConfigHelper.createEnvironmentConfigFile()
|
||||
modelConfigHelper.createPipelineConfigFile()
|
||||
modelConfigHelper.createServiceConfigFile()
|
||||
modelConfigHelper.createWebhookConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
mdao.persist(_) >> _
|
||||
|
||||
|
@ -177,8 +62,8 @@ promotion:
|
|||
|
||||
def "If promotion is missing, then loading pipeline in loadConfigModels throws an exception"() {
|
||||
when:
|
||||
createEnvironmentConfigFile()
|
||||
createPipelineConfigFile()
|
||||
modelConfigHelper.createEnvironmentConfigFile()
|
||||
modelConfigHelper.createPipelineConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
mdao.persist(_) >> _
|
||||
|
||||
|
@ -188,8 +73,8 @@ promotion:
|
|||
|
||||
def "If environment is missing, then loading pipeline in loadConfigModels throws an exception"() {
|
||||
when:
|
||||
createPromotionConfigFile()
|
||||
createPipelineConfigFile()
|
||||
modelConfigHelper.createPromotionConfigFile()
|
||||
modelConfigHelper.createPipelineConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
mdao.persist(_) >> _
|
||||
|
||||
|
@ -199,9 +84,9 @@ promotion:
|
|||
|
||||
def "If pipeline is missing, then loading service in loadConfigModels throws an exception"() {
|
||||
when:
|
||||
createPromotionConfigFile()
|
||||
createEnvironmentConfigFile()
|
||||
createServiceConfigFile()
|
||||
modelConfigHelper.createPromotionConfigFile()
|
||||
modelConfigHelper.createEnvironmentConfigFile()
|
||||
modelConfigHelper.createServiceConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
mdao.persist(_) >> _
|
||||
|
||||
|
@ -212,11 +97,11 @@ promotion:
|
|||
|
||||
def "Reload unchanged config from a directory and make sure its ignored"() {
|
||||
given:
|
||||
createPromotionConfigFile()
|
||||
createEnvironmentConfigFile()
|
||||
createPipelineConfigFile()
|
||||
createServiceConfigFile()
|
||||
createWebhookConfigFile()
|
||||
modelConfigHelper.createPromotionConfigFile()
|
||||
modelConfigHelper.createEnvironmentConfigFile()
|
||||
modelConfigHelper.createPipelineConfigFile()
|
||||
modelConfigHelper.createServiceConfigFile()
|
||||
modelConfigHelper.createWebhookConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
String oldChecksum = app.configChecksum
|
||||
mdao.persist(_) >> _
|
||||
|
@ -231,14 +116,14 @@ promotion:
|
|||
|
||||
def "Reload changed config from a directory and make sure it passes"() {
|
||||
given:
|
||||
createPromotionConfigFile()
|
||||
createEnvironmentConfigFile()
|
||||
createPipelineConfigFile()
|
||||
createServiceConfigFile()
|
||||
createWebhookConfigFile()
|
||||
modelConfigHelper.createPromotionConfigFile()
|
||||
modelConfigHelper.createEnvironmentConfigFile()
|
||||
modelConfigHelper.createPipelineConfigFile()
|
||||
modelConfigHelper.createServiceConfigFile()
|
||||
modelConfigHelper.createWebhookConfigFile()
|
||||
workFlow.loadConfigModels()
|
||||
String oldChecksum = app.configChecksum
|
||||
createAnotherPromotionConfigFile()
|
||||
modelConfigHelper.createAnotherPromotionConfigFile()
|
||||
mdao.persist(_) >> _
|
||||
|
||||
when:
|
||||
|
|
Loading…
Reference in New Issue