Skip to content

Commit

Permalink
[app_dart] Refactor server to run locally (flutter#3364)
Browse files Browse the repository at this point in the history
Fixes flutter/flutter#129651

* There's various issues with running the appengine context locally, and I seem to lack permissions
* This refactors most of the routing logic into lib, which verifies there's no breakages in this block of code
  • Loading branch information
Casey Hillers authored Jan 3, 2024
1 parent f6a3c6c commit ce8e4c1
Show file tree
Hide file tree
Showing 11 changed files with 499 additions and 359 deletions.
14 changes: 2 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,14 @@ All the commands in this section assume that you are in the

### Running a local dev server

**This is for legacy users who were granted old security keys. Due to overground, this is no longer supported.**

```sh
$ export GOOGLE_CLOUD_PROJECT=flutter-dashboard-dev # or flutter-dashboard for prod data
$ export GCLOUD_KEY=#your_secret # Required for reading/writing from Google Cloud
$ export COCOON_USE_IN_MEMORY_CACHE=true # Use an in memory cache locally instead of redis to prevent corruption
$ dart bin/server.dart
dart bin/local_server.dart
```

This will output `Serving requests at 0.0.0.0:8080` indicating the server is working.

New requests will be logged to the console.

To develop and test some features, you need to have a local service
account(key.json) with access to the project you will be connecting to.

If you work for Google you can use the key with flutter-dashboard project
via [internal doc](https://g3doc.corp.google.com/company/teams/flutter/infrastructure/cocoon/local_development.md?cl=head#test-with-flutter-dashboard-dev-project).

### Deploying a test version on Google Cloud

To run live tests, build the app, and provide instructions for deploying to
Expand Down
2 changes: 1 addition & 1 deletion app_dart/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ RUN dart pub get

# Start server.
EXPOSE 8080
CMD ["/usr/lib/dart/bin/dart", "/app/bin/server.dart"]
CMD ["/usr/lib/dart/bin/dart", "/app/bin/gae_server.dart"]
14 changes: 2 additions & 12 deletions app_dart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This folder contains a Dart based backend for Cocoon.
and authenticate yourself by running:

```sh
gcloud auth login
gcloud auth application-default login
gcloud init
```
* [Install Flutter](https://flutter.dev/docs/get-started/install )
Expand Down Expand Up @@ -82,20 +82,10 @@ $ gcloud datastore indexes create index.yaml

#### Using physical machine

* Setting up the environment

```sh
export COCOON_USE_IN_MEMORY_CACHE=true
```

This environment is needed as you don't have access to the remote redis
instance during local development.

* Starting server

```sh
export COCOON_USE_IN_MEMORY_CACHE=true
dart bin/server.dart
dart bin/local_server.dart
```

If you see Serving requests at 0.0.0.0:8080 the dev server is working.
Expand Down
78 changes: 78 additions & 0 deletions app_dart/bin/gae_server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2019 The Flutter 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';

import 'package:appengine/appengine.dart';
import 'package:cocoon_service/cocoon_service.dart';
import 'package:cocoon_service/server.dart';
import 'package:cocoon_service/src/service/commit_service.dart';
import 'package:gcloud/db.dart';

Future<void> main() async {
await withAppEngineServices(() async {
useLoggingPackageAdaptor();

final CacheService cache = CacheService(inMemory: false);
final Config config = Config(dbService, cache);
final AuthenticationProvider authProvider = AuthenticationProvider(config: config);
final AuthenticationProvider swarmingAuthProvider = SwarmingAuthenticationProvider(config: config);
final BuildBucketClient buildBucketClient = BuildBucketClient(
accessTokenService: AccessTokenService.defaultProvider(config),
);

/// LUCI service class to communicate with buildBucket service.
final LuciBuildService luciBuildService = LuciBuildService(
config: config,
cache: cache,
buildBucketClient: buildBucketClient,
pubsub: const PubSub(),
);

/// Github checks api service used to provide luci test execution status on the Github UI.
final GithubChecksService githubChecksService = GithubChecksService(
config,
);

// Gerrit service class to communicate with GoB.
final GerritService gerritService = GerritService(config: config);

/// Cocoon scheduler service to manage validating commits in presubmit and postsubmit.
final Scheduler scheduler = Scheduler(
cache: cache,
config: config,
githubChecksService: githubChecksService,
luciBuildService: luciBuildService,
);

final BranchService branchService = BranchService(
config: config,
gerritService: gerritService,
);

final CommitService commitService = CommitService(config: config);

final Server server = createServer(
config: config,
cache: cache,
authProvider: authProvider,
branchService: branchService,
buildBucketClient: buildBucketClient,
gerritService: gerritService,
scheduler: scheduler,
luciBuildService: luciBuildService,
githubChecksService: githubChecksService,
commitService: commitService,
swarmingAuthProvider: swarmingAuthProvider,
);

return runAppEngine(
server,
onAcceptingConnections: (InternetAddress address, int port) {
final String host = address.isLoopback ? 'localhost' : address.host;
print('Serving requests at http://$host:$port/');
},
);
});
}
84 changes: 84 additions & 0 deletions app_dart/bin/local_server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2019 The Flutter 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';

import 'package:appengine/appengine.dart';
import 'package:cocoon_service/cocoon_service.dart';
import 'package:cocoon_service/server.dart';
import 'package:cocoon_service/src/model/appengine/cocoon_config.dart';
import 'package:cocoon_service/src/service/commit_service.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:gcloud/db.dart';

import '../test/src/datastore/fake_datastore.dart';

Future<void> main() async {
final CacheService cache = CacheService(inMemory: false);
final DatastoreDB dbService = FakeDatastoreDB();
final DatastoreService datastoreService = DatastoreService(dbService, defaultMaxEntityGroups);
await datastoreService.insert(<CocoonConfig>[
CocoonConfig.fake(dbService.emptyKey.append(CocoonConfig, id: 'WebhookKey'), 'fake-secret'),
CocoonConfig.fake(dbService.emptyKey.append(CocoonConfig, id: 'FrobWebhookKey'), 'fake-secret'),
]);
final Config config = Config(dbService, cache);
final AuthenticationProvider authProvider = AuthenticationProvider(config: config);
final AuthenticationProvider swarmingAuthProvider = SwarmingAuthenticationProvider(config: config);
final BuildBucketClient buildBucketClient = BuildBucketClient(
accessTokenService: AccessTokenService.defaultProvider(config),
);

/// LUCI service class to communicate with buildBucket service.
final LuciBuildService luciBuildService = LuciBuildService(
config: config,
cache: cache,
buildBucketClient: buildBucketClient,
pubsub: const PubSub(),
);

/// Github checks api service used to provide luci test execution status on the Github UI.
final GithubChecksService githubChecksService = GithubChecksService(
config,
);

// Gerrit service class to communicate with GoB.
final GerritService gerritService = GerritService(config: config);

/// Cocoon scheduler service to manage validating commits in presubmit and postsubmit.
final Scheduler scheduler = Scheduler(
cache: cache,
config: config,
githubChecksService: githubChecksService,
luciBuildService: luciBuildService,
);

final BranchService branchService = BranchService(
config: config,
gerritService: gerritService,
);

final CommitService commitService = CommitService(config: config);

final Server server = createServer(
config: config,
cache: cache,
authProvider: authProvider,
branchService: branchService,
buildBucketClient: buildBucketClient,
gerritService: gerritService,
scheduler: scheduler,
luciBuildService: luciBuildService,
githubChecksService: githubChecksService,
commitService: commitService,
swarmingAuthProvider: swarmingAuthProvider,
);

return runAppEngine(
server,
onAcceptingConnections: (InternetAddress address, int port) {
final String host = address.isLoopback ? 'localhost' : address.host;
print('Serving requests at http://$host:$port/');
},
);
}
Loading

0 comments on commit ce8e4c1

Please sign in to comment.