Skip to content

Add integration tests for basic interactions with most of the commands #1181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt;
use std::fs::File;
use std::fs::{create_dir_all, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
use std::{env, fmt};

use anyhow::{Context, Result};
use backoff::backoff::Backoff;
Expand All @@ -34,6 +34,7 @@ use serde::{Deserialize, Serialize};
use sha1_smol::Digest;
use symbolic::common::DebugId;
use symbolic::debuginfo::ObjectKind;
use url::Url;

use crate::config::{Auth, Config};
use crate::constants::{ARCH, EXT, PLATFORM, RELEASE_REGISTRY_LATEST_URL, VERSION};
Expand Down Expand Up @@ -323,6 +324,7 @@ impl fmt::Display for Method {
/// Represents an API request. This can be customized before
/// sending but only sent once.
pub struct ApiRequest {
url: String,
handle: r2d2::PooledConnection<CurlConnectionManager>,
headers: curl::easy::List,
is_authenticated: bool,
Expand All @@ -335,6 +337,7 @@ pub struct ApiRequest {
/// Represents an API response.
#[derive(Clone, Debug)]
pub struct ApiResponse {
url: String,
status: u32,
headers: Vec<String>,
body: Option<Vec<u8>>,
Expand Down Expand Up @@ -1562,6 +1565,7 @@ impl ApiRequest {
handle.url(url)?;

let request = ApiRequest {
url: url.to_owned(),
handle,
headers,
is_authenticated: false,
Expand Down Expand Up @@ -1660,10 +1664,12 @@ impl ApiRequest {
let headers = self.get_headers();
self.handle.http_headers(headers)?;
let body = self.body.as_deref();
let url = self.url.clone();
let (status, headers) =
send_req(&mut self.handle, out, body, self.progress_bar_mode.clone())?;
debug!("response status: {}", status);
Ok(ApiResponse {
url,
status,
headers,
body: None,
Expand Down Expand Up @@ -1722,7 +1728,17 @@ impl ApiResponse {
/// non okay response codes into errors.
pub fn into_result(self) -> ApiResult<Self> {
if let Some(ref body) = self.body {
debug!("body: {}", String::from_utf8_lossy(body));
let body = String::from_utf8_lossy(body);
debug!("body: {}", body);

// Internal helper for making it easier to write integration tests.
// Should not be used publicly, as it may be removed without prior warning.
// Accepts a relative or absolute path to the directory where responses should be stored.
if let Ok(dir) = env::var("SENTRY_DUMP_RESPONSES") {
if let Err(err) = dump_response(dir, &self.url, body.into_owned()) {
debug!("Could not dump a response: {}", err);
};
}
}
if self.ok() {
return Ok(self);
Expand Down Expand Up @@ -1864,6 +1880,23 @@ fn log_headers(is_response: bool, data: &[u8]) {
}
}

fn dump_response(mut dir: String, url: &str, body: String) -> Result<()> {
if dir.starts_with('~') {
dir = format!(
"{}{}",
dirs::home_dir().unwrap_or_default().display(),
dir.trim_start_matches('~')
);
}
let filename = Url::parse(url)?.path().trim_matches('/').replace('/', "__");
create_dir_all(&dir)?;
let filepath = format!("{}/{}.json", &dir, filename);
let mut file = File::create(&filepath)?;
file.write_all(&body.into_bytes())?;
debug!("Response dumped to: {}", &filepath);
Ok(())
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
enum ErrorInfo {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/debug_files/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pub mod upload;
macro_rules! each_subcommand {
($mac:ident) => {
$mac!(bundle_sources);
$mac!(find);
$mac!(check);
$mac!(find);
$mac!(upload);
};
}
Expand Down
9 changes: 9 additions & 0 deletions src/commands/login.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::env;

use anyhow::Result;
use clap::{Arg, ArgMatches, Command};
use url::Url;
Expand Down Expand Up @@ -37,6 +39,13 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
.unwrap_or("<unknown>")
);

// It's not currently possible to easily mock I/O with `trycmd`,
// but verifying that `execute` is not panicking, is good enough for now.
if env::var("SENTRY_INTEGRATION_TEST").is_ok() {
println!("Running in integration tests mode. Skipping execution.");
return Ok(());
}

if prompt_to_continue("Open browser now?")? && open::that(&token_url).is_err() {
println!("Cannot open browser. Please manually go to {}", &token_url);
}
Expand Down
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ macro_rules! each_subcommand {
$mac!(uninstall);
#[cfg(not(feature = "managed"))]
$mac!(update);
$mac!(upload_dif);
$mac!(upload_proguard);
};
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/send_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use anyhow::{format_err, Result};
use clap::{Arg, ArgMatches, Command};
use glob::{glob_with, MatchOptions};
use itertools::Itertools;
use log::warn;
use log::{debug, warn};
use sentry::protocol::{Event, Level, LogEntry, User};
use sentry::types::{Dsn, Uuid};
use serde_json::Value;
Expand Down Expand Up @@ -149,6 +149,7 @@ pub fn make_command(command: Command) -> Command {
}

fn send_raw_event(event: Event<'static>, dsn: Dsn) -> Uuid {
debug!("{:?}", event);
with_sentry_client(dsn, |c| c.capture_event(event, None))
}

Expand Down
7 changes: 7 additions & 0 deletions src/commands/uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
return Err(QuietExit(1).into());
}

// It's not currently possible to easily mock I/O with `trycmd`,
// but verifying that `execute` is not panicking, is good enough for now.
if env::var("SENTRY_INTEGRATION_TEST").is_ok() {
println!("Running in integration tests mode. Skipping execution.");
return Ok(());
}

if !matches.is_present("confirm")
&& !prompt_to_continue("Do you really want to uninstall sentry-cli?")?
{
Expand Down
8 changes: 8 additions & 0 deletions src/commands/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
}

println!("Latest release is {}", update.latest_version());

// It's not currently possible to easily mock I/O with `trycmd`,
// but verifying that `execute` is not panicking, is good enough for now.
if env::var("SENTRY_INTEGRATION_TEST").is_ok() {
println!("Running in integration tests mode. Skipping execution.");
return Ok(());
}

if update.is_latest_version() {
if matches.is_present("force") {
println!("Forcing update");
Expand Down
4 changes: 2 additions & 2 deletions src/commands/upload_dif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use anyhow::Result;
use clap::{ArgMatches, Command};

pub fn make_command(command: Command) -> Command {
crate::commands::debug_files_upload::make_command(command).hide(true)
crate::commands::debug_files::upload::make_command(command).hide(true)
}

pub fn execute(matches: &ArgMatches) -> Result<()> {
crate::commands::debug_files_upload::execute(matches)
crate::commands::debug_files::upload::execute(matches)
}
1 change: 0 additions & 1 deletion tests/integration/_api/empty.json

This file was deleted.

14 changes: 14 additions & 0 deletions tests/integration/_cases/debug_files/debug_files-check.trycmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
```
$ sentry-cli debug-files check tests/integration/_fixtures/elf-Linux-ARMv7-ls
? success
Debug Info File Check
Type: elf executable
Contained debug identifiers:
> Debug ID: 307a5402-9480-8ec2-25f1-a4adc744a991
Code ID: 02547a308094c28e25f1a4adc744a9917194db0a
Arch: arm
Contained debug information:
> symtab, unwind
Usable: yes

```
26 changes: 26 additions & 0 deletions tests/integration/_cases/debug_files/debug_files-help.trycmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
```
$ sentry-cli debug-files --help
? success
sentry-cli[..]-debug-files
Locate, analyze or upload debug information files.

USAGE:
sentry-cli[..] debug-files [OPTIONS] <SUBCOMMAND>

OPTIONS:
--auth-token <AUTH_TOKEN> Use the given Sentry auth token.
-h, --help Print help information
--log-level <LOG_LEVEL> Set the log output verbosity. [possible values: trace, debug,
info, warn, error]
--quiet Do not print any output while preserving correct exit code.
This flag is currently implemented only for selected
subcommands. [aliases: silent]

SUBCOMMANDS:
bundle-sources Create a source bundle for a given debug information file
check Check the debug info file at a given path.
find Locate debug information files for given debug identifiers.
help Print this message or the help of the given subcommand(s)
upload Upload debugging information files.

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
```
$ sentry-cli debug-files
? failed
sentry-cli[..]-debug-files
Locate, analyze or upload debug information files.

USAGE:
sentry-cli[..] debug-files [OPTIONS] <SUBCOMMAND>

OPTIONS:
--auth-token <AUTH_TOKEN> Use the given Sentry auth token.
-h, --help Print help information
--log-level <LOG_LEVEL> Set the log output verbosity. [possible values: trace, debug,
info, warn, error]
--quiet Do not print any output while preserving correct exit code.
This flag is currently implemented only for selected
subcommands. [aliases: silent]

SUBCOMMANDS:
bundle-sources Create a source bundle for a given debug information file
check Check the debug info file at a given path.
find Locate debug information files for given debug identifiers.
help Print this message or the help of the given subcommand(s)
upload Upload debugging information files.

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
```
$ sentry-cli debug-files upload --help
? success
sentry-cli[..]-debug-files-upload
Upload debugging information files.

USAGE:
sentry-cli[..] debug-files upload [OPTIONS] [PATH]...

ARGS:
<PATH>... A path to search recursively for symbol files.

OPTIONS:
--auth-token <AUTH_TOKEN> Use the given Sentry auth token.
--derived-data Search for debug symbols in Xcode's derived data.
--force-foreground Wait for the process to finish.
By default, the upload process will detach and continue in the
background when triggered from Xcode. When an error happens, a
dialog is shown. If this parameter is passed Xcode will wait
for the process to finish before the build finishes and output
will be shown in the Xcode build output.
-h, --help Print help information
--id <ID> Search for specific debug identifiers.
--include-sources Include sources from the local file system and upload them as
source bundles.
--info-plist <PATH> Optional path to the Info.plist.
We will try to find this automatically if run from Xcode.
Providing this information will associate the debug symbols
with a specific ITC application and build in Sentry. Note that
if you provide the plist explicitly it must already be
processed.
--log-level <LOG_LEVEL> Set the log output verbosity. [possible values: trace, debug,
info, warn, error]
--no-debug Do not scan for debugging information. This will usually
exclude debug companion files. They might still be uploaded, if
they contain additional processable information (see other
flags).
--no-reprocessing Do not trigger reprocessing after uploading.
--no-sources Do not scan for source information. This will usually exclude
source bundle files. They might still be uploaded, if they
contain additional processable information (see other flags).
--no-unwind Do not scan for stack unwinding information. Specify this flag
for builds with disabled FPO, or when stackwalking occurs on
the device. This usually excludes executables and dynamic
libraries. They might still be uploaded, if they contain
additional processable information (see other flags).
--no-upload Disable the actual upload.
This runs all steps for the processing but does not trigger the
upload (this also automatically disables reprocessing). This
is useful if you just want to verify the setup or skip the
upload in tests.
--no-zips Do not search in ZIP files.
-o, --org <ORG> The organization slug
-p, --project <PROJECT> The project slug.
--quiet Do not print any output while preserving correct exit code.
This flag is currently implemented only for selected
subcommands. [aliases: silent]
--require-all Errors if not all identifiers specified with --id could be
found.
--symbol-maps <PATH> Optional path to BCSymbolMap files which are used to resolve
hidden symbols in dSYM files downloaded from iTunes Connect.
This requires the dsymutil tool to be available. This should
not be used when using the App Store Connect integration, the
.bcsymbolmap files needed for the integration are uploaded
without this option if they are found in the PATH searched for
symbol files.
-t, --type <TYPE> Only consider debug information files of the given type. By
default, all types are considered. [possible values: dsym, elf,
breakpad, pdb, pe, sourcebundle, bcsymbolmap]
--wait Wait for the server to fully process uploaded files. Errors can
only be displayed if --wait is specified, but this will
significantly slow down the upload process.

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
```
$ sentry-cli debug-files upload tests/integration/_fixtures/elf-Linux-ARMv7-ls --no-reprocessing
? success
> Found 1 debug information file
> Prepared debug information file for upload
> Nothing to upload, all files are on the server
> skipped reprocessing

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```
$ sentry-cli debug-files upload tests/integration/_fixtures/elf-Linux-ARMv7-ls --no-upload
? success
> skipping upload.

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```
$ sentry-cli debug-files upload tests/integration/_fixtures/elf-Linux-ARMv7-ls
? success
> Found 1 debug information file
> Prepared debug information file for upload
> Nothing to upload, all files are on the server

```
27 changes: 27 additions & 0 deletions tests/integration/_cases/deploys/deploys-help.trycmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
```
$ sentry-cli deploys --help
? success
sentry-cli[..]-deploys
Manage deployments for Sentry releases.

USAGE:
sentry-cli[..] deploys [OPTIONS] <SUBCOMMAND>

OPTIONS:
--auth-token <AUTH_TOKEN> Use the given Sentry auth token.
-h, --help Print help information
--log-level <LOG_LEVEL> Set the log output verbosity. [possible values: trace, debug,
info, warn, error]
-o, --org <ORG> The organization slug
-p, --project <PROJECT> The project slug.
--quiet Do not print any output while preserving correct exit code.
This flag is currently implemented only for selected
subcommands. [aliases: silent]
-r, --release <RELEASE> The release slug.

SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
list List all deployments of a release.
new Creates a new release deployment.

```
Loading