Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .ci/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ pipeline {
booleanParam(name: "BEATS_USE_CI_SNAPSHOTS", defaultValue: false, description: "If it's needed to use the binary snapshots produced by Beats CI instead of the official releases")
choice(name: 'LOG_LEVEL', choices: ['DEBUG', 'TRACE', 'INFO'], description: 'Log level to be used')
choice(name: 'TIMEOUT_FACTOR', choices: ['5', '3', '7', '11'], description: 'Max number of minutes for timeout backoff strategies')
string(name: 'KIBANA_VERSION', defaultValue: '', description: 'Docker tag of the kibana to be used for the tests. It will refer to an image related to a Kibana PR, under the Observability-CI namespace')
string(name: 'STACK_VERSION', defaultValue: '7.x-SNAPSHOT', description: 'SemVer version of the stack to be used for the tests.')
string(name: 'HELM_CHART_VERSION', defaultValue: '7.11.2', description: 'SemVer version of Helm chart to be used.')
string(name: 'HELM_VERSION', defaultValue: '3.5.2', description: 'SemVer version of Helm to be used.')
string(name: 'HELM_KIND_VERSION', defaultValue: '0.10.0', description: 'SemVer version of Kind to be used.')
string(name: 'HELM_KUBERNETES_VERSION', defaultValue: '1.18.2', description: 'SemVer version of Kubernetes to be used.')
string(name: 'GITHUB_CHECK_NAME', defaultValue: '', description: 'Name of the GitHub check to be updated. Only if this build is triggered from another parent stream.')
string(name: 'GITHUB_CHECK_REPO', defaultValue: '', description: 'Name of the GitHub repo to be updated. Only if this build is triggered from another parent stream.')
string(name: 'GITHUB_CHECK_SHA1', defaultValue: '', description: 'Name of the GitHub repo to be updated. Only if this build is triggered from another parent stream.')
string(name: 'GITHUB_CHECK_SHA1', defaultValue: '', description: 'Git SHA for the Beats upstream project (branch or PR)')
}
stages {
stage('Initializing'){
Expand All @@ -69,6 +70,7 @@ pipeline {
ELASTIC_AGENT_DOWNLOAD_URL = "${params.ELASTIC_AGENT_DOWNLOAD_URL.trim()}"
BEAT_VERSION = "${params.BEAT_VERSION.trim()}"
BEATS_USE_CI_SNAPSHOTS = "${params.BEATS_USE_CI_SNAPSHOTS}"
KIBANA_VERSION = "${params.KIBANA_VERSION.trim()}"
STACK_VERSION = "${params.STACK_VERSION.trim()}"
FORCE_SKIP_GIT_CHECKS = "${params.forceSkipGitChecks}"
FORCE_SKIP_PRESUBMIT = "${params.forceSkipPresubmit}"
Expand Down
129 changes: 129 additions & 0 deletions .ci/e2eKibana.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env groovy

@Library('apm@current') _

pipeline {
agent none
environment {
REPO = 'kibana'
BASE_DIR = "src/github.com/elastic/${env.REPO}"
GITHUB_CHECK_E2E_TESTS_NAME = 'E2E Tests'
PIPELINE_LOG_LEVEL = "INFO"
}
options {
timeout(time: 3, unit: 'HOURS')
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20', daysToKeepStr: '30'))
timestamps()
ansiColor('xterm')
disableResume()
durabilityHint('PERFORMANCE_OPTIMIZED')
disableConcurrentBuilds()
}
// http://JENKINS_URL/generic-webhook-trigger/invoke
// Pull requests events: https://docs.github.com/en/developers/webhooks-and-events/github-event-types#pullrequestevent
triggers {
GenericTrigger(
genericVariables: [
[key: 'GT_REPO', value: '$.repository.full_name'],
[key: 'GT_BASE_REF', value: '$.pull_request.base.ref'],
[key: 'GT_PR', value: '$.issue.number'],
[key: 'GT_PR_HEAD_SHA', value: '$.pull_request.head.sha'],
[key: 'GT_BODY', value: '$.comment.body'],
[key: 'GT_COMMENT_ID', value: '$.comment.id']
],
genericHeaderVariables: [
[key: 'x-github-event', regexpFilter: 'comment']
],
causeString: 'Triggered on comment: $GT_BODY',
printContributedVariables: false,
printPostContent: false,
silentResponse: true,
regexpFilterText: '$GT_REPO$GT_BODY',
regexpFilterExpression: '^elastic/kibana/run-fleet-e2e-tests$'
)
}
parameters {
string(name: 'kibana_pr', defaultValue: "master", description: "PR ID to use to build the Docker image. (e.g 10000)")
}
stages {
stage('Process GitHub Event') {
steps {
checkPermissions()
buildKibanaDockerImage(refspec: getBranch())
catchError(buildResult: 'UNSTABLE', message: 'Unable to run e2e tests', stageResult: 'FAILURE') {
runE2ETests('fleet')
}
}
}
}
}

def checkPermissions(){
if(env.GT_PR){
if(!githubPrCheckApproved(changeId: "${env.GT_PR}", org: 'elastic', repo: 'kibana')){
error("Only PRs from Elasticians can be tested with Fleet E2E tests")
}

if(!hasCommentAuthorWritePermissions(env.GT_PR, env.GT_COMMENT_ID)){
error("Only Elasticians can trigger Fleet E2E tests")
}
}
}

def getBranch(){
if(env.GT_PR){
return "PR/${env.GT_PR}"
}

return "PR/${params.kibana_pr}"
}

def getDockerTag(){
if(env.GT_PR){
return "${env.GT_PR_HEAD_SHA}"
}

// we are going to use the 'pr12345' tag
return "pr${params.kibana_pr}"
}

def hasCommentAuthorWritePermissions(prId, commentId){
def repoName = "elastic/kibana"
def token = getGithubToken()
def url = "https://api.github.com/repos/${repoName}/issues/${prId}/comments/${commentId}"
def comment = githubApiCall(token: token, url: url, noCache: true)
def json = githubRepoGetUserPermission(token: token, repo: repoName, user: comment?.user?.login)

return json?.permission == 'admin' || json?.permission == 'write'
}

def runE2ETests(String suite) {
log(level: 'DEBUG', text: "Triggering '${suite}' E2E tests for PR-${env.GT_PR}.")

// Kibana's maintenance branches follow the 7.11, 7.12 schema.
def branchName = "${env.GT_BASE_REF}.x"
def e2eTestsPipeline = "e2e-tests/e2e-testing-mbp/${branchName}"

def parameters = [
booleanParam(name: 'forceSkipGitChecks', value: true),
booleanParam(name: 'forceSkipPresubmit', value: true),
booleanParam(name: 'notifyOnGreenBuilds', value: false),
booleanParam(name: 'BEATS_USE_CI_SNAPSHOTS', value: true),
string(name: 'runTestsSuites', value: suite),
string(name: 'GITHUB_CHECK_NAME', value: env.GITHUB_CHECK_E2E_TESTS_NAME),
string(name: 'GITHUB_CHECK_REPO', value: env.REPO),
string(name: 'KIBANA_VERSION', value: getDockerTag()),
]

build(job: "${e2eTestsPipeline}",
parameters: parameters,
propagate: false,
wait: false
)

/*
// commented out to avoid sending Github statuses to Kibana PRs
def notifyContext = "${env.pr_head_sha}"
githubNotify(context: "${notifyContext}", description: "${notifyContext} ...", status: 'PENDING', targetUrl: "${env.JENKINS_URL}search/?q=${e2eTestsPipeline.replaceAll('/','+')}")
*/
}
20 changes: 20 additions & 0 deletions .ci/jobs/kibana-e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- job:
name: e2e-tests/e2e-testing-kibana-fleet
display-name: Fleet UI e2e tests Pipeline
description: Jenkins pipeline to run the end2end tests for the Fleet UI
project-type: pipeline
disabled: false
pipeline-scm:
script-path: .ci/e2eKibana.groovy
scm:
- git:
url: git@github.com:elastic/e2e-testing.git
refspec: +refs/heads/*:refs/remotes/origin/* +refs/pull/*/head:refs/remotes/origin/pr/*
wipe-workspace: 'True'
name: origin
shallow-clone: true
credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba
reference-repo: /var/lib/jenkins/.git-references/e2e-testing.git
branches:
- $branch_specifier
2 changes: 1 addition & 1 deletion cli/config/compose/profiles/fleet/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ services:
test: "curl -f http://localhost:5601/login | grep kbn-injected-metadata 2>&1 >/dev/null"
retries: 600
interval: 1s
image: "docker.elastic.co/kibana/kibana:${stackVersion:-7.x-SNAPSHOT}"
image: "docker.elastic.co/${kibanaDockerNamespace:-beats}/kibana:${kibanaVersion:-7.x-SNAPSHOT}"
ports:
- "5601:5601"
volumes:
Expand Down
3 changes: 2 additions & 1 deletion e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ The following environment variables affect how the tests are run in both the CI
- `BEATS_USE_CI_SNAPSHOTS`: Set this environment variable to `true` if it's needed to use the binary snapshots produced by Beats CI instead of the official releases. The snapshots will be downloaded from a bucket in Google Cloud Storage. This variable is used by the Beats repository, when testing the artifacts generated by the packaging job. Default: `false`.
- `LOG_LEVEL`: Set this environment variable to `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR` or `FATAL` to set the log level in the project. Default: `INFO`.
- `DEVELOPER_MODE`: Set this environment variable to `true` to activate developer mode, which means not destroying the services provisioned by the test framework. Default: `false`.
- `STACK_VERSION`. Set this environment variable to the proper version of the Elastic Stack (Elasticsearch and Kibana) to be used in the current execution. The default value depens on the branch you are targeting your work.
- `KIBANA_VERSION`. Set this environment variable to the proper version of the Kibana instance to be used in the current execution, which should be used for the Docker tag of the kibana instance. It will refer to an image related to a Kibana PR, under the Observability-CI namespace. Default is empty
- `STACK_VERSION`. Set this environment variable to the proper version of the Elasticsearch to be used in the current execution. The default value depens on the branch you are targeting your work.
- **master (Fleet):** https://github.com/elastic/e2e-testing/blob/0446248bae1ff604219735998841a21a7576bfdd/e2e/_suites/fleet/ingest-manager_test.go#L39
- **master (Integrations):** https://github.com/elastic/e2e-testing/blob/0446248bae1ff604219735998841a21a7576bfdd/e2e/_suites/metricbeat/metricbeat_test.go#L30
- `TIMEOUT_FACTOR`: Set this environment variable to an integer number, which represents the factor to be used while waiting for resources within the tests. I.e. waiting for Kibana needs around 30 seconds. Instead of hardcoding 30 seconds, or 3 minutes, in the code, we use a backoff strategy to wait until an amount of time, specific per situation, multiplying it by the timeout factor. With that in mind, we are able to set a higher factor on CI without changing the code, and the developer is able to locally set specific conditions when running the tests on slower machines. Default: `3`.
Expand Down
4 changes: 3 additions & 1 deletion e2e/_suites/fleet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ To change it, please use Docker UI, go to `Preferences > Resources > File Sharin
This is an example of the optional configuration:

```shell
# There should be a Docker image for the runtime dependencies (elasticsearch, kibana, package registry)
# There should be a Docker image for the runtime dependencies (elasticsearch, package registry)
export STACK_VERSION=7.x-SNAPSHOT
# There should be a Docker image for the runtime dependencies (kibana)
export KIBANA_VERSION=pr12345
# (Fleet mode) This environment variable will use a fixed version of the Elastic agent binary, obtained from
# https://artifacts-api.elastic.co/v1/search/7.x-SNAPSHOT/elastic-agent
export ELASTIC_AGENT_DOWNLOAD_URL="https://snapshots.elastic.co/7.12.0-069dfaa4/downloads/beats/elastic-agent/elastic-agent-7.12.0-SNAPSHOT-linux-x86_64.tar.gz"
Expand Down
15 changes: 14 additions & 1 deletion e2e/_suites/fleet/ingest_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ func setUpSuite() {
stackVersion = shell.GetEnv("STACK_VERSION", stackVersion)
stackVersion = e2e.GetElasticArtifactVersion(stackVersion)

kibanaVersion = shell.GetEnv("KIBANA_VERSION", "")
if kibanaVersion == "" {
// we want to deploy a released version for Kibana
// if not set, let's use stackVersion
kibanaVersion = e2e.GetElasticArtifactVersion(stackVersion)
}

imts = IngestManagerTestSuite{
Fleet: &FleetTestSuite{
Installers: map[string]ElasticAgentInstaller{}, // do not pre-initialise the map
Expand Down Expand Up @@ -98,8 +105,14 @@ func InitializeIngestManagerTestSuite(ctx *godog.TestSuiteContext) {

workDir, _ := os.Getwd()
profileEnv = map[string]string{
"stackVersion": stackVersion,
"kibanaConfigPath": path.Join(workDir, "configurations", "kibana.config.yml"),
"kibanaVersion": kibanaVersion,
"stackVersion": stackVersion,
}

profileEnv["kibanaDockerNamespace"] = "observability-ci"
if kibanaVersion == "" {
profileEnv["kibanaDockerNamespace"] = "kibana"
}

profile := FleetProfileName
Expand Down
2 changes: 1 addition & 1 deletion e2e/_suites/fleet/stand-alone.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (sats *StandAloneTestSuite) startAgent(image string, env map[string]string)
profileEnv["elasticAgentDockerImageSuffix"] = "-" + image
}

profileEnv["elasticAgentDockerNamespace"] = e2e.GetDockerNamespaceEnvVar()
profileEnv["elasticAgentDockerNamespace"] = e2e.GetDockerNamespaceEnvVar("beats")

containerName := fmt.Sprintf("%s_%s_%d", FleetProfileName, ElasticAgentServiceName, 1)

Expand Down
4 changes: 4 additions & 0 deletions e2e/_suites/fleet/world.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ var agentVersion = agentVersionBase
// It can be overriden by ELASTIC_AGENT_STALE_VERSION env var. Using latest GA as a default.
var agentStaleVersion = "7.11-SNAPSHOT"

// kibanaVersion is the version of the kibana to use
// It can be overriden by KIBANA_VERSION env var
var kibanaVersion = agentVersionBase

// stackVersion is the version of the stack to use
// It can be overriden by STACK_VERSION env var
var stackVersion = agentVersionBase
Expand Down
4 changes: 2 additions & 2 deletions e2e/_suites/metricbeat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ To change it, please use Docker UI, go to `Preferences > Resources > File Sharin
This is an example of the optional configuration:

```shell
# There should be a Docker image for the runtime dependencies (elasticsearch, kibana, package registry)
# There should be a Docker image for the runtime dependencies (elasticsearch)
export STACK_VERSION="7.x-SNAPSHOT"
export BEAT_VERSIONBEAT_VERSION="7.x-SNAPSHOT"
export BEAT_VERSION="7.x-SNAPSHOT"
# or
# This environment variable will use the snapshots produced by Beats CI
export BEATS_USE_CI_SNAPSHOTS="true"
Expand Down
2 changes: 1 addition & 1 deletion e2e/_suites/metricbeat/metricbeat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (mts *MetricbeatTestSuite) runMetricbeatService() error {
"serviceName": mts.ServiceName,
}

env["metricbeatDockerNamespace"] = e2e.GetDockerNamespaceEnvVar()
env["metricbeatDockerNamespace"] = e2e.GetDockerNamespaceEnvVar("beats")
env["metricbeatPlatform"] = "linux/amd64"

err := serviceManager.AddServicesToCompose(testSuite.currentContext, "metricbeat", []string{"metricbeat"}, env)
Expand Down
6 changes: 3 additions & 3 deletions e2e/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,14 +578,14 @@ func Sleep(duration time.Duration) error {

// GetDockerNamespaceEnvVar returns the Docker namespace whether we use one of the CI snapshots or
// the images produced by local Beats build, or not.
// If an error occurred reading the environment, wil return 'beats' as fallback
func GetDockerNamespaceEnvVar() string {
// If an error occurred reading the environment, will return the passed namespace as fallback
func GetDockerNamespaceEnvVar(fallback string) string {
beatsLocalPath := shell.GetEnv("BEATS_LOCAL_PATH", "")
useCISnapshots := shell.GetEnvBool("BEATS_USE_CI_SNAPSHOTS")
if useCISnapshots || beatsLocalPath != "" {
return "observability-ci"
}
return "beats"
return fallback
}

// WaitForProcess polls a container executing "ps" command until the process is in the desired state (present or not),
Expand Down
15 changes: 15 additions & 0 deletions e2e/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,21 @@ func TestGetBucketSearchNextPageParam_HasNoMorePages(t *testing.T) {
assert.True(t, param == "")
}

func TestGetDockerNamespaceEnvVar(t *testing.T) {
t.Run("Returns fallback when environment variable is not set", func(t *testing.T) {
namespace := GetDockerNamespaceEnvVar("beats")
assert.True(t, namespace == "beats")
})

t.Run("Returns Observability CI when environment variable is set", func(t *testing.T) {
defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS")
os.Setenv("BEATS_USE_CI_SNAPSHOTS", "true")

namespace := GetDockerNamespaceEnvVar("beats")
assert.True(t, namespace == "observability-ci")
})
}

func TestGetGCPBucketCoordinates_Commits(t *testing.T) {
artifact := "elastic-agent"
version := testVersion
Expand Down