diff --git a/assets/golang/site.go b/assets/golang/site.go
index 50d2e074d..7bbb8cb4d 100644
--- a/assets/golang/site.go
+++ b/assets/golang/site.go
@@ -4,56 +4,35 @@ import (
"fmt"
"io"
"log"
- "net"
"net/http"
"os"
"time"
)
-type EndpointType struct {
- validationName string
- path string
-}
-
-var endpointTypeMap = map[string]EndpointType{
- "api.ipify.org": {
- validationName: "IPv4",
- path: "/ipv4-test",
- },
- "api6.ipify.org": {
- validationName: "IPv6",
- path: "/ipv6-test",
- },
- "api64.ipify.org": {
- validationName: "Dual stack",
- path: "/dual-stack-test",
- },
+var endpointMap = map[string]string{
+ "/ipv4-test": "https://api.ipify.org",
+ "/ipv6-test": "https://api6.ipify.org",
+ "/dual-stack-test": "https://api64.ipify.org",
}
func main() {
- http.HandleFunc("/", handleRequest)
+ http.HandleFunc("/", hello)
http.HandleFunc("/requesturi/", echo)
- log.Printf("Starting server on %s\n", os.Getenv("PORT"))
-
- server := &http.Server{
- Addr: fmt.Sprintf(":%s", os.Getenv("PORT")),
+ for path, apiURL := range endpointMap {
+ http.HandleFunc(path, createIPHandler(apiURL))
}
- if err := server.ListenAndServe(); err != nil {
- log.Fatalf("Could not start server: %s\n", err)
+ port := os.Getenv("PORT")
+ if port == "" {
+ port = "8080"
}
-}
-func handleRequest(res http.ResponseWriter, req *http.Request) {
- for endpoint, data := range endpointTypeMap {
- if req.URL.Path == data.path {
- testEndpoint(res, endpoint, data.validationName)
- return
- }
+ fmt.Printf("Listening on port %s...\n", port)
+ err := http.ListenAndServe(":"+port, nil)
+ if err != nil {
+ log.Fatalf("Could not start server: %v\n", err)
}
-
- hello(res, req)
}
func hello(res http.ResponseWriter, req *http.Request) {
@@ -61,18 +40,23 @@ func hello(res http.ResponseWriter, req *http.Request) {
}
func echo(res http.ResponseWriter, req *http.Request) {
- fmt.Fprintln(res, fmt.Sprintf("Request URI is [%s]\nQuery String is [%s]", req.RequestURI, req.URL.RawQuery))
+ fmt.Fprintf(res, "Request URI is [%s]\nQuery String is [%s]\n", req.RequestURI, req.URL.RawQuery)
}
-func testEndpoint(res http.ResponseWriter, endpoint, validationName string) {
- client := &http.Client{
- Timeout: 5 * time.Second,
+func createIPHandler(apiURL string) http.HandlerFunc {
+ return func(res http.ResponseWriter, req *http.Request) {
+ fetchAndWriteIP(res, apiURL)
}
+}
+
+func fetchAndWriteIP(res http.ResponseWriter, apiURL string) {
+ client := &http.Client{Timeout: 5 * time.Second}
- resp, err := client.Get(fmt.Sprintf("http://%s", endpoint))
+ resp, err := client.Get(apiURL)
if err != nil {
- log.Printf("Failed to reach %s: %v\n", endpoint, err)
- writeTestResponse(res, validationName, false, "Unknown", err.Error())
+ log.Printf("Error fetching from %s: %v\n", apiURL, err)
+ res.WriteHeader(http.StatusInternalServerError)
+ fmt.Fprintf(res, "Error: %v", err)
return
}
defer resp.Body.Close()
@@ -80,41 +64,11 @@ func testEndpoint(res http.ResponseWriter, endpoint, validationName string) {
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading response: %v\n", err)
- writeTestResponse(res, validationName, false, "Unknown", err.Error())
+ res.WriteHeader(http.StatusInternalServerError)
+ fmt.Fprintf(res, "Error: %v", err)
return
}
- ipType := determineIPType(string(body))
- success := resp.StatusCode == http.StatusOK
-
- writeTestResponse(res, validationName, success, ipType, "")
-}
-
-func writeTestResponse(res http.ResponseWriter, validationName string, success bool, ipType, errorMsg string) {
- responseCode := http.StatusInternalServerError
- if success {
- responseCode = http.StatusOK
- }
- res.WriteHeader(responseCode)
-
- if errorMsg == "" {
- errorMsg = "none"
- }
-
- message := fmt.Sprintf("%s validation resulted in %s. Detected IP type is %s. Error message: %s.\n",
- validationName, map[bool]string{true: "success", false: "failure"}[success], ipType, errorMsg)
- res.Write([]byte(message))
-}
-
-func determineIPType(ipString string) string {
- ip := net.ParseIP(ipString)
- if ip == nil {
- return "Invalid IP"
- }
-
- if ip.To4() != nil {
- return "IPv4"
- }
-
- return "IPv6"
+ res.WriteHeader(resp.StatusCode)
+ fmt.Fprintf(res, "%s", string(body))
}
\ No newline at end of file
diff --git a/assets/java-spring/src/main/java/org/cloudfoundry/SpringBootTrivialApplication.java b/assets/java-spring/src/main/java/org/cloudfoundry/SpringBootTrivialApplication.java
index 342eae33f..37121e422 100644
--- a/assets/java-spring/src/main/java/org/cloudfoundry/SpringBootTrivialApplication.java
+++ b/assets/java-spring/src/main/java/org/cloudfoundry/SpringBootTrivialApplication.java
@@ -7,7 +7,6 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
-import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
@@ -31,9 +30,9 @@ class IPv6TesterController {
static {
ENDPOINT_TYPE_MAP = new HashMap<>();
- ENDPOINT_TYPE_MAP.put("api.ipify.org", new EndpointInfo("IPv4", "/ipv4-test"));
- ENDPOINT_TYPE_MAP.put("api6.ipify.org", new EndpointInfo("IPv6", "/ipv6-test"));
- ENDPOINT_TYPE_MAP.put("api64.ipify.org", new EndpointInfo("Dual stack", "/dual-stack-test"));
+ ENDPOINT_TYPE_MAP.put("api.ipify.org", new EndpointInfo("/ipv4-test"));
+ ENDPOINT_TYPE_MAP.put("api6.ipify.org", new EndpointInfo("/ipv6-test"));
+ ENDPOINT_TYPE_MAP.put("api64.ipify.org", new EndpointInfo("/dual-stack-test"));
}
@GetMapping("/")
@@ -64,40 +63,21 @@ private String testEndpoint(String endpoint) {
URI uri = new URI("http://" + endpoint + "/");
String response = restTemplate.getForObject(uri, String.class);
+ if (response == null || response.isEmpty()) {
+ throw new RuntimeException("Empty response from " + endpoint);
+ }
- String ipType = determineIpType(response);
- boolean success = response != null && !response.isEmpty();
- String resultMessage = success ? "success" : "failure";
-
- logger.info(endpointInfo.validationName + " validation " + resultMessage);
+ return response;
- return endpointInfo.validationName + " validation resulted in " + resultMessage +
- ". Detected IP type is " + ipType + ".";
} catch (URISyntaxException e) {
logger.severe("URI syntax issue with " + endpoint + ": " + e.getMessage());
- return endpointInfo.validationName +
- " validation resulted in failure due to URI issue. Error message: " + e.getMessage() + ".";
+ return e.getMessage();
} catch (Exception e) {
logger.severe("Failed to reach " + endpoint + ": " + e.getMessage());
- return endpointInfo.validationName +
- " validation resulted in failure. Error message: " + e.getMessage() + ".";
+ return e.getMessage();
}
}
- private String determineIpType(String ipString) {
- try {
- InetAddress inetAddress = InetAddress.getByName(ipString);
- if (inetAddress instanceof java.net.Inet4Address) {
- return "IPv4";
- } else if (inetAddress instanceof java.net.Inet6Address) {
- return "IPv6";
- }
- } catch (Exception e) {
- logger.severe("Invalid IP format or unexpected error for: " + ipString + ". Error: " + e.getMessage());
- }
- return "Invalid IP";
- }
-
- private static record EndpointInfo(String validationName, String path) {
+ private static record EndpointInfo(String path) {
}
-}
\ No newline at end of file
+}
diff --git a/assets/java-spring/target/spring-boot-trivial-app-0.0.1.jar b/assets/java-spring/target/spring-boot-trivial-app-0.0.1.jar
index 258c9c954..671aa19e2 100644
Binary files a/assets/java-spring/target/spring-boot-trivial-app-0.0.1.jar and b/assets/java-spring/target/spring-boot-trivial-app-0.0.1.jar differ
diff --git a/assets/nginx-ipv6/nginx.conf b/assets/nginx-ipv6/nginx.conf
old mode 100644
new mode 100755
index cac959f07..1de782f5d
--- a/assets/nginx-ipv6/nginx.conf
+++ b/assets/nginx-ipv6/nginx.conf
@@ -11,22 +11,21 @@ http {
}
location /ipv4-test {
- proxy_pass https://api4.ipify.org/?format=json;
+ proxy_pass https://api4.ipify.org/;
proxy_set_header Host api4.ipify.org;
proxy_ssl_server_name on;
}
location /ipv6-test {
- proxy_pass https://api6.ipify.org/?format=json;
+ proxy_pass https://api6.ipify.org/;
proxy_set_header Host api6.ipify.org;
proxy_ssl_server_name on;
}
location /dual-stack-test {
- proxy_pass https://api64.ipify.org/?format=json;
+ proxy_pass https://api64.ipify.org/;
proxy_set_header Host api64.ipify.org;
proxy_ssl_server_name on;
}
}
-}
-
+}
\ No newline at end of file
diff --git a/assets/node/server.js b/assets/node/server.js
index 5ba41896c..d4c3e4213 100644
--- a/assets/node/server.js
+++ b/assets/node/server.js
@@ -1,95 +1,37 @@
var http = require('http');
var https = require('https');
-var url = require('url');
-var ip = require('ip');
-
-HOST = null;
var host = "0.0.0.0";
var port = process.env.PORT || 3000;
-const ENDPOINT_TYPE_MAP = {
- 'api.ipify.org': {
- validation_name: "IPv4",
- path: "/ipv4-test"
- },
- 'api6.ipify.org': {
- validation_name: "IPv6",
- path: "/ipv6-test"
- },
- 'api64.ipify.org': {
- validation_name: "Dual stack",
- path: "/dual-stack-test"
- }
-};
+http.createServer(async function (req, res) {
+ const path = req.url;
+ const endpoints = {
+ '/ipv4-test': 'api.ipify.org',
+ '/ipv6-test': 'api6.ipify.org',
+ '/dual-stack-test': 'api64.ipify.org'
+ };
-function testIPAddress(endpoint, expectedType) {
- return new Promise((resolve) => {
+ const endpoint = endpoints[path];
+
+ if (endpoint) {
https.get(`https://${endpoint}`, (resp) => {
let data = '';
- resp.on('data', (chunk) => { data += chunk; });
+ resp.on('data', (chunk) => data += chunk);
resp.on('end', () => {
- let success = false;
- let detectedType = 'unknown';
-
- if (expectedType === "IPv4" && ip.isV4Format(data)) {
- success = true;
- detectedType = "IPv4";
- } else if (expectedType === "IPv6" && ip.isV6Format(data)) {
- success = true;
- detectedType = "IPv6";
- } else if (expectedType === "Dual stack") {
- if (ip.isV4Format(data)) {
- success = true;
- detectedType = "IPv4";
- } else if (ip.isV6Format(data)) {
- success = true;
- detectedType = "IPv6";
- }
- }
-
- resolve({
- endpoint,
- success,
- ip_type: detectedType,
- error: success ? 'none' : `Expected ${expectedType}, but got ${data}`
- });
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
+ res.end(data.trim());
});
+
}).on("error", (err) => {
- resolve({ endpoint, success: false, ip_type: 'unknown', error: err.message });
+ console.error(`Error fetching from ${endpoint}: ${err.message}`);
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
+ res.end(err.message);
});
- });
-}
-
-http.createServer(async function (req, res) {
- const parsedUrl = url.parse(req.url, true);
- const path = parsedUrl.pathname;
-
- let endpoint = null;
- for (const [ep, { path: epPath }] of Object.entries(ENDPOINT_TYPE_MAP)) {
- if (path === epPath) {
- endpoint = ep;
- break;
- }
- }
-
- if (endpoint) {
- const expectedType = ENDPOINT_TYPE_MAP[endpoint].validation_name;
- const result = await testIPAddress(endpoint, expectedType);
-
- const responseCode = result.success ? 200 : 500;
- res.writeHead(responseCode, { 'Content-Type': 'text/plain' });
-
- const responseMessage = `${expectedType} validation resulted in ${result.success ? 'success' : 'failure'}. Detected IP type is ${result.ip_type}. Error message: ${result.error}.`;
-
- res.end(responseMessage);
-
} else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
- res.write('
Hello from a node app! ');
- res.write('via: ' + host + ':' + port);
- res.end('
');
+ res.end('Hello from a node app! ');
}
}).listen(port, host, () => {
diff --git a/assets/php/htdocs/.htaccess b/assets/php/htdocs/.htaccess
new file mode 100644
index 000000000..923f2e9f2
--- /dev/null
+++ b/assets/php/htdocs/.htaccess
@@ -0,0 +1,2 @@
+RewriteEngine On
+RewriteRule ^(ipv4|ipv6|dual-stack)-test$ ip-test.php?target=$1 [L]
\ No newline at end of file
diff --git a/assets/php/htdocs/ip-test.php b/assets/php/htdocs/ip-test.php
new file mode 100644
index 000000000..e852dd0f0
--- /dev/null
+++ b/assets/php/htdocs/ip-test.php
@@ -0,0 +1,41 @@
+
\ No newline at end of file
diff --git a/assets/python/server.py b/assets/python/server.py
index 3c1d1fe1d..4b3ad81c7 100644
--- a/assets/python/server.py
+++ b/assets/python/server.py
@@ -1,26 +1,9 @@
import os
import logging
-import ipaddress
import http.client
-
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
-ENDPOINT_TYPE_MAP = {
- 'api.ipify.org': {
- 'validation_name': "IPv4",
- 'path': "/ipv4-test"
- },
- 'api6.ipify.org': {
- 'validation_name': "IPv6",
- 'path': "/ipv6-test"
- },
- 'api64.ipify.org': {
- 'validation_name': "Dual stack",
- 'path': "/dual-stack-test"
- }
-}
-
DEFAULT_PORT = '8080'
HOST = '127.0.0.1'
@@ -29,105 +12,42 @@
format='%(asctime)s | %(levelname)s | %(message)s'
)
-class IPv6Tester:
- """
- The `IPv6Tester` class is responsible for verifying the successful execution of
- egress calls using IPv4, IPv6, and Dual Stack configurations, depending on the input.
- It offers logging result from the call.
- The test execution is deemed successful if the requested endpoint is reached without errors.
-
- """
-
- def __init__(self, endpoints):
- self.endpoints = endpoints
-
- def test_single_address(self, endpoint):
- result = self.test_endpoint(endpoint)
- self.print_result(endpoint, result)
- return result
+def fetch_ip(endpoint):
+ try:
+ connection = http.client.HTTPConnection(endpoint, timeout=0.20)
+ connection.request("GET", "/")
+ response = connection.getresponse()
- def print_result(self, endpoint, result):
- validation_type = ENDPOINT_TYPE_MAP[endpoint]['validation_name']
- if result['success']:
- logging.info(f"{validation_type} validation succeeded.")
+ if response.status == 200:
+ ip_data = response.read().strip().decode('utf-8')
+ connection.close()
+ return 200, ip_data
else:
- logging.error(f"{validation_type} validation failed.")
-
- def test_endpoint(self, endpoint):
- try:
- logging.info(f"Testing endpoint: {endpoint}")
- connection = http.client.HTTPConnection(endpoint, timeout=0.20)
- connection.request("GET", "/")
-
- response = connection.getresponse()
- response_data = response.read().strip().decode('utf-8')
- ip_type = self.determine_ip_type(response_data)
-
connection.close()
- return {
- 'success': response.status == 200,
- 'ip_type': ip_type
- }
-
- except Exception as e:
- logging.error(f"Failed to reach {endpoint}: {e}")
- return {
- 'success': False,
- 'error': str(e),
- 'ip_type': 'Unknown'
- }
+ return 500, f"Error: received status code {response.status}"
- @staticmethod
- def determine_ip_type(ip_string):
- try:
- ip = ipaddress.ip_address(ip_string)
- return "IPv4" if ip.version == 4 else "IPv6"
- except ValueError:
- return "Invalid IP"
+ except Exception as e:
+ logging.error(f"Failed to fetch IP from {endpoint}: {e}")
+ return 500, f"Error fetching IP: {e}"
class Handler(BaseHTTPRequestHandler):
- '''
- The Handler class provides two distinct test paths
- for different testing scenarios. The ipv6-path is dedicated
- to testing IPv6 egress calls, while the default path is used
- for testing the default Hello-Python buildpack test case.
- '''
-
def do_GET(self):
- if self.path in [data['path'] for data in ENDPOINT_TYPE_MAP.values()]:
- self.handle_test()
- else:
- self.send_response(200)
- self.end_headers()
- message = "Hello python, world!"
- self.wfile.write(message.encode('utf-8'))
- self.wfile.write('\n'.encode('utf-8'))
+ endpoints = {
+ '/ipv4-test': 'api.ipify.org',
+ '/ipv6-test': 'api6.ipify.org',
+ '/dual-stack-test': 'api64.ipify.org'
+ }
- def handle_test(self):
- endpoint = self.get_endpoint_from_path()
+ endpoint = endpoints.get(self.path)
if endpoint:
- tester = IPv6Tester([endpoint])
- result = tester.test_single_address(endpoint)
- response_code = 200 if result['success'] else 500
- self.send_response(response_code)
+ status, message = fetch_ip(endpoint)
+ self.send_response(status)
self.end_headers()
-
- validation_name = ENDPOINT_TYPE_MAP[endpoint]['validation_name']
- response_message = (f"{validation_name} validation resulted in "
- f"{'success' if result['success'] else 'failure'}. Detected IP type is "
- f"{result.get('ip_type', 'unknown')}. Error message: {result.get('error', 'none')}.")
- self.wfile.write(response_message.encode('utf-8'))
- self.wfile.write('\n'.encode('utf-8'))
+ self.wfile.write(message.encode('utf-8'))
else:
- self.send_response(404)
+ self.send_response(200)
self.end_headers()
- self.wfile.write(b'Endpoint not found\n')
-
- def get_endpoint_from_path(self):
- for endpoint, data in ENDPOINT_TYPE_MAP.items():
- if self.path == data['path']:
- return endpoint
- return None
+ self.wfile.write(b'Hello python, world!\n')
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
@@ -136,7 +56,7 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
port = int(os.environ.get('PORT', DEFAULT_PORT))
host = os.environ.get('VCAP_APP_HOST', HOST)
- print("Going to start server on %s:%s" % (host, port))
+ print(f"Going to start server on {host}:{port}")
server = ThreadedHTTPServer((host, port), Handler)
print('Starting server, use to stop')
diff --git a/assets/ruby_simple/main.rb b/assets/ruby_simple/main.rb
index 95e1567ef..557096f62 100644
--- a/assets/ruby_simple/main.rb
+++ b/assets/ruby_simple/main.rb
@@ -1,14 +1,67 @@
require 'sinatra'
+require 'net/http'
+require 'logger'
+
STDOUT.sync = true
STDERR.sync = true
+ENDPOINT_TYPE_MAP = {
+ :'api.ipify.org' => {
+ path: '/ipv4-test'
+ },
+ :'api6.ipify.org' => {
+ path: '/ipv6-test'
+ },
+ :'api64.ipify.org' => {
+ path: '/dual-stack-test'
+ }
+}.freeze
+
+def logger
+ @logger ||= Logger.new($stdout).tap do |log|
+ log.progname = 'SinatraApp'
+ log.level = Logger::INFO
+ end
+end
+
+class IPTester
+ def initialize(endpoint)
+ @endpoint = endpoint
+ end
+
+ def fetch_ip
+ uri = URI("http://#{@endpoint}/")
+
+ begin
+ response = Net::HTTP.get_response(uri)
+ response.body.strip
+ rescue => e
+ logger.error("Failed to reach #{@endpoint}: #{e.class} - #{e.message}")
+ "Error fetching IP: #{e.message}"
+ end
+ end
+end
+
+configure do
+ set :port, ENV.fetch('PORT', 8080).to_i
+ set :bind, ENV.fetch('VCAP_APP_HOST', '127.0.0.1')
+end
+
+ENDPOINT_TYPE_MAP.each do |endpoint, data|
+ get data[:path] do
+ tester = IPTester.new(endpoint)
+ message = tester.fetch_ip
+ "#{message}"
+ end
+end
+
get '/' do
<<-RESPONSE
-Healthy
-It just needed to be restarted!
-My application metadata: #{ENV['VCAP_APPLICATION']}
-My port: #{ENV['PORT']}
-My custom env variable: #{ENV['CUSTOM_VAR']}
+Healthy\n
+It just needed to be restarted!\n
+My application metadata: #{ENV['VCAP_APPLICATION']}\n
+My port: #{ENV['PORT']}\n
+My custom env variable: #{ENV['CUSTOM_VAR']}\n
RESPONSE
end
@@ -23,4 +76,4 @@
STDOUT.puts "Tick: #{Time.now.to_i}"
sleep 1
end
-end
+end
\ No newline at end of file
diff --git a/helpers/config/config_test.go b/helpers/config/config_test.go
index 129b12057..8bdd8703f 100644
--- a/helpers/config/config_test.go
+++ b/helpers/config/config_test.go
@@ -204,6 +204,7 @@ type testReporterConfig struct {
}
const BoshLiteDomain = "bosh-lite.env.wg-ard.ci.cloudfoundry.org"
+
var tmpFilePath string
var testCfg testConfig
diff --git a/ipv6/ipv6.go b/ipv6/ipv6.go
index c4922df2a..adc7f8593 100644
--- a/ipv6/ipv6.go
+++ b/ipv6/ipv6.go
@@ -1,7 +1,6 @@
package ipv6
import (
- "encoding/json"
"fmt"
. "github.com/cloudfoundry/cf-acceptance-tests/cats_suite_helpers"
"github.com/cloudfoundry/cf-acceptance-tests/helpers/app_helpers"
@@ -14,8 +13,23 @@ import (
. "github.com/onsi/gomega/gexec"
"net"
"os"
+ "strings"
)
+func ValidateIP(ipAddress, expectedType string) {
+ parsedIP := net.ParseIP(ipAddress)
+ Expect(parsedIP).NotTo(BeNil(), "Expected a valid IP address")
+
+ switch expectedType {
+ case "IPv4":
+ Expect(parsedIP.To4()).NotTo(BeNil(), "Expected an IPv4 address")
+ case "IPv6":
+ Expect(parsedIP.To4()).To(BeNil(), "Expected an IPv6 address")
+ case "Dual stack":
+ Expect(parsedIP).NotTo(BeNil(), "Expected either an IPv4 or IPv6 address")
+ }
+}
+
var _ = IPv6Describe("IPv6 Connectivity Tests", func() {
var appName string
@@ -29,24 +43,24 @@ var _ = IPv6Describe("IPv6 Connectivity Tests", func() {
})
EndpointTypeMap := map[string]struct {
- validationName string
- path string
+ expectedType string
+ path string
}{
- "api.ipify.org": {
- validationName: "IPv4",
- path: "/ipv4-test",
+ "IPv4": {
+ expectedType: "IPv4",
+ path: "/ipv4-test",
},
- "api6.ipify.org": {
- validationName: "IPv6",
- path: "/ipv6-test",
+ "IPv6": {
+ expectedType: "IPv6",
+ path: "/ipv6-test",
},
- "api64.ipify.org": {
- validationName: "Dual stack",
- path: "/dual-stack-test",
+ "Dual stack": {
+ expectedType: "Dual stack",
+ path: "/dual-stack-test",
},
- "default": {
- validationName: "Default app",
- path: "",
+ "Default": {
+ expectedType: "",
+ path: "",
},
}
@@ -54,13 +68,18 @@ var _ = IPv6Describe("IPv6 Connectivity Tests", func() {
pushSession := cf.Cf(commandOptions...)
Expect(pushSession.Wait(Config.DetectTimeoutDuration())).To(Exit(0))
- for key, data := range EndpointTypeMap {
- response := helpers.CurlApp(Config, appName, data.path)
+ for _, data := range EndpointTypeMap {
+ response := helpers.CurlAppWithStatusCode(Config, appName, data.path)
- if key == "default" {
+ if data.expectedType == "" {
Expect(response).To(ContainSubstring(defaultPathExpectMessage))
} else {
- Expect(response).To(ContainSubstring(fmt.Sprintf("%s validation resulted in success", data.validationName)))
+ responseParts := strings.Split(response, "\n")
+ ipAddress := responseParts[0]
+ statusCode := responseParts[1]
+
+ ValidateIP(ipAddress, data.expectedType)
+ Expect(statusCode).To(Equal("200"))
}
}
}
@@ -76,77 +95,51 @@ var _ = IPv6Describe("IPv6 Connectivity Tests", func() {
pushAndValidate(commandOptions, "ok")
}
- describeIpv6NginxTest := func(assetPath, stack string) {
- pushSession := cf.Cf("push", appName, "-s", stack, "-p", assetPath, "-m", DEFAULT_MEMORY_LIMIT)
- Expect(pushSession.Wait(Config.DetectTimeoutDuration())).To(Exit(0))
-
- isIPv4 := func(ip string) bool {
- parsedIP := net.ParseIP(ip)
- return parsedIP != nil && parsedIP.To4() != nil
- }
-
- isIPv6 := func(ip string) bool {
- parsedIP := net.ParseIP(ip)
- return parsedIP != nil && parsedIP.To4() == nil
- }
-
- for key, data := range EndpointTypeMap {
- response := helpers.CurlApp(Config, appName, data.path)
-
- if key == "default" {
- Expect(response).To(ContainSubstring("Hello NGINX!"))
- } else {
- var result map[string]interface{}
- Expect(json.Unmarshal([]byte(response), &result)).To(Succeed())
- ip, ok := result["ip"].(string)
- Expect(ok).To(BeTrue())
-
- validationResult := false
-
- switch data.validationName {
- case "IPv4":
- validationResult = isIPv4(ip)
- case "IPv6":
- validationResult = isIPv6(ip)
- case "Dual stack":
- validationResult = isIPv4(ip) || isIPv6(ip)
- }
-
- Expect(validationResult).To(BeTrue(), fmt.Sprintf("%s validation failed with the following error: %s", data.validationName, ip))
- }
- }
+ describeIPv6RubyTests := func(assetPath, stack string) {
+ commandOptions := []string{"push", appName, "-s", stack, "-p", assetPath, "-m", DEFAULT_MEMORY_LIMIT}
+ pushAndValidate(commandOptions, "Healthy")
}
Describe("Egress Capability in Apps", func() {
for _, stack := range Config.GetStacks() {
-
Context(fmt.Sprintf("Using Python stack: %s", stack), func() {
It("validates IPv6 egress for Python App", func() {
describeIPv6Tests(assets.NewAssets().Python, stack)
})
})
-
- Context(fmt.Sprintf("Using Node.js stack: %s", stack), func() {
- It("validates IPv6 egress for Node.js App", func() {
+ Context(fmt.Sprintf("Using Node stack: %s", stack), func() {
+ It("validates IPv6 egress for Node App", func() {
describeIPv6Tests(assets.NewAssets().Node, stack)
})
})
+ Context(fmt.Sprintf("Using Go stack: %s", stack), func() {
+ It("validates IPv6 egress for Go App", func() {
+ describeIPv6Tests(assets.NewAssets().Golang, stack)
+ })
+ })
+
Context(fmt.Sprintf("Using JavaSpring stack: %s", stack), func() {
It("validates IPv6 egress for JavaSpring App", func() {
describeIPv6JavaSpringTest(stack)
})
})
- Context(fmt.Sprintf("Using Golang stack: %s", stack), func() {
- It("validates IPv6 egress for Golang App", func() {
- describeIPv6Tests(assets.NewAssets().Golang, stack)
+ Context(fmt.Sprintf("Using Ruby stack: %s", stack), func() {
+ It("validates IPv6 egress for Ruby App", func() {
+ describeIPv6RubyTests(assets.NewAssets().RubySimple, stack)
})
})
Context(fmt.Sprintf("Using Nginx stack: %s", stack), func() {
It("validates IPv6 egress for Nginx App", func() {
- describeIpv6NginxTest(assets.NewAssets().NginxIPv6, stack)
+ describeIPv6Tests(assets.NewAssets().NginxIPv6, stack)
+ })
+ })
+
+ Context(fmt.Sprintf("Using PHP stack: %s", stack), func() {
+ It("validates IPv6 egress for PHP App", func() {
+ describeIPv6Tests(assets.NewAssets().Php, stack)
})
})
}
diff --git a/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/app_commands.go b/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/app_commands.go
index e8c4bd825..60268c952 100644
--- a/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/app_commands.go
+++ b/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/app_commands.go
@@ -27,6 +27,12 @@ func CurlApp(cfg helpersinternal.CurlConfig, appName, path string, args ...strin
return appCurler.CurlAndWait(cfg, appName, path, CURL_TIMEOUT, args...)
}
+// Curls an app's endpoint and exit successfully before the default timeout
+func CurlAppWithStatusCode(cfg helpersinternal.CurlConfig, appName, path string, args ...string) string {
+ appCurler := helpersinternal.NewAppCurler(Curl, cfg)
+ return appCurler.CurlWithStatusCode(cfg, appName, path, CURL_TIMEOUT, args...)
+}
+
// Curls an app's root endpoint and exit successfully before the default timeout
func CurlAppRoot(cfg helpersinternal.CurlConfig, appName string) string {
appCurler := helpersinternal.NewAppCurler(Curl, cfg)
diff --git a/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/internal/app_curler.go b/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/internal/app_curler.go
index 7623d3469..2a103ee62 100644
--- a/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/internal/app_curler.go
+++ b/vendor/github.com/cloudfoundry/cf-test-helpers/v2/helpers/internal/app_curler.go
@@ -34,3 +34,15 @@ func (appCurler *AppCurler) CurlAndWait(cfg CurlConfig, appName string, path str
ExpectWithOffset(3, string(curlCmd.Err.Contents())).To(HaveLen(0))
return string(curlCmd.Out.Contents())
}
+
+
+func (appCurler *AppCurler) CurlWithStatusCode(cfg CurlConfig, appName string, path string, timeout time.Duration, args ...string) string {
+ appUri := appCurler.UriCreator.AppUri(appName, path)
+ curlArgs := append([]string{"-s", "-w", "\n%{http_code}", appUri}, args...)
+
+ curlCmd := appCurler.CurlFunc(cfg, curlArgs...).Wait(timeout)
+
+ ExpectWithOffset(3, curlCmd).To(gexec.Exit(0))
+ ExpectWithOffset(3, string(curlCmd.Err.Contents())).To(HaveLen(0))
+ return string(curlCmd.Out.Contents())
+}