Unverified Commit ce3ce20b authored by Casey Hillers's avatar Casey Hillers Committed by GitHub

[devicelab] Upload git branch (#68541)

parent d2314ecf
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert' show json;
import 'dart:convert' show Encoding, json;
import 'dart:io';
import 'package:file/file.dart';
......@@ -15,6 +15,17 @@ import 'package:meta/meta.dart';
import 'task_result.dart';
import 'utils.dart';
typedef ProcessRunSync = ProcessResult Function(
String,
List<String>, {
Map<String, String> environment,
bool includeParentEnvironment,
bool runInShell,
Encoding stderrEncoding,
Encoding stdoutEncoding,
String workingDirectory,
});
/// Class for test runner to interact with Flutter's infrastructure service, Cocoon.
///
/// Cocoon assigns bots to run these devicelab tasks on real devices.
......@@ -24,29 +35,43 @@ class Cocoon {
String serviceAccountTokenPath,
@visibleForTesting Client httpClient,
@visibleForTesting FileSystem filesystem,
@visibleForTesting this.processRunSync = Process.runSync,
}) : _httpClient = AuthenticatedCocoonClient(serviceAccountTokenPath, httpClient: httpClient, filesystem: filesystem);
/// Client to make http requests to Cocoon.
final AuthenticatedCocoonClient _httpClient;
final ProcessRunSync processRunSync;
/// Url used to send results to.
static const String baseCocoonApiUrl = 'https://flutter-dashboard.appspot.com/api';
static final Logger logger = Logger('CocoonClient');
String get commitBranch => _commitBranch ?? _readCommitBranch();
String _commitBranch;
String get commitSha => _commitSha ?? _readCommitSha();
String _commitSha;
/// Parse the local repo for the current running commit.
String _readCommitSha() {
final ProcessResult result = Process.runSync('git', <String>['rev-parse', 'HEAD']);
final ProcessResult result = processRunSync('git', <String>['rev-parse', 'HEAD']);
if (result.exitCode != 0) {
throw CocoonException(result.stderr as String);
}
return _commitSha = result.stdout as String;
}
/// Parse the local repo for the current running branch.
String _readCommitBranch() {
final ProcessResult result = processRunSync('git', <String>['rev-parse', '--abbrev-ref', 'HEAD']);
if (result.exitCode != 0) {
throw Exception(result.stderr);
throw CocoonException(result.stderr as String);
}
_commitSha = result.stdout as String;
return _commitSha;
return _commitBranch = result.stdout as String;
}
/// Send [TaskResult] to Cocoon.
......@@ -58,6 +83,7 @@ class Cocoon {
});
final Map<String, dynamic> status = <String, dynamic>{
'CommitBranch': commitBranch,
'CommitSha': commitSha,
'TaskName': taskName,
'NewStatus': result.succeeded ? 'Succeeded' : 'Failed',
......@@ -150,3 +176,13 @@ class AuthenticatedCocoonClient extends BaseClient {
return response;
}
}
class CocoonException implements Exception {
CocoonException(this.message) : assert(message != null);
/// The message to show to the issuer to explain the error.
final String message;
@override
String toString() => 'CocoonException: $message';
}
......@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'dart:io';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:http/http.dart';
......@@ -13,21 +16,72 @@ import 'package:flutter_devicelab/framework/task_result.dart';
import 'common.dart';
void main() {
group('Cocoon', () {
ProcessResult _processResult;
ProcessResult runSyncStub(String executable, List<String> args,
{Map<String, String> environment,
bool includeParentEnvironment,
bool runInShell,
Encoding stderrEncoding,
Encoding stdoutEncoding,
String workingDirectory}) =>
_processResult;
// Expected test values.
const String commitBranch = 'flutter-1.23-candidate.18';
const String commitSha = 'a4952838bf288a81d8ea11edfd4b4cd649fa94cc';
const String serviceAccountTokenPath = 'test_account_file';
const String serviceAccountToken = 'test_token';
group('Cocoon', () {
Client mockClient;
Cocoon cocoon;
FileSystem fs;
setUp(() {
fs = MemoryFileSystem();
mockClient = MockClient((Request request) async => Response('{}', 200));
final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
serviceAccountFile.writeAsStringSync(serviceAccountToken);
});
test('returns expected commit branch', () {
_processResult = ProcessResult(1, 0, commitBranch, '');
cocoon = Cocoon(
serviceAccountTokenPath: serviceAccountTokenPath,
filesystem: fs,
httpClient: mockClient,
processRunSync: runSyncStub,
);
expect(cocoon.commitBranch, commitBranch);
});
test('returns expected commit sha', () {
_processResult = ProcessResult(1, 0, commitSha, '');
cocoon = Cocoon(
serviceAccountTokenPath: serviceAccountTokenPath,
filesystem: fs,
httpClient: mockClient,
processRunSync: runSyncStub,
);
expect(cocoon.commitSha, commitSha);
});
test('throws exception on git cli errors', () {
_processResult = ProcessResult(1, 1, '', '');
cocoon = Cocoon(
serviceAccountTokenPath: serviceAccountTokenPath,
filesystem: fs,
httpClient: mockClient,
processRunSync: runSyncStub,
);
expect(() => cocoon.commitBranch, throwsA(isA<CocoonException>()));
expect(() => cocoon.commitSha, throwsA(isA<CocoonException>()));
});
test('sends expected request from successful task', () async {
mockClient = MockClient((Request request) async => Response('{}', 200));
......@@ -57,26 +111,23 @@ void main() {
});
group('AuthenticatedCocoonClient', () {
const String serviceAccountPath = 'test_account_file';
const String serviceAccountToken = 'test_token';
FileSystem fs;
setUp(() {
fs = MemoryFileSystem();
final File serviceAccountFile = fs.file(serviceAccountPath)..createSync();
final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
serviceAccountFile.writeAsStringSync(serviceAccountToken);
});
test('reads token from service account file', () {
final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountPath, filesystem: fs);
final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountTokenPath, filesystem: fs);
expect(client.serviceAccountToken, serviceAccountToken);
});
test('reads token from service account file with whitespace', () {
final File serviceAccountFile = fs.file(serviceAccountPath)..createSync();
final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
serviceAccountFile.writeAsStringSync(serviceAccountToken + ' \n');
final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountPath, filesystem: fs);
final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountTokenPath, filesystem: fs);
expect(client.serviceAccountToken, serviceAccountToken);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment