mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #861 from ProgVal/test-tail-f
tail: Add test for `tail -f`.
This commit is contained in:
commit
02779fd3d2
3 changed files with 63 additions and 25 deletions
2
Makefile
2
Makefile
|
@ -33,7 +33,7 @@ BUILDDIR := $(BASEDIR)/target/${PROFILE}/
|
||||||
PKG_BUILDDIR := $(BUILDDIR)/deps/
|
PKG_BUILDDIR := $(BUILDDIR)/deps/
|
||||||
|
|
||||||
BUSYBOX_ROOT := $(BASEDIR)/tmp/
|
BUSYBOX_ROOT := $(BASEDIR)/tmp/
|
||||||
BUSYBOX_VER := 1.24.1
|
BUSYBOX_VER := 1.22.0
|
||||||
BUSYBOX_SRC:=$(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)/
|
BUSYBOX_SRC:=$(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)/
|
||||||
|
|
||||||
# Possible programs
|
# Possible programs
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
extern crate tempdir;
|
extern crate tempdir;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File, OpenOptions};
|
||||||
use std::io::{Read, Write, Result};
|
use std::io::{Read, Write, Result};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -11,11 +11,13 @@ use std::os::unix::fs::symlink as symlink_file;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use std::os::windows::fs::symlink_file;
|
use std::os::windows::fs::symlink_file;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio, Child};
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use self::tempdir::TempDir;
|
use self::tempdir::TempDir;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
static PROGNAME: &'static str = "target\\debug\\uutils.exe";
|
static PROGNAME: &'static str = "target\\debug\\uutils.exe";
|
||||||
|
@ -242,6 +244,12 @@ impl AtPath {
|
||||||
let _ = f.write(contents.as_bytes());
|
let _ = f.write(contents.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn append(&self, name: &str, contents: &str) {
|
||||||
|
log_info("open(append)", self.plus_as_string(name));
|
||||||
|
let mut f = OpenOptions::new().write(true).append(true).open(self.plus(name)).unwrap();
|
||||||
|
let _ = f.write(contents.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mkdir(&self, dir: &str) {
|
pub fn mkdir(&self, dir: &str) {
|
||||||
log_info("mkdir", self.plus_as_string(dir));
|
log_info("mkdir", self.plus_as_string(dir));
|
||||||
fs::create_dir(&self.plus(dir)).unwrap();
|
fs::create_dir(&self.plus(dir)).unwrap();
|
||||||
|
@ -480,14 +488,13 @@ impl UCommand {
|
||||||
Box::new(self)
|
Box::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) -> CmdResult {
|
/// Spawns the command, feeds the stdin if any, and returns immediately.
|
||||||
|
pub fn run_no_wait(&mut self) -> Child {
|
||||||
if self.has_run {
|
if self.has_run {
|
||||||
panic!(ALREADY_RUN);
|
panic!(ALREADY_RUN);
|
||||||
}
|
}
|
||||||
self.has_run = true;
|
self.has_run = true;
|
||||||
log_info("run", &self.comm_string);
|
log_info("run", &self.comm_string);
|
||||||
let prog = match self.stdin {
|
|
||||||
Some(ref input) => {
|
|
||||||
let mut result = self.raw
|
let mut result = self.raw
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
@ -495,6 +502,7 @@ impl UCommand {
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
if let Some(ref input) = self.stdin {
|
||||||
result.stdin
|
result.stdin
|
||||||
.take()
|
.take()
|
||||||
.unwrap_or_else(
|
.unwrap_or_else(
|
||||||
|
@ -502,13 +510,16 @@ impl UCommand {
|
||||||
"Could not take child process stdin"))
|
"Could not take child process stdin"))
|
||||||
.write_all(&input)
|
.write_all(&input)
|
||||||
.unwrap_or_else(|e| panic!("{}", e));
|
.unwrap_or_else(|e| panic!("{}", e));
|
||||||
|
}
|
||||||
|
|
||||||
result.wait_with_output().unwrap()
|
result
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
self.raw.output().unwrap()
|
/// Spawns the command, feeds the stdin if any, waits for the result
|
||||||
}
|
/// and returns it.
|
||||||
};
|
pub fn run(&mut self) -> CmdResult {
|
||||||
|
let prog = self.run_no_wait().wait_with_output().unwrap();
|
||||||
|
|
||||||
CmdResult {
|
CmdResult {
|
||||||
success: prog.status.success(),
|
success: prog.status.success(),
|
||||||
stdout: from_utf8(&prog.stdout).unwrap().to_string(),
|
stdout: from_utf8(&prog.stdout).unwrap().to_string(),
|
||||||
|
@ -541,6 +552,14 @@ impl UCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_size(child: &mut Child, size: usize) -> String {
|
||||||
|
let mut output = Vec::new();
|
||||||
|
output.resize(size, 0);
|
||||||
|
sleep(Duration::from_millis(100));
|
||||||
|
child.stdout.as_mut().unwrap().read(output.as_mut_slice()).unwrap();
|
||||||
|
String::from_utf8(output).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
// returns a testSet and a ucommand initialized to the utility binary
|
// returns a testSet and a ucommand initialized to the utility binary
|
||||||
// operating in the fixtures directory with a cleared environment
|
// operating in the fixtures directory with a cleared environment
|
||||||
pub fn testset_and_ucommand(utilname: &str) -> (TestSet, UCommand) {
|
pub fn testset_and_ucommand(utilname: &str) -> (TestSet, UCommand) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
extern crate uu_tail;
|
extern crate uu_tail;
|
||||||
use uu_tail::parse_size;
|
use uu_tail::parse_size;
|
||||||
|
|
||||||
|
use std::io::Read;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -41,6 +42,24 @@ fn test_null_default() {
|
||||||
assert_eq!(result.stdout, at.read("foobar_with_null_default.expected"));
|
assert_eq!(result.stdout, at.read("foobar_with_null_default.expected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_follow() {
|
||||||
|
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
|
||||||
|
let mut child = ucmd.arg("-f").arg(FOOBAR_TXT).run_no_wait();
|
||||||
|
|
||||||
|
let expected = at.read("foobar_single_default.expected");
|
||||||
|
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||||
|
|
||||||
|
// We write in a temporary copy of foobar.txt
|
||||||
|
let expected = "line1\nline2\n";
|
||||||
|
at.append(FOOBAR_TXT, expected);
|
||||||
|
|
||||||
|
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||||
|
|
||||||
|
child.kill().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_single_big_args() {
|
fn test_single_big_args() {
|
||||||
const FILE: &'static str = "single_big_args.txt";
|
const FILE: &'static str = "single_big_args.txt";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue