From 52372d632fa4dd49e34e302cdb322642538ddce5 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:06:07 +0400 Subject: [PATCH 001/163] add download support for Windows --- src/constants.ts | 52 ++++- src/index.ts | 3 +- src/libraries/Version.ts | 66 ++++-- src/versions.json | 422 --------------------------------------- types/index.ts | 8 - 5 files changed, 95 insertions(+), 456 deletions(-) delete mode 100644 src/versions.json diff --git a/src/constants.ts b/src/constants.ts index 799c3392..f88feabd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,8 +4,6 @@ import {normalize as normalizePath} from 'path' import { tmpdir } from "os"; import { valid as validSemver, coerce as coerceSemver } from "semver"; -export const MIN_SUPPORTED_MYSQL = '5.7.19'; - export const DEFAULT_OPTIONS_GENERATOR: () => InternalServerOptions = () => ({ version: undefined, dbName: 'dbdata', @@ -115,4 +113,52 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { errorMessage: `Option arch must be either of the following: ${allowedArches.join(', ')}`, definedType: 'string' } -} as const; \ No newline at end of file +} as const; + +export const MIN_SUPPORTED_MYSQL = '5.7.19'; +export const DOWNLOADABLE_MYSQL_VERSIONS = [ + '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', + + '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', + + '8.0.11', '8.0.12', '8.0.13', '8.0.14', '8.0.15', '8.0.16', '8.0.17', '8.0.18', '8.0.19', '8.0.20', '8.0.21', '8.0.22', '8.0.23', '8.0.24', '8.0.25', '8.0.26', '8.0.27', '8.0.28', '8.0.30', '8.0.31', '8.0.32', '8.0.33', '8.0.34', '8.0.35', '8.0.36', '8.0.37', '8.0.39', '8.0.40', '8.0.41', + + '8.1.0', '8.2.0', '8.3.0', + + '8.4.0', '8.4.1', '8.4.2', '8.4.3', '8.4.4', + + '9.0.0', '9.1.0', '9.2.0' +] as const; +export const MYSQL_ARCH_SUPPORT = { + darwin: { + arm64: '8.0.26 - 9.2.0', + x64: '5.7.19 - 9.2.0' + }, + linux: { + arm64: '8.0.31 - 9.2.0', + x64: '5.7.19 - 9.2.0' + }, + win32: { + x64: '5.7.19 - 9.2.0' + } +} as const; +export const MYSQL_MIN_OS_SUPPORT = { + win32: { + x: 'x' + }, + linux: { + x: 'x' + }, + darwin: { + '5.7.19 - 5.7.23 || 8.0.1 - 8.0.3 || 8.0.11 - 8.0.12': '16.0.0', + '5.7.24 - 5.7.29 || 8.0.4 || 8.0.13 - 8.0.18': '17.0.0', + '5.7.30 - 5.7.31, 8.0.19 - 8.0.22': '18.0.0', + //5.7.32 - 5.7.44 is not supported for macOS by MySQL. Those versions are not appearing in this list + '8.0.0': '13.0.0', + '8.0.23 - 8.0.27': '19.0.0', + '8.0.28 - 8.0.31': '20.0.0', + '8.0.32 - 8.0.34': '21.0.0', + '8.0.35 - 8.0.39 || 8.1.0 - 8.4.2': '22.0.0', + '8.0.40 - 8.0.41 || 8.4.3 - 9.2.0': '23.0.0' + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4556a5ce..44ad02a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,6 @@ import Executor from "./libraries/Executor" import { satisfies, lt, coerce } from "semver" import { BinaryInfo, ServerOptions } from '../types' import getBinaryURL from './libraries/Version' -import MySQLVersions from './versions.json' import { downloadBinary } from './libraries/Downloader' import { MIN_SUPPORTED_MYSQL, DEFAULT_OPTIONS_KEYS, OPTION_TYPE_CHECKS, DEFAULT_OPTIONS_GENERATOR } from './constants' @@ -48,7 +47,7 @@ export async function createDB(opts?: ServerOptions) { let binaryInfo: BinaryInfo; let binaryFilepath: string; try { - binaryInfo = getBinaryURL(MySQLVersions, options.version, options) + binaryInfo = getBinaryURL(options.version, options) logger.log('Using MySQL binary version:', binaryInfo.version, 'from URL:', binaryInfo.url) } catch (e) { if (options.version && lt(coerce(options.version), MIN_SUPPORTED_MYSQL)) { diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 53af00c5..4edb75e9 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,37 +1,61 @@ -import { InternalServerOptions, MySQLVersion } from "../../types"; +import { BinaryInfo, InternalServerOptions } from "../../types"; import * as os from 'os' -import { satisfies, coerce } from "semver"; +import { satisfies, coerce, lt, major, minor } from "semver"; +import { DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT } from "../constants"; -export default function getBinaryURL(versions: MySQLVersion[], versionToGet: string = "x", options: InternalServerOptions) { - let availableVersions = versions; +export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): BinaryInfo { + const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(versionToGet, version)); - availableVersions = availableVersions.filter(v => v.arch === options.arch) + if (selectedVersions.length === 0) { + throw `mysql-memory-server does not support downloading the version of MySQL requested (${versionToGet}). Please check for typos, choose a different version of MySQL to use, or make an issue or pull request to add support for this MySQL version on GitHub.` + } - if (availableVersions.length === 0) throw `No MySQL binary could be found for your CPU architecture: ${options.arch}. ${process.platform === 'win32' && process.arch === 'arm64' ? 'This package has detected you are running Windows on ARM. MySQL does not support Windows on ARM. To get this package working, please try setting the "arch" option to "x64".' : ''}` + //Sorts versions in descending order + selectedVersions.sort((a, b) => a < b ? 1 : -1) - availableVersions = availableVersions.filter(v => v.os === process.platform) + const selectedVersion = selectedVersions[0] - if (availableVersions.length === 0) throw `No MySQL binary could be found for your OS: ${process.platform}` + // Start of checking if the OS version is compatible with the selected MySQL version + const currentOS = os.platform(); + const OSVersionSupport = MYSQL_MIN_OS_SUPPORT[currentOS]; - availableVersions = availableVersions.filter(v => { - const release = coerce(os.release()) - if (!release) return false - return satisfies(release.version, v.osKernelVersionsSupported) - }) + if (!OSVersionSupport) throw `MySQL and/or mysql-memory-server does not support your operating system. Please try running on a different operating system or report an issue on GitHub if you believe this is a bug.` - if (availableVersions.length === 0) throw `No MySQL binary could be found that supports your OS version: ${os.release()} | ${os.version()}` + const OSSupportVersionRanges = Object.keys(OSVersionSupport); - const wantedVersions = availableVersions.filter(v => satisfies(v.version, versionToGet)) + const OSKey = OSSupportVersionRanges.find(item => satisfies(selectedVersion, item)) - if (wantedVersions.length === 0) throw `No MySQL binary could be found that meets your version requirement: ${versionToGet} for OS ${process.platform} version ${os.release()} on arch ${process.arch}. The available versions for download are: ${availableVersions.map(v => v.version)}` + if (!OSKey) throw `This version of MySQL (${selectedVersion}) does not support your operating system. Please choose a different version of MySQL or report an issue on GitHub if you believe this is a bug.` - //Sorts versions in descending order - wantedVersions.sort((a, b) => a.version < b.version ? 1 : a.version === b.version ? 0 : -1) + const minOSForMySQLVersion = OSVersionSupport[OSKey] + + if (lt(coerce(os.release()), minOSForMySQLVersion)) throw `Your operating system is too out of date to use version ${selectedVersion} of MySQL. MySQL requires >= ${minOSForMySQLVersion} but your system is ${os.release()}. Please update your operating system, choose a different version of MySQL to use, or report an issue on GitHub if you believe this is a bug.` + // End of checking if the OS version is compatible with the selected MySQL version + + // Start of checking if the CPU architecture is compatible with the selected MySQL version + const currentArch = options.arch; + const archSupport = MYSQL_ARCH_SUPPORT[currentOS][currentArch] + + if (!archSupport) { + if (currentOS === 'win32' && currentArch === 'arm64') throw 'mysql-memory-server has detected you are running Windows on ARM. MySQL does not support Windows on ARM. To get this package working, please try setting the "arch" option to "x64".' + throw `MySQL and/or mysql-memory-server does not support the CPU architecture you want to use (${currentArch}). Please try using a different architecture, or if you believe this is a bug, please report this on GitHub.` + } + + if (!satisfies(selectedVersion, archSupport)) { + throw `The desired version of MySQL to run (${selectedVersion}) does not support the CPU architecture (${currentArch}). Please try using a different architecture or MySQL version, or if you believe this is a bug, please report this on GitHub.` + } + // End of checking if the CPU architecture is compatible with the selected MySQL version + + let url: string = ''; + + if (currentOS === 'win32') { + url = `https://cdn.mysql.com//Downloads/MySQL-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` + } - const v = wantedVersions[0] + //TODO: Support for other platforms will be coming soon. return { - url: v.url, - version: v.version + version: selectedVersion, + url } } \ No newline at end of file diff --git a/src/versions.json b/src/versions.json deleted file mode 100644 index aa0f48db..00000000 --- a/src/versions.json +++ /dev/null @@ -1,422 +0,0 @@ -[ - { - "version": "9.2.0", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.2/mysql-9.2.0-macos15-arm64.tar.gz" - }, - { - "version": "9.2.0", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.2/mysql-9.2.0-macos15-x86_64.tar.gz" - }, - { - "version": "9.2.0", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.2/mysql-9.2.0-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "9.2.0", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.2/mysql-9.2.0-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "9.2.0", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.2/mysql-9.2.0-winx64.zip" - }, - { - "version": "8.4.4", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.4-macos15-arm64.tar.gz" - }, - { - "version": "8.4.4", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.4-macos15-x86_64.tar.gz" - }, - { - "version": "8.4.4", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.4-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.4.4", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.4-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.4.4", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.4-winx64.zip" - }, - { - "version": "8.0.41", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.41-macos15-arm64.tar.gz" - }, - { - "version": "8.0.41", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.41-macos15-x86_64.tar.gz" - }, - { - "version": "8.0.41", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.41-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.0.41", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.41-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.0.41", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.41-winx64.zip" - }, - { - "version": "9.1.0", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-macos14-arm64.tar.gz" - }, - { - "version": "9.1.0", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-macos14-x86_64.tar.gz" - }, - { - "version": "9.1.0", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "9.1.0", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "9.1.0", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.1/mysql-9.1.0-winx64.zip" - }, - { - "version": "8.4.3", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-macos14-arm64.tar.gz" - }, - { - "version": "8.4.3", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-macos14-x86_64.tar.gz" - }, - { - "version": "8.4.3", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.4.3", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.4.3", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.3-winx64.zip" - }, - { - "version": "8.0.40", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-macos14-arm64.tar.gz" - }, - { - "version": "8.0.40", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-macos14-x86_64.tar.gz" - }, - { - "version": "8.0.40", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.0.40", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.0.40", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.40-winx64.zip" - }, - { - "version": "9.0.1", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.0/mysql-9.0.1-macos14-arm64.tar.gz" - }, - { - "version": "9.0.1", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.0/mysql-9.0.1-macos14-x86_64.tar.gz" - }, - { - "version": "9.0.1", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.0/mysql-9.0.1-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "9.0.1", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.0/mysql-9.0.1-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "9.0.1", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-9.0/mysql-9.0.1-winx64.zip" - }, - { - "version": "8.4.2", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.2-macos14-arm64.tar.gz" - }, - { - "version": "8.4.2", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.2-macos14-x86_64.tar.gz" - }, - { - "version": "8.4.2", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.2-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.4.2", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.2-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.4.2", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.2-winx64.zip" - }, - { - "version": "8.0.39", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-macos14-arm64.tar.gz" - }, - { - "version": "8.0.39", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-macos14-x86_64.tar.gz" - }, - { - "version": "8.0.39", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.0.39", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.0.39", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip" - }, - { - "version": "8.1.0", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.1/mysql-8.1.0-macos13-arm64.tar.gz" - }, - { - "version": "8.1.0", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.1/mysql-8.1.0-macos13-x86_64.tar.gz" - }, - { - "version": "8.1.0", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.1/mysql-8.1.0-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.1.0", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.1/mysql-8.1.0-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.1.0", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.1/mysql-8.1.0-winx64.zip" - }, - { - "version": "8.2.0", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-macos13-arm64.tar.gz" - }, - { - "version": "8.2.0", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-macos13-x86_64.tar.gz" - }, - { - "version": "8.2.0", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.2.0", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.2.0", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-winx64.zip" - }, - { - "version": "8.3.0", - "arch": "arm64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.3/mysql-8.3.0-macos14-arm64.tar.gz" - }, - { - "version": "8.3.0", - "arch": "x64", - "os": "darwin", - "osKernelVersionsSupported": ">=22", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.3/mysql-8.3.0-macos14-x86_64.tar.gz" - }, - { - "version": "8.3.0", - "arch": "x64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.3/mysql-8.3.0-linux-glibc2.17-x86_64-minimal.tar.xz" - }, - { - "version": "8.3.0", - "arch": "arm64", - "os": "linux", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.3/mysql-8.3.0-linux-glibc2.17-aarch64-minimal.tar.xz" - }, - { - "version": "8.3.0", - "arch": "x64", - "os": "win32", - "osKernelVersionsSupported": "*", - "url": "https://cdn.mysql.com//Downloads/MySQL-8.3/mysql-8.3.0-winx64.zip" - } -] \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index 6038dbee..44cf62f7 100644 --- a/types/index.ts +++ b/types/index.ts @@ -60,14 +60,6 @@ export type MySQLDB = { stop: () => Promise } -export type MySQLVersion = { - version: string, - arch: string, - os: string, - osKernelVersionsSupported: string, - url: string -} - export type DownloadedMySQLVersion = { version: string, path: string, From 2ca801e746fe762f95be288d611e370e510fd427 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:08:13 +0400 Subject: [PATCH 002/163] use all MySQL versions --- tests/versions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 3039185c..f0d8d601 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,8 +5,8 @@ import { coerce } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; +import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; -const versions = ['8.0.39', '8.0.40', '8.0.41', '8.1.0', '8.2.0', '8.3.0', '8.4.2', '8.4.3', '8.4.4', '9.0.1', '9.1.0', '9.2.0'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' @@ -15,7 +15,7 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); -for (const version of versions) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) From 7a003eb02e5c31303a3e69c6b79bc82557442c61 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:12:42 +0400 Subject: [PATCH 003/163] remove x in minOS --- src/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index f88feabd..2378f81b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -144,10 +144,10 @@ export const MYSQL_ARCH_SUPPORT = { } as const; export const MYSQL_MIN_OS_SUPPORT = { win32: { - x: 'x' + x: '0.0.0' // No minimum version is documented as far as I can tell, so allow any minimum version }, linux: { - x: 'x' + x: '0.0.0'// No minimum version is documented as far as I can tell, so allow any minimum version }, darwin: { '5.7.19 - 5.7.23 || 8.0.1 - 8.0.3 || 8.0.11 - 8.0.12': '16.0.0', From cec459a585d0343eb9fa888cb9c697e2bdd26029 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:15:51 +0400 Subject: [PATCH 004/163] update base URL --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 4edb75e9..3dbd312f 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -49,7 +49,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern let url: string = ''; if (currentOS === 'win32') { - url = `https://cdn.mysql.com//Downloads/MySQL-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` + url = `https://cdn.mysql.com/archives//mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` } //TODO: Support for other platforms will be coming soon. From 0ae6011b3948509aef5d785f276cf4b1712ef70e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:39:31 +0400 Subject: [PATCH 005/163] update messages and error handling --- src/index.ts | 24 ++++++++---------------- src/libraries/Version.ts | 6 +++--- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/index.ts b/src/index.ts index 44ad02a1..4f97b8df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,24 +44,16 @@ export async function createDB(opts?: ServerOptions) { logger.log('Version currently installed:', version) if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { + if (options.version && lt(coerce(options.version), MIN_SUPPORTED_MYSQL)) { + //The difference between the throw here and the throw above is this throw is because the selected "version" is not supported. + //The throw above is because the system-installed MySQL is out of date and "ignoreUnsupportedSystemVersion" is not set to true. + throw `The selected version of MySQL (${options.version}) is not currently supported by this package. Please choose a different version to use.` + } + let binaryInfo: BinaryInfo; let binaryFilepath: string; - try { - binaryInfo = getBinaryURL(options.version, options) - logger.log('Using MySQL binary version:', binaryInfo.version, 'from URL:', binaryInfo.url) - } catch (e) { - if (options.version && lt(coerce(options.version), MIN_SUPPORTED_MYSQL)) { - //The difference between the throw here and the throw above is this throw is because the selected "version" is not supported. - //The throw above is because the system-installed MySQL is out of date and "ignoreUnsupportedSystemVersion" is not set to true. - throw `The selected version of MySQL (${options.version}) is not currently supported by this package. Please choose a different version to use.` - } - - logger.error(e) - if (options.version) { - throw `A MySQL version ${options.version} binary could not be found that supports your OS (${os.platform()} | ${os.version()} | ${os.release()}) and CPU architecture (${os.arch()}). Please check you have the latest version of mysql-memory-server. If the latest version still doesn't support the version you want to use, feel free to make a pull request to add support!` - } - throw `A MySQL binary could not be found that supports your OS (${os.platform()} | ${os.version()} | ${os.release()}) and CPU architecture (${os.arch()}). Please check you have the latest version of mysql-memory-server. If the latest version still doesn't support your OS and CPU architecture, feel free to make a pull request to add support!` - } + binaryInfo = getBinaryURL(options.version, options) + logger.log('Using MySQL binary version:', binaryInfo.version, 'from URL:', binaryInfo.url) try { binaryFilepath = await downloadBinary(binaryInfo, options, logger); diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 3dbd312f..b9602f3a 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -19,13 +19,13 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const currentOS = os.platform(); const OSVersionSupport = MYSQL_MIN_OS_SUPPORT[currentOS]; - if (!OSVersionSupport) throw `MySQL and/or mysql-memory-server does not support your operating system. Please try running on a different operating system or report an issue on GitHub if you believe this is a bug.` + if (!OSVersionSupport) throw `MySQL and/or mysql-memory-server does not support your operating system. Please make sure you are running the latest version of mysql-memory-server or try running on a different operating system or report an issue on GitHub if you believe this is a bug.` const OSSupportVersionRanges = Object.keys(OSVersionSupport); const OSKey = OSSupportVersionRanges.find(item => satisfies(selectedVersion, item)) - if (!OSKey) throw `This version of MySQL (${selectedVersion}) does not support your operating system. Please choose a different version of MySQL or report an issue on GitHub if you believe this is a bug.` + if (!OSKey) throw `This version of MySQL (${selectedVersion}) does not support your operating system. Please make sure you are running the latest version of mysql-memory-server or choose a different version of MySQL or report an issue on GitHub if you believe this is a bug.` const minOSForMySQLVersion = OSVersionSupport[OSKey] @@ -38,7 +38,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern if (!archSupport) { if (currentOS === 'win32' && currentArch === 'arm64') throw 'mysql-memory-server has detected you are running Windows on ARM. MySQL does not support Windows on ARM. To get this package working, please try setting the "arch" option to "x64".' - throw `MySQL and/or mysql-memory-server does not support the CPU architecture you want to use (${currentArch}). Please try using a different architecture, or if you believe this is a bug, please report this on GitHub.` + throw `MySQL and/or mysql-memory-server does not support the CPU architecture you want to use (${currentArch}). Please make sure you are using the latest version of mysql-memory-server or try using a different architecture, or if you believe this is a bug, please report this on GitHub.` } if (!satisfies(selectedVersion, archSupport)) { From a821783b71a98473e8b35518eb8c1759082b6ba9 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:42:34 +0400 Subject: [PATCH 006/163] fix typo --- src/libraries/Version.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index b9602f3a..125e5b42 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -49,7 +49,8 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern let url: string = ''; if (currentOS === 'win32') { - url = `https://cdn.mysql.com/archives//mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` + url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` + } //TODO: Support for other platforms will be coming soon. From 16afb649844ffc685c77cfc1697ee4d11e13d7dd Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:50:33 +0400 Subject: [PATCH 007/163] use 404 for temp link --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 125e5b42..1e7bb6fb 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -46,7 +46,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern } // End of checking if the CPU architecture is compatible with the selected MySQL version - let url: string = ''; + let url: string = 'https://www.google.com/404'; if (currentOS === 'win32') { url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` From 31e5f7ac2965624a3418ddc3b36c81a09aca621c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 01:27:27 +0400 Subject: [PATCH 008/163] add download log --- src/libraries/Downloader.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 71ffeb43..410be441 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -233,6 +233,7 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp try { downloadTries++; await downloadFromCDN(url, archivePath, logger) + logger.log(`Finished downloading MySQL version ${version} from ${url}`) await extractBinary(url, archivePath, extractedPath, logger) break } catch (e) { @@ -280,6 +281,7 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp try { downloadTries++ await downloadFromCDN(url, zipFilepath, logger) + logger.log(`Finished downloading MySQL version ${version} from ${url}`) const binaryPath = await extractBinary(url, zipFilepath, extractedPath, logger) return resolve(binaryPath) } catch (e) { From e3d2064969edc603eb6c20c18e97d5b5e5ff97ae Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 01:38:05 +0400 Subject: [PATCH 009/163] add ability to download DMR and RC MySQL versions --- src/constants.ts | 4 +++- src/libraries/Version.ts | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 2378f81b..14206699 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -161,4 +161,6 @@ export const MYSQL_MIN_OS_SUPPORT = { '8.0.35 - 8.0.39 || 8.1.0 - 8.4.2': '22.0.0', '8.0.40 - 8.0.41 || 8.4.3 - 9.2.0': '23.0.0' } -} \ No newline at end of file +} as const; +export const DMR_MYSQL_VERSIONS = '8.0.0 - 8.02'; +export const RC_MYSQL_VERSIONS = '8.0.3 - 8.0.4' \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 1e7bb6fb..28e05fa5 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,7 +1,7 @@ import { BinaryInfo, InternalServerOptions } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT } from "../constants"; +import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): BinaryInfo { const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(versionToGet, version)); @@ -48,8 +48,11 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern let url: string = 'https://www.google.com/404'; + const isRC = satisfies(selectedVersion, RC_MYSQL_VERSIONS) + const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) + if (currentOS === 'win32') { - url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-winx64.zip` + url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` } From 9b42e0483905dea7569fcdbfea5ad26f919a0c98 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 01:57:41 +0400 Subject: [PATCH 010/163] temporarily remove 5.7.19 download --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 14206699..3c2d6ce8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -117,7 +117,7 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { export const MIN_SUPPORTED_MYSQL = '5.7.19'; export const DOWNLOADABLE_MYSQL_VERSIONS = [ - '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', + '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', From eaad71621132d11901defa5fd57eb1b4ba1c5361 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 02:19:14 +0400 Subject: [PATCH 011/163] fix typo --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 3c2d6ce8..1639d50c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -162,5 +162,5 @@ export const MYSQL_MIN_OS_SUPPORT = { '8.0.40 - 8.0.41 || 8.4.3 - 9.2.0': '23.0.0' } } as const; -export const DMR_MYSQL_VERSIONS = '8.0.0 - 8.02'; +export const DMR_MYSQL_VERSIONS = '8.0.0 - 8.0.2'; export const RC_MYSQL_VERSIONS = '8.0.3 - 8.0.4' \ No newline at end of file From 33c0ea02f437bdee9ab260c9ccc5424a0b0ee111 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:54:25 +0400 Subject: [PATCH 012/163] reduce versions for regular test --- tests/versions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index f0d8d601..f6e7046c 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,8 +5,8 @@ import { coerce } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; +const versions = ['5.7.20', '5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' @@ -15,7 +15,7 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of versions) { for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) From d823384b2e79e10ca8dc6767dc433f15617e2708 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:32:11 +0400 Subject: [PATCH 013/163] swap satisifes parameters --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 28e05fa5..3c789bea 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -4,7 +4,7 @@ import { satisfies, coerce, lt, major, minor } from "semver"; import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): BinaryInfo { - const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(versionToGet, version)); + const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { throw `mysql-memory-server does not support downloading the version of MySQL requested (${versionToGet}). Please check for typos, choose a different version of MySQL to use, or make an issue or pull request to add support for this MySQL version on GitHub.` From 7b1f220f47c49b7bd8c3529773706751a6e5ea98 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:25:50 +0400 Subject: [PATCH 014/163] change url --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 3c789bea..afb3ebe1 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -52,7 +52,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) if (currentOS === 'win32') { - url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` + url = `https://cdn.mysql.com//Downloads/MySQL-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` } From 1af1d6e6374a69004b95487939f926e1414bddae Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:32:10 +0400 Subject: [PATCH 015/163] modify tests --- tests/versions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index f6e7046c..89a6f4e7 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -1,7 +1,7 @@ import {expect, test, jest} from '@jest/globals' import { createDB } from '../src/index' import sql from 'mysql2/promise' -import { coerce } from 'semver'; +import { coerce, satisfies } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; @@ -48,7 +48,7 @@ for (const version of versions) { await connection.end(); await db.stop(); - expect(coerce(mySQLVersion)?.version).toBe(version) + expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) } } \ No newline at end of file From b489220dd22ca25c65f37f7578181baf8851a5f4 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:37:55 +0400 Subject: [PATCH 016/163] add version 9.0.1 --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 89a6f4e7..25babc2e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.20', '5.7.x', '8.0.x', '8.4.x', '9.x'] +const versions = ['5.7.20', '5.7.x', '8.0.x', '8.4.x', '9.x', '9.0.1'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From 230b0320b9a84398cf8ac74d56dff24615ad140f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:39:28 +0400 Subject: [PATCH 017/163] change test versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 25babc2e..414a405e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.20', '5.7.x', '8.0.x', '8.4.x', '9.x', '9.0.1'] +const versions = ['5.7.20', '8.0.40', '8.4.3', '9.0.1'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From ddbe7158b6718b6ffe6b06cd0894ea69256d7037 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:44:05 +0400 Subject: [PATCH 018/163] add version 9.0.1 --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 1639d50c..b5c69863 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -127,7 +127,7 @@ export const DOWNLOADABLE_MYSQL_VERSIONS = [ '8.4.0', '8.4.1', '8.4.2', '8.4.3', '8.4.4', - '9.0.0', '9.1.0', '9.2.0' + '9.0.0', '9.0.1', '9.1.0', '9.2.0' ] as const; export const MYSQL_ARCH_SUPPORT = { darwin: { From c7724021c5b1de6ab8e56126d2b2f313fa618b4d Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:44:42 +0400 Subject: [PATCH 019/163] update test versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 414a405e..ab74e78c 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.20', '8.0.40', '8.4.3', '9.0.1'] +const versions = ['5.7.20', '5.7.43', '8.0.11', '8.0.0', '8.0.40', '8.4.3', '9.0.1'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From b2c9bf93a3dbb04d97faa1ca6db874563b0f7eca Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:49:08 +0400 Subject: [PATCH 020/163] update test versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index ab74e78c..d26f5e48 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.20', '5.7.43', '8.0.11', '8.0.0', '8.0.40', '8.4.3', '9.0.1'] +const versions = ['5.7.20', '5.7.43', '8.0.11', '8.0.0', '8.0.30', '8.1.0', '8.4.0', '9.0.0'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From 04198c923c482633640ce13c33dbb0444215b6df Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 16:03:04 +0400 Subject: [PATCH 021/163] change downloadBinaryOnce to true for versions test --- tests/versions.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index d26f5e48..4544c8a1 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,8 +5,8 @@ import { coerce, satisfies } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; +import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; -const versions = ['5.7.20', '5.7.43', '8.0.11', '8.0.0', '8.0.30', '8.1.0', '8.4.0', '9.0.0'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' @@ -15,7 +15,7 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); -for (const version of versions) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) @@ -25,7 +25,8 @@ for (const version of versions) { dbName: 'testingdata', username: username, logLevel: 'LOG', - initSQLString: 'CREATE DATABASE mytestdb;' + initSQLString: 'CREATE DATABASE mytestdb;', + downloadBinaryOnce: true } if (process.env.useCIDBPath) { From b12fe724545d322aab70bb5d25343af458c3456a Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 16:24:20 +0400 Subject: [PATCH 022/163] update base url --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index afb3ebe1..3c789bea 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -52,7 +52,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) if (currentOS === 'win32') { - url = `https://cdn.mysql.com//Downloads/MySQL-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` + url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` } From cf40d1e484af8a59736f56d59698546a651268df Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:34:25 +0400 Subject: [PATCH 023/163] set downloadBinaryOnce to false --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 4544c8a1..41375a1e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -26,7 +26,7 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { username: username, logLevel: 'LOG', initSQLString: 'CREATE DATABASE mytestdb;', - downloadBinaryOnce: true + downloadBinaryOnce: false } if (process.env.useCIDBPath) { From 1aa3b46af29fb603cea5515e7f0560cd9bab6b80 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:47:42 +0400 Subject: [PATCH 024/163] move all version tests to stress and shard stress tests --- .github/workflows/stress.yml | 3 ++- stress-tests/stress.test.ts | 10 ++++++---- tests/versions.test.ts | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 2665885a..5cfb6d8b 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -14,6 +14,7 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] + shard-number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] steps: - name: Free Disk Space (Ubuntu) @@ -52,7 +53,7 @@ jobs: run: npm ci - name: Run tests - run: npm run stress + run: npm run stress --shard=${{ matrix.shard-number }}/10 - name: Upload mysqlmsn directory (Windows) if: ${{ failure() && runner.os == 'Windows' }} diff --git a/stress-tests/stress.test.ts b/stress-tests/stress.test.ts index 0f522f6b..221328ff 100644 --- a/stress-tests/stress.test.ts +++ b/stress-tests/stress.test.ts @@ -3,6 +3,7 @@ import { createDB } from '../src/index' import sql from 'mysql2/promise' import { ServerOptions } from '../types'; import { normalize } from 'path'; +import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; jest.setTimeout(500_000); @@ -10,19 +11,20 @@ const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNE const dbPath = normalize(GitHubActionsTempFolder + '/dbs') const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') -for (let i = 0; i < 100; i++) { - test(`if run ${i} is successful`, async () => { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { + test(`if ${version} works with package`, async () => { console.log('CI:', process.env.useCIDBPath) process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) const options: ServerOptions = { username: 'dbuser', - logLevel: 'LOG' + logLevel: 'LOG', + version } if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = `${dbPath}/${i}` + process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = `${dbPath}/${version}` process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath } diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 41375a1e..82179426 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,8 +5,8 @@ import { coerce, satisfies } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; +const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' @@ -15,7 +15,7 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of versions) { for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) From ab924f130ea2127318ca0864fd16c1512eab4fc5 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:01:57 +0400 Subject: [PATCH 025/163] add ci name to stress tests --- .github/workflows/stress.yml | 2 +- CONTRIBUTING.md | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 5cfb6d8b..7a7e77dc 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -53,7 +53,7 @@ jobs: run: npm ci - name: Run tests - run: npm run stress --shard=${{ matrix.shard-number }}/10 + run: npm run stress:ci - name: Upload mysqlmsn directory (Windows) if: ${{ failure() && runner.os == 'Windows' }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f4c6eda..85171b60 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ There are also automated tests which you can run by running the command: npm test ``` -Please do not run the `npm run test:ci` command to test your code locally. That command is meant to only be used in GitHub Actions. +Please do not run the `npm run test:ci` or `npm run stress:ci` command to test your code locally. That command is meant to only be used in GitHub Actions. # Submitting the pull request diff --git a/package.json b/package.json index 82de6444..ddef7517 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "scripts": { "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors", "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors", - "stress": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" + "stress:ci": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { "node": ">=16.6.0", From f179814d07c6796d48e0bcd8e0048a52362f6962 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:09:11 +0400 Subject: [PATCH 026/163] remove shards --- .github/workflows/stress.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 7a7e77dc..52576b47 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -14,7 +14,6 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] - shard-number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] steps: - name: Free Disk Space (Ubuntu) From 19832c11d24fc906e468e2968c48a5f1c3f5821f Mon Sep 17 00:00:00 2001 From: Sebastian Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:56:38 +0400 Subject: [PATCH 027/163] replace unlink with rm (#185) --- src/libraries/Downloader.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 410be441..82d15ce0 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -69,9 +69,9 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) } - fs.unlink(downloadLocation, (unlinkErr) => { - if (unlinkErr) { - logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', err) + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) } logger.error('Received status code:', response.statusCode, 'while downloading MySQL binary.') @@ -92,9 +92,9 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): error = err; logger.error(err) fileStream.end(() => { - fs.unlink(downloadLocation, (unlinkError) => { - if (unlinkError) { - logger.error('An error occurred while deleting downloadLocation after an error occurred with the MySQL server binary download. The error was:', unlinkError) + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after an error occurred with the MySQL server binary download. The error was:', rmError) } reject(err.message); }) @@ -106,9 +106,9 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): error = err; logger.error(err) fileStream.end(() => { - fs.unlink(downloadLocation, (unlinkError) => { - if (unlinkError) { - logger.error('An error occurred while deleting downloadLocation after an error occurred with the fileStream. The error was:', unlinkError) + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after an error occurred with the fileStream. The error was:', rmError) } reject(err.message) }) From 736a7a47d1f343edc68f52fa3b7d2e0e6f7e81d3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:53:36 +0400 Subject: [PATCH 028/163] add retrying MySQL download with different URL on 404 error --- src/index.ts | 30 ++++++++++++++++++------------ src/libraries/Version.ts | 27 +++++++++++++++++---------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4f97b8df..b7b23078 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import Logger from './libraries/Logger' -import * as os from 'node:os' import Executor from "./libraries/Executor" -import { satisfies, lt, coerce } from "semver" +import { satisfies, lt } from "semver" import { BinaryInfo, ServerOptions } from '../types' import getBinaryURL from './libraries/Version' import { downloadBinary } from './libraries/Downloader' @@ -44,22 +43,29 @@ export async function createDB(opts?: ServerOptions) { logger.log('Version currently installed:', version) if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { - if (options.version && lt(coerce(options.version), MIN_SUPPORTED_MYSQL)) { - //The difference between the throw here and the throw above is this throw is because the selected "version" is not supported. - //The throw above is because the system-installed MySQL is out of date and "ignoreUnsupportedSystemVersion" is not set to true. - throw `The selected version of MySQL (${options.version}) is not currently supported by this package. Please choose a different version to use.` - } - let binaryInfo: BinaryInfo; let binaryFilepath: string; - binaryInfo = getBinaryURL(options.version, options) + const binaryInfoArray = getBinaryURL(options.version, options) logger.log('Using MySQL binary version:', binaryInfo.version, 'from URL:', binaryInfo.url) try { - binaryFilepath = await downloadBinary(binaryInfo, options, logger); + binaryFilepath = await downloadBinary(binaryInfoArray[0], options, logger); + binaryInfo = binaryInfoArray[0] } catch (error) { - logger.error('Failed to download binary:', error) - throw `Failed to download binary. The error was: "${error}"` + if (error.includes?.('404')) { + //Error includes 404. Most likely because the download got a 404 response. Try using the 2nd URL provided by getBinaryURL. + logger.warn('Failed to download binary because of error:', error, ' | This download will be retried with a different URL before giving up.') + try { + binaryFilepath = await downloadBinary(binaryInfoArray[1], options, logger); + binaryInfo = binaryInfoArray[1] + } catch (retryError) { + logger.error('Failed to download binary after retry because of error:', retryError) + throw `Failed to download binary after retrying with a different URL. The error was: "${error}"` + } + } else { + logger.error('Failed to download binary:', error) + throw `Failed to download binary. The error was: "${error}"` + } } logger.log('Running downloaded binary') diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 3c789bea..62122928 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,13 +1,13 @@ import { BinaryInfo, InternalServerOptions } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MIN_SUPPORTED_MYSQL, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; -export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): BinaryInfo { +export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): [BinaryInfo, BinaryInfo] { const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { - throw `mysql-memory-server does not support downloading the version of MySQL requested (${versionToGet}). Please check for typos, choose a different version of MySQL to use, or make an issue or pull request to add support for this MySQL version on GitHub.` + throw `mysql-memory-server does not support downloading the version of MySQL requested (${versionToGet}). This package only supports downloads of MySQL for MySQL >= ${MIN_SUPPORTED_MYSQL} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` } //Sorts versions in descending order @@ -46,20 +46,27 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern } // End of checking if the CPU architecture is compatible with the selected MySQL version - let url: string = 'https://www.google.com/404'; - const isRC = satisfies(selectedVersion, RC_MYSQL_VERSIONS) const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) + const downloadsURL = 'https://cdn.mysql.com//Downloads/MySQL-' + const archiveURL = 'https://cdn.mysql.com/archives/mysql-' + let fileLocation: string = '' if (currentOS === 'win32') { - url = `https://cdn.mysql.com/archives/mysql-${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` } //TODO: Support for other platforms will be coming soon. - return { - version: selectedVersion, - url - } + return [ + { + version: selectedVersion, + url: archiveURL + fileLocation + }, + { + version: selectedVersion, + url: downloadsURL + fileLocation + }, + ] } \ No newline at end of file From 70631d6285d12503182f44c06c287a26ef143400 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:04:39 +0400 Subject: [PATCH 029/163] fix error in log --- src/index.ts | 1 - src/libraries/Downloader.ts | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index b7b23078..792a5cfc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -46,7 +46,6 @@ export async function createDB(opts?: ServerOptions) { let binaryInfo: BinaryInfo; let binaryFilepath: string; const binaryInfoArray = getBinaryURL(options.version, options) - logger.log('Using MySQL binary version:', binaryInfo.version, 'from URL:', binaryInfo.url) try { binaryFilepath = await downloadBinary(binaryInfoArray[0], options, logger); diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 82d15ce0..86f24a99 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -232,9 +232,11 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp do { try { downloadTries++; + logger.log(`Starting download for MySQL version ${version} from ${url}.`) await downloadFromCDN(url, archivePath, logger) - logger.log(`Finished downloading MySQL version ${version} from ${url}`) + logger.log(`Finished downloading MySQL version ${version} from ${url}. Now starting binary extraction.`) await extractBinary(url, archivePath, extractedPath, logger) + logger.log(`Finished extraction for version ${version}`) break } catch (e) { //Delete generated files since either download or extraction failed From 569066c2088a86312a110ddf52305f73802e387b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:18:27 +0400 Subject: [PATCH 030/163] set downloadBinaryOnce to false --- stress-tests/stress.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stress-tests/stress.test.ts b/stress-tests/stress.test.ts index 221328ff..b093c38d 100644 --- a/stress-tests/stress.test.ts +++ b/stress-tests/stress.test.ts @@ -20,7 +20,8 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { const options: ServerOptions = { username: 'dbuser', logLevel: 'LOG', - version + version, + downloadBinaryOnce: false } if (process.env.useCIDBPath) { From 5c09f6e66284afefff6b41631e14158ee7f2e6ac Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:44:44 +0400 Subject: [PATCH 031/163] add extra logs for downloadBinaryOnce false --- src/libraries/Downloader.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 86f24a99..9c96a5f1 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -282,9 +282,11 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp try { downloadTries++ + logger.log(`Starting download for MySQL version ${version} from ${url}.`) await downloadFromCDN(url, zipFilepath, logger) - logger.log(`Finished downloading MySQL version ${version} from ${url}`) + logger.log(`Finished downloading MySQL version ${version} from ${url}. Now starting binary extraction.`) const binaryPath = await extractBinary(url, zipFilepath, extractedPath, logger) + logger.log(`Finished extraction for version ${version}`) return resolve(binaryPath) } catch (e) { //Delete generated files since either download or extraction failed From 5c4bde7e11a4df256332c2f4209d836e41036504 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 02:16:47 +0400 Subject: [PATCH 032/163] add macOS download support --- src/constants.ts | 17 +++++++++++++++-- src/libraries/Version.ts | 6 +++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index b5c69863..68181948 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -116,6 +116,7 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { } as const; export const MIN_SUPPORTED_MYSQL = '5.7.19'; +// Versions 8.0.29, 8.0.38, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', @@ -127,7 +128,7 @@ export const DOWNLOADABLE_MYSQL_VERSIONS = [ '8.4.0', '8.4.1', '8.4.2', '8.4.3', '8.4.4', - '9.0.0', '9.0.1', '9.1.0', '9.2.0' + '9.0.1', '9.1.0', '9.2.0' ] as const; export const MYSQL_ARCH_SUPPORT = { darwin: { @@ -163,4 +164,16 @@ export const MYSQL_MIN_OS_SUPPORT = { } } as const; export const DMR_MYSQL_VERSIONS = '8.0.0 - 8.0.2'; -export const RC_MYSQL_VERSIONS = '8.0.3 - 8.0.4' \ No newline at end of file +export const RC_MYSQL_VERSIONS = '8.0.3 - 8.0.4'; +export const MYSQL_MACOS_VERSIONS_IN_FILENAME = { + '5.7.19 - 5.7.20 || 8.0.1 - 8.0.3': 'macos10.12', + '5.7.21 - 5.7.23 || 8.0.4 - 8.0.12': 'macos10.13', + '5.7.24 - 5.7.31 || 8.0.13 - 8.0.18': 'macos10.14', + '8.0.0': 'osx10.11', + '8.0.19 - 8.0.23': 'macos10.15', + '8.0.24 - 8.0.28': 'macos11', + '8.0.30 - 8.0.31': 'macos12', + '8.0.32 - 8.0.35 || 8.1.0 - 8.2.0': 'macos13', + '8.0.36 - 8.0.40 || 8.3.0 - 8.4.3 || 9.0.1 - 9.1.0': 'macos14', + '8.0.41 || 8.4.4 || 9.2.0': 'macos15' +} as const; \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 62122928..d028b4a0 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,7 +1,7 @@ import { BinaryInfo, InternalServerOptions } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MIN_SUPPORTED_MYSQL, MYSQL_ARCH_SUPPORT, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MIN_SUPPORTED_MYSQL, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): [BinaryInfo, BinaryInfo] { const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); @@ -54,7 +54,11 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern if (currentOS === 'win32') { fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-winx64.zip` + } else if (currentOS === 'darwin') { + const MySQLmacOSVersionNameKeys = Object.keys(MYSQL_MACOS_VERSIONS_IN_FILENAME); + const macOSVersionNameKey = MySQLmacOSVersionNameKeys.find(range => satisfies(selectedVersion, range)) + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-${MYSQL_MACOS_VERSIONS_IN_FILENAME[macOSVersionNameKey]}-${currentArch}.tar.gz` } //TODO: Support for other platforms will be coming soon. From 9bfbbb67f4391d17003d0432d67697b017bb45b8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:08:10 +0400 Subject: [PATCH 033/163] change compression level --- .github/workflows/stress.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 52576b47..92b8d59d 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -60,7 +60,7 @@ jobs: with: name: ${{ matrix.os }} path: "C:\\Users\\RUNNER~1\\mysqlmsn" - compression-level: 9 + compression-level: 0 - name: Upload mysqlmsn directory (Not Windows) if: ${{ failure() && runner.os != 'Windows' }} @@ -68,4 +68,4 @@ jobs: with: name: ${{ matrix.os }} path: /tmp/mysqlmsn - compression-level: 9 \ No newline at end of file + compression-level: 0 \ No newline at end of file From 850cbb4ddd1245359aac72ea7b58414cd774dd60 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:18:45 +0400 Subject: [PATCH 034/163] remove 8.4.1 for download --- src/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 68181948..25f625a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -116,7 +116,7 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { } as const; export const MIN_SUPPORTED_MYSQL = '5.7.19'; -// Versions 8.0.29, 8.0.38, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. +// Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', @@ -126,7 +126,7 @@ export const DOWNLOADABLE_MYSQL_VERSIONS = [ '8.1.0', '8.2.0', '8.3.0', - '8.4.0', '8.4.1', '8.4.2', '8.4.3', '8.4.4', + '8.4.0', '8.4.2', '8.4.3', '8.4.4', '9.0.1', '9.1.0', '9.2.0' ] as const; From ab0c65563c54a792e70535f9d673bebe4a601bdc Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:21:04 +0400 Subject: [PATCH 035/163] demote download try failure from error to warn --- src/libraries/Downloader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 9c96a5f1..a6b7735d 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -74,7 +74,7 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) } - logger.error('Received status code:', response.statusCode, 'while downloading MySQL binary.') + logger.warn('Received status code:', response.statusCode, 'while downloading MySQL binary.') reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) }) }) From 1d3693b2bf601812d97074dc2a0273c2bb77d02f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:22:05 +0400 Subject: [PATCH 036/163] remove warning --- src/libraries/Downloader.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index a6b7735d..0fa5f4b5 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -74,7 +74,6 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) } - logger.warn('Received status code:', response.statusCode, 'while downloading MySQL binary.') reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) }) }) From 2d41980c0c3633ddbdc0b6706a652261e8238c2f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 15:08:13 +0400 Subject: [PATCH 037/163] add version 5.7.19 back --- src/constants.ts | 2 +- tests/versions.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 25f625a0..1e6587b6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -118,7 +118,7 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { export const MIN_SUPPORTED_MYSQL = '5.7.19'; // Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ - '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', + '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 82179426..8879a828 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] +const versions = ['5.7.19', '5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From 5ffb21c536e15a74854dc9734419b94bc37f7311 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 16:55:34 +0400 Subject: [PATCH 038/163] remove 5.7.19 from download and update README about versions available for download --- README.md | 4 ++-- src/constants.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a169b24d..76278b9a 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Requirements for Linux: #### Currently supported MySQL versions -- Running MySQL versions already installed on the system: 5.7.19 and newer -- MySQL versions available to download through ```mysql-memory-server``` and run: 8.0.39 - 8.0.41, 8.1.0 - 8.3.0, 8.4.2 - 8.4.4, and 9.0.1 - 9.2.0 +- ```mysql-memory-server``` can run MySQL versions 5.7.19 and newer +- ```mysql-memory-server``` can download MySQL versions 5.7.20 - 9.2.0 ## Example Usage - Application Code diff --git a/src/constants.ts b/src/constants.ts index 1e6587b6..25f625a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -118,7 +118,7 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { export const MIN_SUPPORTED_MYSQL = '5.7.19'; // Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ - '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', + '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', From c9fe07862405f5cf63dd45f336377cfc25f94b5b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:28:47 +0400 Subject: [PATCH 039/163] do OS, OS version, and arch checks before choosing a version to run --- src/libraries/Version.ts | 54 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index d028b4a0..4f1e3c17 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -7,15 +7,9 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { - throw `mysql-memory-server does not support downloading the version of MySQL requested (${versionToGet}). This package only supports downloads of MySQL for MySQL >= ${MIN_SUPPORTED_MYSQL} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` + throw `mysql-memory-server does not support downloading a version of MySQL that fits the following version requirement: ${versionToGet}. This package only supports downloads of MySQL for MySQL >= ${MIN_SUPPORTED_MYSQL} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` } - //Sorts versions in descending order - selectedVersions.sort((a, b) => a < b ? 1 : -1) - - const selectedVersion = selectedVersions[0] - - // Start of checking if the OS version is compatible with the selected MySQL version const currentOS = os.platform(); const OSVersionSupport = MYSQL_MIN_OS_SUPPORT[currentOS]; @@ -23,16 +17,15 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const OSSupportVersionRanges = Object.keys(OSVersionSupport); - const OSKey = OSSupportVersionRanges.find(item => satisfies(selectedVersion, item)) + selectedVersions.filter(possibleVersion => { + const OSKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) + return !!OSKey + }) - if (!OSKey) throw `This version of MySQL (${selectedVersion}) does not support your operating system. Please make sure you are running the latest version of mysql-memory-server or choose a different version of MySQL or report an issue on GitHub if you believe this is a bug.` - - const minOSForMySQLVersion = OSVersionSupport[OSKey] - - if (lt(coerce(os.release()), minOSForMySQLVersion)) throw `Your operating system is too out of date to use version ${selectedVersion} of MySQL. MySQL requires >= ${minOSForMySQLVersion} but your system is ${os.release()}. Please update your operating system, choose a different version of MySQL to use, or report an issue on GitHub if you believe this is a bug.` - // End of checking if the OS version is compatible with the selected MySQL version + if (selectedVersions.length === 0) { + throw `No version of MySQL could be found that supports your operating system and fits the following version requirement: ${versionToGet}. Please check for typos, choose a different version of MySQL to run, or if you think this is a bug, please report this on GitHub.` + } - // Start of checking if the CPU architecture is compatible with the selected MySQL version const currentArch = options.arch; const archSupport = MYSQL_ARCH_SUPPORT[currentOS][currentArch] @@ -41,10 +34,35 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern throw `MySQL and/or mysql-memory-server does not support the CPU architecture you want to use (${currentArch}). Please make sure you are using the latest version of mysql-memory-server or try using a different architecture, or if you believe this is a bug, please report this on GitHub.` } - if (!satisfies(selectedVersion, archSupport)) { - throw `The desired version of MySQL to run (${selectedVersion}) does not support the CPU architecture (${currentArch}). Please try using a different architecture or MySQL version, or if you believe this is a bug, please report this on GitHub.` + selectedVersions.filter(possibleVersion => satisfies(possibleVersion, archSupport)) + + if (selectedVersions.length === 0) { + throw `No version of MySQL could be found that supports the CPU architecture ${options.arch === os.arch() ? 'for your system' : 'you have chosen'} (${options.arch}). Please try choosing a different version of MySQL, or if you believe this is a bug, please report this on GitHub.` + } + + const versionsBeforeOSVersionCheck = selectedVersions.slice() + const coercedOSRelease = coerce(os.release()) + selectedVersions.filter(possibleVersion => { + const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) + return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) + }) + + if (selectedVersions.length === 0) { + const versionKeys = new Set() + for (const v of versionsBeforeOSVersionCheck) { + versionKeys.add(OSSupportVersionRanges.find(item => satisfies(v, item))) + } + const minVersions = Array.from(versionKeys).map(v => OSVersionSupport[v]) + //Sorts versions in ascending order + minVersions.sort((a, b) => a < b ? -1 : 1) + const minVersion = minVersions[0] + throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.` } - // End of checking if the CPU architecture is compatible with the selected MySQL version + + //Sorts versions in descending order + selectedVersions.sort((a, b) => a < b ? 1 : -1) + + const selectedVersion = selectedVersions[0] const isRC = satisfies(selectedVersion, RC_MYSQL_VERSIONS) const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) From c62dfcc8bb54e5022804a50def9b6146df86f8d3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:31:34 +0400 Subject: [PATCH 040/163] get min version for MySQL download from downloadable versions array --- src/libraries/Version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 4f1e3c17..e94d6170 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,13 +1,13 @@ import { BinaryInfo, InternalServerOptions } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MIN_SUPPORTED_MYSQL, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): [BinaryInfo, BinaryInfo] { const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { - throw `mysql-memory-server does not support downloading a version of MySQL that fits the following version requirement: ${versionToGet}. This package only supports downloads of MySQL for MySQL >= ${MIN_SUPPORTED_MYSQL} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` + throw `mysql-memory-server does not support downloading a version of MySQL that fits the following version requirement: ${versionToGet}. This package only supports downloads of MySQL for MySQL >= ${DOWNLOADABLE_MYSQL_VERSIONS[0]} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` } const currentOS = os.platform(); From 70dabfac7ce414f38ef2222b3b3aea8cc804cba1 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:32:28 +0400 Subject: [PATCH 041/163] add OSVersionKey log --- src/libraries/Version.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index e94d6170..d76cffb8 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -44,6 +44,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const coercedOSRelease = coerce(os.release()) selectedVersions.filter(possibleVersion => { const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) + console.log('OSVersionKey:', OSVersionKey) return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) }) From 12479fc962ac442a49b407ba6f322cb5b54b4ddd Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:33:03 +0400 Subject: [PATCH 042/163] remove 5.7.19 test --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 8879a828..82179426 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -const versions = ['5.7.19', '5.7.x', '8.0.x', '8.4.x', '9.x'] +const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' From 3613dd64ed28d73a12f5ae44ada8178892ed107c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:34:30 +0400 Subject: [PATCH 043/163] add possibleVersion log --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index d76cffb8..89582b2c 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -44,7 +44,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const coercedOSRelease = coerce(os.release()) selectedVersions.filter(possibleVersion => { const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OSVersionKey:', OSVersionKey) + console.log('OSVersionKey:', OSVersionKey, 'possibleVersion:', possibleVersion) return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) }) From 95e4ead9e0f77601f5e7c8838264d763645b54e0 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:36:54 +0400 Subject: [PATCH 044/163] fix runningMySQL versions that need >= macOS 10.14 throws an error --- src/constants.ts | 2 +- src/libraries/Version.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 25f625a0..9152d016 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -153,7 +153,7 @@ export const MYSQL_MIN_OS_SUPPORT = { darwin: { '5.7.19 - 5.7.23 || 8.0.1 - 8.0.3 || 8.0.11 - 8.0.12': '16.0.0', '5.7.24 - 5.7.29 || 8.0.4 || 8.0.13 - 8.0.18': '17.0.0', - '5.7.30 - 5.7.31, 8.0.19 - 8.0.22': '18.0.0', + '5.7.30 - 5.7.31 || 8.0.19 - 8.0.22': '18.0.0', //5.7.32 - 5.7.44 is not supported for macOS by MySQL. Those versions are not appearing in this list '8.0.0': '13.0.0', '8.0.23 - 8.0.27': '19.0.0', diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 89582b2c..e94d6170 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -44,7 +44,6 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const coercedOSRelease = coerce(os.release()) selectedVersions.filter(possibleVersion => { const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OSVersionKey:', OSVersionKey, 'possibleVersion:', possibleVersion) return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) }) From e12e0e5bb4dee2e57bfab722e4ca2fbcfb608415 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:38:48 +0400 Subject: [PATCH 045/163] remove downloadBinaryOnce false for versions test --- tests/versions.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 82179426..d44d1f99 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -25,8 +25,7 @@ for (const version of versions) { dbName: 'testingdata', username: username, logLevel: 'LOG', - initSQLString: 'CREATE DATABASE mytestdb;', - downloadBinaryOnce: false + initSQLString: 'CREATE DATABASE mytestdb;' } if (process.env.useCIDBPath) { From d8a5b3be140ff70ecb9ab31f58ca8bdc1371c5bc Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:40:30 +0400 Subject: [PATCH 046/163] add log for os version check --- src/libraries/Version.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index e94d6170..89582b2c 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -44,6 +44,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const coercedOSRelease = coerce(os.release()) selectedVersions.filter(possibleVersion => { const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) + console.log('OSVersionKey:', OSVersionKey, 'possibleVersion:', possibleVersion) return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) }) From 495a0c675d8134566451796e91c65097febfb3d2 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:43:53 +0400 Subject: [PATCH 047/163] add OSKey log --- src/libraries/Version.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 89582b2c..6dbec563 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -19,6 +19,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern selectedVersions.filter(possibleVersion => { const OSKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) + console.log('OS check key:', OSKey) return !!OSKey }) From c1f3de1d97adc5bb468232f359f14fa8bd856244 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:45:28 +0400 Subject: [PATCH 048/163] add possibleVersion log --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 6dbec563..3b8d9dd6 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -19,7 +19,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern selectedVersions.filter(possibleVersion => { const OSKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OS check key:', OSKey) + console.log('OS check key:', OSKey, 'possibleVersion:', possibleVersion) return !!OSKey }) From aae8cf9e737876ab2a09c1fd90f1b811cfbcaac3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:48:59 +0400 Subject: [PATCH 049/163] update log --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 3b8d9dd6..9c8f02b7 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -19,7 +19,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern selectedVersions.filter(possibleVersion => { const OSKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OS check key:', OSKey, 'possibleVersion:', possibleVersion) + console.log('OS check key:', OSKey, 'possibleVersion:', possibleVersion, !!OSKey) return !!OSKey }) From 986bf76adcc4ae5540c98bc31c625da3405a4a76 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:51:20 +0400 Subject: [PATCH 050/163] add selectedVersions log --- src/libraries/Version.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 9c8f02b7..18fdf440 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -23,6 +23,8 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern return !!OSKey }) + console.log('Selected versions after OS filter:', selectedVersions) + if (selectedVersions.length === 0) { throw `No version of MySQL could be found that supports your operating system and fits the following version requirement: ${versionToGet}. Please check for typos, choose a different version of MySQL to run, or if you think this is a bug, please report this on GitHub.` } From 862219af575fcd2f73e27f2ff24582e0d9823166 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:54:02 +0400 Subject: [PATCH 051/163] fix macOS tests failing for 5.7.x --- src/libraries/Version.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 18fdf440..4b47e2b9 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -4,7 +4,7 @@ import { satisfies, coerce, lt, major, minor } from "semver"; import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): [BinaryInfo, BinaryInfo] { - const selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); + let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { throw `mysql-memory-server does not support downloading a version of MySQL that fits the following version requirement: ${versionToGet}. This package only supports downloads of MySQL for MySQL >= ${DOWNLOADABLE_MYSQL_VERSIONS[0]} <= ${DOWNLOADABLE_MYSQL_VERSIONS.at(-1)}. Please check for typos, choose a different version of MySQL to use, or make an issue or pull request on GitHub if you belive this is a bug.` @@ -17,14 +17,11 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const OSSupportVersionRanges = Object.keys(OSVersionSupport); - selectedVersions.filter(possibleVersion => { + selectedVersions = selectedVersions.filter(possibleVersion => { const OSKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OS check key:', OSKey, 'possibleVersion:', possibleVersion, !!OSKey) return !!OSKey }) - console.log('Selected versions after OS filter:', selectedVersions) - if (selectedVersions.length === 0) { throw `No version of MySQL could be found that supports your operating system and fits the following version requirement: ${versionToGet}. Please check for typos, choose a different version of MySQL to run, or if you think this is a bug, please report this on GitHub.` } @@ -37,7 +34,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern throw `MySQL and/or mysql-memory-server does not support the CPU architecture you want to use (${currentArch}). Please make sure you are using the latest version of mysql-memory-server or try using a different architecture, or if you believe this is a bug, please report this on GitHub.` } - selectedVersions.filter(possibleVersion => satisfies(possibleVersion, archSupport)) + selectedVersions = selectedVersions.filter(possibleVersion => satisfies(possibleVersion, archSupport)) if (selectedVersions.length === 0) { throw `No version of MySQL could be found that supports the CPU architecture ${options.arch === os.arch() ? 'for your system' : 'you have chosen'} (${options.arch}). Please try choosing a different version of MySQL, or if you believe this is a bug, please report this on GitHub.` @@ -45,9 +42,8 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern const versionsBeforeOSVersionCheck = selectedVersions.slice() const coercedOSRelease = coerce(os.release()) - selectedVersions.filter(possibleVersion => { + selectedVersions = selectedVersions.filter(possibleVersion => { const OSVersionKey = OSSupportVersionRanges.find(item => satisfies(possibleVersion, item)) - console.log('OSVersionKey:', OSVersionKey, 'possibleVersion:', possibleVersion) return !lt(coercedOSRelease, OSVersionSupport[OSVersionKey]) }) From 44518f36dd78d938bd1f56bbe5ecd9d555d5527b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:23:00 +0400 Subject: [PATCH 052/163] removed macOS 13 test --- .github/workflows/os-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 9281e194..77db41f9 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] + os: [macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: - name: Checkout From b3b406baa505c2768ab4eaa1dd09eec78155a3a7 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:24:04 +0400 Subject: [PATCH 053/163] use x64 if on windows on arm otherwise use native arch for tests --- tests/versions.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index d44d1f99..dae128ae 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -25,7 +25,8 @@ for (const version of versions) { dbName: 'testingdata', username: username, logLevel: 'LOG', - initSQLString: 'CREATE DATABASE mytestdb;' + initSQLString: 'CREATE DATABASE mytestdb;', + arch: process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64' } if (process.env.useCIDBPath) { From 0043c0ffa4a677df0e3f8ab10d214f7f16571153 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:32:06 +0400 Subject: [PATCH 054/163] skip tests if the MySQL version does not support the CPU architecture --- tests/versions.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index dae128ae..f4ee5faa 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,6 +5,7 @@ import { coerce, satisfies } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; +import { MYSQL_ARCH_SUPPORT } from '../src/constants'; const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] @@ -15,7 +16,15 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); +const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; +const archSupport = MYSQL_ARCH_SUPPORT[process.platform]?.[arch] + for (const version of versions) { + if (!archSupport || !satisfies(version, archSupport)) { + console.warn(`Skipping test for version ${version} because this version either does not support this type of operating system and/or CPU architecture.`) + continue + } + for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) @@ -26,7 +35,7 @@ for (const version of versions) { username: username, logLevel: 'LOG', initSQLString: 'CREATE DATABASE mytestdb;', - arch: process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64' + arch } if (process.env.useCIDBPath) { From 9e7ad1d668681a7a0525cb23e11c7630a6d0c3c7 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:42:26 +0400 Subject: [PATCH 055/163] check if binary is supported before running test --- src/index.ts | 2 +- src/libraries/Version.ts | 7 +++---- tests/versions.test.ts | 8 +++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 792a5cfc..2a9db66a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,7 +45,7 @@ export async function createDB(opts?: ServerOptions) { if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { let binaryInfo: BinaryInfo; let binaryFilepath: string; - const binaryInfoArray = getBinaryURL(options.version, options) + const binaryInfoArray = getBinaryURL(options.version, options.arch) try { binaryFilepath = await downloadBinary(binaryInfoArray[0], options, logger); diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 4b47e2b9..eba221bb 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,9 +1,9 @@ -import { BinaryInfo, InternalServerOptions } from "../../types"; +import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; -export default function getBinaryURL(versionToGet: string = "x", options: InternalServerOptions): [BinaryInfo, BinaryInfo] { +export default function getBinaryURL(versionToGet: string = "x", currentArch: string): [BinaryInfo, BinaryInfo] { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { @@ -26,7 +26,6 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern throw `No version of MySQL could be found that supports your operating system and fits the following version requirement: ${versionToGet}. Please check for typos, choose a different version of MySQL to run, or if you think this is a bug, please report this on GitHub.` } - const currentArch = options.arch; const archSupport = MYSQL_ARCH_SUPPORT[currentOS][currentArch] if (!archSupport) { @@ -37,7 +36,7 @@ export default function getBinaryURL(versionToGet: string = "x", options: Intern selectedVersions = selectedVersions.filter(possibleVersion => satisfies(possibleVersion, archSupport)) if (selectedVersions.length === 0) { - throw `No version of MySQL could be found that supports the CPU architecture ${options.arch === os.arch() ? 'for your system' : 'you have chosen'} (${options.arch}). Please try choosing a different version of MySQL, or if you believe this is a bug, please report this on GitHub.` + throw `No version of MySQL could be found that supports the CPU architecture ${currentArch === os.arch() ? 'for your system' : 'you have chosen'} (${currentArch}). Please try choosing a different version of MySQL, or if you believe this is a bug, please report this on GitHub.` } const versionsBeforeOSVersionCheck = selectedVersions.slice() diff --git a/tests/versions.test.ts b/tests/versions.test.ts index f4ee5faa..604bcdc9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -6,6 +6,7 @@ import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; import { MYSQL_ARCH_SUPPORT } from '../src/constants'; +import getBinaryURL from '../src/libraries/Version'; const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] @@ -17,11 +18,12 @@ const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -const archSupport = MYSQL_ARCH_SUPPORT[process.platform]?.[arch] for (const version of versions) { - if (!archSupport || !satisfies(version, archSupport)) { - console.warn(`Skipping test for version ${version} because this version either does not support this type of operating system and/or CPU architecture.`) + try { + getBinaryURL(version, arch) + } catch (e) { + console.warn(`Skipping version ${version} because the version is not supported on this system. The reason given from getBinaryURL was: ${e}`) continue } From 3d9e4a43140353e9a8b2f171bbc41a285e350cfb Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:51:59 +0400 Subject: [PATCH 056/163] detect open handles --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ddef7517..7ca0d0a9 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "scripts": { "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors", - "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors", + "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors --detectOpenHandles", "stress:ci": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { From e770f5ac4810865f11af820c5bfb2c206c0aaee5 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:59:30 +0400 Subject: [PATCH 057/163] remove detectOpenHandles --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ca0d0a9..ddef7517 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "scripts": { "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors", - "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors --detectOpenHandles", + "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors", "stress:ci": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { From 7ee4e4313932deb7979febb77ab0c5c6164370ab Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:06:52 +0400 Subject: [PATCH 058/163] use fileStream.end instead of fileStream.close --- src/libraries/Downloader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 0fa5f4b5..e9d3ff0a 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -64,7 +64,7 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): fileStream.on('open', () => { const request = https.get(url, (response) => { if (response.statusCode !== 200) { - fileStream.close((err) => { + fileStream.end((err) => { if (err) { logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) } From 664315a7a5c8ed4215b297d49346e606e8738438 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:10:27 +0400 Subject: [PATCH 059/163] move 404 retry to downloadBinary method --- src/constants.ts | 2 ++ src/index.ts | 21 ++++------------ src/libraries/Downloader.ts | 48 ++++++++++++++++++++++++++++++------- src/libraries/Version.ts | 21 ++++++---------- 4 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 9152d016..028cebb7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -116,6 +116,8 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = { } as const; export const MIN_SUPPORTED_MYSQL = '5.7.19'; +export const downloadsBaseURL = 'https://cdn.mysql.com//Downloads/MySQL-' +export const archiveBaseURL = 'https://cdn.mysql.com/archives/mysql-' // Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', diff --git a/src/index.ts b/src/index.ts index 2a9db66a..48cfa42a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,26 +45,13 @@ export async function createDB(opts?: ServerOptions) { if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { let binaryInfo: BinaryInfo; let binaryFilepath: string; - const binaryInfoArray = getBinaryURL(options.version, options.arch) + binaryInfo = getBinaryURL(options.version, options.arch) try { - binaryFilepath = await downloadBinary(binaryInfoArray[0], options, logger); - binaryInfo = binaryInfoArray[0] + binaryFilepath = await downloadBinary(binaryInfo, options, logger); } catch (error) { - if (error.includes?.('404')) { - //Error includes 404. Most likely because the download got a 404 response. Try using the 2nd URL provided by getBinaryURL. - logger.warn('Failed to download binary because of error:', error, ' | This download will be retried with a different URL before giving up.') - try { - binaryFilepath = await downloadBinary(binaryInfoArray[1], options, logger); - binaryInfo = binaryInfoArray[1] - } catch (retryError) { - logger.error('Failed to download binary after retry because of error:', retryError) - throw `Failed to download binary after retrying with a different URL. The error was: "${error}"` - } - } else { - logger.error('Failed to download binary:', error) - throw `Failed to download binary. The error was: "${error}"` - } + logger.error('Failed to download binary:', error) + throw `Failed to download binary. The error was: "${error}"` } logger.log('Running downloaded binary') diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index e9d3ff0a..00e9a32d 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -8,7 +8,7 @@ import { randomUUID } from 'crypto'; import { execFile } from 'child_process'; import { BinaryInfo, InternalServerOptions } from '../../types'; import { lockFile, waitForLock } from './FileLock'; -import { getInternalEnvVariable } from '../constants'; +import { archiveBaseURL, downloadsBaseURL, getInternalEnvVariable } from '../constants'; function getZipData(entry: AdmZip.IZipEntry): Promise { return new Promise((resolve, reject) => { @@ -227,14 +227,16 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp //The code below only runs if the lock has been acquired by us let downloadTries = 0; + let useDownloadsURL = false; do { try { downloadTries++; - logger.log(`Starting download for MySQL version ${version} from ${url}.`) - await downloadFromCDN(url, archivePath, logger) - logger.log(`Finished downloading MySQL version ${version} from ${url}. Now starting binary extraction.`) - await extractBinary(url, archivePath, extractedPath, logger) + const downloadURL = useDownloadsURL ? url.replace(archiveBaseURL, downloadsBaseURL) : url + logger.log(`Starting download for MySQL version ${version} from ${downloadURL}.`) + await downloadFromCDN(downloadURL, archivePath, logger) + logger.log(`Finished downloading MySQL version ${version} from ${downloadURL}. Now starting binary extraction.`) + await extractBinary(downloadURL, archivePath, extractedPath, logger) logger.log(`Finished extraction for version ${version}`) break } catch (e) { @@ -248,6 +250,22 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp logger.error('An error occurred while deleting extractedPath and/or archivePath:', e) } + if (e?.includes?.('status code 404')) { + if (!useDownloadsURL) { + //Retry with downloads URL + downloadTries--; + useDownloadsURL = true; + } else { + try { + await releaseFunction() + } catch (e) { + logger.error('An error occurred while releasing lock after receiving a 404 error on both downloads and archives URLs. The error was:', e) + } + + return reject(`Both URLs for MySQL version ${binaryInfo.version} returned status code 404. Aborting download.`) + } + } + if (downloadTries > options.downloadRetries) { //Only reject if we have met the downloadRetries limit try { @@ -272,6 +290,7 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp return resolve(binaryPath) } else { let downloadTries = 0; + let useDownloadsURL = false; do { const uuid = randomUUID() @@ -281,10 +300,11 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp try { downloadTries++ - logger.log(`Starting download for MySQL version ${version} from ${url}.`) - await downloadFromCDN(url, zipFilepath, logger) - logger.log(`Finished downloading MySQL version ${version} from ${url}. Now starting binary extraction.`) - const binaryPath = await extractBinary(url, zipFilepath, extractedPath, logger) + const downloadURL = useDownloadsURL ? url.replace(archiveBaseURL, downloadsBaseURL) : url + logger.log(`Starting download for MySQL version ${version} from ${downloadURL}.`) + await downloadFromCDN(downloadURL, zipFilepath, logger) + logger.log(`Finished downloading MySQL version ${version} from ${downloadURL}. Now starting binary extraction.`) + const binaryPath = await extractBinary(downloadURL, zipFilepath, extractedPath, logger) logger.log(`Finished extraction for version ${version}`) return resolve(binaryPath) } catch (e) { @@ -298,6 +318,16 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp logger.error('An error occurred while deleting extractedPath and/or archivePath:', e) } + if (e?.includes?.('status code 404')) { + if (!useDownloadsURL) { + //Retry with downloads URL + downloadTries--; + useDownloadsURL = true; + } else { + return reject(`Both URLs for MySQL version ${binaryInfo.version} returned status code 404. Aborting download.`) + } + } + if (downloadTries > options.downloadRetries) { //Only reject if we have met the downloadRetries limit return reject(e) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index eba221bb..f67d4fef 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,9 +1,9 @@ import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; -export default function getBinaryURL(versionToGet: string = "x", currentArch: string): [BinaryInfo, BinaryInfo] { +export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { @@ -65,8 +65,7 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st const isRC = satisfies(selectedVersion, RC_MYSQL_VERSIONS) const isDMR = satisfies(selectedVersion, DMR_MYSQL_VERSIONS) - const downloadsURL = 'https://cdn.mysql.com//Downloads/MySQL-' - const archiveURL = 'https://cdn.mysql.com/archives/mysql-' + let fileLocation: string = '' if (currentOS === 'win32') { @@ -80,14 +79,8 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st //TODO: Support for other platforms will be coming soon. - return [ - { - version: selectedVersion, - url: archiveURL + fileLocation - }, - { - version: selectedVersion, - url: downloadsURL + fileLocation - }, - ] + return { + version: selectedVersion, + url: archiveBaseURL + fileLocation + } } \ No newline at end of file From 4e64210b34424e3e43302d55b5ab134184b2d33e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:18:56 +0400 Subject: [PATCH 060/163] continue on 404 error --- src/libraries/Downloader.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 00e9a32d..2726a29f 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -255,6 +255,8 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp //Retry with downloads URL downloadTries--; useDownloadsURL = true; + logger.log(`Encountered error 404 when using archives URL for version ${version}. Now retrying with the downloads URL.`) + continue; } else { try { await releaseFunction() @@ -276,7 +278,7 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp logger.error('downloadRetries have been exceeded. Aborting download.') return reject(e) } else { - console.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e) + logger.warn(`An error was encountered during the binary download process. Retrying for retry ${downloadTries}/${options.downloadRetries}. The error was:`, e) } } } while (downloadTries <= options.downloadRetries) @@ -323,6 +325,8 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp //Retry with downloads URL downloadTries--; useDownloadsURL = true; + logger.log(`Encountered error 404 when using archives URL for version ${version}. Now retrying with the downloads URL.`) + continue; } else { return reject(`Both URLs for MySQL version ${binaryInfo.version} returned status code 404. Aborting download.`) } From f7d239dcc9e100bf9a8ef338dc3dbf8d63cd7b03 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:15:01 +0400 Subject: [PATCH 061/163] add support for MySQL downloads on Linux --- src/constants.ts | 9 +++++++++ src/libraries/Version.ts | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 028cebb7..1907e657 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -178,4 +178,13 @@ export const MYSQL_MACOS_VERSIONS_IN_FILENAME = { '8.0.32 - 8.0.35 || 8.1.0 - 8.2.0': 'macos13', '8.0.36 - 8.0.40 || 8.3.0 - 8.4.3 || 9.0.1 - 9.1.0': 'macos14', '8.0.41 || 8.4.4 || 9.2.0': 'macos15' +} as const; +export const MYSQL_LINUX_GLIBC_VERSIONS = { + '5.7.19 - 8.0.20': '2.12', + '8.0.21 - 9.2.0': '2.17' +} as const; +export const MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE = { + '5.7.19 - 8.0.15': 'no', + '8.0.16 - 8.0.20': 'no-glibc-tag', + '8.0.21 - 9.2.0': 'glibc-tag' } as const; \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index f67d4fef..4ca94b19 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,7 +1,7 @@ import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); @@ -73,11 +73,18 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st } else if (currentOS === 'darwin') { const MySQLmacOSVersionNameKeys = Object.keys(MYSQL_MACOS_VERSIONS_IN_FILENAME); const macOSVersionNameKey = MySQLmacOSVersionNameKeys.find(range => satisfies(selectedVersion, range)) - - fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-${MYSQL_MACOS_VERSIONS_IN_FILENAME[macOSVersionNameKey]}-${currentArch}.tar.gz` - } + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-${MYSQL_MACOS_VERSIONS_IN_FILENAME[macOSVersionNameKey]}-${currentArch === 'x64' ? 'x86_64' : 'arm64'}.tar.gz` + } else if (currentOS === 'linux') { + const glibcVersionKeys = Object.keys(MYSQL_LINUX_GLIBC_VERSIONS); + const glibcVersionKey = glibcVersionKeys.find(range => satisfies(selectedVersion, range)) + const glibcVersion = MYSQL_LINUX_GLIBC_VERSIONS[glibcVersionKey]; + + const minimalInstallAvailableKeys = Object.keys(MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE); + const minimalInstallAvailableKey = minimalInstallAvailableKeys.find(range => satisfies(selectedVersion, range)) + const minimalInstallAvailable = MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE[minimalInstallAvailableKey] - //TODO: Support for other platforms will be coming soon. + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.xz` + } return { version: selectedVersion, From 5bafde06706c763567df42c2dd70e9e4869915bf Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:16:41 +0400 Subject: [PATCH 062/163] fix Linux downloads not working --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 4ca94b19..a1b8ecc1 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -83,7 +83,7 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st const minimalInstallAvailableKey = minimalInstallAvailableKeys.find(range => satisfies(selectedVersion, range)) const minimalInstallAvailable = MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE[minimalInstallAvailableKey] - fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.xz` + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.xz` } return { From f8abdd1de71440842e9d7491bae469b034018cd0 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:20:03 +0400 Subject: [PATCH 063/163] fix downloads not working for MySQL < 8.0.12 on linux --- src/constants.ts | 6 +++++- src/libraries/Version.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 1907e657..84522301 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -187,4 +187,8 @@ export const MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE = { '5.7.19 - 8.0.15': 'no', '8.0.16 - 8.0.20': 'no-glibc-tag', '8.0.21 - 9.2.0': 'glibc-tag' -} as const; \ No newline at end of file +} as const; +export const MYSQL_LINUX_FILE_EXTENSIONS = { + '5.7.19 - 8.0.11': 'gz', + '8.0.12 - 9.2.0': 'xz' +} \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index a1b8ecc1..2f172c62 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,7 +1,7 @@ import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); @@ -83,7 +83,11 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st const minimalInstallAvailableKey = minimalInstallAvailableKeys.find(range => satisfies(selectedVersion, range)) const minimalInstallAvailable = MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE[minimalInstallAvailableKey] - fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.xz` + const fileExtensionKeys = Object.keys(MYSQL_LINUX_FILE_EXTENSIONS); + const fileExtensionKey = fileExtensionKeys.find(range => satisfies(selectedVersion, range)) + const fileExtension = MYSQL_LINUX_FILE_EXTENSIONS[fileExtensionKey] + + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.${fileExtension}` } return { From fc2443c018ccfa330b5ccc52c6a74ab4f7a1656d Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:26:58 +0400 Subject: [PATCH 064/163] add fedora 40 stress test --- .github/workflows/stress.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 92b8d59d..dcf04be9 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -9,11 +9,15 @@ on: jobs: stress: runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} strategy: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] + include: + - os: ubuntu-latest + container: fedora:40 steps: - name: Free Disk Space (Ubuntu) From 0415b8549dd90ae7fdc1eb47c02268ccf19d9c2a Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:28:59 +0400 Subject: [PATCH 065/163] add container matrix --- .github/workflows/stress.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index dcf04be9..fa0397eb 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -15,6 +15,7 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] + container: [] include: - os: ubuntu-latest container: fedora:40 From 3c0afe00047f55b74006ad43d9b8c229ee9e36df Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:30:27 +0400 Subject: [PATCH 066/163] use all downloadable MySQL versions in versions test --- .github/workflows/stress.yml | 2 -- tests/versions.test.ts | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index fa0397eb..b6e981c2 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -15,10 +15,8 @@ jobs: fail-fast: false matrix: os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] - container: [] include: - os: ubuntu-latest - container: fedora:40 steps: - name: Free Disk Space (Ubuntu) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 604bcdc9..1f71c03c 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -5,10 +5,9 @@ import { coerce, satisfies } from 'semver'; import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; import { normalize } from 'path'; -import { MYSQL_ARCH_SUPPORT } from '../src/constants'; import getBinaryURL from '../src/libraries/Version'; +import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; -const versions = ['5.7.x', '8.0.x', '8.4.x', '9.x'] const usernames = ['root', 'dbuser'] const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' @@ -19,7 +18,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of versions) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { try { getBinaryURL(version, arch) } catch (e) { From 14fe7590106eda4d37990bb3bbba0b96e009358d Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:04:19 +0400 Subject: [PATCH 067/163] free space for ubuntu and mac --- .github/workflows/os-compatibility.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 77db41f9..b248322b 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -16,6 +16,29 @@ jobs: os: [macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + if: ${{ runner.os == 'Linux' }} + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Free Disk Space (macOS) + if: ${{ runner.os == 'macOS' }} + working-directory: /Applications + run: | + echo 'BEFORE CLEANUP:' + df -h + sudo find . -name Xcode\*.app -delete + sudo rm -rf /Users/runner/Library/Android + echo 'AFTER CLEANUP:' + df -h + - name: Checkout uses: actions/checkout@v4 From 37b829b4de1d82652848917d41c00792199ba4cc Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:05:22 +0400 Subject: [PATCH 068/163] fix typo --- .github/workflows/os-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index b248322b..39ae14a0 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -16,7 +16,7 @@ jobs: os: [macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: - - name: Free Disk Space (Ubuntu) + - name: Free Disk Space (Ubuntu) uses: jlumbroso/free-disk-space@main if: ${{ runner.os == 'Linux' }} with: From 84036f71ec25f1e43350428bca159eabfac37d2d Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:15:19 +0400 Subject: [PATCH 069/163] add free disk space to fedora --- .github/workflows/os-compatibility.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 39ae14a0..30f59576 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -81,6 +81,17 @@ jobs: container: fedora:${{ matrix.version }} steps: + - name: Free Disk Space + uses: jlumbroso/free-disk-space@main + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + - name: Checkout uses: actions/checkout@v4 From a8d88be30ae0b320137c1a76414cf346084f8f30 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:22:59 +0400 Subject: [PATCH 070/163] delete the database if the run was successful --- .github/workflows/os-compatibility.yml | 11 ----------- tests/versions.test.ts | 14 +++++++++++++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 30f59576..39ae14a0 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -81,17 +81,6 @@ jobs: container: fedora:${{ matrix.version }} steps: - - name: Free Disk Space - uses: jlumbroso/free-disk-space@main - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - name: Checkout uses: actions/checkout@v4 diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 1f71c03c..16d59ba1 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -7,6 +7,7 @@ import { ServerOptions } from '../types'; import { normalize } from 'path'; import getBinaryURL from '../src/libraries/Version'; import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; +import fsPromises from 'fs/promises' const usernames = ['root', 'dbuser'] @@ -38,9 +39,11 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { initSQLString: 'CREATE DATABASE mytestdb;', arch } + + const CIDBPath = `${dbPath}/${randomUUID()}` if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = `${dbPath}/${randomUUID()}` + process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath } @@ -58,6 +61,15 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { await connection.end(); await db.stop(); + + //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) + try { + if (process.env.useCIDBPath) { + await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) + } + } catch (e) { + console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) + } expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) From 24018cbf6aa26d9cfd76b8eda6a009a059732d95 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:23:16 +0400 Subject: [PATCH 071/163] set downloadBinaryOnce to false --- tests/versions.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 16d59ba1..0c324ee9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -37,7 +37,8 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { username: username, logLevel: 'LOG', initSQLString: 'CREATE DATABASE mytestdb;', - arch + arch, + downloadBinaryOnce: false } const CIDBPath = `${dbPath}/${randomUUID()}` From 04a40f372999053b8fc441bbd8f88169cb7cef8b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:41:18 +0400 Subject: [PATCH 072/163] add macos 13 tests --- .github/workflows/os-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 39ae14a0..d7a4ffd7 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] + os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: - name: Free Disk Space (Ubuntu) From 2e95371cab9ba738b7d988c0f75afbe23c3b95ae Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:42:26 +0400 Subject: [PATCH 073/163] print available storage space in fedora --- .github/workflows/os-compatibility.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index d7a4ffd7..c45f04e6 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -81,6 +81,9 @@ jobs: container: fedora:${{ matrix.version }} steps: + - name: Print available storage space + run: df -h + - name: Checkout uses: actions/checkout@v4 From 2e1620ca523864b4fc988f4db89258e6a0d397a8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:48:02 +0400 Subject: [PATCH 074/163] move available storage step --- .github/workflows/os-compatibility.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index c45f04e6..4105336b 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -81,9 +81,6 @@ jobs: container: fedora:${{ matrix.version }} steps: - - name: Print available storage space - run: df -h - - name: Checkout uses: actions/checkout@v4 @@ -99,6 +96,9 @@ jobs: - name: Install packages run: npm ci + - name: Print available storage space + run: df -h + - name: Run tests run: npm run test:ci From 33e73556ec423839b0e054fd2b9acd5bf1b81e55 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:52:21 +0400 Subject: [PATCH 075/163] add logs when deleting database in ci --- tests/versions.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 0c324ee9..61038ac9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -66,7 +66,9 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) try { if (process.env.useCIDBPath) { + console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) + console.log('Successfully deleted database with version:', version, 'and username:', username) } } catch (e) { console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) From fa0c461bf752a04b0aa6f3e7757e354da91626b7 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:55:16 +0400 Subject: [PATCH 076/163] decrease versions temporarily --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 61038ac9..e38cb8a5 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of ['5.7.20', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From c3586801d3f648382423407682be3b92d9f5bd3e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:58:48 +0400 Subject: [PATCH 077/163] increase versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index e38cb8a5..4f81bf68 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.20', '9.x']) { +for (const version of ['5.7.20', '5.7.30', '5.7.40', '8.0.11', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 8ad400125f8b6c5ba06c574f768452d62f4ef919 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:18:38 +0400 Subject: [PATCH 078/163] increase versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 4f81bf68..06417e56 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.20', '5.7.30', '5.7.40', '8.0.11', '9.x']) { +for (const version of ['8.0.11', '8.0.20', '8.0.30', '8.0.35', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From ed1e4aa5c261fbc46bbe0167441fa3d5bb094e3b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:10:59 +0400 Subject: [PATCH 079/163] increase versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 06417e56..4cc5d6bd 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.11', '8.0.20', '8.0.30', '8.0.35', '9.x']) { +for (const version of ['8.0.20', '8.0.21', '8.0.22', '8.0.23', '8.0.24', '8.0.25', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From e36a94ad8fdbd9ea7332c1c6f2854d7f75482851 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:13:54 +0400 Subject: [PATCH 080/163] increase versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 4cc5d6bd..f37290cb 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.20', '8.0.21', '8.0.22', '8.0.23', '8.0.24', '8.0.25', '9.x']) { +for (const version of ['8.0.26', '8.0.27', '8.0.28', '8.0.29', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From c3c781c47e4bf584c6fadb28837cd2709f76a998 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:20:37 +0400 Subject: [PATCH 081/163] add support for downloading MySQL 8.0.26 on Linux --- src/constants.ts | 3 ++- src/libraries/Version.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 84522301..f993f9b9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -191,4 +191,5 @@ export const MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE = { export const MYSQL_LINUX_FILE_EXTENSIONS = { '5.7.19 - 8.0.11': 'gz', '8.0.12 - 9.2.0': 'xz' -} \ No newline at end of file +} as const; +export const MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS = '8.0.26'; \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 2f172c62..b4169c5f 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,7 +1,7 @@ import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; -import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS } from "../constants"; +import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS } from "../constants"; export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); @@ -87,7 +87,7 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st const fileExtensionKey = fileExtensionKeys.find(range => satisfies(selectedVersion, range)) const fileExtension = MYSQL_LINUX_FILE_EXTENSIONS[fileExtensionKey] - fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? '-minimal' : ''}.tar.${fileExtension}` + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? `-minimal${satisfies(selectedVersion, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS) ? '-rebuild' : ''}` : ''}.tar.${fileExtension}` } return { From a7e93c376ae9ab2f0bbd4d2f5747c55c9a438538 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:20:54 +0400 Subject: [PATCH 082/163] increase versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index f37290cb..57607497 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.26', '8.0.27', '8.0.28', '8.0.29', '9.x']) { +for (const version of ['8.0.25', '8.0.26', '8.0.27', '8.0.28', '8.0.29', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 545690975b68a73f681470e82fb559a3cebee6de Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:27:44 +0400 Subject: [PATCH 083/163] install required package on fedora --- .github/workflows/os-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 4105336b..6a037ba3 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -91,7 +91,7 @@ jobs: check-latest: true - name: Install required libraries - run: sudo dnf install libaio numactl -y + run: sudo dnf install libaio numactl libxcrypt-compat -y - name: Install packages run: npm ci From e1df467ccf7898a9f711ef9e212d6e35807e2d26 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:33:36 +0400 Subject: [PATCH 084/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 57607497..a977a749 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.25', '8.0.26', '8.0.27', '8.0.28', '8.0.29', '9.x']) { +for (const version of ['5.7.44', '8.0.11', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 912c55852a23b247358d6f9fda9e2a4e9e802012 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:20:18 +0400 Subject: [PATCH 085/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index a977a749..7bbdd5a0 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.44', '8.0.11', '9.x']) { +for (const version of ['8.0.11', '8.0.15', '8.0.20', '8.0.25', '8.0.30', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 27622c41277bd3a31ebcf5b43de853f966501eba Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:29:13 +0400 Subject: [PATCH 086/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 7bbdd5a0..9ddf49fa 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.11', '8.0.15', '8.0.20', '8.0.25', '8.0.30', '9.x']) { +for (const version of ['8.0.15', '8.0.16', '8.0.17', '8.0.18', '8.0.19', '8.0.20', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From ea3e531eb2d5106a049dfdd7c432927b7e46e7b3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:44:12 +0400 Subject: [PATCH 087/163] change libaio copy path --- src/libraries/Executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 6023be33..bb6562a1 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -348,7 +348,7 @@ class Executor { const libaioPath = await fsPromises.realpath(libaioSymlinkPath) - const copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) + const copyPath = resolvePath(`${binaryFilepath}/../../lib/libaio.so.1`) let lockRelease: () => Promise; From e8bab8f923b081eab63f9b0021ed25d81ff11923 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:44:38 +0400 Subject: [PATCH 088/163] remove free space steps --- .github/workflows/os-compatibility.yml | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 6a037ba3..fdf9cf53 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -16,28 +16,28 @@ jobs: os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - if: ${{ runner.os == 'Linux' }} - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - name: Free Disk Space (macOS) - if: ${{ runner.os == 'macOS' }} - working-directory: /Applications - run: | - echo 'BEFORE CLEANUP:' - df -h - sudo find . -name Xcode\*.app -delete - sudo rm -rf /Users/runner/Library/Android - echo 'AFTER CLEANUP:' - df -h + # - name: Free Disk Space (Ubuntu) + # uses: jlumbroso/free-disk-space@main + # if: ${{ runner.os == 'Linux' }} + # with: + # tool-cache: true + # android: true + # dotnet: true + # haskell: true + # large-packages: true + # docker-images: true + # swap-storage: true + + # - name: Free Disk Space (macOS) + # if: ${{ runner.os == 'macOS' }} + # working-directory: /Applications + # run: | + # echo 'BEFORE CLEANUP:' + # df -h + # sudo find . -name Xcode\*.app -delete + # sudo rm -rf /Users/runner/Library/Android + # echo 'AFTER CLEANUP:' + # df -h - name: Checkout uses: actions/checkout@v4 From 861214d1c09cc706766ff6848615fee2758de5d9 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:52:08 +0400 Subject: [PATCH 089/163] make private folder if version is less than 8.0.18 --- src/libraries/Executor.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index bb6562a1..ec3306d7 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -348,7 +348,11 @@ class Executor { const libaioPath = await fsPromises.realpath(libaioSymlinkPath) - const copyPath = resolvePath(`${binaryFilepath}/../../lib/libaio.so.1`) + const copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) + + if (lt(this.version, '8.0.18')) { + await fsPromises.mkdir(resolvePath(`${binaryFilepath}/../../lib/private`)) + } let lockRelease: () => Promise; From 721e2bce5a9929ec3cbf6081d76607a13a939b53 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:12:37 +0400 Subject: [PATCH 090/163] only put libaio in private folder if gte 8.0.18 --- src/libraries/Executor.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index ec3306d7..53185c5b 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -348,11 +348,7 @@ class Executor { const libaioPath = await fsPromises.realpath(libaioSymlinkPath) - const copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) - - if (lt(this.version, '8.0.18')) { - await fsPromises.mkdir(resolvePath(`${binaryFilepath}/../../lib/private`)) - } + const copyPath = resolvePath(`${binaryFilepath}/../../lib${!lt(this.version, '8.0.18') ? '/private' : ''}/libaio.so.1`) let lockRelease: () => Promise; From 1f9c096e11d9a8d5329cef1220a123fdec2dd640 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:32:42 +0400 Subject: [PATCH 091/163] change location for libaio copy --- src/libraries/Executor.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 53185c5b..473e655d 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -348,7 +348,13 @@ class Executor { const libaioPath = await fsPromises.realpath(libaioSymlinkPath) - const copyPath = resolvePath(`${binaryFilepath}/../../lib${!lt(this.version, '8.0.18') ? '/private' : ''}/libaio.so.1`) + let copyPath: string; + + if (lt(this.version, '8.0.18')) { + copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) + } else { + copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) + } let lockRelease: () => Promise; From 80044131ce6e344addc0e8181a0222a8ef6ddd35 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:38:00 +0400 Subject: [PATCH 092/163] copy libaio into bin for all versions --- src/libraries/Executor.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 473e655d..9847bc9d 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -350,11 +350,8 @@ class Executor { let copyPath: string; - if (lt(this.version, '8.0.18')) { - copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) - } else { - copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) - } + + copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) let lockRelease: () => Promise; From 54e6d22ecd3168a99cd7db87cef784b3bc185707 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:41:56 +0400 Subject: [PATCH 093/163] revert libaio copy path --- src/libraries/Executor.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 9847bc9d..473e655d 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -350,8 +350,11 @@ class Executor { let copyPath: string; - - copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) + if (lt(this.version, '8.0.18')) { + copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) + } else { + copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) + } let lockRelease: () => Promise; From a2a693ddde3a8b0b9ad2836c5e5fad009690c515 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 00:19:05 +0400 Subject: [PATCH 094/163] test all downloadable MySQL versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 9ddf49fa..61038ac9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.15', '8.0.16', '8.0.17', '8.0.18', '8.0.19', '8.0.20', '9.x']) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { try { getBinaryURL(version, arch) } catch (e) { From 5973ddebe2fa1bda631ceb5e6fdfd53619bf1a0d Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 00:34:11 +0400 Subject: [PATCH 095/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 61038ac9..162bdbd0 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of ['5.7.44', '8.0.15', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 1c2783a905a6d5624c9635fcfcdecf7cace00ba1 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 00:38:31 +0400 Subject: [PATCH 096/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 162bdbd0..715d4559 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.44', '8.0.15', '9.x']) { +for (const version of ['5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.15', '9.x']) { try { getBinaryURL(version, arch) } catch (e) { From 6cb073e6ec941c916fcb9ff8cd8296046803721c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 00:47:25 +0400 Subject: [PATCH 097/163] add support for MySQL 8.0.0 - 8.0.4 on Linux --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index b4169c5f..dc210bac 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -87,7 +87,7 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st const fileExtensionKey = fileExtensionKeys.find(range => satisfies(selectedVersion, range)) const fileExtension = MYSQL_LINUX_FILE_EXTENSIONS[fileExtensionKey] - fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? `-minimal${satisfies(selectedVersion, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS) ? '-rebuild' : ''}` : ''}.tar.${fileExtension}` + fileLocation = `${major(selectedVersion)}.${minor(selectedVersion)}/mysql-${selectedVersion}${isRC ? '-rc' : isDMR ? '-dmr' : ''}-linux-${minimalInstallAvailable !== 'no-glibc-tag' ? `glibc${glibcVersion}-` : ''}${currentArch === 'x64' ? 'x86_64' : 'arm64'}${minimalInstallAvailable !== 'no' ? `-minimal${satisfies(selectedVersion, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS) ? '-rebuild' : ''}` : ''}.tar.${fileExtension}` } return { From 0d8d08f1bdeb0408d1c6dff92b806dedd20063c9 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:04:20 +0400 Subject: [PATCH 098/163] change libaio copy path for lt 8.0.4 --- src/libraries/Executor.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 473e655d..fbe6fa9b 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -350,7 +350,9 @@ class Executor { let copyPath: string; - if (lt(this.version, '8.0.18')) { + if (lt(this.version, '8.0.4')) { + copyPath = resolvePath(`${binaryFilepath}/../../lib/libaio.so.1`) + } else if (lt(this.version, '8.0.18')) { copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) } else { copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) From b387847745abe3a8ab42a0ce645f16f15ddfea94 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:15:20 +0400 Subject: [PATCH 099/163] change libaio copy path for lt 8.0.4 --- src/libraries/Executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index fbe6fa9b..dadcbce2 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -351,7 +351,7 @@ class Executor { let copyPath: string; if (lt(this.version, '8.0.4')) { - copyPath = resolvePath(`${binaryFilepath}/../../lib/libaio.so.1`) + copyPath = resolvePath(`${binaryFilepath}/../../support-files/libaio.so.1`) } else if (lt(this.version, '8.0.18')) { copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) } else { From 1bd4328c38966976dad0dc03fdc32f594bcd1fe8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:17:56 +0400 Subject: [PATCH 100/163] change libaio copy path for lt 8.0.4 --- src/libraries/Executor.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index dadcbce2..4df36383 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -351,7 +351,8 @@ class Executor { let copyPath: string; if (lt(this.version, '8.0.4')) { - copyPath = resolvePath(`${binaryFilepath}/../../support-files/libaio.so.1`) + await fsPromises.mkdir(resolvePath(`${binaryFilepath}/../../lib/private`)) + copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) } else if (lt(this.version, '8.0.18')) { copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) } else { From 9cdef033fc58497071604c8de346a09d08f781bc Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 02:35:47 +0400 Subject: [PATCH 101/163] remove compression and add free space back --- .github/workflows/os-compatibility.yml | 50 +++++++++++++------------- src/libraries/Executor.ts | 5 +-- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index fdf9cf53..85608336 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -16,28 +16,28 @@ jobs: os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] steps: - # - name: Free Disk Space (Ubuntu) - # uses: jlumbroso/free-disk-space@main - # if: ${{ runner.os == 'Linux' }} - # with: - # tool-cache: true - # android: true - # dotnet: true - # haskell: true - # large-packages: true - # docker-images: true - # swap-storage: true - - # - name: Free Disk Space (macOS) - # if: ${{ runner.os == 'macOS' }} - # working-directory: /Applications - # run: | - # echo 'BEFORE CLEANUP:' - # df -h - # sudo find . -name Xcode\*.app -delete - # sudo rm -rf /Users/runner/Library/Android - # echo 'AFTER CLEANUP:' - # df -h + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + if: ${{ runner.os == 'Linux' }} + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Free Disk Space (macOS) + if: ${{ runner.os == 'macOS' }} + working-directory: /Applications + run: | + echo 'BEFORE CLEANUP:' + df -h + sudo find . -name Xcode\*.app -delete + sudo rm -rf /Users/runner/Library/Android + echo 'AFTER CLEANUP:' + df -h - name: Checkout uses: actions/checkout@v4 @@ -60,7 +60,7 @@ jobs: with: name: ${{ matrix.os }} path: "C:\\Users\\RUNNER~1\\mysqlmsn" - compression-level: 9 + compression-level: 0 - name: Upload mysqlmsn directory (Not Windows) if: ${{ failure() && runner.os != 'Windows' }} @@ -68,7 +68,7 @@ jobs: with: name: ${{ matrix.os }} path: /tmp/mysqlmsn - compression-level: 9 + compression-level: 0 fedora-docker: runs-on: ubuntu-latest @@ -108,4 +108,4 @@ jobs: with: name: docker-fedora-${{ matrix.version }} path: /tmp/mysqlmsn - compression-level: 9 \ No newline at end of file + compression-level: 0 \ No newline at end of file diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 4df36383..473e655d 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -350,10 +350,7 @@ class Executor { let copyPath: string; - if (lt(this.version, '8.0.4')) { - await fsPromises.mkdir(resolvePath(`${binaryFilepath}/../../lib/private`)) - copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) - } else if (lt(this.version, '8.0.18')) { + if (lt(this.version, '8.0.18')) { copyPath = resolvePath(`${binaryFilepath}/../../bin/libaio.so.1`) } else { copyPath = resolvePath(`${binaryFilepath}/../../lib/private/libaio.so.1`) From 8623a96dfd7647d703676893b90597bbc3d5fd26 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 02:37:15 +0400 Subject: [PATCH 102/163] use all downloadable versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 715d4559..61038ac9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.15', '9.x']) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { try { getBinaryURL(version, arch) } catch (e) { From df3252e243bdeb528653275b910cef2f60ccf063 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:27:20 +0400 Subject: [PATCH 103/163] test low 8.x versions --- tests/versions.test.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 61038ac9..92aef061 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of ['8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.11']) { try { getBinaryURL(version, arch) } catch (e) { @@ -62,17 +62,6 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { await connection.end(); await db.stop(); - - //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) - try { - if (process.env.useCIDBPath) { - console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') - await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) - console.log('Successfully deleted database with version:', version, 'and username:', username) - } - } catch (e) { - console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) - } expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) From bf45700a27fa79b2bf2ceb68915eeb46ba5d4c3e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 19:15:20 +0400 Subject: [PATCH 104/163] add 5.7.44 --- tests/versions.test.ts | 2 +- types/index.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 92aef061..6acdc6ea 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.11']) { +for (const version of ['5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.11']) { try { getBinaryURL(version, arch) } catch (e) { diff --git a/types/index.ts b/types/index.ts index 44cf62f7..e3339730 100644 --- a/types/index.ts +++ b/types/index.ts @@ -77,4 +77,15 @@ export type OptionTypeChecks = { errorMessage: string, definedType: "string" | "boolean" | "number" } +} + +export type LinuxEtcOSRelease = { + PRETTY_NAME?: string, + NAME?: string, + VERSION_ID?: string, + VERSION?: string, + VERSION_CODENAME?: string, + ID?: string, + ID_LIKE: string, + UBUNTU_CODENAME?: string } \ No newline at end of file From c695b6f8bf649b327d3cc9ce4d2a46a1174cd36c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:53:16 +0400 Subject: [PATCH 105/163] change how username is changed --- src/libraries/Executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index 473e655d..a5966aa4 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -431,7 +431,7 @@ class Executor { let initText = `CREATE DATABASE ${options.dbName};`; if (options.username !== 'root') { - initText += `\nRENAME USER 'root'@'localhost' TO '${options.username}'@'localhost';` + initText += `\nCREATE USER '${options.username}'@'localhost';\nGRANT ALL ON *.* TO '${options.username}'@'localhost' WITH GRANT OPTION;` } if (options.initSQLString.length > 0) { From e9156b961021079b683002a68711abd80f9db4f7 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:55:30 +0400 Subject: [PATCH 106/163] change versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 6acdc6ea..7f8b73bd 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.0.11']) { +for (const version of ['5.7.44', '8.0.0', '8.0.1']) { try { getBinaryURL(version, arch) } catch (e) { From 523d4c5e302dc116ebe373e22c92017bb650dbe8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:31:13 +0400 Subject: [PATCH 107/163] add successful database deletion back --- tests/versions.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 7f8b73bd..bf9200d5 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -62,6 +62,17 @@ for (const version of ['5.7.44', '8.0.0', '8.0.1']) { await connection.end(); await db.stop(); + + //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) + try { + if (process.env.useCIDBPath) { + console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') + await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) + console.log('Successfully deleted database with version:', version, 'and username:', username) + } + } catch (e) { + console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) + } expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) From 7cee79650e5e77de912a60aac7f1bc5c0406476c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:32:40 +0400 Subject: [PATCH 108/163] test 5.7.x --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index bf9200d5..8357f763 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.44', '8.0.0', '8.0.1']) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=5.7.20 <=5.7.44'))) { try { getBinaryURL(version, arch) } catch (e) { From e49fb008f4411325ca5696dff181bb09a07d1eb8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:54:44 +0400 Subject: [PATCH 109/163] test 5.7.19 --- src/constants.ts | 2 +- tests/versions.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index f993f9b9..3f7dbc17 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -120,7 +120,7 @@ export const downloadsBaseURL = 'https://cdn.mysql.com//Downloads/MySQL-' export const archiveBaseURL = 'https://cdn.mysql.com/archives/mysql-' // Versions 8.0.29, 8.0.38, 8.4.1, and 9.0.0 have been purposefully left out of this list as MySQL has removed them from the CDN due to critical issues. export const DOWNLOADABLE_MYSQL_VERSIONS = [ - '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', + '5.7.19', '5.7.20', '5.7.21', '5.7.22', '5.7.23', '5.7.24', '5.7.25', '5.7.26', '5.7.27', '5.7.28', '5.7.29', '5.7.30', '5.7.31', '5.7.32', '5.7.33', '5.7.34', '5.7.35', '5.7.36', '5.7.37', '5.7.38', '5.7.39', '5.7.40', '5.7.41', '5.7.42', '5.7.43', '5.7.44', '8.0.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 8357f763..3c182657 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=5.7.20 <=5.7.44'))) { +for (const version of ['5.7.19']) { try { getBinaryURL(version, arch) } catch (e) { From 38334be96d30858b71989f537605eae43e0b2aee Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:55:13 +0400 Subject: [PATCH 110/163] test 8.x --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 3c182657..170bb79a 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.19']) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <9.0.0'))) { try { getBinaryURL(version, arch) } catch (e) { From de564b99df3bd42d2f4ac04880dd273fd3b860de Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:56:11 +0400 Subject: [PATCH 111/163] test 5.7.19 --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 170bb79a..3c182657 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <9.0.0'))) { +for (const version of ['5.7.19']) { try { getBinaryURL(version, arch) } catch (e) { From 94e390c7144380c0b701aaa1ff8141e555299b92 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:56:30 +0400 Subject: [PATCH 112/163] test 8.x --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 3c182657..170bb79a 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of ['5.7.19']) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <9.0.0'))) { try { getBinaryURL(version, arch) } catch (e) { From 3f4d8d05e51fc7a1465e02100062cea05cf493d9 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:57:16 +0400 Subject: [PATCH 113/163] test 9.x --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 170bb79a..a50ee93b 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <9.0.0'))) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=9.0.0'))) { try { getBinaryURL(version, arch) } catch (e) { From 2aacf4728e4616074cdb2a42485d9088373b23ae Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:34:35 +0400 Subject: [PATCH 114/163] use zip.extractAllToAsync --- src/libraries/Downloader.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 2726a29f..1d7f825b 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -137,21 +137,9 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: if (fileExtension === 'zip') { //Only Windows MySQL files use the .zip extension const zip = new AdmZip(archiveLocation) - const entries = zip.getEntries() - for (const entry of entries) { - if (entry.entryName.indexOf('..') === -1) { - if (entry.isDirectory) { - if (entry.name === folderName) { - await fsPromises.mkdir(`${extractedLocation}/mysql`, {recursive: true}) - } else { - await fsPromises.mkdir(`${extractedLocation}/${entry.entryName}`, {recursive: true}) - } - } else { - const data = await getZipData(entry) - await fsPromises.writeFile(`${extractedLocation}/${entry.entryName}`, data) - } - } - } + + zip.extractAllToAsync(extractedLocation, true, false, (err) => {throw err;}) + try { await fsPromises.rm(archiveLocation) } catch (e) { From 69ae7f5f67e489df1f0302eb5fa0a39efedaab5b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:35:00 +0400 Subject: [PATCH 115/163] use 8.0.0 - 8.0.11 in tests --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index a50ee93b..aed6250a 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(500_000); const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=9.0.0'))) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <=8.0.11'))) { try { getBinaryURL(version, arch) } catch (e) { From 474e358ad9afb7965ba6c85d08bb33e754d1788b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:01:46 +0400 Subject: [PATCH 116/163] add folder name log --- src/libraries/Downloader.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 1d7f825b..0a1ab40d 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -133,6 +133,8 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: return reject(`Folder name is undefined for url: ${url}`) } const folderName = mySQLFolderName.replace(`.${fileExtension}`, '') + + console.log('The MySQL folder:', folderName, 'will be renamed.') if (fileExtension === 'zip') { //Only Windows MySQL files use the .zip extension From f1a0ab1c1fff169f20fe7cbc491f18f7880cf573 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:04:31 +0400 Subject: [PATCH 117/163] keep original permission --- src/libraries/Downloader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 0a1ab40d..5c7897c0 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -140,7 +140,7 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: //Only Windows MySQL files use the .zip extension const zip = new AdmZip(archiveLocation) - zip.extractAllToAsync(extractedLocation, true, false, (err) => {throw err;}) + zip.extractAllToAsync(extractedLocation, true, true, (err) => {throw err;}) try { await fsPromises.rm(archiveLocation) From 18efb5a2d8c4c1f0d67c9a9f8687b43b12127941 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 18:01:25 +0400 Subject: [PATCH 118/163] lower timeout and versions --- tests/versions.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index aed6250a..dc1110a1 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -15,11 +15,11 @@ const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNE const dbPath = normalize(GitHubActionsTempFolder + '/dbs') const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') -jest.setTimeout(500_000); +jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '>=8.0.0 <=8.0.11'))) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '8.0.0 - 8.0.1'))) { try { getBinaryURL(version, arch) } catch (e) { From 49964ea026f877f022dd1c66ccbfb9e3425cbf5c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 20:52:23 +0400 Subject: [PATCH 119/163] add temp message --- src/libraries/Downloader.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 5c7897c0..2d0e5304 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -147,6 +147,7 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: } catch (e) { logger.error('A non-fatal error occurred while removing no longer needed archive file:', e) } finally { + logger.log('readdir:', fs.readdirSync(extractedLocation)) await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) return resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) } From 45bc5a2e5f3ab42a4ff15ec4d3c40efa084798ac Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Fri, 31 Jan 2025 21:06:01 +0400 Subject: [PATCH 120/163] change zip extraction params --- src/libraries/Downloader.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 2d0e5304..72c86f80 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -140,14 +140,13 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: //Only Windows MySQL files use the .zip extension const zip = new AdmZip(archiveLocation) - zip.extractAllToAsync(extractedLocation, true, true, (err) => {throw err;}) + zip.extractAllToAsync(extractedLocation, false, false, (err) => {throw err;}) try { await fsPromises.rm(archiveLocation) } catch (e) { logger.error('A non-fatal error occurred while removing no longer needed archive file:', e) } finally { - logger.log('readdir:', fs.readdirSync(extractedLocation)) await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) return resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) } From d3fbfa564aa8463b235623056757d637e1adc1a6 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:29:17 +0400 Subject: [PATCH 121/163] disallow MySQL < 8.0.4 downloads on Ubuntu >= 24.04 --- src/index.ts | 2 +- src/libraries/LinuxOSRelease.ts | 12 ++++++++++++ src/libraries/Version.ts | 18 ++++++++++++++++-- types/index.ts | 2 +- 4 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/libraries/LinuxOSRelease.ts diff --git a/src/index.ts b/src/index.ts index 48cfa42a..3088c9a5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,7 +45,7 @@ export async function createDB(opts?: ServerOptions) { if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { let binaryInfo: BinaryInfo; let binaryFilepath: string; - binaryInfo = getBinaryURL(options.version, options.arch) + binaryInfo = await getBinaryURL(options.version, options.arch) try { binaryFilepath = await downloadBinary(binaryInfo, options, logger); diff --git a/src/libraries/LinuxOSRelease.ts b/src/libraries/LinuxOSRelease.ts new file mode 100644 index 00000000..797fe3ee --- /dev/null +++ b/src/libraries/LinuxOSRelease.ts @@ -0,0 +1,12 @@ +import fs from 'fs' +import { LinuxEtcOSRelease } from '../../types' + +const file = fs.readFileSync('/etc/os-release', 'utf8') +const entries = file.split('\n') +const releaseDetails = {} +for (const entry of entries) { + const [key, value] = entry.split('=') + releaseDetails[key] = value +} + +export default releaseDetails as LinuxEtcOSRelease; \ No newline at end of file diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index dc210bac..237c3066 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,9 +1,10 @@ -import { BinaryInfo } from "../../types"; +import { BinaryInfo, LinuxEtcOSRelease } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS } from "../constants"; +import etcOSRelease from "./LinuxOSRelease"; -export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { +export default async function getBinaryURL(versionToGet: string = "x", currentArch: string): Promise { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { @@ -58,6 +59,19 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.` } + if (process.platform === 'linux' && etcOSRelease.NAME === 'Ubuntu' && lt(etcOSRelease.VERSION_ID, '24.04')) { + //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1". + //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04. + //If there is a suitable filepath for libaio1t64 to be copied into for MySQL < 8.0.4 then this check can be removed and these older MySQL versions can run on Ubuntu. + //Pull requests are welcome for adding >= Ubuntu 24.04 support for MySQL < 8.0.4. + //A way to get MySQL running on Ubuntu >= 24.04 is to symlink libaio1t64 to the location libaio would be. It is not suitable for this package to be doing that automatically, so instead this package has been copying libaio1t64 into the MySQL binary folder. + selectedVersions = selectedVersions.filter(v => lt(v, '8.0.4')) + } + + if (selectedVersions.length === 0) { + throw `You are running a version of Ubuntu that is too modern to run any MySQL versions with this package that match the following version requirement: ${versionToGet}. Please choose a newer version of MySQL to use, or if you believe this is a bug please report this on GitHub.` + } + //Sorts versions in descending order selectedVersions.sort((a, b) => a < b ? 1 : -1) diff --git a/types/index.ts b/types/index.ts index e3339730..1272ae54 100644 --- a/types/index.ts +++ b/types/index.ts @@ -86,6 +86,6 @@ export type LinuxEtcOSRelease = { VERSION?: string, VERSION_CODENAME?: string, ID?: string, - ID_LIKE: string, + ID_LIKE?: string, UBUNTU_CODENAME?: string } \ No newline at end of file From bb9aa5415887d477996880a0306940316dc12921 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:42:29 +0400 Subject: [PATCH 122/163] only check os-release on Linux --- src/libraries/LinuxOSRelease.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libraries/LinuxOSRelease.ts b/src/libraries/LinuxOSRelease.ts index 797fe3ee..d3d9d5a6 100644 --- a/src/libraries/LinuxOSRelease.ts +++ b/src/libraries/LinuxOSRelease.ts @@ -1,12 +1,15 @@ import fs from 'fs' import { LinuxEtcOSRelease } from '../../types' -const file = fs.readFileSync('/etc/os-release', 'utf8') -const entries = file.split('\n') const releaseDetails = {} -for (const entry of entries) { - const [key, value] = entry.split('=') - releaseDetails[key] = value + +if (process.platform === 'linux') { + const file = fs.readFileSync('/etc/os-release', 'utf8') + const entries = file.split('\n') + for (const entry of entries) { + const [key, value] = entry.split('=') + releaseDetails[key] = value + } } export default releaseDetails as LinuxEtcOSRelease; \ No newline at end of file From 2089640f3372b6f170c78a13cca062d66372e1e0 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:43:36 +0400 Subject: [PATCH 123/163] filter any items not less than 8.0.4 --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 237c3066..7790a01f 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -65,7 +65,7 @@ export default async function getBinaryURL(versionToGet: string = "x", currentAr //If there is a suitable filepath for libaio1t64 to be copied into for MySQL < 8.0.4 then this check can be removed and these older MySQL versions can run on Ubuntu. //Pull requests are welcome for adding >= Ubuntu 24.04 support for MySQL < 8.0.4. //A way to get MySQL running on Ubuntu >= 24.04 is to symlink libaio1t64 to the location libaio would be. It is not suitable for this package to be doing that automatically, so instead this package has been copying libaio1t64 into the MySQL binary folder. - selectedVersions = selectedVersions.filter(v => lt(v, '8.0.4')) + selectedVersions = selectedVersions.filter(v => !lt(v, '8.0.4')) } if (selectedVersions.length === 0) { From fe72de231e8386ea4ae30cd12f2e1ce6a18f234e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:10:51 +0400 Subject: [PATCH 124/163] etcOSRelease --- src/libraries/Version.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 7790a01f..a25b75fe 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -59,6 +59,7 @@ export default async function getBinaryURL(versionToGet: string = "x", currentAr throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.` } + console.log('etcOSRelease:', etcOSRelease) if (process.platform === 'linux' && etcOSRelease.NAME === 'Ubuntu' && lt(etcOSRelease.VERSION_ID, '24.04')) { //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1". //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04. From 543088869346617ecb0df0e80fd5b0d16d8316fd Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:19:25 +0400 Subject: [PATCH 125/163] use es2021 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 3440b0d7..3dda31ca 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "commonjs", - "target": "es2019", + "target": "es2021", "declaration": true, "outDir": "./dist", "resolveJsonModule": true, From b78f4ceef1813fa39ebf14d05014ac098db5ae96 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:19:44 +0400 Subject: [PATCH 126/163] remove quotation marks in etcOSRelease string --- src/libraries/LinuxOSRelease.ts | 2 +- src/libraries/Version.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/LinuxOSRelease.ts b/src/libraries/LinuxOSRelease.ts index d3d9d5a6..0ae02baf 100644 --- a/src/libraries/LinuxOSRelease.ts +++ b/src/libraries/LinuxOSRelease.ts @@ -8,7 +8,7 @@ if (process.platform === 'linux') { const entries = file.split('\n') for (const entry of entries) { const [key, value] = entry.split('=') - releaseDetails[key] = value + releaseDetails[key] = value.replaceAll('"', '') } } diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index a25b75fe..7790a01f 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -59,7 +59,6 @@ export default async function getBinaryURL(versionToGet: string = "x", currentAr throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.` } - console.log('etcOSRelease:', etcOSRelease) if (process.platform === 'linux' && etcOSRelease.NAME === 'Ubuntu' && lt(etcOSRelease.VERSION_ID, '24.04')) { //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1". //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04. From 0f5b38d8e0426969f26858b7b1bf446a24f31c7f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:27:13 +0400 Subject: [PATCH 127/163] add type safety to os release checker --- src/libraries/LinuxOSRelease.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/LinuxOSRelease.ts b/src/libraries/LinuxOSRelease.ts index 0ae02baf..52bee717 100644 --- a/src/libraries/LinuxOSRelease.ts +++ b/src/libraries/LinuxOSRelease.ts @@ -8,7 +8,9 @@ if (process.platform === 'linux') { const entries = file.split('\n') for (const entry of entries) { const [key, value] = entry.split('=') - releaseDetails[key] = value.replaceAll('"', '') + if (typeof key === 'string' && typeof value === 'string') { + releaseDetails[key] = value.replaceAll('"', '') + } } } From e3decf442aab60fbab34730e730f4d444d670e36 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:35:04 +0400 Subject: [PATCH 128/163] stop using semver lt for ubuntu version comparison --- src/libraries/Version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 7790a01f..bf4a25dc 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -59,7 +59,7 @@ export default async function getBinaryURL(versionToGet: string = "x", currentAr throw `Your operating system is too out of date to run a version of MySQL that fits the following requirement: ${versionToGet}. The oldest version for your operating system that you would need to get a version that satisfies the version requirement is ${minVersion} but your current operating system is ${coercedOSRelease.version}. Please try changing your MySQL version requirement, updating your OS to a newer version, or if you believe this is a bug, please report this on GitHub.` } - if (process.platform === 'linux' && etcOSRelease.NAME === 'Ubuntu' && lt(etcOSRelease.VERSION_ID, '24.04')) { + if (process.platform === 'linux' && etcOSRelease.NAME === 'Ubuntu' && etcOSRelease.VERSION_ID >= '24.04') { //Since Ubuntu >= 24.04 uses libaio1t64 instead of libaio, this package has to copy libaio1t64 into a folder that MySQL looks in for dynamically linked libraries with the filename "libaio.so.1". //I have not been able to find a suitable folder for libaio1t64 to be copied into for MySQL < 8.0.4, so here we are filtering all versions lower than 8.0.4 since they fail to launch in Ubuntu 24.04. //If there is a suitable filepath for libaio1t64 to be copied into for MySQL < 8.0.4 then this check can be removed and these older MySQL versions can run on Ubuntu. From 717563808d238063ef98c34902c105cc223db8e3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:43:37 +0400 Subject: [PATCH 129/163] change versions test to properly check what versions can run on the system --- tests/versions.test.ts | 101 ++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index dc1110a1..3ea23bec 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -20,61 +20,58 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '8.0.0 - 8.0.1'))) { - try { - getBinaryURL(version, arch) - } catch (e) { - console.warn(`Skipping version ${version} because the version is not supported on this system. The reason given from getBinaryURL was: ${e}`) - continue - } - - for (const username of usernames) { - test(`running on version ${version} with username ${username}`, async () => { - process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) - - const options: ServerOptions = { - version, - dbName: 'testingdata', - username: username, - logLevel: 'LOG', - initSQLString: 'CREATE DATABASE mytestdb;', - arch, - downloadBinaryOnce: false - } - - const CIDBPath = `${dbPath}/${randomUUID()}` - - if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath - process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath - } - - const db = await createDB(options) - const connection = await sql.createConnection({ - host: '127.0.0.1', - user: db.username, - port: db.port - }) + getBinaryURL(version, arch).then(() => { + for (const username of usernames) { + test(`running on version ${version} with username ${username}`, async () => { + process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) - const mySQLVersion = (await connection.query('SELECT VERSION()'))[0][0]["VERSION()"] - - //If this does not fail, it means initSQLString works as expected and the database was successfully created. - await connection.query('USE mytestdb;') + const options: ServerOptions = { + version, + dbName: 'testingdata', + username: username, + logLevel: 'LOG', + initSQLString: 'CREATE DATABASE mytestdb;', + arch, + downloadBinaryOnce: false + } - await connection.end(); - await db.stop(); - - //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) - try { + const CIDBPath = `${dbPath}/${randomUUID()}` + if (process.env.useCIDBPath) { - console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') - await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) - console.log('Successfully deleted database with version:', version, 'and username:', username) + process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath + process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath } - } catch (e) { - console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) - } + + const db = await createDB(options) + const connection = await sql.createConnection({ + host: '127.0.0.1', + user: db.username, + port: db.port + }) + + const mySQLVersion = (await connection.query('SELECT VERSION()'))[0][0]["VERSION()"] + + //If this does not fail, it means initSQLString works as expected and the database was successfully created. + await connection.query('USE mytestdb;') + + await connection.end(); + await db.stop(); - expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) - }) - } + //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) + try { + if (process.env.useCIDBPath) { + console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') + await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) + console.log('Successfully deleted database with version:', version, 'and username:', username) + } + } catch (e) { + console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) + } + + expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) + }) + } + }).catch(e => { + console.warn(`Skipping version ${version} because the version is not supported on this system. The reason given from getBinaryURL was: ${e}`) + }) } \ No newline at end of file From b166cb6b7c5b9a88b3c2b96f179757105a07f398 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:47:27 +0400 Subject: [PATCH 130/163] make getBinaryURL synchronous --- src/index.ts | 2 +- src/libraries/Version.ts | 2 +- tests/versions.test.ts | 101 ++++++++++++++++++++------------------- 3 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3088c9a5..48cfa42a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,7 +45,7 @@ export async function createDB(opts?: ServerOptions) { if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) { let binaryInfo: BinaryInfo; let binaryFilepath: string; - binaryInfo = await getBinaryURL(options.version, options.arch) + binaryInfo = getBinaryURL(options.version, options.arch) try { binaryFilepath = await downloadBinary(binaryInfo, options, logger); diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index bf4a25dc..3ecb1b52 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -4,7 +4,7 @@ import { satisfies, coerce, lt, major, minor } from "semver"; import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS } from "../constants"; import etcOSRelease from "./LinuxOSRelease"; -export default async function getBinaryURL(versionToGet: string = "x", currentArch: string): Promise { +export default function getBinaryURL(versionToGet: string = "x", currentArch: string): BinaryInfo { let selectedVersions = DOWNLOADABLE_MYSQL_VERSIONS.filter(version => satisfies(version, versionToGet)); if (selectedVersions.length === 0) { diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 3ea23bec..dc1110a1 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -20,58 +20,61 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '8.0.0 - 8.0.1'))) { - getBinaryURL(version, arch).then(() => { - for (const username of usernames) { - test(`running on version ${version} with username ${username}`, async () => { - process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) + try { + getBinaryURL(version, arch) + } catch (e) { + console.warn(`Skipping version ${version} because the version is not supported on this system. The reason given from getBinaryURL was: ${e}`) + continue + } + + for (const username of usernames) { + test(`running on version ${version} with username ${username}`, async () => { + process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) + + const options: ServerOptions = { + version, + dbName: 'testingdata', + username: username, + logLevel: 'LOG', + initSQLString: 'CREATE DATABASE mytestdb;', + arch, + downloadBinaryOnce: false + } + + const CIDBPath = `${dbPath}/${randomUUID()}` - const options: ServerOptions = { - version, - dbName: 'testingdata', - username: username, - logLevel: 'LOG', - initSQLString: 'CREATE DATABASE mytestdb;', - arch, - downloadBinaryOnce: false - } + if (process.env.useCIDBPath) { + process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath + process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath + } - const CIDBPath = `${dbPath}/${randomUUID()}` - - if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath - process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath - } - - const db = await createDB(options) - const connection = await sql.createConnection({ - host: '127.0.0.1', - user: db.username, - port: db.port - }) - - const mySQLVersion = (await connection.query('SELECT VERSION()'))[0][0]["VERSION()"] + const db = await createDB(options) + const connection = await sql.createConnection({ + host: '127.0.0.1', + user: db.username, + port: db.port + }) - //If this does not fail, it means initSQLString works as expected and the database was successfully created. - await connection.query('USE mytestdb;') - - await connection.end(); - await db.stop(); + const mySQLVersion = (await connection.query('SELECT VERSION()'))[0][0]["VERSION()"] + + //If this does not fail, it means initSQLString works as expected and the database was successfully created. + await connection.query('USE mytestdb;') - //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) - try { - if (process.env.useCIDBPath) { - console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') - await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) - console.log('Successfully deleted database with version:', version, 'and username:', username) - } - } catch (e) { - console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) + await connection.end(); + await db.stop(); + + //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) + try { + if (process.env.useCIDBPath) { + console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') + await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) + console.log('Successfully deleted database with version:', version, 'and username:', username) } - - expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) - }) - } - }).catch(e => { - console.warn(`Skipping version ${version} because the version is not supported on this system. The reason given from getBinaryURL was: ${e}`) - }) + } catch (e) { + console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) + } + + expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) + }) + } } \ No newline at end of file From 8d56db65fd8e881283b5f2332ef52c40026f93e6 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 01:00:57 +0400 Subject: [PATCH 131/163] test all downloadable versions --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index dc1110a1..2a8d8ad4 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, '8.0.0 - 8.0.1'))) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { try { getBinaryURL(version, arch) } catch (e) { From 7dfaa6074397e3b3b213a4ca384eb7fea9b48a96 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:42:03 +0400 Subject: [PATCH 132/163] split seperate versions into different jobs --- .github/workflows/os-compatibility.yml | 6 ++++++ package.json | 2 +- tests/versions.test.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 85608336..8cc85692 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -14,6 +14,7 @@ jobs: fail-fast: false matrix: os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] + version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '>8.0.40 <9.0.0', '>=9.0.0'] steps: - name: Free Disk Space (Ubuntu) @@ -52,6 +53,8 @@ jobs: run: npm ci - name: Run tests + env: + VERSION_REQUIREMENT: ${{ matrix.version-requirement }} run: npm run test:ci - name: Upload mysqlmsn directory (Windows) @@ -77,6 +80,7 @@ jobs: fail-fast: false matrix: version: [40] + version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '>8.0.40 <9.0.0', '>=9.0.0'] container: fedora:${{ matrix.version }} @@ -100,6 +104,8 @@ jobs: run: df -h - name: Run tests + env: + VERSION_REQUIREMENT: ${{ matrix.version-requirement }} run: npm run test:ci - name: Upload mysqlmsn directory diff --git a/package.json b/package.json index ddef7517..a168d957 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "scripts": { "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors", - "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors", + "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors --passWithNoTests", "stress:ci": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 2a8d8ad4..3a2e7a0d 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => !process.env.VERSION_REQUIREMENT ? true : satisfies(v, process.env.VERSISON_REQUIREMENT || 'error'))) { try { getBinaryURL(version, arch) } catch (e) { From c95d5ea5652d477c0c2a87cd9a95a03b847f3ff3 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:42:17 +0400 Subject: [PATCH 133/163] change versions test --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 3a2e7a0d..718c80a9 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => !process.env.VERSION_REQUIREMENT ? true : satisfies(v, process.env.VERSISON_REQUIREMENT || 'error'))) { +for (const version of !process.env.VERSION_REQUIREMENT ? DOWNLOADABLE_MYSQL_VERSIONS : DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, process.env.VERSISON_REQUIREMENT || 'error'))) { try { getBinaryURL(version, arch) } catch (e) { From 58768b44937446736de578fec3282c92653c3765 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:44:14 +0400 Subject: [PATCH 134/163] add version requirement to artifact name --- .github/workflows/os-compatibility.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 8cc85692..47c241db 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -61,7 +61,7 @@ jobs: if: ${{ failure() && runner.os == 'Windows' }} uses: actions/upload-artifact@v4.3.5 with: - name: ${{ matrix.os }} + name: ${{ matrix.os }}-${{ matrix.version-requirement }} path: "C:\\Users\\RUNNER~1\\mysqlmsn" compression-level: 0 @@ -69,7 +69,7 @@ jobs: if: ${{ failure() && runner.os != 'Windows' }} uses: actions/upload-artifact@v4.3.5 with: - name: ${{ matrix.os }} + name: ${{ matrix.os }}-${{ matrix.version-requirement }} path: /tmp/mysqlmsn compression-level: 0 @@ -112,6 +112,6 @@ jobs: if: ${{ failure() }} uses: actions/upload-artifact@v4.3.5 with: - name: docker-fedora-${{ matrix.version }} + name: docker-fedora-${{ matrix.version }}-${{ matrix.version-requirement }} path: /tmp/mysqlmsn compression-level: 0 \ No newline at end of file From 09920d82961f84f4917651c6475cb521f436895e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 2 Feb 2025 04:24:23 +0400 Subject: [PATCH 135/163] use all versions for tests --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 718c80a9..2a8d8ad4 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of !process.env.VERSION_REQUIREMENT ? DOWNLOADABLE_MYSQL_VERSIONS : DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, process.env.VERSISON_REQUIREMENT || 'error'))) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { try { getBinaryURL(version, arch) } catch (e) { From d81893064c1f7c545316d749aed11cc89d44f261 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:40:39 +0400 Subject: [PATCH 136/163] only run versions that fit the version requirement --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 2a8d8ad4..8d1d867e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -19,7 +19,7 @@ jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { +for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, process.env.VERSION_REQUIREMENT || '>0.0.0'))) { try { getBinaryURL(version, arch) } catch (e) { From 1bbadeeeeb7df943c6463384bcfe935660acb66b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:45:25 +0400 Subject: [PATCH 137/163] remove free space steps --- .github/workflows/os-compatibility.yml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 47c241db..4a398895 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -17,29 +17,6 @@ jobs: version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '>8.0.40 <9.0.0', '>=9.0.0'] steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - if: ${{ runner.os == 'Linux' }} - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - name: Free Disk Space (macOS) - if: ${{ runner.os == 'macOS' }} - working-directory: /Applications - run: | - echo 'BEFORE CLEANUP:' - df -h - sudo find . -name Xcode\*.app -delete - sudo rm -rf /Users/runner/Library/Android - echo 'AFTER CLEANUP:' - df -h - - name: Checkout uses: actions/checkout@v4 From c1a6a5386a70105e74c624ae63d8b3b17ad281b0 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:47:39 +0400 Subject: [PATCH 138/163] correct version requirement names --- .github/workflows/os-compatibility.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 4a398895..5749c7d7 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -14,7 +14,8 @@ jobs: fail-fast: false matrix: os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] - version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '>8.0.40 <9.0.0', '>=9.0.0'] + #There is no 10.0.0 at the time of writing, but since greater than characters are not allowed in GitHub Actions artifacts names, 9.0.1 - 10.0.0 will be used instead of >9.0.0 + version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '8.0.41 - 9.0.0', '9.0.1 - 10.0.0'] steps: - name: Checkout @@ -57,7 +58,8 @@ jobs: fail-fast: false matrix: version: [40] - version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '>8.0.40 <9.0.0', '>=9.0.0'] + #There is no 10.0.0 at the time of writing, but since greater than characters are not allowed in GitHub Actions artifacts names, 9.0.1 - 10.0.0 will be used instead of >9.0.0 + version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '8.0.41 - 9.0.0', '9.0.1 - 10.0.0'] container: fedora:${{ matrix.version }} From bbe0667d45f982aa829101aab5d2c36b9151386e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:48:23 +0400 Subject: [PATCH 139/163] add dummy test --- tests/versions.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 8d1d867e..4c90e2b6 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -77,4 +77,8 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) } -} \ No newline at end of file +} + +test('dummy test', () => { + expect(1 + 1).toBe(2) +}) \ No newline at end of file From a798212c0cf03173de82822e9c0cd1ee832cbcbc Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:52:40 +0400 Subject: [PATCH 140/163] add comment --- tests/versions.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 4c90e2b6..68795f3e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -79,6 +79,8 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce } } +//The test suites will fail if there aren't any tests. Since we're skipping creating tests if the test platform doesn't support the MySQL +//binary, we need this test here just in case all the MySQL binaries are skipped test('dummy test', () => { expect(1 + 1).toBe(2) }) \ No newline at end of file From 5f8261a56ab9fcaaef6d5f10371b44f804575a54 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:36:56 +0400 Subject: [PATCH 141/163] properly wait for zip extraction --- src/libraries/Downloader.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 72c86f80..af5dbfb2 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -116,6 +116,20 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): }) } +function promisifiedZipExtraction(archiveLocation: string, extractedLocation: string): Promise { + const zip = new AdmZip(archiveLocation) + + return new Promise((resolve, reject) => { + zip.extractAllToAsync(extractedLocation, false, false, (err) => { + if (err) { + reject(err); + } else { + resolve() + } + }) + }) +} + function extractBinary(url: string, archiveLocation: string, extractedLocation: string, logger: Logger): Promise { return new Promise(async (resolve, reject) => { if (fs.existsSync(extractedLocation)) { @@ -138,10 +152,9 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: if (fileExtension === 'zip') { //Only Windows MySQL files use the .zip extension - const zip = new AdmZip(archiveLocation) - - zip.extractAllToAsync(extractedLocation, false, false, (err) => {throw err;}) + await promisifiedZipExtraction(archiveLocation, extractedLocation) + try { await fsPromises.rm(archiveLocation) } catch (e) { From c6933915c041c1595627c357f87dcd95cb2ce69e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:14:39 +0400 Subject: [PATCH 142/163] remove successful db deletion in version test --- tests/versions.test.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 68795f3e..74633584 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -62,17 +62,6 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce await connection.end(); await db.stop(); - - //If everything was successful, delete the database if running in CI (if not running in CI, deleteDBAfterStopped is set to true and so the db is deleted automatically) - try { - if (process.env.useCIDBPath) { - console.log('Deleting database with version:', version, 'and username:', username, 'because the test run was successful.') - await fsPromises.rm(CIDBPath, {recursive: true, force: true, retryDelay: 100, maxRetries: 50}) - console.log('Successfully deleted database with version:', version, 'and username:', username) - } - } catch (e) { - console.error('An error occurred while deleting successful database with version:', version, 'and username:', username, '. The error was:', e) - } expect(satisfies(coerce(mySQLVersion) || 'error', version)).toBe(true) }) From 87516c6959c32f4bf337f3fd83d588ae863de673 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:15:05 +0400 Subject: [PATCH 143/163] remove downloadBinaryOnce for version test --- tests/versions.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 74633584..09619f5b 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -37,8 +37,7 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce username: username, logLevel: 'LOG', initSQLString: 'CREATE DATABASE mytestdb;', - arch, - downloadBinaryOnce: false + arch } const CIDBPath = `${dbPath}/${randomUUID()}` From 09da8c31fb7e1873bbad66f60d6afd1d424ef943 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 00:41:35 +0400 Subject: [PATCH 144/163] fix subsequent database creations failing and change tests --- ciSetup.js | 11 ++++++++- package.json | 5 ++-- src/constants.ts | 8 +++--- src/index.ts | 7 +++--- src/libraries/Executor.ts | 11 ++++++--- stress-tests/stress.test.ts | 49 ------------------------------------- tests/concurrency.test.ts | 26 ++++++++++++++++++++ tests/sql.test.ts | 14 ----------- tests/versions.test.ts | 16 ------------ types/index.ts | 4 --- 10 files changed, 53 insertions(+), 98 deletions(-) delete mode 100644 stress-tests/stress.test.ts create mode 100644 tests/concurrency.test.ts diff --git a/ciSetup.js b/ciSetup.js index 73c1ccdb..aaa87092 100644 --- a/ciSetup.js +++ b/ciSetup.js @@ -1 +1,10 @@ -process.env.useCIDBPath = true; \ No newline at end of file +const { normalize } = require("path"); + +process.env.useCIDBPath = true; + +const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' + +process.env.mysqlmsn_internal_DO_NOT_USE_databaseDirectoryPath = normalize(GitHubActionsTempFolder + '/dbs') +process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = normalize(GitHubActionsTempFolder + '/binaries') + +process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = false; diff --git a/package.json b/package.json index a168d957..b2eb6ed8 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,8 @@ "memory database" ], "scripts": { - "test": "jest --testPathIgnorePatterns=/stress-tests/ --verbose --colors", - "test:ci": "jest --testPathIgnorePatterns=/stress-tests/ --setupFilesAfterEnv ./ciSetup.js --verbose --colors --passWithNoTests", - "stress:ci": "jest --runTestsByPath stress-tests/stress.test.ts --setupFilesAfterEnv ./ciSetup.js --verbose --colors" + "test": "jest --verbose --colors", + "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { "node": ">=16.6.0", diff --git a/src/constants.ts b/src/constants.ts index 3f7dbc17..58c257f9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,7 +4,7 @@ import {normalize as normalizePath} from 'path' import { tmpdir } from "os"; import { valid as validSemver, coerce as coerceSemver } from "semver"; -export const DEFAULT_OPTIONS_GENERATOR: () => InternalServerOptions = () => ({ +export const DEFAULT_OPTIONS: InternalServerOptions = { version: undefined, dbName: 'dbdata', logLevel: 'ERROR', @@ -19,9 +19,9 @@ export const DEFAULT_OPTIONS_GENERATOR: () => InternalServerOptions = () => ({ downloadRetries: 10, initSQLString: '', arch: process.arch -}); +} as const; -export const DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys(DEFAULT_OPTIONS_GENERATOR())) +export const DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys(DEFAULT_OPTIONS)) export const LOG_LEVELS = { 'LOG': 0, @@ -32,7 +32,7 @@ export const LOG_LEVELS = { const internalOptions = { deleteDBAfterStopped: 'true', //mysqlmsn = MySQL Memory Server Node.js - dbPath: normalizePath(`${tmpdir()}/mysqlmsn/dbs/${randomUUID().replace(/-/g, '')}`), + databaseDirectoryPath: normalizePath(`${tmpdir()}/mysqlmsn/dbs`), binaryDirectoryPath: `${tmpdir()}/mysqlmsn/binaries`, cli: 'false' } diff --git a/src/index.ts b/src/index.ts index 48cfa42a..308aca06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,17 @@ import Logger from './libraries/Logger' import Executor from "./libraries/Executor" import { satisfies, lt } from "semver" -import { BinaryInfo, ServerOptions } from '../types' +import { BinaryInfo, InternalServerOptions, ServerOptions } from '../types' import getBinaryURL from './libraries/Version' import { downloadBinary } from './libraries/Downloader' -import { MIN_SUPPORTED_MYSQL, DEFAULT_OPTIONS_KEYS, OPTION_TYPE_CHECKS, DEFAULT_OPTIONS_GENERATOR } from './constants' +import { MIN_SUPPORTED_MYSQL, DEFAULT_OPTIONS_KEYS, OPTION_TYPE_CHECKS, DEFAULT_OPTIONS } from './constants' +import crypto from 'crypto' export async function createDB(opts?: ServerOptions) { const suppliedOpts = opts || {}; const suppliedOptsKeys = Object.keys(suppliedOpts); - const options = DEFAULT_OPTIONS_GENERATOR(); + const options: InternalServerOptions = {...DEFAULT_OPTIONS} for (const opt of suppliedOptsKeys) { if (!DEFAULT_OPTIONS_KEYS.includes(opt)) { diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index a5966aa4..caa68228 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -18,6 +18,7 @@ class Executor { removeExitHandler: () => void; version: string; versionInstalledOnSystem: boolean; + databasePath: string constructor(logger: Logger) { this.logger = logger; @@ -440,7 +441,7 @@ class Executor { this.logger.log('Writing init file') - await fsPromises.writeFile(`${getInternalEnvVariable('dbPath')}/init.sql`, initText, {encoding: 'utf8'}) + await fsPromises.writeFile(`${this.databasePath}/init.sql`, initText, {encoding: 'utf8'}) this.logger.log('Finished writing init file') } @@ -457,7 +458,7 @@ class Executor { if (getInternalEnvVariable('deleteDBAfterStopped') === 'true') { try { - fs.rmSync(getInternalEnvVariable('dbPath'), {recursive: true, maxRetries: 50, force: true}) + fs.rmSync(this.databasePath, {recursive: true, maxRetries: 50, force: true}) } catch (e) { this.logger.error('An error occurred while deleting database directory path:', e) } @@ -479,7 +480,9 @@ class Executor { let retries = 0; - const datadir = normalizePath(`${getInternalEnvVariable('dbPath')}/data`) + this.databasePath = normalizePath(`${getInternalEnvVariable('databaseDirectoryPath')}/${randomUUID()}`) + + const datadir = normalizePath(`${this.databasePath}/data`) do { await this.#setupDataDirectories(options, installedMySQLBinary.path, datadir, true); @@ -491,7 +494,7 @@ class Executor { try { this.logger.log('Starting MySQL process') - const resolved = await this.#startMySQLProcess(options, port, mySQLXPort, datadir, getInternalEnvVariable('dbPath'), installedMySQLBinary.path) + const resolved = await this.#startMySQLProcess(options, port, mySQLXPort, datadir, this.databasePath, installedMySQLBinary.path) this.logger.log('Starting process was successful') return resolved } catch (e) { diff --git a/stress-tests/stress.test.ts b/stress-tests/stress.test.ts deleted file mode 100644 index b093c38d..00000000 --- a/stress-tests/stress.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {expect, test, jest} from '@jest/globals' -import { createDB } from '../src/index' -import sql from 'mysql2/promise' -import { ServerOptions } from '../types'; -import { normalize } from 'path'; -import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; - -jest.setTimeout(500_000); - -const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' -const dbPath = normalize(GitHubActionsTempFolder + '/dbs') -const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') - -for (const version of DOWNLOADABLE_MYSQL_VERSIONS) { - test(`if ${version} works with package`, async () => { - console.log('CI:', process.env.useCIDBPath) - - process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) - - const options: ServerOptions = { - username: 'dbuser', - logLevel: 'LOG', - version, - downloadBinaryOnce: false - } - - if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = `${dbPath}/${version}` - process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath - } - - const db = await createDB(options) - try { - const connection = await sql.createConnection({ - host: '127.0.0.1', - user: db.username, - port: db.port - }) - - const result = await connection.query('SELECT 1 + 1') - - await connection.end(); - - expect(result[0][0]['1 + 1']).toBe(2) - } finally { - await db.stop(); - } - }) -} \ No newline at end of file diff --git a/tests/concurrency.test.ts b/tests/concurrency.test.ts new file mode 100644 index 00000000..e875475c --- /dev/null +++ b/tests/concurrency.test.ts @@ -0,0 +1,26 @@ +import {expect, test, jest} from '@jest/globals' +import { createDB } from '../src/index' +import sql from 'mysql2/promise' + +jest.setTimeout(500_000); + +test('concurrency with 10 simulataneous database creations', async () => { + const dbs = await Promise.all( + new Array(10).fill(createDB({logLevel: 'LOG'})) + ) + + for (const db of dbs) { + const connection = await sql.createConnection({ + host: '127.0.0.1', + user: db.username, + port: db.port + }) + + const result = await connection.query('SELECT 1 + 1') + + await connection.end() + await db.stop() + + expect(result[0][0]['1 + 1']).toBe(2) + } +}) \ No newline at end of file diff --git a/tests/sql.test.ts b/tests/sql.test.ts index e60bd45f..0fe59ea9 100644 --- a/tests/sql.test.ts +++ b/tests/sql.test.ts @@ -2,29 +2,16 @@ import {expect, test, jest, beforeEach, afterEach} from '@jest/globals' import { createDB } from '../src/index' import sql from 'mysql2/promise' import { MySQLDB, ServerOptions } from '../types'; -import { randomUUID } from 'crypto'; -import { normalize } from 'path'; jest.setTimeout(500_000); let db: MySQLDB; -const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' -const dbPath = normalize(GitHubActionsTempFolder + '/dbs') -const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') - beforeEach(async () => { - process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) - const options: ServerOptions = { username: 'root', logLevel: 'LOG' } - - if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = `${dbPath}/${randomUUID()}` - process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath - } db = await createDB(options) }) @@ -34,7 +21,6 @@ afterEach(async () => { }) test('Runs with installed version (or downloads version if one is not available)', async () => { - Error.stackTraceLimit = Infinity const connection = await sql.createConnection({ host: '127.0.0.1', user: db.username, diff --git a/tests/versions.test.ts b/tests/versions.test.ts index 09619f5b..a6716885 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -2,19 +2,12 @@ import {expect, test, jest} from '@jest/globals' import { createDB } from '../src/index' import sql from 'mysql2/promise' import { coerce, satisfies } from 'semver'; -import { randomUUID } from 'crypto'; import { ServerOptions } from '../types'; -import { normalize } from 'path'; import getBinaryURL from '../src/libraries/Version'; import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; -import fsPromises from 'fs/promises' const usernames = ['root', 'dbuser'] -const GitHubActionsTempFolder = process.platform === 'win32' ? 'C:\\Users\\RUNNER~1\\mysqlmsn' : '/tmp/mysqlmsn' -const dbPath = normalize(GitHubActionsTempFolder + '/dbs') -const binaryPath = normalize(GitHubActionsTempFolder + '/binaries') - jest.setTimeout(120_000); //2 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; @@ -29,8 +22,6 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce for (const username of usernames) { test(`running on version ${version} with username ${username}`, async () => { - process.env.mysqlmsn_internal_DO_NOT_USE_deleteDBAfterStopped = String(!process.env.useCIDBPath) - const options: ServerOptions = { version, dbName: 'testingdata', @@ -39,13 +30,6 @@ for (const version of DOWNLOADABLE_MYSQL_VERSIONS.filter(v => satisfies(v, proce initSQLString: 'CREATE DATABASE mytestdb;', arch } - - const CIDBPath = `${dbPath}/${randomUUID()}` - - if (process.env.useCIDBPath) { - process.env.mysqlmsn_internal_DO_NOT_USE_dbPath = CIDBPath - process.env.mysqlmsn_internal_DO_NOT_USE_binaryDirectoryPath = binaryPath - } const db = await createDB(options) const connection = await sql.createConnection({ diff --git a/types/index.ts b/types/index.ts index 1272ae54..89c04e5f 100644 --- a/types/index.ts +++ b/types/index.ts @@ -36,10 +36,6 @@ export type InternalServerOptions = { arch: string } -export type ExecutorOptions = { - logLevel: LOG_LEVEL -} - export type ExecuteFileReturn = { error: ExecFileException | null, stdout: string, From 9a3f26923851a9e99baa95d3a79e2ecccb91f96b Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 00:45:43 +0400 Subject: [PATCH 145/163] fix concurrency test bug --- tests/concurrency.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/concurrency.test.ts b/tests/concurrency.test.ts index e875475c..a35dd5db 100644 --- a/tests/concurrency.test.ts +++ b/tests/concurrency.test.ts @@ -6,7 +6,7 @@ jest.setTimeout(500_000); test('concurrency with 10 simulataneous database creations', async () => { const dbs = await Promise.all( - new Array(10).fill(createDB({logLevel: 'LOG'})) + Array.from(new Array(10)).map(() => createDB({logLevel: 'LOG'})) ) for (const db of dbs) { From c88ef540e6b1febe1554bf6f6e99a4300068f1ec Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 00:53:20 +0400 Subject: [PATCH 146/163] lower concurrency test amount to 3 from 10 --- tests/concurrency.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/concurrency.test.ts b/tests/concurrency.test.ts index a35dd5db..2d8d759c 100644 --- a/tests/concurrency.test.ts +++ b/tests/concurrency.test.ts @@ -6,7 +6,7 @@ jest.setTimeout(500_000); test('concurrency with 10 simulataneous database creations', async () => { const dbs = await Promise.all( - Array.from(new Array(10)).map(() => createDB({logLevel: 'LOG'})) + Array.from(new Array(3)).map(() => createDB({logLevel: 'LOG'})) ) for (const db of dbs) { From ac244775674bd555ec9520e6cb40339e9c2f1f1e Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 02:04:39 +0400 Subject: [PATCH 147/163] split tests up further --- .github/workflows/os-compatibility.yml | 4 ++-- tests/concurrency.test.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index 5749c7d7..cc3edcd0 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -15,7 +15,7 @@ jobs: matrix: os: [macos-13, macos-14, macos-15, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022] #There is no 10.0.0 at the time of writing, but since greater than characters are not allowed in GitHub Actions artifacts names, 9.0.1 - 10.0.0 will be used instead of >9.0.0 - version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '8.0.41 - 9.0.0', '9.0.1 - 10.0.0'] + version-requirement: ['5.7.19 - 5.7.24', '5.7.25 - 5.7.29', '5.7.30 - 5.7.34', '5.7.35 - 5.7.39', '5.7.40 - 5.7.44', '8.0.0 - 8.0.4', '8.0.4 - 8.0.13', '8.0.14 - 8.0.19', '8.0.20 - 8.0.24', '8.0.25 - 8.0.29', '8.0.30 - 8.0.34', '8.0.35 - 8.0.39', '8.0.40 - 8.3.0', '8.4.0 - 9.0.0', '9.0.1 - 10.0.0'] steps: - name: Checkout @@ -59,7 +59,7 @@ jobs: matrix: version: [40] #There is no 10.0.0 at the time of writing, but since greater than characters are not allowed in GitHub Actions artifacts names, 9.0.1 - 10.0.0 will be used instead of >9.0.0 - version-requirement: ['5.7.19 - 5.7.30', '5.7.31 - 5.7.40', '5.7.41 - 5.7.44', '8.0.0 - 8.0.12', '8.0.13 - 8.0.26', '8.0.27 - 8.0.40', '8.0.41 - 9.0.0', '9.0.1 - 10.0.0'] + version-requirement: ['5.7.19 - 5.7.24', '5.7.25 - 5.7.29', '5.7.30 - 5.7.34', '5.7.35 - 5.7.39', '5.7.40 - 5.7.44', '8.0.0 - 8.0.4', '8.0.4 - 8.0.13', '8.0.14 - 8.0.19', '8.0.20 - 8.0.24', '8.0.25 - 8.0.29', '8.0.30 - 8.0.34', '8.0.35 - 8.0.39', '8.0.40 - 8.3.0', '8.4.0 - 9.0.0', '9.0.1 - 10.0.0'] container: fedora:${{ matrix.version }} diff --git a/tests/concurrency.test.ts b/tests/concurrency.test.ts index 2d8d759c..4ca457c2 100644 --- a/tests/concurrency.test.ts +++ b/tests/concurrency.test.ts @@ -4,9 +4,11 @@ import sql from 'mysql2/promise' jest.setTimeout(500_000); -test('concurrency with 10 simulataneous database creations', async () => { +const databaseCount = 3; + +test(`concurrency with ${databaseCount} simulataneous database creations`, async () => { const dbs = await Promise.all( - Array.from(new Array(3)).map(() => createDB({logLevel: 'LOG'})) + Array.from(new Array(databaseCount)).map(() => createDB({logLevel: 'LOG'})) ) for (const db of dbs) { From 056fc8bbe7ff7b54c9b7669b1c8d95ece1733aa6 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:07:57 +0400 Subject: [PATCH 148/163] change timeout for version tests --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index a6716885..af8420bb 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -8,7 +8,7 @@ import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; const usernames = ['root', 'dbuser'] -jest.setTimeout(120_000); //2 minutes +jest.setTimeout(300_000); //5 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; From d31df4990526b697258a011b24f245f173aff540 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:44:52 +0400 Subject: [PATCH 149/163] detect open handles --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b2eb6ed8..b95bc13b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "scripts": { "test": "jest --verbose --colors", - "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors" + "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --detectOpenHandles" }, "engines": { "node": ">=16.6.0", From 1b5054a62e8be32c2d1e19334a89b7c45f05fb8f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:20:25 +0400 Subject: [PATCH 150/163] remove unneccesary imports --- src/index.ts | 1 - src/libraries/Version.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 308aca06..b4872d6a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,6 @@ import { BinaryInfo, InternalServerOptions, ServerOptions } from '../types' import getBinaryURL from './libraries/Version' import { downloadBinary } from './libraries/Downloader' import { MIN_SUPPORTED_MYSQL, DEFAULT_OPTIONS_KEYS, OPTION_TYPE_CHECKS, DEFAULT_OPTIONS } from './constants' -import crypto from 'crypto' export async function createDB(opts?: ServerOptions) { const suppliedOpts = opts || {}; diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 3ecb1b52..5ac184ce 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,4 +1,4 @@ -import { BinaryInfo, LinuxEtcOSRelease } from "../../types"; +import { BinaryInfo } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS } from "../constants"; From d7a189403fa694b38fd44faa69e9626b91bf0c9f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:20:38 +0400 Subject: [PATCH 151/163] await lock release --- src/libraries/Downloader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index af5dbfb2..05653e60 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -287,7 +287,7 @@ export function downloadBinary(binaryInfo: BinaryInfo, options: InternalServerOp } while (downloadTries <= options.downloadRetries) try { - releaseFunction() + await releaseFunction() } catch (e) { logger.error('An error occurred while releasing lock after successful binary download. The error was:', e) } From 108c136e4aadb8558d0912c112bfcdfe8d603515 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:29:02 +0400 Subject: [PATCH 152/163] removed unneccesary code --- src/libraries/Downloader.ts | 48 ++++++++----------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 05653e60..bc88b312 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -10,18 +10,6 @@ import { BinaryInfo, InternalServerOptions } from '../../types'; import { lockFile, waitForLock } from './FileLock'; import { archiveBaseURL, downloadsBaseURL, getInternalEnvVariable } from '../constants'; -function getZipData(entry: AdmZip.IZipEntry): Promise { - return new Promise((resolve, reject) => { - entry.getDataAsync((data, err) => { - if (err) { - reject(err) - } else { - resolve(data) - } - }) - }) -} - function handleTarExtraction(filepath: string, extractedPath: string): Promise { return new Promise((resolve, reject) => { execFile(`tar`, ['-xf', filepath, '-C', extractedPath], (error, stdout, stderr) => { @@ -33,23 +21,6 @@ function handleTarExtraction(filepath: string, extractedPath: string): Promise { - return new Promise((resolve, reject) => { - let json = ""; - - https.get("https://github.com/Sebastian-Webster/mysql-memory-server-nodejs/raw/main/versions.json", function(response) { - response - .on("data", append => json += append ) - .on("error", e => { - reject(e) - } ) - .on("end", ()=>{ - resolve(json) - } ); - }); - }) -} - function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): Promise { return new Promise(async (resolve, reject) => { if (fs.existsSync(downloadLocation)) { @@ -117,9 +88,8 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): } function promisifiedZipExtraction(archiveLocation: string, extractedLocation: string): Promise { - const zip = new AdmZip(archiveLocation) - return new Promise((resolve, reject) => { + const zip = new AdmZip(archiveLocation) zip.extractAllToAsync(extractedLocation, false, false, (err) => { if (err) { reject(err); @@ -161,11 +131,16 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: logger.error('A non-fatal error occurred while removing no longer needed archive file:', e) } finally { await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) - return resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) + resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) + } + } else { + try { + await handleTarExtraction(archiveLocation, extractedLocation) + } catch (e) { + logger.error(`An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was: ${e}`) + reject(e) } - } - handleTarExtraction(archiveLocation, extractedLocation).then(async () => { try { await fsPromises.rm(archiveLocation) } catch (e) { @@ -174,10 +149,7 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) resolve(`${extractedLocation}/mysql/bin/mysqld`) } - }).catch(error => { - logger.error(`An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was: ${error}`) - reject(error) - }) + } }) } From 7807c1f2445ef72a66cdb5c810bf878a1d2a1ee4 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:45:13 +0400 Subject: [PATCH 153/163] reogranise extractBinary function --- src/libraries/Downloader.ts | 51 +++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index bc88b312..4c97ff3a 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -118,37 +118,62 @@ function extractBinary(url: string, archiveLocation: string, extractedLocation: } const folderName = mySQLFolderName.replace(`.${fileExtension}`, '') - console.log('The MySQL folder:', folderName, 'will be renamed.') + let extractionError: any = undefined; if (fileExtension === 'zip') { //Only Windows MySQL files use the .zip extension - await promisifiedZipExtraction(archiveLocation, extractedLocation) - try { - await fsPromises.rm(archiveLocation) + await promisifiedZipExtraction(archiveLocation, extractedLocation) } catch (e) { - logger.error('A non-fatal error occurred while removing no longer needed archive file:', e) + extractionError = e + logger.log('An error occurred while extracting the ZIP file. The error was:', e) } finally { + try { + await fsPromises.rm(archiveLocation) + } catch (e) { + logger.error('A non-fatal error occurred while deleting archive location. The error was:', e) + } + } + + if (extractionError) { + return reject(extractionError) + } + + try { await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) - resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) + } catch (e) { + logger.error('An error occurred while moving MySQL binary into correct folder (mysql folder). The error was:', e) + return reject(e) } + + resolve(normalizePath(`${extractedLocation}/mysql/bin/mysqld.exe`)) } else { try { await handleTarExtraction(archiveLocation, extractedLocation) } catch (e) { - logger.error(`An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was: ${e}`) - reject(e) + extractionError = e + logger.error('An error occurred while extracting the tar file. Please make sure tar is installed and there is enough storage space for the extraction. The error was:', e) + } finally { + try { + await fsPromises.rm(archiveLocation) + } catch (e) { + logger.error('A non-fatal error occurred while deleting archive location. The error was:', e) + } + } + + if (extractionError) { + return reject(extractionError) } try { - await fsPromises.rm(archiveLocation) - } catch (e) { - logger.error('A non-fatal error occurred while removing no longer needed archive file:', e) - } finally { await fsPromises.rename(`${extractedLocation}/${folderName}`, `${extractedLocation}/mysql`) - resolve(`${extractedLocation}/mysql/bin/mysqld`) + } catch (e) { + logger.error('An error occurred while moving MySQL binary into correct folder (mysql folder). The error was:', e) + return reject(e) } + + resolve(`${extractedLocation}/mysql/bin/mysqld`) } }) } From 04ff083a734b83afa8b577bea7e7a740f3083554 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:21:35 +0400 Subject: [PATCH 154/163] end request on error --- src/libraries/Downloader.ts | 66 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 4c97ff3a..55916efd 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -36,24 +36,28 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): const request = https.get(url, (response) => { if (response.statusCode !== 200) { fileStream.end((err) => { - if (err) { - logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) - } - - fs.rm(downloadLocation, {force: true}, (rmError) => { - if (rmError) { - logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) + request.end(() => { + if (err) { + logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) } - - reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) + + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) + } + + reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) + }) }) }) } else { response.pipe(fileStream) fileStream.on('finish', () => { - if (!error) { - resolve() - } + request.end(() => { + if (!error) { + resolve() + } + }) }) } }) @@ -61,26 +65,32 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): request.on('error', (err) => { error = err; logger.error(err) - fileStream.end(() => { - fs.rm(downloadLocation, {force: true}, (rmError) => { - if (rmError) { - logger.error('An error occurred while deleting downloadLocation after an error occurred with the MySQL server binary download. The error was:', rmError) - } - reject(err.message); + request.end(() => { + fileStream.end(() => { + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after an error occurred with the MySQL server binary download. The error was:', rmError) + } + + reject(err.message); + }) }) }) }) - }) - fileStream.on('error', (err) => { - error = err; - logger.error(err) - fileStream.end(() => { - fs.rm(downloadLocation, {force: true}, (rmError) => { - if (rmError) { - logger.error('An error occurred while deleting downloadLocation after an error occurred with the fileStream. The error was:', rmError) - } - reject(err.message) + fileStream.on('error', (err) => { + error = err; + logger.error(err) + request.end(() => { + fileStream.end(() => { + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after an error occurred with the fileStream. The error was:', rmError) + } + + reject(err.message) + }) + }) }) }) }) From d6c66c99600305e8b6287b8d5605f50bc8e6485c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 20:40:52 +0400 Subject: [PATCH 155/163] remove detectOpenHandles --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b95bc13b..b2eb6ed8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "scripts": { "test": "jest --verbose --colors", - "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --detectOpenHandles" + "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors" }, "engines": { "node": ">=16.6.0", From 31c5d32c36e786c113de8b0cf196c6749c7f90a8 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 20:53:48 +0400 Subject: [PATCH 156/163] os compat tests will now only run versions test --- .github/workflows/os-compatibility.yml | 4 +- .github/workflows/stress.yml | 74 -------------------------- package.json | 3 +- tests/sql.test.ts | 35 ------------ 4 files changed, 4 insertions(+), 112 deletions(-) delete mode 100644 .github/workflows/stress.yml delete mode 100644 tests/sql.test.ts diff --git a/.github/workflows/os-compatibility.yml b/.github/workflows/os-compatibility.yml index cc3edcd0..72ce8112 100644 --- a/.github/workflows/os-compatibility.yml +++ b/.github/workflows/os-compatibility.yml @@ -33,7 +33,7 @@ jobs: - name: Run tests env: VERSION_REQUIREMENT: ${{ matrix.version-requirement }} - run: npm run test:ci + run: npm run os-compat:ci - name: Upload mysqlmsn directory (Windows) if: ${{ failure() && runner.os == 'Windows' }} @@ -85,7 +85,7 @@ jobs: - name: Run tests env: VERSION_REQUIREMENT: ${{ matrix.version-requirement }} - run: npm run test:ci + run: npm run os-compat:ci - name: Upload mysqlmsn directory if: ${{ failure() }} diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml deleted file mode 100644 index b6e981c2..00000000 --- a/.github/workflows/stress.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Stress Tests - -on: - push: - branches: [ main ] - pull_request: - workflow_dispatch: - -jobs: - stress: - runs-on: ${{ matrix.os }} - container: ${{ matrix.container }} - - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest, windows-2019, windows-2022] - include: - - os: ubuntu-latest - - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - if: ${{ runner.os == 'Linux' }} - with: - tool-cache: true - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: false - - - name: Free Disk Space (macOS) - if: ${{ runner.os == 'macOS' }} - working-directory: /Applications - run: | - echo 'BEFORE CLEANUP:' - df -h - sudo find . -name Xcode\*.app -delete - sudo rm -rf /Users/runner/Library/Android - echo 'AFTER CLEANUP:' - df -h - - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node LTS - uses: actions/setup-node@v4 - with: - node-version: lts/* - check-latest: true - - - name: Install packages - run: npm ci - - - name: Run tests - run: npm run stress:ci - - - name: Upload mysqlmsn directory (Windows) - if: ${{ failure() && runner.os == 'Windows' }} - uses: actions/upload-artifact@v4.3.5 - with: - name: ${{ matrix.os }} - path: "C:\\Users\\RUNNER~1\\mysqlmsn" - compression-level: 0 - - - name: Upload mysqlmsn directory (Not Windows) - if: ${{ failure() && runner.os != 'Windows' }} - uses: actions/upload-artifact@v4.3.5 - with: - name: ${{ matrix.os }} - path: /tmp/mysqlmsn - compression-level: 0 \ No newline at end of file diff --git a/package.json b/package.json index b2eb6ed8..b430a8b6 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ ], "scripts": { "test": "jest --verbose --colors", - "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors" + "test:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --runTestsByPath tests/concurrency.test.ts", + "os-compat:ci": "jest --setupFilesAfterEnv ./ciSetup.js --verbose --colors --runTestsByPath tests/versions.test.ts" }, "engines": { "node": ">=16.6.0", diff --git a/tests/sql.test.ts b/tests/sql.test.ts deleted file mode 100644 index 0fe59ea9..00000000 --- a/tests/sql.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {expect, test, jest, beforeEach, afterEach} from '@jest/globals' -import { createDB } from '../src/index' -import sql from 'mysql2/promise' -import { MySQLDB, ServerOptions } from '../types'; - -jest.setTimeout(500_000); - -let db: MySQLDB; - -beforeEach(async () => { - const options: ServerOptions = { - username: 'root', - logLevel: 'LOG' - } - - db = await createDB(options) -}) - -afterEach(async () => { - await db.stop(); -}) - -test('Runs with installed version (or downloads version if one is not available)', async () => { - const connection = await sql.createConnection({ - host: '127.0.0.1', - user: db.username, - port: db.port - }) - - const result = await connection.query('SELECT 1 + 1') - - expect(result[0][0]['1 + 1']).toBe(2) - - await connection.end(); -}) \ No newline at end of file From 60a6a8cb4aa939c6088f9ae79a31d3bcf53715e5 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 20:56:28 +0400 Subject: [PATCH 157/163] use macos latest in ci test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18834cf1..b0ec89be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: jobs: ci: - runs-on: ubuntu-latest + runs-on: macos-latest steps: - name: Checkout From 337bb4c73684eb7ecdc680f21ca4ff03add1854f Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:06:36 +0400 Subject: [PATCH 158/163] remove dashes in database path --- src/libraries/Executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index caa68228..dbd79b56 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -480,7 +480,7 @@ class Executor { let retries = 0; - this.databasePath = normalizePath(`${getInternalEnvVariable('databaseDirectoryPath')}/${randomUUID()}`) + this.databasePath = normalizePath(`${getInternalEnvVariable('databaseDirectoryPath')}/${randomUUID().replaceAll("-", '')}`) const datadir = normalizePath(`${this.databasePath}/data`) From 9b98a76ac1f9a3b886f33d4f32cfa08a8d2d8651 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:45:01 +0400 Subject: [PATCH 159/163] increase timeout to 10 minutes --- tests/versions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/versions.test.ts b/tests/versions.test.ts index af8420bb..59a1033e 100644 --- a/tests/versions.test.ts +++ b/tests/versions.test.ts @@ -8,7 +8,7 @@ import { DOWNLOADABLE_MYSQL_VERSIONS } from '../src/constants'; const usernames = ['root', 'dbuser'] -jest.setTimeout(300_000); //5 minutes +jest.setTimeout(500_000); //5 minutes const arch = process.arch === 'x64' || (process.platform === 'win32' && process.arch === 'arm64') ? 'x64' : 'arm64'; From 1f2d173bc98873bfc17dd399d766e4c2261cf789 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 5 Feb 2025 01:08:11 +0400 Subject: [PATCH 160/163] add user agent to download request --- src/libraries/Downloader.ts | 6 +++++- src/libraries/Version.ts | 16 +++++++++++++++- types/index.ts | 5 +++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index 55916efd..c900ad68 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -9,6 +9,7 @@ import { execFile } from 'child_process'; import { BinaryInfo, InternalServerOptions } from '../../types'; import { lockFile, waitForLock } from './FileLock'; import { archiveBaseURL, downloadsBaseURL, getInternalEnvVariable } from '../constants'; +import { getJSRuntimeVersion } from './Version'; function handleTarExtraction(filepath: string, extractedPath: string): Promise { return new Promise((resolve, reject) => { @@ -32,8 +33,11 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): let error: Error; + const JSRuntime = getJSRuntimeVersion() + const userAgent = `${JSRuntime.runtimeName}/${JSRuntime.runtimeVersion}` + fileStream.on('open', () => { - const request = https.get(url, (response) => { + const request = https.get(url, {headers: {"user-agent": userAgent}}, (response) => { if (response.statusCode !== 200) { fileStream.end((err) => { request.end(() => { diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 5ac184ce..08346010 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -1,4 +1,4 @@ -import { BinaryInfo } from "../../types"; +import { BinaryInfo, JSRuntimeVersion } from "../../types"; import * as os from 'os' import { satisfies, coerce, lt, major, minor } from "semver"; import { archiveBaseURL, DMR_MYSQL_VERSIONS, DOWNLOADABLE_MYSQL_VERSIONS, MYSQL_ARCH_SUPPORT, MYSQL_LINUX_FILE_EXTENSIONS, MYSQL_LINUX_GLIBC_VERSIONS, MYSQL_LINUX_MINIMAL_INSTALL_AVAILABLE, MYSQL_MACOS_VERSIONS_IN_FILENAME, MYSQL_MIN_OS_SUPPORT, RC_MYSQL_VERSIONS, MYSQL_LINUX_MINIMAL_REBUILD_VERSIONS } from "../constants"; @@ -108,4 +108,18 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st version: selectedVersion, url: archiveBaseURL + fileLocation } +} + +export function getJSRuntimeVersion(): JSRuntimeVersion { + if (process.versions.bun) { + return { + runtimeName: 'Bun', + runtimeVersion: process.versions.bun + } + } + + return { + runtimeName: 'NodeJS', + runtimeVersion: process.versions.node + } } \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index 89c04e5f..071e359f 100644 --- a/types/index.ts +++ b/types/index.ts @@ -84,4 +84,9 @@ export type LinuxEtcOSRelease = { ID?: string, ID_LIKE?: string, UBUNTU_CODENAME?: string +} + +export type JSRuntimeVersion = { + runtimeName: string, + runtimeVersion: string } \ No newline at end of file From 04a1555b9c3088331725bb213c1a15c3b99f4a79 Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:00:13 +0400 Subject: [PATCH 161/163] do not run asynchronous tasks on exit from signal --- src/libraries/Executor.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/Executor.ts b/src/libraries/Executor.ts index dbd79b56..aabda158 100644 --- a/src/libraries/Executor.ts +++ b/src/libraries/Executor.ts @@ -116,6 +116,11 @@ class Executor { let resolveFunction: () => void; process.on('close', async (code, signal) => { + if (signal) { + this.logger.log('Exiting because of aborted signal.') + return + } + let errorLog: string; try { From fda439b4049d1a55258d4b43373d6d2923cb239c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 9 Feb 2025 02:22:25 +0400 Subject: [PATCH 162/163] destroy https request on non-200 status code --- src/libraries/Downloader.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index c900ad68..e99120bf 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -39,19 +39,19 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): fileStream.on('open', () => { const request = https.get(url, {headers: {"user-agent": userAgent}}, (response) => { if (response.statusCode !== 200) { + request.destroy(); + fileStream.end((err) => { - request.end(() => { - if (err) { - logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) + if (err) { + logger.error('An error occurred while closing the fileStream for non-200 status code. The error was:', err) + } + + fs.rm(downloadLocation, {force: true}, (rmError) => { + if (rmError) { + logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) } - - fs.rm(downloadLocation, {force: true}, (rmError) => { - if (rmError) { - logger.error('An error occurred while deleting downloadLocation after non-200 status code download attempt. The error was:', rmError) - } - - reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) - }) + + reject(`Received status code ${response.statusCode} while downloading MySQL binary.`) }) }) } else { From ce4ab3973277d6f8d470e968aa8e80c4a0ffe93c Mon Sep 17 00:00:00 2001 From: Sebastian-Webster <84299475+Sebastian-Webster@users.noreply.github.com> Date: Sun, 9 Feb 2025 11:41:23 +0400 Subject: [PATCH 163/163] remove user agent --- src/libraries/Downloader.ts | 6 +----- src/libraries/Version.ts | 14 -------------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/libraries/Downloader.ts b/src/libraries/Downloader.ts index e99120bf..a2072a12 100644 --- a/src/libraries/Downloader.ts +++ b/src/libraries/Downloader.ts @@ -9,7 +9,6 @@ import { execFile } from 'child_process'; import { BinaryInfo, InternalServerOptions } from '../../types'; import { lockFile, waitForLock } from './FileLock'; import { archiveBaseURL, downloadsBaseURL, getInternalEnvVariable } from '../constants'; -import { getJSRuntimeVersion } from './Version'; function handleTarExtraction(filepath: string, extractedPath: string): Promise { return new Promise((resolve, reject) => { @@ -33,11 +32,8 @@ function downloadFromCDN(url: string, downloadLocation: string, logger: Logger): let error: Error; - const JSRuntime = getJSRuntimeVersion() - const userAgent = `${JSRuntime.runtimeName}/${JSRuntime.runtimeVersion}` - fileStream.on('open', () => { - const request = https.get(url, {headers: {"user-agent": userAgent}}, (response) => { + const request = https.get(url, (response) => { if (response.statusCode !== 200) { request.destroy(); diff --git a/src/libraries/Version.ts b/src/libraries/Version.ts index 08346010..a1f5d356 100644 --- a/src/libraries/Version.ts +++ b/src/libraries/Version.ts @@ -108,18 +108,4 @@ export default function getBinaryURL(versionToGet: string = "x", currentArch: st version: selectedVersion, url: archiveBaseURL + fileLocation } -} - -export function getJSRuntimeVersion(): JSRuntimeVersion { - if (process.versions.bun) { - return { - runtimeName: 'Bun', - runtimeVersion: process.versions.bun - } - } - - return { - runtimeName: 'NodeJS', - runtimeVersion: process.versions.node - } } \ No newline at end of file