blob: df8e74865105895922c50183c103d2fd75c9e91d [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Directory, File, FileSystemException, Platform;
/// Supports dumping a trace of data received in various facades as
/// timestamped files into a directory in the filesystem.
class Dump {
/// Environment variable for the directory to dump images in. If this var is
/// present, screenshots can optionally be dumped in there.
static const _dumpDirectoryEnvVar = 'FUCHSIA_TEST_OUTDIR';
/// Directory to dump screenshots taken. This may be null if it's neither
/// passed nor set in the environment, in which case no dumps are written.
final String _dumpDirectory;
/// Not supplying a dumpDirectory parameter, or supplying null, or
/// supplying an empty string, means the dump directory specification
/// is taken from the environment. If that's not specified, or is
/// specified to be the empty string, dump is disabled.
///
/// If dump is not disabled, then the dump directory specification
/// must be valid in that it designates a directory that exists by an
/// absolute path name. It's asserted below; invalid specification
/// causes to crash.
///
/// The dump directory must be given by an absolute path. A relative
/// path is ambiguous, because it's not clear relative to what. It
/// would normally be the current working directory, but other
/// relative paths in this library are resolved relative to the
/// location of the binary.
///
/// To easily supply a path relative to the current working directory
/// on the command line, use $(pwd).
Dump([String dumpDirectory])
: _dumpDirectory = _notEmptyString(dumpDirectory)
? dumpDirectory
: Platform.environment[_dumpDirectoryEnvVar] {
if (_hasDumpDirectory) {
// See explanation above. Relative path would be ambiguous.
if (!_dumpDirectory.startsWith('/')) {
throw ArgumentError.value(_dumpDirectory, 'Must be absolute path');
}
// Has to be sync because this is a constructor.
if (!Directory(_dumpDirectory).existsSync()) {
throw FileSystemException(
'Not found or not a directory', _dumpDirectory);
}
}
}
/// Writes the bytes to the dump directory under a timestamp, the
/// given topic name and the given file type suffix. Does nothing if
/// no dump directory is configured.
void writeAsBytes(String name, String suffix, List<int> bytes) {
if (_hasDumpDirectory) {
final filename = '${DateTime.now().toIso8601String()}-$name.$suffix';
// Writes to the file asynchronously so the test can continue.
File([_dumpDirectory, filename].join('/')).writeAsBytes(bytes);
}
}
bool get _hasDumpDirectory => _notEmptyString(_dumpDirectory);
static bool _notEmptyString(final String value) =>
value != null && value.isNotEmpty;
}