Merge "Add delay to SOURCE_IP_PORT TCP test"
diff --git a/octavia_tempest_plugin/contrib/test_server/README.rst b/octavia_tempest_plugin/contrib/test_server/README.rst
index f6ec4bb..66a6030 100644
--- a/octavia_tempest_plugin/contrib/test_server/README.rst
+++ b/octavia_tempest_plugin/contrib/test_server/README.rst
@@ -44,20 +44,24 @@
 
   Usage of ./test_server.bin:
     -cert string
-          Server side PEM format certificate.
+          Server side PEM format certificate file path.
     -client_ca string
-          Client side PEM format CA certificate.
+          Client auth PEM format CA certificate file path.
     -https_port int
           HTTPS port to listen on, -1 is disabled. (default -1)
+    -https_client_auth_port int
+          HTTPS with client authentication port to listen on, -1 is disabled.
+          (default -1)
     -id string
           Server ID (default "1")
     -key string
-          Server side PEM format key.
+          Server side PEM format key file path.
     -port int
           Port to listen on (default 8080)
 
 If -https_port is not specified, the server will not accept HTTPS requests.
 When --https_port is specified, -cert and -key are required parameters.
-If -https_port is specified, the -client_ca parameter is optional. When
--client_ca is specified, it will configure the HTTPS port to require a valid
-client certificate to connect.
+
+If -https_client_auth_port is specified, the -client_ca parameter is required.
+When -client_ca is specified, it will configure the HTTPS client auth port to
+require a valid client certificate to connect.
diff --git a/octavia_tempest_plugin/contrib/test_server/test_server.go b/octavia_tempest_plugin/contrib/test_server/test_server.go
index 27b6b2c..fa8f8d7 100644
--- a/octavia_tempest_plugin/contrib/test_server/test_server.go
+++ b/octavia_tempest_plugin/contrib/test_server/test_server.go
@@ -12,6 +12,7 @@
 	"net"
 	"net/http"
 	"os"
+	"strconv"
 	"sync"
 	"time"
 )
@@ -69,6 +70,34 @@
 	io.WriteString(w, resp)
 }
 
+func requestHandler(w http.ResponseWriter, r *http.Request) {
+	scoreboard.open()
+	defer scoreboard.close()
+
+	http.SetCookie(w, &sessCookie)
+
+	params := r.URL.Query()
+	if value, ok := params["response_code"]; ok {
+		if responseCode, err := strconv.Atoi(value[0]); err == nil {
+			w.WriteHeader(responseCode)
+		}
+	}
+
+	io.WriteString(w, fmt.Sprintf("%s %s %s\n",
+	                              r.Method, r.RequestURI, r.Proto))
+
+	io.WriteString(w, fmt.Sprintf("Host: %s\n", r.Host))
+
+	for key, values := range r.Header {
+		for _, value := range values {
+			header := fmt.Sprintf("%s: %s\n", key, value)
+			io.WriteString(w, header)
+		}
+	}
+	io.WriteString(w, "\n")
+	io.WriteString(w, resp)
+}
+
 func slowHandler(w http.ResponseWriter, r *http.Request) {
 	scoreboard.open()
 	defer scoreboard.close()
@@ -113,6 +142,7 @@
 	http.HandleFunc("/slow", slowHandler)
 	http.HandleFunc("/stats", statsHandler)
 	http.HandleFunc("/reset", resetHandler)
+	http.HandleFunc("/request", requestHandler)
 }
 
 func httpServe(port int, id string) {
@@ -128,6 +158,7 @@
 	mux.Handle("/slow", httpsWrapper(slowHandler))
 	mux.Handle("/stats", httpsWrapper(statsHandler))
 	mux.Handle("/reset", httpsWrapper(resetHandler))
+	mux.Handle("/request", httpsWrapper(requestHandler))
 
 	var tlsConfig *tls.Config
 	if certpool != nil {
@@ -205,11 +236,14 @@
 	idPtr := flag.String("id", "1", "Server ID")
 	httpsPortPtr := flag.Int("https_port", -1,
 		"HTTPS port to listen on, -1 is disabled.")
+	httpsClientAuthPortPtr := flag.Int("https_client_auth_port", -1,
+		"HTTPS with client authentication port to listen on, -1 is disabled.")
 	serverCertPem := flag.String("cert", "",
-		"Server side PEM format certificate.")
-	serverKey := flag.String("key", "", "Server side PEM format key.")
+		"Server side PEM format certificate file path.")
+	serverKey := flag.String("key", "",
+        "Server side PEM format key file path.")
 	clientCaCertPem := flag.String("client_ca", "",
-		"Client side PEM format CA certificate.")
+		"Client auth PEM format CA certificate file path.")
 
 	flag.Parse()
 
@@ -223,21 +257,27 @@
 			fmt.Println("Error load server certificate and key.")
 			os.Exit(1)
 		}
-		certpool := x509.NewCertPool()
-		if *clientCaCertPem != "" {
-			caPem, err := ioutil.ReadFile(*clientCaCertPem)
-			if err != nil {
-				fmt.Println("Error load client side CA cert.")
-				os.Exit(1)
-			}
-			if !certpool.AppendCertsFromPEM(caPem) {
-				fmt.Println("Can't parse client side certificate authority")
-				os.Exit(1)
-			}
-		} else {
-			certpool = nil
+		go httpsServe(*httpsPortPtr, *idPtr, cert, nil,
+			*serverCertPem, *serverKey)
+	}
+
+	if *httpsClientAuthPortPtr > -1 {
+		cert, err := tls.LoadX509KeyPair(*serverCertPem, *serverKey)
+		if err != nil {
+			fmt.Println("Error load server certificate and key.\n")
+			os.Exit(1)
 		}
-		go httpsServe(*httpsPortPtr, *idPtr, cert, certpool,
+		certpool := x509.NewCertPool()
+		caPem, err := ioutil.ReadFile(*clientCaCertPem)
+		if err != nil {
+			fmt.Println("Error loading client auth CA cert.\n")
+			os.Exit(1)
+		}
+		if !certpool.AppendCertsFromPEM(caPem) {
+			fmt.Println("Can't parse client auth certificate authority")
+			os.Exit(1)
+		}
+		go httpsServe(*httpsClientAuthPortPtr, *idPtr, cert, certpool,
 			*serverCertPem, *serverKey)
 	}
 
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 0918602..2753923 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -475,11 +475,6 @@
     override-checkout: stable/train
 
 - job:
-    name: octavia-v2-dsvm-noop-api-stable-stein
-    parent: octavia-v2-dsvm-noop-api
-    override-checkout: stable/stein
-
-- job:
     name: octavia-v2-dsvm-scenario
     parent: octavia-dsvm-live-base
     vars:
@@ -543,20 +538,6 @@
     parent: octavia-v2-dsvm-scenario
     override-checkout: stable/train
 
-- job:
-    name: octavia-v2-dsvm-scenario-stable-stein
-    parent: octavia-v2-dsvm-scenario
-    override-checkout: stable/stein
-    required-projects:
-      - name: openstack/diskimage-builder
-        override-checkout: 2.30.0
-    vars:
-      devstack_local_conf:
-        test-config:
-          "$TEMPEST_CONFIG":
-            loadbalancer-feature-enabled:
-              log_offload_enabled: False
-
 # Legacy jobs for the transition to the act-stdby two node jobs
 - job:
     name: octavia-v2-dsvm-scenario-two-node
@@ -683,14 +664,6 @@
     override-checkout: stable/train
 
 - job:
-    name: octavia-v2-dsvm-tls-barbican-stable-stein
-    parent: octavia-v2-dsvm-tls-barbican
-    override-checkout: stable/stein
-    required-projects:
-      - name: openstack/diskimage-builder
-        override-checkout: 2.30.0
-
-- job:
     name: octavia-v2-dsvm-tls-barbican-stable-rocky
     parent: octavia-v2-dsvm-tls-barbican
     nodeset: openstack-single-node-xenial
@@ -738,14 +711,6 @@
     override-checkout: stable/train
 
 - job:
-    name: octavia-v2-dsvm-spare-pool-stable-stein
-    parent: octavia-v2-dsvm-spare-pool
-    override-checkout: stable/stein
-    required-projects:
-      - name: openstack/diskimage-builder
-        override-checkout: 2.30.0
-
-- job:
     name: octavia-v2-dsvm-cinder-amphora
     parent: octavia-v2-dsvm-scenario
     required-projects:
@@ -884,14 +849,6 @@
     parent: octavia-v2-act-stdby-dsvm-scenario
     override-checkout: stable/train
 
-- job:
-    name: octavia-v2-act-stdby-dsvm-scenario-stable-stein
-    parent: octavia-v2-act-stdby-dsvm-scenario
-    override-checkout: stable/stein
-    required-projects:
-      - name: openstack/diskimage-builder
-        override-checkout: 2.30.0
-
 ######### Third party jobs ##########
 
 - job:
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index d66f616..9f7385d 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -11,15 +11,12 @@
         - octavia-v2-dsvm-noop-api
         - octavia-v2-dsvm-noop-api-stable-ussuri
         - octavia-v2-dsvm-noop-api-stable-train
-        - octavia-v2-dsvm-noop-api-stable-stein
         - octavia-v2-dsvm-scenario
         - octavia-v2-dsvm-scenario-stable-ussuri
         - octavia-v2-dsvm-scenario-stable-train
-        - octavia-v2-dsvm-scenario-stable-stein
         - octavia-v2-dsvm-tls-barbican
         - octavia-v2-dsvm-tls-barbican-stable-ussuri
         - octavia-v2-dsvm-tls-barbican-stable-train
-        - octavia-v2-dsvm-tls-barbican-stable-stein
         - octavia-v2-dsvm-scenario-ipv6-only:
             voting: false
         - octavia-v2-dsvm-scenario-centos-8:
@@ -32,16 +29,12 @@
             voting: false
         - octavia-v2-act-stdby-dsvm-scenario-stable-train:
             voting: false
-        - octavia-v2-act-stdby-dsvm-scenario-stable-stein:
-            voting: false
         - octavia-v2-dsvm-spare-pool:
             voting: false
         - octavia-v2-dsvm-spare-pool-stable-ussuri:
             voting: false
         - octavia-v2-dsvm-spare-pool-stable-train:
             voting: false
-        - octavia-v2-dsvm-spare-pool-stable-stein:
-            voting: false
         - octavia-v2-dsvm-cinder-amphora:
             voting: false
         # Third party provider jobs
@@ -56,12 +49,9 @@
         - octavia-v2-dsvm-noop-api
         - octavia-v2-dsvm-noop-api-stable-ussuri
         - octavia-v2-dsvm-noop-api-stable-train
-        - octavia-v2-dsvm-noop-api-stable-stein
         - octavia-v2-dsvm-scenario
         - octavia-v2-dsvm-scenario-stable-ussuri
         - octavia-v2-dsvm-scenario-stable-train
-        - octavia-v2-dsvm-scenario-stable-stein
         - octavia-v2-dsvm-tls-barbican
         - octavia-v2-dsvm-tls-barbican-stable-ussuri
         - octavia-v2-dsvm-tls-barbican-stable-train
-        - octavia-v2-dsvm-tls-barbican-stable-stein