diff --git a/src/db/vm.rs b/src/db/vm.rs index c9ddcee..80d14c0 100644 --- a/src/db/vm.rs +++ b/src/db/vm.rs @@ -814,6 +814,12 @@ impl ActiveVmWithNode { pub fn price_per_minute(&self) -> u64 { self.total_units() * self.price_per_unit } + + pub async fn list_all(db: &Surreal) -> Result, Error> { + let mut query_response = db.query(format!("SELECT * FROM {ACTIVE_VM} FETCH out;")).await?; + let active_vms: Vec = query_response.take(0)?; + Ok(active_vms) + } } // TODO: delete all of these From implementation after migration 0 gets executed diff --git a/src/grpc/general.rs b/src/grpc/general.rs index 6f1fe00..3dcb31c 100644 --- a/src/grpc/general.rs +++ b/src/grpc/general.rs @@ -195,20 +195,19 @@ impl BrainGeneralCli for GeneralCliServer { async fn list_all_vm_contracts( &self, - _req: Request, + req: Request, ) -> Result, Status> { - todo!(); - // check_admin_key(&req)?; - // let _ = check_sig_from_req(req)?; - // let contracts = self.data.list_all_contracts(); - // let (tx, rx) = mpsc::channel(6); - // tokio::spawn(async move { - // for contract in contracts { - // let _ = tx.send(Ok(contract.into())).await; - // } - // }); - // let output_stream = ReceiverStream::new(rx); - // Ok(Response::new(Box::pin(output_stream) as Self::ListAllVmContractsStream)) + check_admin_key(&req)?; + check_sig_from_req(req)?; + let contracts = db::ActiveVmWithNode::list_all(&self.db).await?; + let (tx, rx) = mpsc::channel(6); + tokio::spawn(async move { + for contract in contracts { + let _ = tx.send(Ok(contract.into())).await; + } + }); + let output_stream = ReceiverStream::new(rx); + Ok(Response::new(Box::pin(output_stream) as Self::ListAllVmContractsStream)) } async fn list_all_app_contracts( diff --git a/tests/common/vm_cli_utils.rs b/tests/common/vm_cli_utils.rs index 68251b6..6a6937f 100644 --- a/tests/common/vm_cli_utils.rs +++ b/tests/common/vm_cli_utils.rs @@ -108,3 +108,29 @@ pub async fn list_accounts(brain_channel: &Channel, admin_key: &Key) -> Result Result> { + let mut cli_client = BrainGeneralCliClient::new(brain_channel.clone()); + let mut stream = cli_client + .list_all_vm_contracts(admin_key.sign_request(Empty {}).unwrap()) + .await? + .into_inner(); + + let mut vm_contracts = Vec::new(); + + while let Some(stream_data) = stream.next().await { + match stream_data { + Ok(vm_contract) => { + vm_contracts.push(vm_contract); + } + Err(e) => { + panic!("Error while listing vm_contracts: {e:?}"); + } + } + } + + Ok(vm_contracts) +} diff --git a/tests/grpc_general_test.rs b/tests/grpc_general_test.rs index 0a65c5b..e9b0332 100644 --- a/tests/grpc_general_test.rs +++ b/tests/grpc_general_test.rs @@ -2,14 +2,16 @@ use common::prepare_test_env::{ prepare_test_db, run_service_for_stream, run_service_in_background, }; use common::test_utils::{admin_keys, Key}; -use common::vm_cli_utils::{airdrop, create_new_vm, list_accounts, register_operator, report_node}; +use common::vm_cli_utils::{ + airdrop, create_new_vm, list_accounts, list_all_vm_contracts, register_operator, report_node, +}; use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node}; use detee_shared::common_proto::{Empty, Pubkey}; use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient; use detee_shared::general_proto::{AirdropReq, BanUserReq, SlashReq}; use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient; use futures::StreamExt; -use surreal_brain::constants::{ACCOUNT, BAN, TOKEN_DECIMAL, VM_NODE}; +use surreal_brain::constants::{ACCOUNT, ACTIVE_VM, BAN, TOKEN_DECIMAL, VM_NODE}; use surreal_brain::db::prelude as db; use surreal_brain::db::vm::VmNodeWithReports; @@ -397,3 +399,21 @@ async fn test_admin_list_account() { let accounts = list_accounts(&brain_channel, &admin_key).await.unwrap(); assert_eq!(accounts.len(), acc_in_db.len()); } + +#[tokio::test] +async fn test_admin_list_all_vm_contracts() { + let db_conn = prepare_test_db().await.unwrap(); + let brain_channel = run_service_for_stream().await.unwrap(); + + let admin_key = admin_keys()[0].clone(); + + let unauthenticated = list_all_vm_contracts(&brain_channel, &Key::new()).await.err().unwrap(); + assert!(unauthenticated.to_string().contains("reserved to admin accounts")); + + let vm_in_db = db_conn.select::>(ACTIVE_VM).await.unwrap(); + + let vm_contracts = list_all_vm_contracts(&brain_channel, &admin_key).await.unwrap(); + assert_eq!(vm_contracts.len(), vm_in_db.len()); + + // TODO: mock vm daemon and deploy a new vm, then list again +}