Test
Some checks failed
Build Project / test (push) Failing after 6m9s

This commit is contained in:
2025-02-06 17:27:59 +00:00
parent 31b90e223f
commit 0257434b26
8 changed files with 60 additions and 41 deletions

View File

@@ -5,20 +5,14 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: rust:bullseye image: rust:latest
# Service containers to run with `container-job`
services: services:
# Label used to access the service container
db: db:
# Docker Hub image
image: postgres:latest image: postgres:latest
# Provide the password for postgres
env: env:
POSTGRES_USER: dev POSTGRES_USER: dev
POSTGRES_PASSWORD: dev POSTGRES_PASSWORD: dev
POSTGRES_DB: iot POSTGRES_DB: iot
# Set health checks to wait until postgres has started
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10s --health-interval 10s
@@ -43,14 +37,22 @@ jobs:
- name: Log in to Docker Registry - name: Log in to Docker Registry
uses: docker/login-action@v1 uses: docker/login-action@v1
with: with:
registry: gitea.maiertobi.de # Replace with your Docker registry URL registry: gitea.maiertobi.de
username: tobimai username: tobimai
password: ${{ secrets.docker_registry_key }} password: ${{ secrets.docker_registry_key }}
- name: Extract Version from Cargo.toml
id: cargo_version
run: |
VERSION=$(grep '^version' Cargo.toml | head -n 1 | cut -d ' ' -f 3 | tr -d '"')
echo "VERSION=$VERSION" >> $GITEA_ENV
- name: Test
run: echo $VERSION
- name: Build and Push Docker Image - name: Build and Push Docker Image
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2
with: with:
context: . context: .
push: true push: true
tags: gitea.maiertobi.de/tobimai/iot # Replace with your Docker image's details tags: gitea.maiertobi.de/tobimai/iot:$VERSION

View File

@@ -6,19 +6,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: rust:latest image: rust:latest
# Service containers to run with `container-job`
services: services:
# Label used to access the service container
db: db:
# Docker Hub image
image: postgres:latest image: postgres:latest
# Provide the password for postgres
env: env:
POSTGRES_USER: dev POSTGRES_USER: dev
POSTGRES_PASSWORD: dev POSTGRES_PASSWORD: dev
POSTGRES_DB: iot POSTGRES_DB: iot
# Set health checks to wait until postgres has started
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10s --health-interval 10s

View File

@@ -17,3 +17,7 @@ sqlx-cli = "0.8"
strum = { version = "0.26.3", features = ["derive"] } strum = { version = "0.26.3", features = ["derive"] }
thiserror = "1.0" thiserror = "1.0"
tokio = { version = "1", features = ["fs", "rt-multi-thread"] } tokio = { version = "1", features = ["fs", "rt-multi-thread"] }
[lints.clippy]
pedantic = "warn"

View File

@@ -41,7 +41,7 @@ impl Database {
} }
#[cfg(test)] #[cfg(test)]
pub async fn init_from_pool(pool: Pool<Postgres>) -> Database { pub fn init_from_pool(pool: Pool<Postgres>) -> Database {
Database { conn_pool: pool } Database { conn_pool: pool }
} }
@@ -49,7 +49,7 @@ impl Database {
pub async fn init_db(&self) { pub async fn init_db(&self) {
info!("Checking if required tables exist"); info!("Checking if required tables exist");
match migrate!().run(&self.conn_pool).await { match migrate!().run(&self.conn_pool).await {
Ok(_) => {} Ok(()) => {}
Err(e) => { Err(e) => {
error!("Error when running migrations {}", e); error!("Error when running migrations {}", e);
std::process::exit(1); std::process::exit(1);
@@ -142,7 +142,7 @@ impl Database {
pub async fn add_value( pub async fn add_value(
&self, &self,
msg: &web::Json<ValueMessageFromDevice>, msg: &ValueMessageFromDevice,
device_id: &MacAddress, device_id: &MacAddress,
) -> Result<(), DatabaseError> { ) -> Result<(), DatabaseError> {
info!("Adding value to DB"); info!("Adding value to DB");
@@ -201,8 +201,8 @@ mod tests {
use sqlx::PgPool; use sqlx::PgPool;
#[sqlx::test] #[sqlx::test]
async fn add_device(pool: PgPool) { async fn add_device_and_display_name(pool: PgPool) {
let db = Database::init_from_pool(pool).await; let db = Database::init_from_pool(pool);
let test_device = Device { let test_device = Device {
display_name: Some("Waterlevel daheim".to_owned()), display_name: Some("Waterlevel daheim".to_owned()),
@@ -211,7 +211,7 @@ mod tests {
db.add_device(&MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F])) db.add_device(&MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]))
.await .await
.unwrap(); .unwrap();
db.add_display_name( db.update_display_name(
&MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]), &MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]),
"Waterlevel daheim", "Waterlevel daheim",
) )
@@ -221,4 +221,27 @@ mod tests {
let devices = db.get_devices().await.unwrap(); let devices = db.get_devices().await.unwrap();
assert_eq!(test_device, devices[0]); assert_eq!(test_device, devices[0]);
} }
#[sqlx::test]
async fn add_value(pool: PgPool) {
let db = Database::init_from_pool(pool);
let device_id = MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]);
db.add_device(&device_id)
.await
.unwrap();
let msg = ValueMessageFromDevice{
active_errors: 0,
value: 112.0,
value_id: 1
};
db.add_value(&msg, &device_id).await.unwrap();
let values = db.get_values_for_id(&device_id).await.unwrap();
assert!((values[0].value - msg.value).abs() < 1e-5);
assert_eq!(values[0].value_id, msg.value_id);
}
} }

View File

@@ -17,7 +17,7 @@ async fn receive_telemetry(
}; };
let mac_converted = MacAddress::from(mac_converted); let mac_converted = MacAddress::from(mac_converted);
match data.db.create_device_if_not_exists(&mac_converted).await { match data.db.create_device_if_not_exists(&mac_converted).await {
Ok(_) => {} Ok(()) => {}
Err(e) => { Err(e) => {
error!("Error creating new device: {}", e); error!("Error creating new device: {}", e);
return HttpResponse::InternalServerError(); return HttpResponse::InternalServerError();
@@ -29,7 +29,7 @@ async fn receive_telemetry(
.add_telemetry(&telemetry_message, &mac_converted) .add_telemetry(&telemetry_message, &mac_converted)
.await .await
{ {
Ok(_) => HttpResponse::Created(), Ok(()) => HttpResponse::Created(),
Err(e) => { Err(e) => {
error!("adding Telemetry message to DB failed \n{}", e); error!("adding Telemetry message to DB failed \n{}", e);
HttpResponse::InternalServerError() HttpResponse::InternalServerError()
@@ -66,7 +66,7 @@ async fn receive_value(
}; };
let mac_converted = MacAddress::from(mac_converted); let mac_converted = MacAddress::from(mac_converted);
match data.db.create_device_if_not_exists(&mac_converted).await { match data.db.create_device_if_not_exists(&mac_converted).await {
Ok(_) => {} Ok(()) => {}
Err(e) => { Err(e) => {
error!("Error creating new device: {}", e); error!("Error creating new device: {}", e);
return HttpResponse::InternalServerError(); return HttpResponse::InternalServerError();
@@ -74,7 +74,7 @@ async fn receive_value(
}; };
match data.db.add_value(&value_message, &mac_converted).await { match data.db.add_value(&value_message, &mac_converted).await {
Ok(_) => HttpResponse::Created(), Ok(()) => HttpResponse::Created(),
Err(e) => { Err(e) => {
error!("adding Telemetry message to DB failed \n{}", e); error!("adding Telemetry message to DB failed \n{}", e);
HttpResponse::InternalServerError() HttpResponse::InternalServerError()
@@ -122,13 +122,10 @@ async fn set_display_name(data: web::Data<AppState>, device_id: web::Path<String
return HttpResponse::InternalServerError().finish(); return HttpResponse::InternalServerError().finish();
}; };
let mac_converted = MacAddress::from(mac_converted); let mac_converted = MacAddress::from(mac_converted);
match db.update_display_name(&mac_converted, &display_name).await { if let Ok(()) = db.update_display_name(&mac_converted, &display_name).await { HttpResponse::Ok().finish() } else {
Ok(_) => HttpResponse::Ok().finish(),
Err(_) => {
error!("Failed to update/set displayName for device"); error!("Failed to update/set displayName for device");
HttpResponse::InternalServerError().finish() HttpResponse::InternalServerError().finish()
} }
}
} }

View File

@@ -13,7 +13,7 @@ async fn upload_firmware(
body: web::Bytes, body: web::Bytes,
) -> impl Responder { ) -> impl Responder {
let (device, config, version) = path.into_inner(); let (device, config, version) = path.into_inner();
let version = version.replace(".", "-"); let version = version.replace('.', "-");
let firmware_root_path = &data.firmwares_path; let firmware_root_path = &data.firmwares_path;
@@ -34,8 +34,7 @@ async fn upload_firmware(
debug!("{x:?}"); debug!("{x:?}");
HttpResponse::Ok().body(format!( HttpResponse::Ok().body(format!(
"Firmware version {} uploaded successfully", "Firmware version {version} uploaded successfully"
version
)) ))
} }
@@ -63,7 +62,7 @@ async fn serve_firmware(
data: web::Data<AppState>, data: web::Data<AppState>,
) -> impl Responder { ) -> impl Responder {
let (product, config, version) = path.into_inner(); let (product, config, version) = path.into_inner();
let version = version.replace(".", "-").replace("_", "-"); let version = version.replace(['.', '_'], "-");
let fw_root_path = &data.firmwares_path; let fw_root_path = &data.firmwares_path;
let file_path = PathBuf::from(format!("{product}/firmware_{config}_{version}.bin")); let file_path = PathBuf::from(format!("{product}/firmware_{config}_{version}.bin"));
let file_path = fw_root_path.join(&file_path); let file_path = fw_root_path.join(&file_path);

View File

@@ -24,14 +24,14 @@ pub struct TelemetryMessageFromDevice {
pub software_version: i32, pub software_version: i32,
} }
#[derive(Deserialize, Debug, Serialize)] #[derive(Deserialize, Debug, Serialize, PartialEq)]
pub struct ValueMessageFromDevice { pub struct ValueMessageFromDevice {
pub value: f64, pub value: f64,
pub value_id: i32, pub value_id: i32,
pub active_errors: i32, pub active_errors: i32,
} }
#[derive(Deserialize, Debug, Serialize)] #[derive(Deserialize, Debug, Serialize, PartialEq)]
pub struct ValueMessage { pub struct ValueMessage {
pub value: f64, pub value: f64,
pub value_id: i32, pub value_id: i32,

View File

@@ -63,15 +63,15 @@ pub fn get_files(
.ok_or(GetFilesError::Filename)? .ok_or(GetFilesError::Filename)?
.to_str() .to_str()
.ok_or(GetFilesError::Filename)? .ok_or(GetFilesError::Filename)?
.split("_") .split('_')
.collect(); .collect();
let version = split_name[2] let version = split_name[2]
.strip_suffix(".bin") .strip_suffix(".bin")
.ok_or(GetFilesError::Extension)? .ok_or(GetFilesError::Extension)?
.replace("-", "."); .replace('-', ".");
let board_config = BoardConfig::from_str(split_name[1])?; let board_config = BoardConfig::from_str(split_name[1])?;
let board_type = BoardType::from_str(&product_name).unwrap(); let board_type = BoardType::from_str(&product_name).unwrap();
let version_replaced = version.replace(".", "_"); let version_replaced = version.replace('.', "_");
let fw_url = let fw_url =
format!("{hostname}/firmware/{board_type}/{board_config}/{version_replaced}.bin"); format!("{hostname}/firmware/{board_type}/{board_config}/{version_replaced}.bin");
let cfg = OTAConfiguration { let cfg = OTAConfiguration {
@@ -82,7 +82,7 @@ pub fn get_files(
}; };
configs.push(cfg); configs.push(cfg);
} else if path.is_dir() { } else if path.is_dir() {
println!("Directory: {:?}", path); println!("Directory: {path:?}");
} }
} }