devtools_launcher_test.dart 10.8 KB
Newer Older
1 2 3 4
// Copyright 2014 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.

5 6
// @dart = 2.8

7 8
import 'dart:async';

9
import 'package:flutter_tools/src/base/file_system.dart';
10 11
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
12
import 'package:flutter_tools/src/base/platform.dart';
13
import 'package:flutter_tools/src/devtools_launcher.dart';
14 15
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/persistent_tool_state.dart';
16 17 18 19
import 'package:flutter_tools/src/resident_runner.dart';

import '../src/common.dart';
import '../src/context.dart';
20
import '../src/fake_http_client.dart';
21 22

void main() {
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
  BufferLogger logger;
  FakePlatform platform;
  PersistentToolState persistentToolState;

  setUp(() {
    logger = BufferLogger.test();
    platform = FakePlatform(environment: <String, String>{});

    final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('devtools_launcher_test');
    persistentToolState = PersistentToolState.test(
      directory: tempDir,
      logger: logger,
    );
  });

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
   testWithoutContext('DevtoolsLauncher does not launch devtools if unable to reach pub.dev', () async {
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
      platform: platform,
      persistentToolState: persistentToolState,
      httpClient: FakeHttpClient.list(<FakeRequest>[
        FakeRequest(
          Uri.https('pub.dev', ''),
          method: HttpMethod.head,
          response: const FakeResponse(statusCode: HttpStatus.internalServerError),
        ),
      ]),
      processManager: FakeProcessManager.list(<FakeCommand>[]),
    );

    final DevToolsServerAddress address = await launcher.serve();
    expect(address, isNull);
  });

  testWithoutContext('DevtoolsLauncher pings PUB_HOSTED_URL instead of pub.dev for online check', () async {
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
      platform: FakePlatform(environment: <String, String>{
        'PUB_HOSTED_URL': 'https://pub2.dev'
      }),
      persistentToolState: persistentToolState,
      httpClient: FakeHttpClient.list(<FakeRequest>[
        FakeRequest(
          Uri.https('pub2.dev', ''),
          method: HttpMethod.head,
          response: const FakeResponse(statusCode: HttpStatus.internalServerError),
        ),
      ]),
      processManager: FakeProcessManager.list(<FakeCommand>[]),
    );

    final DevToolsServerAddress address = await launcher.serve();
    expect(address, isNull);
  });

  testWithoutContext('DevtoolsLauncher handles an invalid PUB_HOSTED_URL', () async {
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
      platform: FakePlatform(environment: <String, String>{
        'PUB_HOSTED_URL': r'not_an_http_url'
      }),
      persistentToolState: persistentToolState,
      httpClient: FakeHttpClient.list(<FakeRequest>[]),
      processManager: FakeProcessManager.list(<FakeCommand>[]),
    );

    final DevToolsServerAddress address = await launcher.serve();
    expect(address, isNull);
    expect(logger.errorText, contains('PUB_HOSTED_URL was set to an invalid URL: "not_an_http_url".'));
  });

97 98 99 100
  testWithoutContext('DevtoolsLauncher launches DevTools through pub and saves the URI', () async {
    final Completer<void> completer = Completer<void>();
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
101 102 103
      logger: logger,
      platform: platform,
      persistentToolState: persistentToolState,
104
      httpClient: FakeHttpClient.any(),
105 106 107 108 109 110 111 112 113 114
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'activate',
            'devtools',
          ],
          stdout: 'Activated DevTools 0.9.5',
        ),
115 116 117 118 119 120 121 122
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
123 124 125 126 127 128
        FakeCommand(
          command: const <String>[
            'pub',
            'global',
            'run',
            'devtools',
129
            '--no-launch-browser',
130 131 132 133 134 135 136 137 138 139 140 141
          ],
          stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
          completer: completer,
        ),
      ]),
    );

    final DevToolsServerAddress address = await launcher.serve();
    expect(address.host, '127.0.0.1');
    expect(address.port, 9100);
  });

142 143 144 145
  testWithoutContext('DevtoolsLauncher launches DevTools in browser', () async {
    final Completer<void> completer = Completer<void>();
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
146 147 148
      logger: logger,
      platform: platform,
      persistentToolState: persistentToolState,
149
      httpClient: FakeHttpClient.any(),
150 151 152 153 154 155 156 157 158 159
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'activate',
            'devtools',
          ],
          stdout: 'Activated DevTools 0.9.5',
        ),
160 161 162 163 164 165 166 167
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
168 169 170 171 172 173
        FakeCommand(
          command: const <String>[
            'pub',
            'global',
            'run',
            'devtools',
174
            '--no-launch-browser',
175 176 177 178 179 180 181
          ],
          stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
          completer: completer,
        ),
      ]),
    );

182
    final DevToolsServerAddress address = await launcher.serve();
183 184 185 186
    expect(address.host, '127.0.0.1');
    expect(address.port, 9100);
  });

187 188 189 190 191 192 193
  testWithoutContext('DevtoolsLauncher does not launch a new DevTools instance if one is already active', () async {
    final Completer<void> completer = Completer<void>();
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
      platform: platform,
      persistentToolState: persistentToolState,
194
      httpClient: FakeHttpClient.any(),
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'activate',
            'devtools',
          ],
          stdout: 'Activated DevTools 0.9.5',
        ),
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
        FakeCommand(
          command: const <String>[
            'pub',
            'global',
            'run',
            'devtools',
            '--no-launch-browser',
          ],
          stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
          completer: completer,
        ),
      ]),
    );

    DevToolsServerAddress address = await launcher.serve();
    expect(address.host, '127.0.0.1');
    expect(address.port, 9100);

    // Call `serve` again and verify that the already running server is returned.
    address = await launcher.serve();
    expect(address.host, '127.0.0.1');
    expect(address.port, 9100);
  });

237 238 239 240 241 242 243
  testWithoutContext('DevtoolsLauncher does not activate DevTools if it was recently activated', () async {
    persistentToolState.lastDevToolsActivationTime = DateTime.now();
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
      platform: platform,
      persistentToolState: persistentToolState,
244
      httpClient: FakeHttpClient.any(),
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'run',
            'devtools',
            '--no-launch-browser',
          ],
          stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
        ),
      ]),
    );

    await launcher.serve();
  });

270 271 272 273
  testWithoutContext('DevtoolsLauncher prints error if exception is thrown during activate', () async {
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
274 275
      platform: platform,
      persistentToolState: persistentToolState,
276
      httpClient: FakeHttpClient.any(),
277 278 279 280 281 282 283 284 285 286 287
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'activate',
            'devtools',
          ],
          stderr: 'Error - could not activate devtools',
          exitCode: 1,
        ),
288 289 290 291 292 293 294 295
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
296 297 298 299 300 301 302 303 304 305
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'run',
            'devtools',
            '--no-launch-browser',
            '--vm-uri=http://127.0.0.1:1234/abcdefg',
          ],
          exception: ProcessException('pub', <String>[]),
306 307 308 309 310 311 312 313 314 315 316 317 318
        )
      ]),
    );

    await launcher.launch(Uri.parse('http://127.0.0.1:1234/abcdefg'));

    expect(logger.errorText, contains('Error running `pub global activate devtools`:\nError - could not activate devtools'));
  });

  testWithoutContext('DevtoolsLauncher prints error if exception is thrown during launch', () async {
    final DevtoolsLauncher launcher = DevtoolsServerLauncher(
      pubExecutable: 'pub',
      logger: logger,
319 320
      platform: platform,
      persistentToolState: persistentToolState,
321
      httpClient: FakeHttpClient.any(),
322 323 324 325 326 327 328 329 330 331
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'activate',
            'devtools',
          ],
          stdout: 'Activated DevTools 0.9.5',
        ),
332 333 334 335 336 337 338 339
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'list',
          ],
          stdout: 'devtools 0.9.6',
        ),
340 341 342 343 344 345 346 347 348 349
        const FakeCommand(
          command: <String>[
            'pub',
            'global',
            'run',
            'devtools',
            '--no-launch-browser',
            '--vm-uri=http://127.0.0.1:1234/abcdefg',
          ],
          exception: ProcessException('pub', <String>[]),
350 351 352 353 354 355 356 357 358
        )
      ]),
    );

    await launcher.launch(Uri.parse('http://127.0.0.1:1234/abcdefg'));

    expect(logger.errorText, contains('Failed to launch DevTools: ProcessException'));
  });
}