summaryrefslogtreecommitdiff
path: root/Jenkinsfile
blob: f9431eac06781afd832c588f033c678b9553d94c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!groovy

def imageNameBase = "dockerpinata/docker-py"
def imageNamePy3
def imageDindSSH
def images = [:]

def buildImage = { name, buildargs, pyTag ->
  img = docker.image(name)
  try {
    img.pull()
  } catch (Exception exc) {
    img = docker.build(name, buildargs)
    img.push()
  }
  if (pyTag?.trim()) images[pyTag] = img.id
}

def buildImages = { ->
  wrappedNode(label: "amd64 && ubuntu-2004 && overlay2", cleanWorkspace: true) {
    stage("build image") {
      checkout(scm)

      imageNamePy3 = "${imageNameBase}:py3-${gitCommit()}"
      imageDindSSH = "${imageNameBase}:sshdind-${gitCommit()}"
      withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
        buildImage(imageDindSSH, "-f tests/Dockerfile-ssh-dind .", "")
        buildImage(imageNamePy3, "-f tests/Dockerfile --build-arg PYTHON_VERSION=3.10 .", "py3.10")
      }
    }
  }
}

def getDockerVersions = { ->
  def dockerVersions = ["19.03.12"]
  wrappedNode(label: "amd64 && ubuntu-2004 && overlay2") {
    def result = sh(script: """docker run --rm \\
        --entrypoint=python \\
        ${imageNamePy3} \\
        /src/scripts/versions.py
      """, returnStdout: true
    )
    dockerVersions = dockerVersions + result.trim().tokenize(' ')
  }
  return dockerVersions
}

def getAPIVersion = { engineVersion ->
  def versionMap = [
    '18.09': '1.39',
    '19.03': '1.40'
  ]
  def result = versionMap[engineVersion.substring(0, 5)]
  if (!result) {
    return '1.40'
  }
  return result
}

def runTests = { Map settings ->
  def dockerVersion = settings.get("dockerVersion", null)
  def pythonVersion = settings.get("pythonVersion", null)
  def testImage = settings.get("testImage", null)
  def apiVersion = getAPIVersion(dockerVersion)

  if (!testImage) {
    throw new Exception("Need test image object, e.g.: `runTests(testImage: img)`")
  }
  if (!dockerVersion) {
    throw new Exception("Need Docker version to test, e.g.: `runTests(dockerVersion: '19.03.12')`")
  }
  if (!pythonVersion) {
    throw new Exception("Need Python version being tested, e.g.: `runTests(pythonVersion: 'py3.x')`")
  }

  { ->
    wrappedNode(label: "amd64 && ubuntu-2004 && overlay2", cleanWorkspace: true) {
      stage("test python=${pythonVersion} / docker=${dockerVersion}") {
        checkout(scm)
        def dindContainerName = "dpy-dind-\$BUILD_NUMBER-\$EXECUTOR_NUMBER-${pythonVersion}-${dockerVersion}"
        def testContainerName = "dpy-tests-\$BUILD_NUMBER-\$EXECUTOR_NUMBER-${pythonVersion}-${dockerVersion}"
        def testNetwork = "dpy-testnet-\$BUILD_NUMBER-\$EXECUTOR_NUMBER-${pythonVersion}-${dockerVersion}"
        withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
          try {
            // unit tests
            sh """docker run --rm \\
              -e 'DOCKER_TEST_API_VERSION=${apiVersion}' \\
              ${testImage} \\
              py.test -v -rxs --cov=docker tests/unit
            """
            // integration tests
            sh """docker network create ${testNetwork}"""
            sh """docker run --rm -d --name ${dindContainerName} -v /tmp --privileged --network ${testNetwork} \\
              ${imageDindSSH} dockerd -H tcp://0.0.0.0:2375
            """
            sh """docker run --rm \\
              --name ${testContainerName} \\
              -e "DOCKER_HOST=tcp://${dindContainerName}:2375" \\
              -e 'DOCKER_TEST_API_VERSION=${apiVersion}' \\
              --network ${testNetwork} \\
              --volumes-from ${dindContainerName} \\
              -v $DOCKER_CONFIG/config.json:/root/.docker/config.json \\
              ${testImage} \\
              py.test -v -rxs --cov=docker tests/integration
            """
            sh """docker stop ${dindContainerName}"""
            // start DIND container with SSH
            sh """docker run --rm -d --name ${dindContainerName} -v /tmp --privileged --network ${testNetwork} \\
              ${imageDindSSH} dockerd --experimental"""
            sh """docker exec ${dindContainerName} sh -c /usr/sbin/sshd """
            // run SSH tests only
            sh """docker run --rm \\
              --name ${testContainerName} \\
              -e "DOCKER_HOST=ssh://${dindContainerName}:22" \\
              -e 'DOCKER_TEST_API_VERSION=${apiVersion}' \\
              --network ${testNetwork} \\
              --volumes-from ${dindContainerName} \\
              -v $DOCKER_CONFIG/config.json:/root/.docker/config.json \\
              ${testImage} \\
              py.test -v -rxs --cov=docker tests/ssh
            """
          } finally {
            sh """
              docker stop ${dindContainerName}
              docker network rm ${testNetwork}
            """
          }
        }
      }
    }
  }
}


buildImages()

def dockerVersions = getDockerVersions()

def testMatrix = [failFast: false]

for (imgKey in new ArrayList(images.keySet())) {
  for (version in dockerVersions) {
    testMatrix["${imgKey}_${version}"] = runTests([testImage: images[imgKey], dockerVersion: version, pythonVersion: imgKey])
  }
}

parallel(testMatrix)