mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-09-23 13:16:27 +00:00
Add upgrade system
This commit is contained in:
@ -16,7 +16,7 @@ use super::BenchDeriveArgs;
|
||||
use crate::common::assets::{self, Asset};
|
||||
use crate::common::client::Client;
|
||||
use crate::common::command::{run_commands, Command};
|
||||
use crate::common::meili_process;
|
||||
use crate::common::process::{self, delete_db, start_meili};
|
||||
|
||||
/// A bench workload.
|
||||
/// Not to be confused with [a test workload](crate::test::workload::Workload).
|
||||
@ -128,7 +128,9 @@ async fn execute_run(
|
||||
binary_path: Option<&Path>,
|
||||
run_number: u16,
|
||||
) -> anyhow::Result<tokio::task::JoinHandle<anyhow::Result<std::fs::File>>> {
|
||||
let meilisearch = meili_process::start(
|
||||
delete_db().await;
|
||||
|
||||
let meilisearch = start_meili(
|
||||
meili_client,
|
||||
master_key,
|
||||
&workload.extra_cli_args,
|
||||
@ -148,7 +150,7 @@ async fn execute_run(
|
||||
)
|
||||
.await?;
|
||||
|
||||
meili_process::kill(meilisearch).await;
|
||||
process::kill_meili(meilisearch).await;
|
||||
|
||||
tracing::info!(run_number, "Successful run");
|
||||
|
||||
|
@ -3,5 +3,5 @@ pub mod assets;
|
||||
pub mod client;
|
||||
pub mod command;
|
||||
pub mod logs;
|
||||
pub mod meili_process;
|
||||
pub mod process;
|
||||
pub mod workload;
|
||||
|
@ -9,7 +9,7 @@ use tokio::time;
|
||||
use crate::common::client::Client;
|
||||
use crate::common::command::{health_command, run as run_command};
|
||||
|
||||
pub async fn kill(mut meilisearch: tokio::process::Child) {
|
||||
pub async fn kill_meili(mut meilisearch: tokio::process::Child) {
|
||||
let Some(id) = meilisearch.id() else { return };
|
||||
|
||||
match TokioCommand::new("kill").args(["--signal=TERM", &id.to_string()]).spawn() {
|
||||
@ -65,15 +65,13 @@ async fn build() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(client, master_key), fields(workload = _workload))]
|
||||
pub async fn start(
|
||||
pub async fn start_meili(
|
||||
client: &Client,
|
||||
master_key: Option<&str>,
|
||||
extra_cli_args: &[String],
|
||||
_workload: &str,
|
||||
binary_path: Option<&Path>,
|
||||
) -> anyhow::Result<tokio::process::Child> {
|
||||
delete_db();
|
||||
|
||||
let mut command = match binary_path {
|
||||
Some(binary_path) => tokio::process::Command::new(binary_path),
|
||||
None => {
|
||||
@ -103,6 +101,21 @@ pub async fn start(
|
||||
|
||||
command.kill_on_drop(true);
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
if let Some(binary_path) = binary_path {
|
||||
let mut perms = tokio::fs::metadata(binary_path)
|
||||
.await
|
||||
.with_context(|| format!("could not get metadata for {binary_path:?}"))?
|
||||
.permissions();
|
||||
perms.set_mode(perms.mode() | 0o111);
|
||||
tokio::fs::set_permissions(binary_path, perms)
|
||||
.await
|
||||
.with_context(|| format!("could not set permissions for {binary_path:?}"))?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut meilisearch = command.spawn().context("Error starting Meilisearch")?;
|
||||
|
||||
wait_for_health(client, &mut meilisearch).await?;
|
||||
@ -139,6 +152,6 @@ async fn wait_for_health(
|
||||
bail!("meilisearch is not responding")
|
||||
}
|
||||
|
||||
async fn delete_db() {
|
||||
pub async fn delete_db() {
|
||||
let _ = tokio::fs::remove_dir_all("./_xtask_benchmark.ms").await;
|
||||
}
|
@ -1,9 +1,67 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::{collections::BTreeMap, fmt::Display, path::PathBuf};
|
||||
|
||||
use crate::common::assets::{Asset, AssetFormat};
|
||||
use anyhow::Context;
|
||||
use cargo_metadata::semver::Version;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum VersionOrLatest {
|
||||
Version(Version),
|
||||
Latest,
|
||||
}
|
||||
|
||||
impl<'a> Deserialize<'a> for VersionOrLatest {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let s: &str = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
if s.eq_ignore_ascii_case("latest") {
|
||||
Ok(VersionOrLatest::Latest)
|
||||
} else {
|
||||
let version = Version::parse(s).map_err(serde::de::Error::custom)?;
|
||||
Ok(VersionOrLatest::Version(version))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for VersionOrLatest {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
VersionOrLatest::Version(v) => serializer.serialize_str(&v.to_string()),
|
||||
VersionOrLatest::Latest => serializer.serialize_str("latest"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionOrLatest {
|
||||
pub fn binary_path(&self, asset_folder: &str) -> anyhow::Result<Option<PathBuf>> {
|
||||
match self {
|
||||
VersionOrLatest::Version(version) => {
|
||||
let mut asset_folder: PathBuf = asset_folder.parse().context("parsing asset folder")?;
|
||||
let arch = get_arch()?;
|
||||
let local_filename = format!("meilisearch-{version}-{arch}");
|
||||
asset_folder.push(local_filename);
|
||||
Ok(Some(asset_folder))
|
||||
}
|
||||
VersionOrLatest::Latest => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for VersionOrLatest {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
VersionOrLatest::Version(v) => v.fmt(f),
|
||||
VersionOrLatest::Latest => write!(f, "latest"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_sha256(version: &Version, asset_name: &str) -> anyhow::Result<String> {
|
||||
// If version is lower than 1.15 there is no point in trying to get the sha256, GitHub didn't support it
|
||||
@ -45,7 +103,7 @@ async fn get_sha256(version: &Version, asset_name: &str) -> anyhow::Result<Strin
|
||||
Ok(sha256)
|
||||
}
|
||||
|
||||
async fn add_asset(assets: &mut BTreeMap<String, Asset>, version: &Version) -> anyhow::Result<()> {
|
||||
pub fn get_arch() -> anyhow::Result<&'static str> {
|
||||
let arch;
|
||||
|
||||
// linux-aarch64
|
||||
@ -82,6 +140,11 @@ async fn add_asset(assets: &mut BTreeMap<String, Asset>, version: &Version) -> a
|
||||
anyhow::bail!("unsupported platform");
|
||||
}
|
||||
|
||||
Ok(arch)
|
||||
}
|
||||
|
||||
async fn add_asset(assets: &mut BTreeMap<String, Asset>, version: &Version) -> anyhow::Result<()> {
|
||||
let arch = get_arch()?;
|
||||
let local_filename = format!("meilisearch-{version}-{arch}");
|
||||
if assets.contains_key(&local_filename) {
|
||||
return Ok(());
|
||||
|
@ -8,45 +8,15 @@ use crate::{
|
||||
assets::{fetch_assets, Asset},
|
||||
client::Client,
|
||||
command::{run_commands, Command},
|
||||
process::{self, delete_db, kill_meili},
|
||||
workload::Workload,
|
||||
},
|
||||
test::{versions::expand_assets_with_versions, TestDeriveArgs},
|
||||
test::{
|
||||
versions::{expand_assets_with_versions, VersionOrLatest},
|
||||
TestDeriveArgs,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum VersionOrLatest {
|
||||
Version(Version),
|
||||
Latest,
|
||||
}
|
||||
|
||||
impl<'a> Deserialize<'a> for VersionOrLatest {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let s: &str = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
if s.eq_ignore_ascii_case("latest") {
|
||||
Ok(VersionOrLatest::Latest)
|
||||
} else {
|
||||
let version = Version::parse(s).map_err(serde::de::Error::custom)?;
|
||||
Ok(VersionOrLatest::Version(version))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for VersionOrLatest {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
VersionOrLatest::Version(v) => serializer.serialize_str(&v.to_string()),
|
||||
VersionOrLatest::Latest => serializer.serialize_str("latest"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CommandOrUpgrade {
|
||||
@ -105,6 +75,19 @@ impl TestWorkload {
|
||||
expand_assets_with_versions(&mut self.assets, &all_versions).await?;
|
||||
fetch_assets(assets_client, &self.assets, &args.common.asset_folder).await?;
|
||||
|
||||
// Run server
|
||||
delete_db().await;
|
||||
let binary_path = VersionOrLatest::Version(self.initial_version.clone())
|
||||
.binary_path(&args.common.asset_folder)?;
|
||||
let mut process = process::start_meili(
|
||||
meili_client,
|
||||
args.common.master_key.as_deref(),
|
||||
&[],
|
||||
&self.name,
|
||||
binary_path.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let assets = Arc::new(self.assets.clone());
|
||||
let return_responses = dbg!(args.add_missing_responses || args.update_responses);
|
||||
for command_or_upgrade in commands_or_upgrade {
|
||||
@ -133,7 +116,16 @@ impl TestWorkload {
|
||||
}
|
||||
}
|
||||
CommandOrUpgradeVec::Upgrade(version) => {
|
||||
todo!()
|
||||
kill_meili(process).await;
|
||||
let binary_path = version.binary_path(&args.common.asset_folder)?;
|
||||
process = process::start_meili(
|
||||
meili_client,
|
||||
args.common.master_key.as_deref(),
|
||||
&[String::from("--experimental-dumpless-upgrade")],
|
||||
&self.name,
|
||||
binary_path.as_deref(),
|
||||
).await?;
|
||||
tracing::info!("Upgraded to {version}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,14 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"expectedStatus": 202,
|
||||
"expectedResponse": {
|
||||
"enqueuedAt": "2025-08-26T09:31:44.665991Z",
|
||||
"indexUid": "movies",
|
||||
"status": "enqueued",
|
||||
"taskUid": 0,
|
||||
"type": "settingsUpdate"
|
||||
},
|
||||
"synchronous": "DontWait"
|
||||
},
|
||||
{
|
||||
@ -36,6 +44,14 @@
|
||||
"body": {
|
||||
"asset": "movies.json"
|
||||
},
|
||||
"expectedStatus": 202,
|
||||
"expectedResponse": {
|
||||
"enqueuedAt": "2025-08-26T09:31:44.732206Z",
|
||||
"indexUid": "movies",
|
||||
"status": "enqueued",
|
||||
"taskUid": 1,
|
||||
"type": "documentAdditionOrUpdate"
|
||||
},
|
||||
"synchronous": "WaitForTask"
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user