add tests

This commit is contained in:
jb-alvarado 2022-10-12 15:28:49 +02:00
parent bbb0e1371b
commit 87c508be54
31 changed files with 22767 additions and 48 deletions

26
Cargo.lock generated
View File

@ -2743,6 +2743,32 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "tests"
version = "0.1.0"
dependencies = [
"chrono",
"crossbeam-channel",
"ffplayout",
"ffplayout-lib",
"ffprobe",
"file-rotate",
"jsonrpc-http-server",
"lettre",
"log",
"notify",
"rand",
"regex",
"reqwest",
"serde",
"serde_json",
"serde_yaml",
"shlex",
"simplelog",
"time 0.3.14",
"walkdir",
]
[[package]]
name = "textwrap"
version = "0.15.1"

View File

@ -1,6 +1,6 @@
[workspace]
members = ["ffplayout-api", "ffplayout-engine", "lib"]
default-members = ["ffplayout-api", "ffplayout-engine"]
members = ["ffplayout-api", "ffplayout-engine", "lib", "tests"]
default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
[profile.release]
opt-level = 3

View File

@ -42,7 +42,7 @@ pub fn watchman(
match res {
Create(new_path) => {
let index = sources.lock().unwrap().len();
let media = Media::new(index, new_path.display().to_string(), false);
let media = Media::new(index, &new_path.to_string_lossy(), false);
if include_file(config.clone(), &new_path) {
sources.lock().unwrap().push(media);
@ -66,7 +66,7 @@ pub fn watchman(
.position(|x| *x.source == old_path.display().to_string())
.unwrap();
let media = Media::new(index, new_path.display().to_string(), false);
let media = Media::new(index, &new_path.to_string_lossy(), false);
sources.lock().unwrap()[index] = media;
info!("Rename file: <b><magenta>{old_path:?}</></b> to <b><magenta>{new_path:?}</></b>");

View File

@ -84,7 +84,7 @@ pub fn ingest_server(
let mut buffer: [u8; 65088] = [0; 65088];
let mut server_cmd = vec_strings!["-hide_banner", "-nostats", "-v", "level+info"];
let stream_input = config.ingest.input_cmd.clone().unwrap();
let mut dummy_media = Media::new(0, "Live Stream".to_string(), false);
let mut dummy_media = Media::new(0, "Live Stream", false);
dummy_media.is_live = Some(true);
let mut filters = filter_chains(&config, &mut dummy_media, &Arc::new(Mutex::new(vec![])));

View File

@ -69,7 +69,7 @@ impl CurrentProgram {
json_path: json.current_file,
json_date: json.date,
nodes: current_list,
current_node: Media::new(0, String::new(), false),
current_node: Media::new(0, "", false),
index: global_index,
is_terminated,
playout_stat,
@ -118,7 +118,7 @@ impl CurrentProgram {
"Playlist <b><magenta>{}</></b> not exists!",
self.json_path.clone().unwrap()
);
let mut media = Media::new(0, String::new(), false);
let mut media = Media::new(0, "", false);
media.begin = Some(get_sec());
media.duration = DUMMY_LEN;
media.out = DUMMY_LEN;
@ -304,7 +304,7 @@ impl Iterator for CurrentProgram {
current_time += self.config.playlist.length_sec.unwrap() + 1.0;
}
let mut media = Media::new(0, String::new(), false);
let mut media = Media::new(0, "", false);
media.begin = Some(current_time);
media.duration = duration;
media.out = duration;
@ -357,7 +357,7 @@ impl Iterator for CurrentProgram {
// Test if playlist is to early finish,
// and if we have to fill it with a placeholder.
let index = self.index.load(Ordering::SeqCst);
self.current_node = Media::new(index, String::new(), false);
self.current_node = Media::new(index, "", false);
self.current_node.begin = Some(get_sec());
let mut duration = total_delta.abs();
@ -454,7 +454,7 @@ fn timed_source(
}
/// Generate the source CMD, or when clip not exist, get a dummy.
fn gen_source(
pub fn gen_source(
config: &PlayoutConfig,
mut node: Media,
filter_chain: &Arc<Mutex<Vec<String>>>,

View File

@ -0,0 +1,4 @@
pub mod input;
pub mod output;
pub mod rpc;
pub mod utils;

View File

@ -12,18 +12,10 @@ use serde::{Deserialize, Serialize};
use serde_json::json;
use simplelog::*;
pub mod input;
pub mod output;
pub mod rpc;
// #[cfg(test)]
// mod tests;
pub mod utils;
use utils::{arg_parse::get_args, get_config};
use crate::{
use ffplayout::{
output::{player, write_hls},
rpc::json_rpc_server,
utils::{arg_parse::get_args, get_config},
};
use ffplayout_lib::utils::{
@ -32,7 +24,7 @@ use ffplayout_lib::utils::{
};
#[cfg(debug_assertions)]
use utils::Args;
use ffplayout::utils::Args;
#[cfg(debug_assertions)]
use ffplayout_lib::utils::{mock_time, time_now};

View File

@ -47,7 +47,7 @@ fn ingest_to_hls_server(
let mut server_prefix = vec_strings!["-hide_banner", "-nostats", "-v", "level+info"];
let stream_input = config.ingest.input_cmd.clone().unwrap();
server_prefix.append(&mut stream_input.clone());
let mut dummy_media = Media::new(0, "Live Stream".to_string(), false);
let mut dummy_media = Media::new(0, "Live Stream", false);
dummy_media.is_live = Some(true);
let mut is_running;

View File

@ -28,10 +28,7 @@ pub fn filter_node(
// TODO: in Rust 1.65 use let_chains instead
if config.text.text_from_filename && node.is_some() {
let source = node
.unwrap_or(&Media::new(0, String::new(), false))
.source
.clone();
let source = node.unwrap_or(&Media::new(0, "", false)).source.clone();
let regex: Regex = Regex::new(&config.text.regex).unwrap();
let text: String = match regex.captures(&source) {

View File

@ -4,6 +4,3 @@ extern crate simplelog;
pub mod filter;
pub mod macros;
pub mod utils;
#[cfg(test)]
mod tests;

View File

@ -167,7 +167,7 @@ impl PlayerControl {
pub fn new() -> Self {
Self {
current_media: Arc::new(Mutex::new(None)),
current_list: Arc::new(Mutex::new(vec![Media::new(0, String::new(), false)])),
current_list: Arc::new(Mutex::new(vec![Media::new(0, "", false)])),
index: Arc::new(AtomicUsize::new(0)),
}
}

View File

@ -49,7 +49,7 @@ impl FolderSource {
.filter(|f| f.path().is_file())
{
if include_file(config.clone(), entry.path()) {
let media = Media::new(0, entry.path().display().to_string(), false);
let media = Media::new(0, &entry.path().to_string_lossy(), false);
media_list.push(media);
}
}
@ -83,7 +83,7 @@ impl FolderSource {
config: config.clone(),
filter_chain,
nodes: current_list,
current_node: Media::new(0, String::new(), false),
current_node: Media::new(0, "", false),
index: global_index,
}
}

View File

@ -65,7 +65,7 @@ pub fn generate_playlist(
}
}
};
let current_list = Arc::new(Mutex::new(vec![Media::new(0, "".to_string(), false)]));
let current_list = Arc::new(Mutex::new(vec![Media::new(0, "", false)]));
let index = Arc::new(AtomicUsize::new(0));
let playlist_root = Path::new(&config.playlist.path);
let mut playlists = vec![];
@ -119,7 +119,7 @@ pub fn generate_playlist(
playlist_file.display()
);
let mut filler = Media::new(0, config.storage.filler_clip.clone(), true);
let mut filler = Media::new(0, &config.storage.filler_clip, true);
let filler_length = filler.duration;
let mut length = 0.0;
let mut round = 0;

View File

@ -48,7 +48,7 @@ pub fn import_file(
let line = line?;
if !line.starts_with('#') {
let item = Media::new(0, line, true);
let item = Media::new(0, &line, true);
playlist.program.push(item);
}

View File

@ -34,7 +34,7 @@ pub struct JsonPlaylist {
impl JsonPlaylist {
fn new(date: String, start: f64) -> Self {
let mut media = Media::new(0, String::new(), false);
let mut media = Media::new(0, "", false);
media.begin = Some(start);
media.duration = DUMMY_LEN;
media.out = DUMMY_LEN;

View File

@ -100,12 +100,12 @@ pub struct Media {
}
impl Media {
pub fn new(index: usize, src: String, do_probe: bool) -> Self {
pub fn new(index: usize, src: &str, do_probe: bool) -> Self {
let mut duration = 0.0;
let mut probe = None;
if do_probe && Path::new(&src).is_file() {
probe = Some(MediaProbe::new(&src));
if do_probe && Path::new(src).is_file() {
probe = Some(MediaProbe::new(src));
if let Some(dur) = probe
.as_ref()
@ -123,9 +123,9 @@ impl Media {
out: duration,
duration,
category: String::new(),
source: src.clone(),
source: src.to_string(),
audio: String::new(),
cmd: Some(vec!["-i".to_string(), src]),
cmd: Some(vec_strings!["-i", src]),
filter: Some(vec![]),
custom_filter: String::new(),
probe,

42
tests/Cargo.toml Normal file
View File

@ -0,0 +1,42 @@
[package]
name = "tests"
version = "0.1.0"
edition = "2021"
publish = false
[dev-dependencies]
ffplayout = { path = "../ffplayout-engine" }
# ffplayout-api = { path = "../ffplayout-api" }
ffplayout-lib = { path = "../lib" }
chrono = "0.4"
crossbeam-channel = "0.5"
ffprobe = "0.3"
file-rotate = "0.7.0"
jsonrpc-http-server = "18.0"
lettre = "0.10"
log = "0.4"
notify = "4.0"
rand = "0.8"
regex = "1"
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.8"
shlex = "1.1"
simplelog = { version = "^0.12", features = ["paris"] }
time = { version = "0.3", features = ["formatting", "macros"] }
walkdir = "2"
[[test]]
name = "lib_utils"
path = "src/lib_utils.rs"
[[test]]
name = "engine_playlist"
path = "src/engine_playlist.rs"
[[test]]
name = "engine_cmd"
path = "src/engine_cmd.rs"

BIN
tests/assets/ad.mp4 Normal file

Binary file not shown.

BIN
tests/assets/audio.mp3 Normal file

Binary file not shown.

BIN
tests/assets/av_sync.mp4 Normal file

Binary file not shown.

BIN
tests/assets/dual_audio.mp4 Normal file

Binary file not shown.

BIN
tests/assets/no_audio.mp4 Normal file

Binary file not shown.

22526
tests/assets/playlist_full.json Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
{
"channel": "Channel 1",
"date": "2022-11-01",
"program": [
{
"in": 0.0,
"out": 30.0,
"duration": 30.0,
"source": "tests/assets/av_sync.mp4"
},
{
"in": 0.0,
"out": 30.0,
"duration": 30.0,
"source": "tests/assets/dual_audio.mp4"
},
{
"in": 0.0,
"out": 10.0,
"duration": 10.0,
"source": "tests/assets/short_video.mp4"
},
{
"in": 0.0,
"out": 10.0,
"duration": 10.0,
"source": "tests/assets/still.jpg"
},
{
"in": 0.0,
"out": 10.0,
"duration": 10.0,
"source": "tests/assets/short_audio.mp4"
},
{
"in": 0.0,
"out": 30.0,
"duration": 30.0,
"source": "tests/assets/no_audio.mp4"
},
{
"in": 0.0,
"out": 10.0,
"duration": 10.0,
"source": "tests/assets/still.jpg",
"audio": "tests/assets/audio.mp3"
},
{
"in": 0.0,
"out": 25.0,
"duration": 25.0,
"source": "tests/assets/ad.mp4",
"category": "advertisement"
}
]
}

Binary file not shown.

Binary file not shown.

BIN
tests/assets/still.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
tests/assets/with_audio.mp4 Normal file

Binary file not shown.

82
tests/src/engine_cmd.rs Normal file
View File

@ -0,0 +1,82 @@
use ffplayout::input::playlist::gen_source;
use ffplayout_lib::{
utils::{Media, PlayoutConfig},
vec_strings,
};
use std::sync::{Arc, Mutex};
#[test]
fn video_audio_input() {
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
config.out.mode = "stream".to_string();
config.processing.logo = "../assets/logo.png".to_string();
let media_obj = Media::new(0, "assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &Arc::new(Mutex::new(vec![])));
let test_filter_cmd = Some(
vec_strings![
"-filter_complex",
"[0:v:0]scale=1024:576,null[v];movie=../assets/logo.png:loop=0,setpts=N/(FRAME_RATE*TB),format=rgba,colorchannelmixer=aa=0.7[l];[v][l]overlay=W-w-12:12:shortest=1[vout0];[0:a:0]anull[aout0]",
"-map",
"[vout0]",
"-map",
"[aout0]"
],
);
assert_eq!(media.cmd, Some(vec_strings!["-i", "assets/with_audio.mp4"]));
assert_eq!(media.filter, test_filter_cmd);
}
#[test]
fn dual_audio_aevalsrc_input() {
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
config.out.mode = "stream".to_string();
config.processing.audio_tracks = 2;
config.processing.add_logo = false;
let media_obj = Media::new(0, "assets/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &Arc::new(Mutex::new(vec![])));
let test_filter_cmd = Some(
vec_strings![
"-filter_complex",
"[0:v:0]scale=1024:576[vout0];[0:a:0]anull[aout0];aevalsrc=0:channel_layout=stereo:duration=30:sample_rate=48000,anull[aout1]",
"-map",
"[vout0]",
"-map",
"[aout0]",
"-map",
"[aout1]"
],
);
assert_eq!(media.cmd, Some(vec_strings!["-i", "assets/with_audio.mp4"]));
assert_eq!(media.filter, test_filter_cmd);
}
#[test]
fn dual_audio_input() {
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
config.out.mode = "stream".to_string();
config.processing.audio_tracks = 2;
config.processing.add_logo = false;
let media_obj = Media::new(0, "assets/dual_audio.mp4", true);
let media = gen_source(&config, media_obj, &Arc::new(Mutex::new(vec![])));
let test_filter_cmd = Some(vec_strings![
"-filter_complex",
"[0:v:0]scale=1024:576[vout0];[0:a:0]anull[aout0];[0:a:1]anull[aout1]",
"-map",
"[vout0]",
"-map",
"[aout0]",
"-map",
"[aout1]"
]);
assert_eq!(media.cmd, Some(vec_strings!["-i", "assets/dual_audio.mp4"]));
assert_eq!(media.filter, test_filter_cmd);
}

View File

@ -3,13 +3,11 @@ use std::{
time::Duration,
};
#[cfg(test)]
use crate::output::player;
#[cfg(test)]
use ffplayout_lib::utils::*;
#[cfg(test)]
use simplelog::*;
use ffplayout::output::player;
use ffplayout_lib::utils::*;
fn timed_kill(sec: u64, mut proc_ctl: ProcessControl) {
sleep(Duration::from_secs(sec));

View File

@ -2,8 +2,7 @@
use chrono::prelude::*;
#[cfg(test)]
use crate::utils::*;
use crate::vec_strings;
use ffplayout_lib::{utils::*, vec_strings};
#[test]
fn mock_date_time() {