From 467b8dec7676e5846966732715946d1461c805c0 Mon Sep 17 00:00:00 2001 From: Bing O'Dowd Date: Wed, 5 Aug 2026 13:30:51 +0200 Subject: [PATCH] Automatically determine appropriate URL based off platform in VersionDownloadSource Currently, downloading the cratedb releases assumes the following URL "https://cdn.crate.io/downloads/releases/crate-%s.tar.gz" However, this will not work if the user is running on aarch64_mac, and potentially other platforms. We now check the architecture of the system running the code and then determine the appropriate URL for downloading the desired cratedb release. --- .../download/VersionDownloadSource.java | 62 +++++++- .../download/VersionDownloadSourceTest.java | 134 ++++++++++++++++++ 2 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 src/test/java/io/crate/testing/download/VersionDownloadSourceTest.java diff --git a/src/main/java/io/crate/testing/download/VersionDownloadSource.java b/src/main/java/io/crate/testing/download/VersionDownloadSource.java index e11a7f9..3088ff1 100644 --- a/src/main/java/io/crate/testing/download/VersionDownloadSource.java +++ b/src/main/java/io/crate/testing/download/VersionDownloadSource.java @@ -28,7 +28,14 @@ class VersionDownloadSource implements DownloadSource { - public static final String VERSION_DOWNLOAD_URL = "https://cdn.crate.io/downloads/releases/crate-%s.tar.gz"; + public static final String RELEASE_URL = "https://cdn.crate.io/downloads/releases/crate-%s.tar.gz"; + public static final String RELEASE_PLATFORM_URL = "https://cdn.crate.io/downloads/releases/cratedb/%s/crate-%s.tar.gz"; + public static final String NIGHTLY_URL = "https://cdn.crate.io/downloads/releases/nightly/crate-latest.tar.gz"; + public static final String NIGHTLY_PLATFORM_URL = "https://cdn.crate.io/downloads/releases/nightly/%s/crate-latest.tar.gz"; + public static final String X64_LINUX = "x64_linux"; + public static final String X64_WINDOWS = "x64_windows"; + public static final String AARCH64_LINUX = "aarch64_linux"; + public static final String AARCH64_MAC = "aarch64_mac"; private final String version; private final String folderName; @@ -45,7 +52,58 @@ public File folder(File containingFolder) { @Override public URL downloadUrl() throws MalformedURLException { - return new URL(String.format(Locale.ENGLISH, VERSION_DOWNLOAD_URL, version)); + return buildDownloadUrl(this.version, platform( + System.getProperty("os.name"), + System.getProperty("os.arch"))); + } + + static URL buildDownloadUrl(String version, String platform) throws MalformedURLException { + if (version.equals("latest") || version.equals("nightly")) { + switch (platform) { + case AARCH64_MAC: + case AARCH64_LINUX: + return new URL(String.format(Locale.ENGLISH, NIGHTLY_PLATFORM_URL, platform)); + case X64_LINUX: + return new URL(NIGHTLY_URL); + default: + throw new MalformedURLException(String.format("Platform %s not supported", platform)); + } + } + switch (platform) { + // There are currently no aarch64_mac releases besides nightly. Fallback to x64_mac release + // which needs an emulation layer (i.e. Rosetta 2) + case AARCH64_MAC: + return new URL(String.format(Locale.ENGLISH, RELEASE_PLATFORM_URL, "x64_mac", version)); + case AARCH64_LINUX: + case X64_WINDOWS: + return new URL(String.format(Locale.ENGLISH, RELEASE_PLATFORM_URL, platform, version)); + case X64_LINUX: + return new URL(String.format(Locale.ENGLISH, RELEASE_URL, version)); + default: + throw new MalformedURLException(String.format("Platform %s not supported", platform)); + } + } + + static String platform(String rawOsName, String rawArchName) { + String archName = rawArchName.toLowerCase(); + String osName = rawOsName.toLowerCase(); + String os; + String arch; + + if (archName.equals("arm") || archName.equals("aarch64")) { + arch = "aarch64"; + } else { + arch = "x64"; + } + + if (osName.equals("mac os x")) { + os = "mac"; + } else if (osName.startsWith("windows")) { + os = "windows"; + } else { + os = osName; + } + return arch + "_" + os; } @Override diff --git a/src/test/java/io/crate/testing/download/VersionDownloadSourceTest.java b/src/test/java/io/crate/testing/download/VersionDownloadSourceTest.java new file mode 100644 index 0000000..a468459 --- /dev/null +++ b/src/test/java/io/crate/testing/download/VersionDownloadSourceTest.java @@ -0,0 +1,134 @@ +/* + * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. Crate licenses + * this file to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may + * obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * However, if you have executed another commercial license agreement + * with Crate these terms will supersede the license and you may use the + * software solely pursuant to the terms of the relevant commercial agreement. + */ + +package io.crate.testing.download; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Suite; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import java.util.Arrays; +import java.util.Collection; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + VersionDownloadSourceTest.PlatformTest.class, + VersionDownloadSourceTest.BuildDownloadUrlTest.class, + VersionDownloadSourceTest.BuildDownloadUrlExceptionsTest.class +}) +public class VersionDownloadSourceTest { + + @RunWith(Parameterized.class) + public static class PlatformTest { + @Parameterized.Parameters(name = "OS Name: {0}, Arch: {1}, Expected: {2}") + public static Collection data() { + return Arrays.asList(new Object[][] { + { "Mac OS X", "arm", "aarch64_mac" }, + { "Mac OS X", "aarch64", "aarch64_mac" }, + { "Linux", "x86_64", "x64_linux" }, + { "Windows 10", "amd64", "x64_windows" }, + }); + } + + private String osName; + private String arch; + private String expected; + + public PlatformTest(String osName, String arch, String expected) { + this.osName = osName; + this.arch = arch; + this.expected = expected; + } + + @Test + public void testPlatform() { + assertThat(VersionDownloadSource.platform(osName, arch), is(expected)); + } + + } + + @RunWith(Parameterized.class) + public static class BuildDownloadUrlTest { + @Parameterized.Parameters(name = "Version: {0}, Platform: {1}, Expected: {2}") + public static Collection data() { + return Arrays.asList(new Object[][] { + { "6.4.0", "aarch64_mac", + "https://cdn.crate.io/downloads/releases/cratedb/x64_mac/crate-6.4.0.tar.gz" }, + { "6.4.0", "aarch64_linux", + "https://cdn.crate.io/downloads/releases/cratedb/aarch64_linux/crate-6.4.0.tar.gz" }, + { "6.4.0", "x64_windows", + "https://cdn.crate.io/downloads/releases/cratedb/x64_windows/crate-6.4.0.tar.gz" }, + { "6.4.0", "x64_linux", + "https://cdn.crate.io/downloads/releases/crate-6.4.0.tar.gz" }, + { "latest", "aarch64_mac", + "https://cdn.crate.io/downloads/releases/nightly/aarch64_mac/crate-latest.tar.gz" }, + { "latest", "aarch64_linux", + "https://cdn.crate.io/downloads/releases/nightly/aarch64_linux/crate-latest.tar.gz" }, + { "latest", "x64_linux", + "https://cdn.crate.io/downloads/releases/nightly/crate-latest.tar.gz" }, + }); + } + + private String version; + private String platform; + private String expected; + + public BuildDownloadUrlTest(String version, String platform, String expected) { + this.version = version; + this.platform = platform; + this.expected = expected; + } + + @Test + public void testBuildDownloadUrl() throws Exception { + assertThat(VersionDownloadSource.buildDownloadUrl(version, platform).toString(), is(expected)); + } + } + + @RunWith(Parameterized.class) + public static class BuildDownloadUrlExceptionsTest { + @Parameterized.Parameters(name = "Version: {0}, Platform: {1}") + public static Collection data() { + return Arrays.asList(new Object[][] { + { "latest", "x64_windows" }, + { "6.4.0", "x64_sunos" } + }); + } + + private String version; + private String platform; + + public BuildDownloadUrlExceptionsTest(String version, String platform) { + this.version = version; + this.platform = platform; + } + + @Test(expected = java.net.MalformedURLException.class) + public void testBuildDownloadUrlException() throws Exception { + VersionDownloadSource.buildDownloadUrl(version, platform); + } + } + +}