From 674183c35d83331f05f7c04cd5aecafcff5f9fc0 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Tue, 15 Jun 2021 14:14:58 -0500 Subject: [PATCH] client/fingerprint/java: improve java version string regex matching This PR improves the regular expression used for matching the java version string, which varies a lot depending on the java vendor and version. These are the example strings we now test for: java version "1.7.0_80" openjdk version "11.0.1" 2018-10-16 openjdk version "11.0.1" 2018-10-16 java version "1.6.0_36" openjdk version "1.8.0_192" openjdk 11.0.11 2021-04-20 LTS The last one is a new test added on behalf of #6081, which is still broken on today's CentOS 7 default JDK package. openjdk 11.0.11 2021-04-20 LTS OpenJDK Runtime Environment 18.9 (build 11.0.11+9-LTS) OpenJDK 64-Bit Server VM 18.9 (build 11.0.11+9-LTS, mixed mode, sharing) ==> Evaluation "21c6caf7" finished with status "complete" but failed to place all allocations: Task Group "example" (failed to place 1 allocation): * Constraint "${driver.java.version} >= 11.0.0": 1 nodes excluded by filter Evaluation "2b737d48" waiting for additional capacity to place remainder Fixes #6081 --- drivers/java/driver.go | 4 ++-- drivers/java/utils.go | 7 +++++-- drivers/java/utils_test.go | 42 +++++++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/java/driver.go b/drivers/java/driver.go index f5951ad2b433..ec286c547460 100644 --- a/drivers/java/driver.go +++ b/drivers/java/driver.go @@ -356,7 +356,7 @@ func (d *Driver) buildFingerprint() *drivers.Fingerprint { } } - version, runtime, vm, err := javaVersionInfo() + version, jdkJRE, vm, err := javaVersionInfo() if err != nil { // return no error, as it isn't an error to not find java, it just means we // can't use it. @@ -367,7 +367,7 @@ func (d *Driver) buildFingerprint() *drivers.Fingerprint { fp.Attributes[driverAttr] = pstructs.NewBoolAttribute(true) fp.Attributes[driverVersionAttr] = pstructs.NewStringAttribute(version) - fp.Attributes["driver.java.runtime"] = pstructs.NewStringAttribute(runtime) + fp.Attributes["driver.java.runtime"] = pstructs.NewStringAttribute(jdkJRE) fp.Attributes["driver.java.vm"] = pstructs.NewStringAttribute(vm) return fp diff --git a/drivers/java/utils.go b/drivers/java/utils.go index 87b0aac3928c..fe5a95ca7e3d 100644 --- a/drivers/java/utils.go +++ b/drivers/java/utils.go @@ -50,6 +50,10 @@ func javaVersionInfo() (version, runtime, vm string, err error) { return } +var ( + javaVersionRe = regexp.MustCompile(`([.\d_]+)`) +) + func parseJavaVersionOutput(infoString string) (version, runtime, vm string) { infoString = strings.TrimSpace(infoString) @@ -65,8 +69,7 @@ func parseJavaVersionOutput(infoString string) (version, runtime, vm string) { versionString := strings.TrimSpace(lines[0]) - re := regexp.MustCompile(`version "([^"]*)"`) - if match := re.FindStringSubmatch(lines[0]); len(match) == 2 { + if match := javaVersionRe.FindStringSubmatch(versionString); len(match) == 2 { versionString = match[1] } diff --git a/drivers/java/utils_test.go b/drivers/java/utils_test.go index d09884ed49e2..8f2d7ad5b65e 100644 --- a/drivers/java/utils_test.go +++ b/drivers/java/utils_test.go @@ -8,11 +8,6 @@ import ( "github.com/stretchr/testify/require" ) -const oracleJDKOutput = `java version "1.7.0_80" -Java(TM) SE Runtime Environment (build 1.7.0_80-b15) -Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode) -` - func TestDriver_parseJavaVersionOutput(t *testing.T) { cases := []struct { name string @@ -23,7 +18,9 @@ func TestDriver_parseJavaVersionOutput(t *testing.T) { }{ { "OracleJDK", - oracleJDKOutput, + `java version "1.7.0_80" + Java(TM) SE Runtime Environment (build 1.7.0_80-b15) + Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)`, "1.7.0_80", "Java(TM) SE Runtime Environment (build 1.7.0_80-b15)", "Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)", @@ -69,14 +66,22 @@ func TestDriver_parseJavaVersionOutput(t *testing.T) { "OpenJDK Runtime Environment (build 1.8.0_192-b12_openj9)", "Eclipse OpenJ9 VM (build openj9-0.11.0, JRE 1.8.0 Linux amd64-64-Bit Compressed References", }, + { + "OpenJDK on CentOS 7", + `openjdk 11.0.11 2021-04-20 LTS + OpenJDK Runtime Environment 18.9 (build 11.0.11+9-LTS) + OpenJDK 64-Bit Server VM 18.9 (build 11.0.11+9-LTS, mixed mode, sharing)`, + `11.0.11`, + `OpenJDK Runtime Environment 18.9 (build 11.0.11+9-LTS)`, + `OpenJDK 64-Bit Server VM 18.9 (build 11.0.11+9-LTS, mixed mode, sharing)`, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - version, runtime, vm := parseJavaVersionOutput(c.output) - - require.Equal(t, c.version, version) - require.Equal(t, c.runtime, runtime) + jdkVersion, jdkJRE, vm := parseJavaVersionOutput(c.output) + require.Equal(t, c.version, jdkVersion) + require.Equal(t, c.runtime, jdkJRE) require.Equal(t, c.vm, vm) }) } @@ -94,13 +99,16 @@ func TestDriver_javaVersionInfo(t *testing.T) { javaVersionCommand = []string{ "/bin/sh", "-c", - fmt.Sprintf("printf '%%s\n' '%s' >/dev/stderr", oracleJDKOutput), + fmt.Sprintf("printf '%%s\n' '%s' >/dev/stderr", + `java version "1.7.0_80" + Java(TM) SE Runtime Environment (build 1.7.0_80-b15) + Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)`), } - version, runtime, vm, err := javaVersionInfo() + version, jdkJRE, vm, err := javaVersionInfo() require.NoError(t, err) require.Equal(t, "1.7.0_80", version) - require.Equal(t, "Java(TM) SE Runtime Environment (build 1.7.0_80-b15)", runtime) + require.Equal(t, "Java(TM) SE Runtime Environment (build 1.7.0_80-b15)", jdkJRE) require.Equal(t, "Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)", vm) } @@ -120,10 +128,10 @@ func TestDriver_javaVersionInfo_UnexpectedOutput(t *testing.T) { fmt.Sprintf("printf '%%s\n' '%s' >/dev/stderr", "unexpected java -version output"), } - version, runtime, vm, err := javaVersionInfo() + version, jdkJRE, vm, err := javaVersionInfo() require.NoError(t, err) require.Equal(t, "", version) - require.Equal(t, "", runtime) + require.Equal(t, "", jdkJRE) require.Equal(t, "", vm) } @@ -142,11 +150,11 @@ func TestDriver_javaVersionInfo_JavaVersionFails(t *testing.T) { "exit 127", } - version, runtime, vm, err := javaVersionInfo() + version, jdkJRE, vm, err := javaVersionInfo() require.Error(t, err) require.Contains(t, err.Error(), "failed to check java version") require.Equal(t, "", version) - require.Equal(t, "", runtime) + require.Equal(t, "", jdkJRE) require.Equal(t, "", vm) }