-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 444126e
Showing
9 changed files
with
691 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/target/ | ||
**/*.rs.bk |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "vtebench" | ||
version = "0.1.0" | ||
authors = ["Joe Wilm <joe@jwilm.com>"] | ||
|
||
[dependencies] | ||
structopt = "0.1" | ||
structopt-derive = "0.1" | ||
terminfo = "0.4" | ||
failure = "0.1" | ||
rand = "0.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
vtebench | ||
======== | ||
|
||
A tool for generating terminal benchmarks | ||
|
||
## Usage | ||
|
||
The general usage pattern is | ||
|
||
``` | ||
vtebench -w $(tput cols) -h $(tput lines) [-c|-b=BYTES|-t=TERM] <benchmark> | ||
``` | ||
|
||
Terminal protocol will be output to `stdout`. Output **must be** directed into a | ||
file rather than used directly to benchmark. `vtebench` is written for ease of | ||
understanding, **not** performance. To benchmark the currently running terminal | ||
then, something like this would work: | ||
|
||
```sh | ||
vtebench -w $(tput cols) -h $(tput lines) alt-screen-random-write \ | ||
> /tmp/100mb.vte | ||
|
||
time cat /tmp/100mb.vte | ||
``` | ||
|
||
In the future, it would be nice to have a script to automate generating all of | ||
the tests, running them several times and generate statistics, and print all the | ||
results in a machine+human friendly format. | ||
|
||
## Contributing | ||
|
||
If you wish to add a new test, do the following: | ||
|
||
1. Add a new function in _bench.rs_ with the same pattern as an existing | ||
function. | ||
2. Add a subcommand to run it in the `Benchmark` enum within _cli.rs_. | ||
3. Handle the subcommand in _main.rs_. | ||
|
||
If there are escape codes that are not yet supported on `Context` it is quite | ||
helpful to reference the `terminfo` man page and cross reference with the | ||
`terminfo` **crate**'s `capability` submodule documentation. Each capability | ||
name has a corresponding type in that submodule. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use std::io::Write; | ||
|
||
use rand::{self, Rng}; | ||
|
||
use context::Context; | ||
use cli::Options; | ||
use result::Result; | ||
|
||
pub fn alt_screen_random_write<W: Write>(ctx: &mut Context<W>, options: &Options) -> Result<usize> { | ||
let mut written = 0; | ||
let mut rng = rand::thread_rng(); | ||
let h = options.height; | ||
let w = options.width; | ||
let mut buf = Vec::<u8>::with_capacity(w as usize); | ||
|
||
ctx.smcup()?; | ||
|
||
while written < options.bytes { | ||
buf.clear(); | ||
let (l, c) = (rng.gen_range(0, h), rng.gen_range(0, w - 2)); | ||
let space = w - c; | ||
let to_write = rng.gen_range(0, space); | ||
|
||
written += ctx.cup(l, c)?; | ||
if options.colorize { | ||
written += ctx.setaf(rng.gen_range(0, 8))?; | ||
} | ||
written += ctx.write_ascii(to_write as _)?; | ||
} | ||
|
||
ctx.sgr0()?; | ||
ctx.rmcup()?; | ||
|
||
Ok(written) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/// Command line options | ||
#[derive(StructOpt, Debug)] | ||
#[structopt(name = "vtebench", about = "Benchmark Terminal Emulators")] | ||
pub struct Options { | ||
#[structopt(short = "w", help = "width of terminal", default_value = "80")] | ||
pub width: u16, | ||
|
||
#[structopt(short = "h", help = "height of terminal", default_value = "24")] | ||
pub height: u16, | ||
|
||
#[structopt( | ||
short = "b", | ||
long = "bytes", | ||
help = "minimum bytes to output; actual value may be slightly higher", | ||
default_value = "1048576" | ||
)] | ||
pub bytes: usize, | ||
|
||
#[structopt(short = "c", help = "colorized output (not all tests support)")] | ||
pub colorize: bool, | ||
|
||
#[structopt(long = "term", help = "height of terminal", default_value = "xterm-256color")] | ||
pub term: String, | ||
|
||
#[structopt(subcommand)] | ||
pub benchmark: Benchmark, | ||
} | ||
|
||
#[derive(StructOpt, Debug)] | ||
#[structopt(name = "vtebench", about = "Benchmark Terminal Emulators")] | ||
pub enum Benchmark { | ||
#[structopt( | ||
name = "alt-screen-random-write", | ||
help = "Set alt screen; repeatedly: pick random location, write ascii" | ||
)] | ||
AltScreenRandomWrite, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use std::io::{self, Write}; | ||
use terminfo::{Database, capability as cap}; | ||
|
||
use rand::{self, Rng}; | ||
|
||
use result::Result; | ||
|
||
pub struct Context<'a, W: Write + 'a> { | ||
pub out: &'a mut W, | ||
pub db: &'a Database, | ||
pub buf: Vec<u8>, | ||
pub rng: rand::ThreadRng, | ||
} | ||
|
||
impl<'a, W: Write + 'a> Context<'a, W> { | ||
pub fn smcup(&mut self) -> Result<usize> { | ||
let smcup = expand!(self.db.get::<cap::EnterCaMode>().unwrap().as_ref())?; | ||
self.write_all(&smcup)?; | ||
Ok(smcup.len()) | ||
} | ||
|
||
pub fn rmcup(&mut self) -> Result<usize> { | ||
let rmcup = expand!(self.db.get::<cap::ExitCaMode>().unwrap().as_ref())?; | ||
self.write_all(&rmcup)?; | ||
Ok(rmcup.len()) | ||
} | ||
|
||
pub fn cup(&mut self, line: u16, col: u16) -> Result<usize> { | ||
let cup = expand!(self.db.get::<cap::CursorAddress>().unwrap().as_ref(); line, col)?; | ||
self.write_all(&cup)?; | ||
Ok(cup.len()) | ||
} | ||
|
||
pub fn write_ascii(&mut self, count: usize) -> Result<usize> { | ||
self.buf.clear(); | ||
for _ in 0..count { | ||
self.buf.push(self.rng.gen_range(32, 127)); | ||
} | ||
|
||
self.out.write_all(&self.buf)?; | ||
Ok(count) | ||
} | ||
|
||
pub fn setaf(&mut self, v: u16) -> Result<usize> { | ||
let setaf = expand!( | ||
self.db.get::<cap::SetAForeground>().unwrap().as_ref(); v | ||
)?; | ||
self.write_all(&setaf)?; | ||
Ok(setaf.len()) | ||
} | ||
|
||
pub fn sgr0(&mut self) -> Result<usize> { | ||
let sgr0 = expand!(self.db.get::<cap::ExitAttributeMode>().unwrap().as_ref())?; | ||
self.write_all(&sgr0)?; | ||
Ok(sgr0.len()) | ||
} | ||
} | ||
|
||
impl<'a, W: Write + 'a> Write for Context<'a, W> { | ||
#[inline] | ||
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { | ||
self.out.write(bytes) | ||
} | ||
|
||
#[inline] | ||
fn flush(&mut self) -> io::Result<()> { | ||
self.out.flush() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
//! A tool for generating benchmark scripts for terminal emulators | ||
//! | ||
//~ This program is intended to be run and its output piped into a file, and the | ||
//~ file can simply be `cat`ed from the terminal emulator under test. This | ||
//~ ensures that the terminal is being benchmarked and not this vtebench | ||
//~ application. | ||
extern crate rand; | ||
extern crate structopt; | ||
|
||
#[macro_use] extern crate failure; | ||
#[macro_use] extern crate structopt_derive; | ||
#[macro_use] extern crate terminfo; | ||
|
||
use std::io::{self, BufWriter}; | ||
|
||
use structopt::StructOpt; | ||
use terminfo::Database; | ||
|
||
mod bench; | ||
mod cli; | ||
mod context; | ||
mod result; | ||
|
||
use cli::{Options, Benchmark}; | ||
use context::Context; | ||
use result::Result; | ||
|
||
fn main() { | ||
run().unwrap(); | ||
} | ||
|
||
fn run() -> Result<()> { | ||
// Load command line options | ||
let options = Options::from_args(); | ||
|
||
// Load terminfo database | ||
let db = Database::from_name(&options.term)?; | ||
|
||
// Get I/O handle | ||
let stdout = io::stdout(); | ||
let mut out = stdout.lock(); | ||
let mut out = BufWriter::new(&mut out); | ||
|
||
// Create the output context | ||
let mut ctx = Context { out: &mut out, db: &db, buf: Vec::new(), rng: rand::thread_rng() }; | ||
|
||
// Run the requested benchmark | ||
match options.benchmark { | ||
Benchmark::AltScreenRandomWrite => bench::alt_screen_random_write(&mut ctx, &options)?, | ||
}; | ||
|
||
// Success! | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use std::io; | ||
use terminfo; | ||
|
||
pub type Result<T> = ::std::result::Result<T, Error>; | ||
|
||
#[derive(Debug, Fail)] | ||
pub enum Error { | ||
#[fail(display = "{}", _0)] | ||
Io(#[cause] io::Error), | ||
|
||
#[fail(display = "{}", _0)] | ||
Terminfo(#[cause] terminfo::Error), | ||
} | ||
|
||
impl From<io::Error> for Error { | ||
fn from(val: io::Error) -> Error { | ||
Error::Io(val) | ||
} | ||
} | ||
|
||
impl From<terminfo::Error> for Error { | ||
fn from(val: terminfo::Error) -> Error { | ||
Error::Terminfo(val) | ||
} | ||
} |