precache_test.dart 14.7 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// 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
import 'package:flutter_tools/src/base/logger.dart';
8
import 'package:flutter_tools/src/base/platform.dart';
9 10
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/precache.dart';
11
import 'package:test/fake.dart';
12

13 14
import '../../src/common.dart';
import '../../src/context.dart';
15
import '../../src/fakes.dart';
16
import '../../src/test_flutter_command_runner.dart';
17 18

void main() {
19
  FakeCache cache;
20 21

  setUp(() {
22 23
    cache = FakeCache();
    cache.isUpToDateValue = false;
24
  });
25

26
  testUsingContext('precache should acquire lock', () async {
27 28 29 30 31 32 33
    final Platform platform = FakePlatform(environment: <String, String>{});
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      platform: platform,
      featureFlags: TestFeatureFlags(),
    );
34 35
    await createTestCommandRunner(command).run(const <String>['precache']);

36
    expect(cache.locked, true);
37 38 39
  });

  testUsingContext('precache should not re-entrantly acquire lock', () async {
40
    final Platform platform = FakePlatform(
41 42 43 44 45
      operatingSystem: 'windows',
      environment: <String, String>{
        'FLUTTER_ROOT': 'flutter',
        'FLUTTER_ALREADY_LOCKED': 'true',
      },
46 47 48 49 50 51 52 53 54
    );
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(),
      platform: platform,
    );
    await createTestCommandRunner(command).run(const <String>['precache']);

55
    expect(cache.locked, false);
56 57
  });

58
  testUsingContext('precache downloads web artifacts on dev branch when feature is enabled.', () async {
59 60 61 62 63 64
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      platform: FakePlatform(environment: <String, String>{}),
    );
65
    await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
66

67
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
68 69 70 71
      DevelopmentArtifact.universal,
      DevelopmentArtifact.web,
    }));
  });
72

73
  testUsingContext('precache does not download web artifacts on dev branch when feature is enabled.', () async {
74 75 76
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
77
      featureFlags: TestFeatureFlags(),
78 79
      platform: FakePlatform(environment: <String, String>{}),
    );
80
    await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
81

82
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
83 84 85
      DevelopmentArtifact.universal,
    }));
  });
86

87
  testUsingContext('precache downloads macOS artifacts on dev branch when macOS is enabled.', () async {
88 89 90 91 92 93
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(isMacOSEnabled: true),
      platform: FakePlatform(environment: <String, String>{}),
    );
94 95
    await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);

96
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
97 98 99 100 101 102
      DevelopmentArtifact.universal,
      DevelopmentArtifact.macOS,
    }));
  });

  testUsingContext('precache does not download macOS artifacts on dev branch when feature is enabled.', () async {
103 104 105
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
106
      featureFlags: TestFeatureFlags(),
107 108
      platform: FakePlatform(environment: <String, String>{}),
    );
109 110
    await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);

111
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
112 113 114 115 116
      DevelopmentArtifact.universal,
    }));
  });

  testUsingContext('precache downloads Windows artifacts on dev branch when feature is enabled.', () async {
117 118 119 120 121 122
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(isWindowsEnabled: true),
      platform: FakePlatform(environment: <String, String>{}),
    );
123 124
    await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);

125
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
126 127 128 129 130 131
      DevelopmentArtifact.universal,
      DevelopmentArtifact.windows,
    }));
  });

  testUsingContext('precache does not download Windows artifacts on dev branch when feature is enabled.', () async {
132 133 134
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
135
      featureFlags: TestFeatureFlags(),
136 137
      platform: FakePlatform(environment: <String, String>{}),
    );
138 139
    await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);

140
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
141 142 143 144 145
      DevelopmentArtifact.universal,
    }));
  });

  testUsingContext('precache downloads Linux artifacts on dev branch when feature is enabled.', () async {
146 147 148 149 150 151
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(isLinuxEnabled: true),
      platform: FakePlatform(environment: <String, String>{}),
    );
152 153
    await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);

154
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
155 156 157 158 159 160
      DevelopmentArtifact.universal,
      DevelopmentArtifact.linux,
    }));
  });

  testUsingContext('precache does not download Linux artifacts on dev branch when feature is enabled.', () async {
161 162 163
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
164
      featureFlags: TestFeatureFlags(),
165 166
      platform: FakePlatform(environment: <String, String>{}),
    );
167 168
    await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);

169
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
170 171 172 173
      DevelopmentArtifact.universal,
    }));
  });

174
  testUsingContext('precache exits if requesting mismatched artifacts.', () async {
175 176 177
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
178
      featureFlags: TestFeatureFlags(),
179 180
      platform: FakePlatform(environment: <String, String>{}),
    );
181 182 183 184 185 186 187

    expect(createTestCommandRunner(command).run(const <String>['precache',
      '--no-android',
      '--android_gen_snapshot',
    ]), throwsToolExit(message: '--android_gen_snapshot requires --android'));
  });

188
  testUsingContext('precache adds artifact flags to requested artifacts', () async {
189 190 191 192 193 194 195 196
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(
        isWebEnabled: true,
        isLinuxEnabled: true,
        isMacOSEnabled: true,
        isWindowsEnabled: true,
197
        isFuchsiaEnabled: true,
198 199 200
      ),
      platform: FakePlatform(environment: <String, String>{}),
    );
201 202 203 204 205 206 207 208 209 210 211 212 213
    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
        '--ios',
        '--android',
        '--web',
        '--macos',
        '--linux',
        '--windows',
        '--fuchsia',
        '--flutter_runner',
      ],
    );
214
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
215 216 217 218 219 220 221 222 223 224 225 226 227
      DevelopmentArtifact.universal,
      DevelopmentArtifact.iOS,
      DevelopmentArtifact.androidGenSnapshot,
      DevelopmentArtifact.androidMaven,
      DevelopmentArtifact.androidInternalBuild,
      DevelopmentArtifact.web,
      DevelopmentArtifact.macOS,
      DevelopmentArtifact.linux,
      DevelopmentArtifact.windows,
      DevelopmentArtifact.fuchsia,
      DevelopmentArtifact.flutterRunner,
    }));
  });
228

229
  testUsingContext('precache expands android artifacts when the android flag is used', () async {
230 231 232 233 234 235
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(),
      platform: FakePlatform(environment: <String, String>{}),
    );
236 237 238 239 240 241 242
    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
        '--no-ios',
        '--android',
      ],
    );
243
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
244 245 246 247 248 249
      DevelopmentArtifact.universal,
      DevelopmentArtifact.androidGenSnapshot,
      DevelopmentArtifact.androidMaven,
      DevelopmentArtifact.androidInternalBuild,
    }));
  });
250

251
  testUsingContext('precache adds artifact flags to requested android artifacts', () async {
252 253 254 255 256 257
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(),
      platform: FakePlatform(environment: <String, String>{}),
    );
258 259 260 261
    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
        '--no-ios',
262
        '--android',
263 264 265 266 267
        '--android_gen_snapshot',
        '--android_maven',
        '--android_internal_build',
      ],
    );
268
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
269 270 271 272 273 274 275
      DevelopmentArtifact.universal,
      DevelopmentArtifact.androidGenSnapshot,
      DevelopmentArtifact.androidMaven,
      DevelopmentArtifact.androidInternalBuild,
    }));
  });

276
  testUsingContext('precache downloads iOS and Android artifacts by default', () async {
277 278 279 280 281 282
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(),
      platform: FakePlatform(environment: <String, String>{}),
    );
283 284 285 286 287 288 289

    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
      ],
    );

290
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
291 292 293 294 295 296 297 298 299
      DevelopmentArtifact.universal,
      DevelopmentArtifact.iOS,
      DevelopmentArtifact.androidGenSnapshot,
      DevelopmentArtifact.androidMaven,
      DevelopmentArtifact.androidInternalBuild,
    }));
  });

  testUsingContext('precache --all-platforms gets all artifacts', () async {
300 301 302 303 304 305 306 307
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(
        isWebEnabled: true,
        isLinuxEnabled: true,
        isMacOSEnabled: true,
        isWindowsEnabled: true,
308
        isFuchsiaEnabled: true,
309 310 311
      ),
      platform: FakePlatform(environment: <String, String>{}),
    );
312 313 314 315 316 317 318 319

    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
        '--all-platforms',
      ],
    );

320
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
      DevelopmentArtifact.universal,
      DevelopmentArtifact.iOS,
      DevelopmentArtifact.androidGenSnapshot,
      DevelopmentArtifact.androidMaven,
      DevelopmentArtifact.androidInternalBuild,
      DevelopmentArtifact.web,
      DevelopmentArtifact.macOS,
      DevelopmentArtifact.linux,
      DevelopmentArtifact.windows,
      DevelopmentArtifact.fuchsia,
      DevelopmentArtifact.flutterRunner,
    }));
  });

  testUsingContext('precache with default artifacts does not override platform filtering', () async {
336 337 338 339 340 341
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(),
      platform: FakePlatform(environment: <String, String>{}),
    );
342 343 344 345 346 347 348

    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
      ],
    );

349
    expect(cache.platformOverrideArtifacts, <String>{});
350 351 352
  });

  testUsingContext('precache with explicit artifact options overrides platform filtering', () async {
353 354 355 356 357 358 359 360 361 362 363 364 365 366
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
        featureFlags: TestFeatureFlags(
        isMacOSEnabled: true,
      ),
      platform: FakePlatform(
        operatingSystem: 'windows',
        environment: <String, String>{
          'FLUTTER_ROOT': 'flutter',
          'FLUTTER_ALREADY_LOCKED': 'true',
        },
      ),
    );
367 368 369 370 371 372 373 374 375 376

    await createTestCommandRunner(command).run(
      const <String>[
        'precache',
        '--no-ios',
        '--no-android',
        '--macos',
      ],
    );

377
    expect(cache.artifacts, unorderedEquals(<DevelopmentArtifact>{
378 379 380
      DevelopmentArtifact.universal,
      DevelopmentArtifact.macOS,
    }));
381
    expect(cache.platformOverrideArtifacts, <String>{'macos'});
382 383
  });

384
  testUsingContext('precache deletes artifact stampfiles when --force is provided', () async {
385
    cache.isUpToDateValue = true;
386 387 388 389 390 391 392 393
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(
        isMacOSEnabled: true,
      ),
      platform: FakePlatform(environment: <String, String>{}),
    );
394
    await createTestCommandRunner(command).run(const <String>['precache', '--force']);
395

396
    expect(cache.clearedStampFiles, true);
397
  });
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415

  testUsingContext('precache downloads all enabled platforms if no flags are provided.', () async {
    final PrecacheCommand command = PrecacheCommand(
      cache: cache,
      logger: BufferLogger.test(),
      featureFlags: TestFeatureFlags(
        isWebEnabled: true,
        isLinuxEnabled: true,
        isWindowsEnabled: true,
        isMacOSEnabled: true,
        isIOSEnabled: false,
        isAndroidEnabled: false,
      ),
      platform: FakePlatform(environment: <String, String>{}),
    );
    await createTestCommandRunner(command).run(const <String>['precache']);

    expect(
416
      cache.artifacts,
417 418 419 420 421 422 423 424 425
      unorderedEquals(<DevelopmentArtifact>{
        DevelopmentArtifact.web,
        DevelopmentArtifact.macOS,
        DevelopmentArtifact.windows,
        DevelopmentArtifact.linux,
        DevelopmentArtifact.universal,
        // iOS and android specifically excluded
      }));
  });
426 427
}

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
class FakeCache extends Fake implements Cache {
  bool isUpToDateValue = false;
  bool clearedStampFiles = false;
  bool locked = false;
  Set<DevelopmentArtifact> artifacts;

  @override
  Future<void> lock() async {
    locked = true;
  }

  @override
  void releaseLock() {
    locked = false;
  }

  @override
  Future<bool> isUpToDate() async => isUpToDateValue;

  @override
448
  Future<void> updateAll(Set<DevelopmentArtifact> requiredArtifacts, {bool offline = false}) async {
449 450 451 452 453 454 455 456 457 458 459 460 461 462
    artifacts = requiredArtifacts;
  }

  @override
  void clearStampFiles() {
    clearedStampFiles = true;
  }

  @override
  Set<String> platformOverrideArtifacts;

  @override
  bool includeAllPlatforms = false;
}