From 447eae227c0b1369346d658c2039b654e59dfd17 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Wed, 11 Jun 2025 23:38:47 +0000 Subject: [PATCH 01/10] Added more tests to CilTokenSourceTest --- .../sdk/core/CliTokenSourceTest.java | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 20e2f6095..f1d230532 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -1,12 +1,104 @@ package com.databricks.sdk.core; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import com.databricks.sdk.core.oauth.Token; +import com.databricks.sdk.core.utils.Environment; +import com.databricks.sdk.core.utils.OSUtils; +import com.databricks.sdk.core.utils.OSUtilities; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.time.Duration; import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; public class CliTokenSourceTest { + private static final String[] DATE_FORMATS = { + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm:ss.SSS", + "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", + "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + }; + + String getExpiryStr(String dateFormat, Duration offset) { + ZonedDateTime futureExpiry = ZonedDateTime.now().plus(offset); + return futureExpiry.format(DateTimeFormatter.ofPattern(dateFormat)); + } + + private static Stream provideTestCases() { + return Stream.of( + Arguments.of("Valid: 30min remaining", 30, false), + Arguments.of("Valid: 1hr remaining", 60, false), + Arguments.of("Valid: 2hrs remaining", 120, false), + Arguments.of("Expired: 30min ago", -30, true), + Arguments.of("Expired: 1hr ago", -60, true), + Arguments.of("Expired: 2hrs ago", -120, true) + ); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("provideTestCases") + public void testRefreshWithExpiry(String testName, int offsetMinutes, boolean shouldBeExpired) throws IOException, InterruptedException { + for (String dateFormat : DATE_FORMATS) { + // Mock environment + Environment env = mock(Environment.class); + Map envMap = new HashMap<>(); + when(env.getEnv()).thenReturn(envMap); + + // Create test command + List cmd = Arrays.asList("test", "command"); + + // Mock OSUtilities + OSUtilities osUtils = mock(OSUtilities.class); + when(osUtils.getCliExecutableCommand(any())).thenReturn(cmd); + + try (MockedStatic mockedOSUtils = mockStatic(OSUtils.class)) { + mockedOSUtils.when(() -> OSUtils.get(any())).thenReturn(osUtils); + + // Create token source + CliTokenSource tokenSource = new CliTokenSource(cmd, "token_type", "access_token", "expiry", env); + + String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(offsetMinutes)); + + // Mock process + Process process = mock(Process.class); + when(process.getInputStream()).thenReturn(new ByteArrayInputStream( + String.format("{\"token_type\": \"Bearer\", \"access_token\": \"test-token\", \"expiry\": \"%s\"}", expiryStr).getBytes())); + when(process.getErrorStream()).thenReturn(new ByteArrayInputStream(new byte[0])); + when(process.waitFor()).thenReturn(0); + + // Mock ProcessBuilder constructor + try (MockedConstruction mocked = mockConstruction(ProcessBuilder.class, + (mock, context) -> { + when(mock.start()).thenReturn(process); + })) { + // Test refresh + Token token = tokenSource.refresh(); + assertEquals("Bearer", token.getTokenType()); + assertEquals("test-token", token.getAccessToken()); + assertEquals(shouldBeExpired, token.isExpired()); + } + } + } + } @Test public void testParseExpiryWithoutTruncate() { From 66335a7098af438045f088d1fbd48613502f6abf Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Thu, 12 Jun 2025 12:02:48 +0000 Subject: [PATCH 02/10] Add test to verify perserved behaviour --- .../sdk/core/CliTokenSourceTest.java | 104 ++++++++++++------ 1 file changed, 73 insertions(+), 31 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index f1d230532..a781159b4 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -9,8 +9,8 @@ import com.databricks.sdk.core.oauth.Token; import com.databricks.sdk.core.utils.Environment; -import com.databricks.sdk.core.utils.OSUtils; import com.databricks.sdk.core.utils.OSUtilities; +import com.databricks.sdk.core.utils.OSUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.time.Duration; @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -32,10 +33,10 @@ public class CliTokenSourceTest { private static final String[] DATE_FORMATS = { - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", - "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm:ss.SSS", + "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", + "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" }; String getExpiryStr(String dateFormat, Duration offset) { @@ -43,20 +44,9 @@ String getExpiryStr(String dateFormat, Duration offset) { return futureExpiry.format(DateTimeFormatter.ofPattern(dateFormat)); } - private static Stream provideTestCases() { - return Stream.of( - Arguments.of("Valid: 30min remaining", 30, false), - Arguments.of("Valid: 1hr remaining", 60, false), - Arguments.of("Valid: 2hrs remaining", 120, false), - Arguments.of("Expired: 30min ago", -30, true), - Arguments.of("Expired: 1hr ago", -60, true), - Arguments.of("Expired: 2hrs ago", -120, true) - ); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("provideTestCases") - public void testRefreshWithExpiry(String testName, int offsetMinutes, boolean shouldBeExpired) throws IOException, InterruptedException { + public void testRefreshWithExpiry( + String testName, int minutesUntilExpiry, boolean shouldBeExpired) + throws IOException, InterruptedException { for (String dateFormat : DATE_FORMATS) { // Mock environment Environment env = mock(Environment.class); @@ -65,31 +55,38 @@ public void testRefreshWithExpiry(String testName, int offsetMinutes, boolean sh // Create test command List cmd = Arrays.asList("test", "command"); - + // Mock OSUtilities OSUtilities osUtils = mock(OSUtilities.class); when(osUtils.getCliExecutableCommand(any())).thenReturn(cmd); - + try (MockedStatic mockedOSUtils = mockStatic(OSUtils.class)) { mockedOSUtils.when(() -> OSUtils.get(any())).thenReturn(osUtils); - - // Create token source - CliTokenSource tokenSource = new CliTokenSource(cmd, "token_type", "access_token", "expiry", env); - String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(offsetMinutes)); + CliTokenSource tokenSource = + new CliTokenSource(cmd, "token_type", "access_token", "expiry", env); + + String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(minutesUntilExpiry)); // Mock process Process process = mock(Process.class); - when(process.getInputStream()).thenReturn(new ByteArrayInputStream( - String.format("{\"token_type\": \"Bearer\", \"access_token\": \"test-token\", \"expiry\": \"%s\"}", expiryStr).getBytes())); + when(process.getInputStream()) + .thenReturn( + new ByteArrayInputStream( + String.format( + "{\"token_type\": \"Bearer\", \"access_token\": \"test-token\", \"expiry\": \"%s\"}", + expiryStr) + .getBytes())); when(process.getErrorStream()).thenReturn(new ByteArrayInputStream(new byte[0])); when(process.waitFor()).thenReturn(0); // Mock ProcessBuilder constructor - try (MockedConstruction mocked = mockConstruction(ProcessBuilder.class, - (mock, context) -> { - when(mock.start()).thenReturn(process); - })) { + try (MockedConstruction mocked = + mockConstruction( + ProcessBuilder.class, + (mock, context) -> { + when(mock.start()).thenReturn(process); + })) { // Test refresh Token token = tokenSource.refresh(); assertEquals("Bearer", token.getTokenType()); @@ -100,6 +97,51 @@ public void testRefreshWithExpiry(String testName, int offsetMinutes, boolean sh } } + private static Stream provideTimezoneTestCases() { + // Timezones to test + List timezones = Arrays.asList("UTC", "GMT+1", "GMT+8", "GMT-1", "GMT-8"); + + // Time to expiry of tokens (minutes, shouldBeExpired) + List minutesUntilExpiry = + Arrays.asList( + Arguments.of(5, false), // 5 minutes remaining + Arguments.of(30, false), // 30 minutes remaining + Arguments.of(60, false), // 1 hour remaining + Arguments.of(120, false), // 2 hours remaining + Arguments.of(-5, true), // 5 minutes ago + Arguments.of(-30, true), // 30 minutes ago + Arguments.of(-60, true), // 1 hour ago + Arguments.of(-120, true) // 2 hours ago + ); + + // Create cross product of timezones and minutesUntilExpiry cases + return timezones.stream() + .flatMap( + timezone -> + minutesUntilExpiry.stream() + .map( + minutesUntilExpiryCase -> { + Object[] args = minutesUntilExpiryCase.get(); + return Arguments.of(timezone, args[0], args[1]); + })); + } + + @ParameterizedTest(name = "Test in {0} with {1} minutes offset") + @MethodSource("provideTimezoneTestCases") + public void testRefreshWithDifferentTimezone( + String timezone, int minutesUntilExpiry, boolean shouldBeExpired) + throws IOException, InterruptedException { + // Save original timezone + TimeZone originalTimeZone = TimeZone.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone(timezone)); + testRefreshWithExpiry("Test in " + timezone, minutesUntilExpiry, shouldBeExpired); + } finally { + // Restore original timezone + TimeZone.setDefault(originalTimeZone); + } + } + @Test public void testParseExpiryWithoutTruncate() { LocalDateTime parsedDateTime = CliTokenSource.parseExpiry("2023-07-17T09:02:22.330612218Z"); From 3a824ebaf85a8f8483ff034cc78ff579f6e2339b Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Thu, 12 Jun 2025 12:48:28 +0000 Subject: [PATCH 03/10] Generate all timezones --- .../com/databricks/sdk/core/CliTokenSourceTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index a781159b4..33c2194e8 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -68,7 +70,7 @@ public void testRefreshWithExpiry( String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(minutesUntilExpiry)); - // Mock process + // Mock process to return the specified expiry string Process process = mock(Process.class); when(process.getInputStream()) .thenReturn( @@ -98,8 +100,11 @@ public void testRefreshWithExpiry( } private static Stream provideTimezoneTestCases() { - // Timezones to test - List timezones = Arrays.asList("UTC", "GMT+1", "GMT+8", "GMT-1", "GMT-8"); + // Generate timezones from GMT-12 to GMT+12 + List timezones = + IntStream.rangeClosed(-12, 12) + .mapToObj(offset -> offset == 0 ? "GMT" : String.format("GMT%+d", offset)) + .collect(Collectors.toList()); // Time to expiry of tokens (minutes, shouldBeExpired) List minutesUntilExpiry = From 95a3c6d5cd1c7ba5493a57a6acc3ce373b52962e Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Thu, 12 Jun 2025 13:52:24 +0000 Subject: [PATCH 04/10] Update test --- .../java/com/databricks/sdk/core/CliTokenSourceTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 33c2194e8..54e762c91 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -37,8 +37,9 @@ public class CliTokenSourceTest { private static final String[] DATE_FORMATS = { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", - "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + TimeZone.getDefault().getID().equals("UTC") + ? "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + : "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" }; String getExpiryStr(String dateFormat, Duration offset) { From d1c1a6c791cedb2d338fbfeb4a82d909488a9847 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Thu, 12 Jun 2025 15:15:37 +0000 Subject: [PATCH 05/10] Generate date formats at run-time --- .../sdk/core/CliTokenSourceTest.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 54e762c91..a7202210b 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -34,13 +34,15 @@ import org.mockito.MockedStatic; public class CliTokenSourceTest { - private static final String[] DATE_FORMATS = { - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm:ss.SSS", - TimeZone.getDefault().getID().equals("UTC") - ? "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" - : "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" - }; + private String[] getDateFormats() { + return new String[] { + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm:ss.SSS", + TimeZone.getDefault().getID().equals("UTC") + ? "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + : "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" + }; + } String getExpiryStr(String dateFormat, Duration offset) { ZonedDateTime futureExpiry = ZonedDateTime.now().plus(offset); @@ -50,7 +52,7 @@ String getExpiryStr(String dateFormat, Duration offset) { public void testRefreshWithExpiry( String testName, int minutesUntilExpiry, boolean shouldBeExpired) throws IOException, InterruptedException { - for (String dateFormat : DATE_FORMATS) { + for (String dateFormat : getDateFormats()) { // Mock environment Environment env = mock(Environment.class); Map envMap = new HashMap<>(); From 785c4009bb1362bfe4534cad7b6836a9f9b19ed7 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Fri, 13 Jun 2025 09:13:03 +0000 Subject: [PATCH 06/10] Update stream of test cases --- .../sdk/core/CliTokenSourceTest.java | 125 +++++++++--------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index a7202210b..0614d11c7 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -18,6 +18,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -34,25 +35,77 @@ import org.mockito.MockedStatic; public class CliTokenSourceTest { - private String[] getDateFormats() { - return new String[] { - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm:ss.SSS", - TimeZone.getDefault().getID().equals("UTC") - ? "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" - : "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" - }; - } - String getExpiryStr(String dateFormat, Duration offset) { ZonedDateTime futureExpiry = ZonedDateTime.now().plus(offset); return futureExpiry.format(DateTimeFormatter.ofPattern(dateFormat)); } + private static Stream provideTimezoneTestCases() { + // Generate timezones from GMT-12 to GMT+12 + List timezones = + IntStream.rangeClosed(-12, 12) + .mapToObj(offset -> offset == 0 ? "GMT" : String.format("GMT%+d", offset)) + .collect(Collectors.toList()); + + // Time to expiry of tokens (minutes, shouldBeExpired) + List minutesUntilExpiry = + Arrays.asList( + Arguments.of(5, false), // 5 minutes remaining + Arguments.of(30, false), // 30 minutes remaining + Arguments.of(60, false), // 1 hour remaining + Arguments.of(120, false), // 2 hours remaining + Arguments.of(-5, true), // 5 minutes ago + Arguments.of(-30, true), // 30 minutes ago + Arguments.of(-60, true), // 1 hour ago + Arguments.of(-120, true) // 2 hours ago + ); + + // Create cross product of timezones and minutesUntilExpiry case and match the timezone with the + // date formats + return timezones.stream() + .flatMap( + timezone -> { + List dateFormats = + new ArrayList<>( + Arrays.asList( + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm:ss.SSS", + "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")); + + if (timezone.equals("GMT")) { + dateFormats.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + } + + return minutesUntilExpiry.stream() + .map( + minutesUntilExpiryCase -> { + Object[] args = minutesUntilExpiryCase.get(); + return Arguments.of(timezone, args[0], args[1], dateFormats); + }); + }); + } + + @ParameterizedTest(name = "Test in {0} with {1} minutes offset") + @MethodSource("provideTimezoneTestCases") + public void testRefreshWithDifferentTimezone( + String timezone, int minutesUntilExpiry, boolean shouldBeExpired, List dateFormats) + throws IOException, InterruptedException { + // Save original timezone + TimeZone originalTimeZone = TimeZone.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone(timezone)); + testRefreshWithExpiry( + "Test in " + timezone, minutesUntilExpiry, shouldBeExpired, dateFormats); + } finally { + // Restore original timezone + TimeZone.setDefault(originalTimeZone); + } + } + public void testRefreshWithExpiry( - String testName, int minutesUntilExpiry, boolean shouldBeExpired) + String testName, int minutesUntilExpiry, boolean shouldBeExpired, List dateFormats) throws IOException, InterruptedException { - for (String dateFormat : getDateFormats()) { + for (String dateFormat : dateFormats) { // Mock environment Environment env = mock(Environment.class); Map envMap = new HashMap<>(); @@ -102,54 +155,6 @@ public void testRefreshWithExpiry( } } - private static Stream provideTimezoneTestCases() { - // Generate timezones from GMT-12 to GMT+12 - List timezones = - IntStream.rangeClosed(-12, 12) - .mapToObj(offset -> offset == 0 ? "GMT" : String.format("GMT%+d", offset)) - .collect(Collectors.toList()); - - // Time to expiry of tokens (minutes, shouldBeExpired) - List minutesUntilExpiry = - Arrays.asList( - Arguments.of(5, false), // 5 minutes remaining - Arguments.of(30, false), // 30 minutes remaining - Arguments.of(60, false), // 1 hour remaining - Arguments.of(120, false), // 2 hours remaining - Arguments.of(-5, true), // 5 minutes ago - Arguments.of(-30, true), // 30 minutes ago - Arguments.of(-60, true), // 1 hour ago - Arguments.of(-120, true) // 2 hours ago - ); - - // Create cross product of timezones and minutesUntilExpiry cases - return timezones.stream() - .flatMap( - timezone -> - minutesUntilExpiry.stream() - .map( - minutesUntilExpiryCase -> { - Object[] args = minutesUntilExpiryCase.get(); - return Arguments.of(timezone, args[0], args[1]); - })); - } - - @ParameterizedTest(name = "Test in {0} with {1} minutes offset") - @MethodSource("provideTimezoneTestCases") - public void testRefreshWithDifferentTimezone( - String timezone, int minutesUntilExpiry, boolean shouldBeExpired) - throws IOException, InterruptedException { - // Save original timezone - TimeZone originalTimeZone = TimeZone.getDefault(); - try { - TimeZone.setDefault(TimeZone.getTimeZone(timezone)); - testRefreshWithExpiry("Test in " + timezone, minutesUntilExpiry, shouldBeExpired); - } finally { - // Restore original timezone - TimeZone.setDefault(originalTimeZone); - } - } - @Test public void testParseExpiryWithoutTruncate() { LocalDateTime parsedDateTime = CliTokenSource.parseExpiry("2023-07-17T09:02:22.330612218Z"); From 2a7cd9544662d2b9cd8e12e02c4e8d6d3c506bc8 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Fri, 13 Jun 2025 11:22:35 +0000 Subject: [PATCH 07/10] Add comment --- .../test/java/com/databricks/sdk/core/CliTokenSourceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 0614d11c7..2e06939e2 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -73,6 +73,7 @@ private static Stream provideTimezoneTestCases() { "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")); if (timezone.equals("GMT")) { + // We only test with this format when timezone is GMT dateFormats.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); } From 257998c649fa181ffa83f38d7f02dc1076d37506 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Fri, 13 Jun 2025 12:23:08 +0000 Subject: [PATCH 08/10] Update comment --- .../java/com/databricks/sdk/core/CliTokenSourceTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 2e06939e2..b8108dc02 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -73,7 +73,11 @@ private static Stream provideTimezoneTestCases() { "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")); if (timezone.equals("GMT")) { - // We only test with this format when timezone is GMT + /* + * The Databricks CLI outputs timestamps with 'Z' suffix (e.g., + * 2024-03-14T10:30:00.000Z) only when in UTC/GMT+0 timezone. + * Thus, we only test with this format together with the GMT timezone. + */ dateFormats.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); } From a3d8f80b155b5a96a31cf500e40672ee90e12a22 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Fri, 13 Jun 2025 12:42:29 +0000 Subject: [PATCH 09/10] update stream of tests --- .../sdk/core/CliTokenSourceTest.java | 117 +++++++++--------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index b8108dc02..24f4e4eae 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -60,8 +60,7 @@ private static Stream provideTimezoneTestCases() { Arguments.of(-120, true) // 2 hours ago ); - // Create cross product of timezones and minutesUntilExpiry case and match the timezone with the - // date formats + // Create cross product of timezones and minutesUntilExpiry case return timezones.stream() .flatMap( timezone -> { @@ -81,26 +80,28 @@ private static Stream provideTimezoneTestCases() { dateFormats.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); } - return minutesUntilExpiry.stream() - .map( - minutesUntilExpiryCase -> { - Object[] args = minutesUntilExpiryCase.get(); - return Arguments.of(timezone, args[0], args[1], dateFormats); - }); + return dateFormats.stream() + .flatMap( + dateFormat -> + minutesUntilExpiry.stream() + .map( + minutesUntilExpiryCase -> { + Object[] args = minutesUntilExpiryCase.get(); + return Arguments.of(timezone, args[0], args[1], dateFormat); + })); }); } - @ParameterizedTest(name = "Test in {0} with {1} minutes offset") + @ParameterizedTest(name = "Test in {0} with {1} minutes offset using format {3}") @MethodSource("provideTimezoneTestCases") public void testRefreshWithDifferentTimezone( - String timezone, int minutesUntilExpiry, boolean shouldBeExpired, List dateFormats) + String timezone, int minutesUntilExpiry, boolean shouldBeExpired, String dateFormat) throws IOException, InterruptedException { // Save original timezone TimeZone originalTimeZone = TimeZone.getDefault(); try { TimeZone.setDefault(TimeZone.getTimeZone(timezone)); - testRefreshWithExpiry( - "Test in " + timezone, minutesUntilExpiry, shouldBeExpired, dateFormats); + testRefreshWithExpiry("Test in " + timezone, minutesUntilExpiry, shouldBeExpired, dateFormat); } finally { // Restore original timezone TimeZone.setDefault(originalTimeZone); @@ -108,54 +109,52 @@ public void testRefreshWithDifferentTimezone( } public void testRefreshWithExpiry( - String testName, int minutesUntilExpiry, boolean shouldBeExpired, List dateFormats) + String testName, int minutesUntilExpiry, boolean shouldBeExpired, String dateFormat) throws IOException, InterruptedException { - for (String dateFormat : dateFormats) { - // Mock environment - Environment env = mock(Environment.class); - Map envMap = new HashMap<>(); - when(env.getEnv()).thenReturn(envMap); - - // Create test command - List cmd = Arrays.asList("test", "command"); - - // Mock OSUtilities - OSUtilities osUtils = mock(OSUtilities.class); - when(osUtils.getCliExecutableCommand(any())).thenReturn(cmd); - - try (MockedStatic mockedOSUtils = mockStatic(OSUtils.class)) { - mockedOSUtils.when(() -> OSUtils.get(any())).thenReturn(osUtils); - - CliTokenSource tokenSource = - new CliTokenSource(cmd, "token_type", "access_token", "expiry", env); - - String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(minutesUntilExpiry)); - - // Mock process to return the specified expiry string - Process process = mock(Process.class); - when(process.getInputStream()) - .thenReturn( - new ByteArrayInputStream( - String.format( - "{\"token_type\": \"Bearer\", \"access_token\": \"test-token\", \"expiry\": \"%s\"}", - expiryStr) - .getBytes())); - when(process.getErrorStream()).thenReturn(new ByteArrayInputStream(new byte[0])); - when(process.waitFor()).thenReturn(0); - - // Mock ProcessBuilder constructor - try (MockedConstruction mocked = - mockConstruction( - ProcessBuilder.class, - (mock, context) -> { - when(mock.start()).thenReturn(process); - })) { - // Test refresh - Token token = tokenSource.refresh(); - assertEquals("Bearer", token.getTokenType()); - assertEquals("test-token", token.getAccessToken()); - assertEquals(shouldBeExpired, token.isExpired()); - } + // Mock environment + Environment env = mock(Environment.class); + Map envMap = new HashMap<>(); + when(env.getEnv()).thenReturn(envMap); + + // Create test command + List cmd = Arrays.asList("test", "command"); + + // Mock OSUtilities + OSUtilities osUtils = mock(OSUtilities.class); + when(osUtils.getCliExecutableCommand(any())).thenReturn(cmd); + + try (MockedStatic mockedOSUtils = mockStatic(OSUtils.class)) { + mockedOSUtils.when(() -> OSUtils.get(any())).thenReturn(osUtils); + + CliTokenSource tokenSource = + new CliTokenSource(cmd, "token_type", "access_token", "expiry", env); + + String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(minutesUntilExpiry)); + + // Mock process to return the specified expiry string + Process process = mock(Process.class); + when(process.getInputStream()) + .thenReturn( + new ByteArrayInputStream( + String.format( + "{\"token_type\": \"Bearer\", \"access_token\": \"test-token\", \"expiry\": \"%s\"}", + expiryStr) + .getBytes())); + when(process.getErrorStream()).thenReturn(new ByteArrayInputStream(new byte[0])); + when(process.waitFor()).thenReturn(0); + + // Mock ProcessBuilder constructor + try (MockedConstruction mocked = + mockConstruction( + ProcessBuilder.class, + (mock, context) -> { + when(mock.start()).thenReturn(process); + })) { + // Test refresh + Token token = tokenSource.refresh(); + assertEquals("Bearer", token.getTokenType()); + assertEquals("test-token", token.getAccessToken()); + assertEquals(shouldBeExpired, token.isExpired()); } } } From 82bf08092b45ad742a75871b76625350af520864 Mon Sep 17 00:00:00 2001 From: emmyzhou-db Date: Fri, 13 Jun 2025 14:09:23 +0000 Subject: [PATCH 10/10] Polish comments --- .../sdk/core/CliTokenSourceTest.java | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java index 24f4e4eae..a551b72d3 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/core/CliTokenSourceTest.java @@ -41,13 +41,13 @@ String getExpiryStr(String dateFormat, Duration offset) { } private static Stream provideTimezoneTestCases() { - // Generate timezones from GMT-12 to GMT+12 + // Generate timezones from GMT-12 to GMT+12. List timezones = IntStream.rangeClosed(-12, 12) .mapToObj(offset -> offset == 0 ? "GMT" : String.format("GMT%+d", offset)) .collect(Collectors.toList()); - // Time to expiry of tokens (minutes, shouldBeExpired) + // Time to expiry of tokens (minutes, shouldBeExpired). List minutesUntilExpiry = Arrays.asList( Arguments.of(5, false), // 5 minutes remaining @@ -60,7 +60,7 @@ private static Stream provideTimezoneTestCases() { Arguments.of(-120, true) // 2 hours ago ); - // Create cross product of timezones and minutesUntilExpiry case + // Create cross product of timezones and minutesUntilExpiry cases. return timezones.stream() .flatMap( timezone -> { @@ -72,11 +72,9 @@ private static Stream provideTimezoneTestCases() { "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")); if (timezone.equals("GMT")) { - /* - * The Databricks CLI outputs timestamps with 'Z' suffix (e.g., - * 2024-03-14T10:30:00.000Z) only when in UTC/GMT+0 timezone. - * Thus, we only test with this format together with the GMT timezone. - */ + // The Databricks CLI outputs timestamps with 'Z' suffix (e.g., + // 2024-03-14T10:30:00.000Z) only when in UTC/GMT+0 timezone. + // Thus, we only test with this format together with the GMT timezone. dateFormats.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); } @@ -97,13 +95,13 @@ private static Stream provideTimezoneTestCases() { public void testRefreshWithDifferentTimezone( String timezone, int minutesUntilExpiry, boolean shouldBeExpired, String dateFormat) throws IOException, InterruptedException { - // Save original timezone + // Save original timezone. TimeZone originalTimeZone = TimeZone.getDefault(); try { TimeZone.setDefault(TimeZone.getTimeZone(timezone)); testRefreshWithExpiry("Test in " + timezone, minutesUntilExpiry, shouldBeExpired, dateFormat); } finally { - // Restore original timezone + // Restore original timezone. TimeZone.setDefault(originalTimeZone); } } @@ -111,15 +109,15 @@ public void testRefreshWithDifferentTimezone( public void testRefreshWithExpiry( String testName, int minutesUntilExpiry, boolean shouldBeExpired, String dateFormat) throws IOException, InterruptedException { - // Mock environment + // Mock environment. Environment env = mock(Environment.class); Map envMap = new HashMap<>(); when(env.getEnv()).thenReturn(envMap); - // Create test command + // Create test command. List cmd = Arrays.asList("test", "command"); - // Mock OSUtilities + // Mock OSUtilities. OSUtilities osUtils = mock(OSUtilities.class); when(osUtils.getCliExecutableCommand(any())).thenReturn(cmd); @@ -131,7 +129,7 @@ public void testRefreshWithExpiry( String expiryStr = getExpiryStr(dateFormat, Duration.ofMinutes(minutesUntilExpiry)); - // Mock process to return the specified expiry string + // Mock process to return the specified expiry string. Process process = mock(Process.class); when(process.getInputStream()) .thenReturn( @@ -143,14 +141,14 @@ public void testRefreshWithExpiry( when(process.getErrorStream()).thenReturn(new ByteArrayInputStream(new byte[0])); when(process.waitFor()).thenReturn(0); - // Mock ProcessBuilder constructor + // Mock ProcessBuilder constructor. try (MockedConstruction mocked = mockConstruction( ProcessBuilder.class, (mock, context) -> { when(mock.start()).thenReturn(process); })) { - // Test refresh + // Test refresh. Token token = tokenSource.refresh(); assertEquals("Bearer", token.getTokenType()); assertEquals("test-token", token.getAccessToken());