blob: aa75dae5c0f5c762d47dc15c920156dc3e0fa812 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library gcloud.test.common_e2e;
import 'dart:async';
import 'dart:io';
import 'package:unittest/unittest.dart';
import 'package:googleapis_auth/auth_io.dart' as auth;
import 'package:http/http.dart' as http;
import 'common.dart';
const PROJECT = 'test-project';
// Environment variables for specifying the cloud project to use and the
// location of the service account key for that project.
const String PROJECT_ENV = 'GCLOUD_E2E_TEST_PROJECT';
const String SERVICE_KEY_LOCATION_ENV = 'GCLOUD_E2E_TEST_KEY';
// Default project and service key location used when running on the package
// bot.
const String DEFAULT_PROJECT = 'dart-gcloud-e2e';
const String DEFAULT_KEY_LOCATION =
'gs://dart-archive-internal/keys/dart-gcloud-e2e.json';
// Used for storage e2e tests:
//
// List operations on buckets are eventually consistent. Bucket deletion is
// also dependent on list operations to ensure the bucket is empty before
// deletion.
//
// So this can make tests flaky. The following delay is introduced as an
// attempt to account for that.
const STORAGE_LIST_DELAY = const Duration(seconds: 5);
bool onBot() {
// When running on the package-bot the current user is chrome-bot.
var envName;
if (Platform.isWindows) {
envName = 'USERNAME';
} else {
envName = 'USER';
}
return Platform.environment[envName] == 'chrome-bot';
}
// Get the service key from the specified location.
Future<String> serviceKeyJson(String serviceKeyLocation) {
if (!serviceKeyLocation.startsWith('gs://')) {
throw new Exception('Service key location must start with gs://');
}
var future;
if (onBot()) {
future = Process.run(
'python', ['third_party/gsutil/gsutil', 'cat', serviceKeyLocation],
runInShell: true);
} else {
var gsutil = Platform.isWindows ? 'gsutil.cmd' : 'gsutil';
future = Process.run(gsutil, ['cat', serviceKeyLocation]);
}
return future.then((result) {
if (result.exitCode != 0) {
throw new Exception('Failed to run gsutil, ${result.stderr}');
}
return result.stdout;
});
}
typedef Future AuthCallback(String project, http.Client client);
Future withAuthClient(List<String> scopes,
AuthCallback callback,
{bool trace: false}) {
String project = Platform.environment[PROJECT_ENV];
String serviceKeyLocation = Platform.environment[SERVICE_KEY_LOCATION_ENV];
if (!onBot() && (project == null || serviceKeyLocation == null)) {
throw new StateError(
'Envoronment variables $PROJECT_ENV and $SERVICE_KEY_LOCATION_ENV '
'required when not running on the package bot');
}
project = project != null ? project : DEFAULT_PROJECT;
serviceKeyLocation =
serviceKeyLocation != null ? serviceKeyLocation : DEFAULT_KEY_LOCATION;
return serviceKeyJson(serviceKeyLocation).then((keyJson) {
var creds = new auth.ServiceAccountCredentials.fromJson(keyJson);
return auth.clientViaServiceAccount(creds, scopes).then((client) {
if (trace) client = new TraceClient(client);
return callback(project, client).whenComplete(() => client.close());
});
});
}
Future runE2EUnittest(Function callback) {
var config = new E2EConfiguration();
unittestConfiguration = config;
callback();
return config.done;
}
class E2EConfiguration extends SimpleConfiguration {
final Completer _completer = new Completer();
Future get done => _completer.future;
onDone(success) {
new Future.sync(() {
super.onDone(success);
}).then((_) => _completer.complete(_))
.catchError((error, stack) => _completer.completeError(error, stack));
}
}