From d8ba7cb5d7a444bd55b6147c6c06ec8bfb973560 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 27 Aug 2019 13:16:09 -0700 Subject: [PATCH 1/4] Sort agent IDs naturally --- app_dart/lib/src/request_handlers/get_status.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app_dart/lib/src/request_handlers/get_status.dart b/app_dart/lib/src/request_handlers/get_status.dart index ab3825d37..5c27520d7 100644 --- a/app_dart/lib/src/request_handlers/get_status.dart +++ b/app_dart/lib/src/request_handlers/get_status.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:collection/collection.dart'; import 'package:gcloud/db.dart'; import 'package:meta/meta.dart'; @@ -37,6 +38,7 @@ class GetStatus extends RequestHandler { final DatastoreService datastore = datastoreProvider(); final Query agentQuery = datastore.db.query()..order('agentId'); final List agents = await agentQuery.run().where(_isVisible).toList(); + agents.sort((Agent a, Agent b) => compareAsciiLowerCaseNatural(a.agentId, b.agentId)); return Body.forJson({ 'Statuses': statuses, From ab5a82e0be5e8393d28884c8243fbe5e6f9678b4 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 27 Aug 2019 13:54:51 -0700 Subject: [PATCH 2/4] Add collection to pubspec --- app_dart/pubspec.lock | 2 +- app_dart/pubspec.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app_dart/pubspec.lock b/app_dart/pubspec.lock index 91a0147a3..e72ee80e1 100644 --- a/app_dart/pubspec.lock +++ b/app_dart/pubspec.lock @@ -121,7 +121,7 @@ packages: source: hosted version: "3.2.0" collection: - dependency: transitive + dependency: "direct main" description: name: collection url: "https://pub.dartlang.org" diff --git a/app_dart/pubspec.yaml b/app_dart/pubspec.yaml index 873ede793..50156b2b1 100644 --- a/app_dart/pubspec.yaml +++ b/app_dart/pubspec.yaml @@ -12,6 +12,7 @@ environment: dependencies: appengine: ^0.10.0 dbcrypt: ^1.0.0 + collection: ^1.14.12 crypto: ^2.0.6 fixnum: ^0.10.9 gcloud: ^0.6.3 From 8445d8241d049573a949b4940a77c3f306d411af Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 27 Aug 2019 17:47:57 -0700 Subject: [PATCH 3/4] Add test --- app_dart/lib/src/model/appengine/agent.dart | 2 +- .../request_handlers/get_status_test.dart | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 app_dart/test/request_handlers/get_status_test.dart diff --git a/app_dart/lib/src/model/appengine/agent.dart b/app_dart/lib/src/model/appengine/agent.dart index c998799f9..5bea60ae6 100644 --- a/app_dart/lib/src/model/appengine/agent.dart +++ b/app_dart/lib/src/model/appengine/agent.dart @@ -19,7 +19,7 @@ class Agent extends Model { this.agentId, this.healthCheckTimestamp, this.isHealthy, - this.isHidden, + this.isHidden = false, this.capabilities, this.healthDetails, this.authToken, diff --git a/app_dart/test/request_handlers/get_status_test.dart b/app_dart/test/request_handlers/get_status_test.dart new file mode 100644 index 000000000..0228a1feb --- /dev/null +++ b/app_dart/test/request_handlers/get_status_test.dart @@ -0,0 +1,82 @@ +// Copyright 2019 The Chromium 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:convert'; +import 'dart:typed_data'; + +import 'package:cocoon_service/src/model/appengine/agent.dart'; +import 'package:cocoon_service/src/request_handlers/get_status.dart'; +import 'package:cocoon_service/src/request_handling/body.dart'; +import 'package:cocoon_service/src/service/build_status_provider.dart'; +import 'package:cocoon_service/src/service/datastore.dart'; +import 'package:test/test.dart'; + +import '../src/datastore/fake_cocoon_config.dart'; +import '../src/datastore/fake_datastore.dart'; +import '../src/service/fake_build_status_provider.dart'; + +void main() { + group('GetStatus', () { + FakeConfig config; + FakeDatastoreDB db; + FakeBuildStatusProvider buildStatusProvider; + GetStatus handler; + + Future> decodeHandlerBody() async { + final Body body = await handler.get(); + final List bytes = await body.serialize().toList(); + final String decodedBody = + utf8.decode(bytes.expand((Uint8List bytes) => bytes).toList()); + return json.decode(decodedBody); + } + + setUp(() { + config = FakeConfig(); + buildStatusProvider = + FakeBuildStatusProvider(commitStatuses: []); + db = FakeDatastoreDB(); + handler = GetStatus( + config, + datastoreProvider: () => DatastoreService(db: db), + buildStatusProvider: buildStatusProvider, + ); + }); + + test('no statuses or agents', () async { + final Map result = await decodeHandlerBody(); + expect(result['Statuses'], isEmpty); + expect(result['AgentStatuses'], isEmpty); + }); + + test('reports agents', () async { + final Agent linux1 = Agent(agentId: 'linux1'); + final Agent mac1 = Agent(agentId: 'mac1'); + final Agent linux100 = Agent(agentId: 'linux100'); + final Agent linux5 = Agent(agentId: 'linux5'); + final Agent windows1 = Agent(agentId: 'windows1', isHidden: true); + + final List reportedAgents = [ + linux1, + mac1, + linux100, + linux5, + windows1, + ]; + + db.addOnQuery((Iterable agents) => reportedAgents); + final Map result = await decodeHandlerBody(); + + expect(result['Statuses'], isEmpty); + + final List expectedOrderedAgents = [ + linux1.toJson(), + linux5.toJson(), + linux100.toJson(), + mac1.toJson(), + ]; + + expect(result['AgentStatuses'], equals(expectedOrderedAgents)); + }); + }); +} From 02f13160d9225c436723843393fda4c9bc002f8d Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 28 Aug 2019 15:31:33 -0700 Subject: [PATCH 4/4] Review edits --- app_dart/test/request_handlers/get_status_test.dart | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app_dart/test/request_handlers/get_status_test.dart b/app_dart/test/request_handlers/get_status_test.dart index 0228a1feb..bcb1794db 100644 --- a/app_dart/test/request_handlers/get_status_test.dart +++ b/app_dart/test/request_handlers/get_status_test.dart @@ -23,18 +23,14 @@ void main() { FakeBuildStatusProvider buildStatusProvider; GetStatus handler; - Future> decodeHandlerBody() async { + Future decodeHandlerBody() async { final Body body = await handler.get(); - final List bytes = await body.serialize().toList(); - final String decodedBody = - utf8.decode(bytes.expand((Uint8List bytes) => bytes).toList()); - return json.decode(decodedBody); + return utf8.decoder.bind(body.serialize()).transform(json.decoder).single; } setUp(() { config = FakeConfig(); - buildStatusProvider = - FakeBuildStatusProvider(commitStatuses: []); + buildStatusProvider = FakeBuildStatusProvider(commitStatuses: []); db = FakeDatastoreDB(); handler = GetStatus( config,