Jonah Williams 859fce9010
[flutter_tools] add feature for iOS, android, and fuchsia (#61481)
Add feature flags for android, ios, and fuchsia (on by default). After updating the g3 rollers, the fuchsia feature will be turned off by default. Creates a simpler base type of feature flags for g3 to extend.

Updates android, ios, fuchsia workflows to use feature flags check.
Removes concept of stable artifacts and checks on flutter version.

Fixes #58999
#52859
#12768
2020-07-16 09:51:59 -07:00

428 lines
14 KiB
Dart

// 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.
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/precache.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart';
import '../../src/testbed.dart';
void main() {
MockCache cache;
Set<DevelopmentArtifact> artifacts;
setUp(() {
cache = MockCache();
// Release lock between test cases.
Cache.releaseLock();
when(cache.isUpToDate()).thenReturn(false);
when(cache.updateAll(any)).thenAnswer((Invocation invocation) {
artifacts = invocation.positionalArguments.first as Set<DevelopmentArtifact>;
return Future<void>.value(null);
});
});
testUsingContext('precache should acquire lock', () async {
final Platform platform = FakePlatform(environment: <String, String>{});
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
platform: platform,
featureFlags: TestFeatureFlags(),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache']);
expect(Cache.isLocked(), isTrue);
// Do not throw StateError, lock is acquired.
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
});
testUsingContext('precache should not re-entrantly acquire lock', () async {
final Platform platform = FakePlatform(
operatingSystem: 'windows',
environment: <String, String>{
'FLUTTER_ROOT': 'flutter',
'FLUTTER_ALREADY_LOCKED': 'true',
},
);
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(),
platform: platform,
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache']);
expect(Cache.isLocked(), isFalse);
// Do not throw StateError, acquired reentrantly with FLUTTER_ALREADY_LOCKED.
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
});
testUsingContext('precache downloads web artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isWebEnabled: true),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.web,
}));
});
testUsingContext('precache does not download web artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isWebEnabled: false),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
}));
});
testUsingContext('precache downloads macOS artifacts on dev branch when macOS is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.macOS,
}));
});
testUsingContext('precache does not download macOS artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isMacOSEnabled: false),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
}));
});
testUsingContext('precache downloads Windows artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isWindowsEnabled: true),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.windows,
}));
});
testUsingContext('precache does not download Windows artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isWindowsEnabled: false),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
}));
});
testUsingContext('precache downloads Linux artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isLinuxEnabled: true),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.linux,
}));
});
testUsingContext('precache does not download Linux artifacts on dev branch when feature is enabled.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isLinuxEnabled: false),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
}));
});
testUsingContext('precache exits if requesting mismatched artifacts.', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(isWebEnabled: false),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
expect(createTestCommandRunner(command).run(const <String>['precache',
'--no-android',
'--android_gen_snapshot',
]), throwsToolExit(message: '--android_gen_snapshot requires --android'));
});
testUsingContext('precache adds artifact flags to requested artifacts', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(
isWebEnabled: true,
isLinuxEnabled: true,
isMacOSEnabled: true,
isWindowsEnabled: true,
),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--ios',
'--android',
'--web',
'--macos',
'--linux',
'--windows',
'--fuchsia',
'--flutter_runner',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.iOS,
DevelopmentArtifact.androidGenSnapshot,
DevelopmentArtifact.androidMaven,
DevelopmentArtifact.androidInternalBuild,
DevelopmentArtifact.web,
DevelopmentArtifact.macOS,
DevelopmentArtifact.linux,
DevelopmentArtifact.windows,
DevelopmentArtifact.fuchsia,
DevelopmentArtifact.flutterRunner,
}));
});
testUsingContext('precache expands android artifacts when the android flag is used', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--no-ios',
'--android',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.androidGenSnapshot,
DevelopmentArtifact.androidMaven,
DevelopmentArtifact.androidInternalBuild,
}));
});
testUsingContext('precache adds artifact flags to requested android artifacts', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--no-ios',
'--android_gen_snapshot',
'--android_maven',
'--android_internal_build',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.androidGenSnapshot,
DevelopmentArtifact.androidMaven,
DevelopmentArtifact.androidInternalBuild,
}));
});
testUsingContext('precache downloads iOS and Android artifacts by default', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.iOS,
DevelopmentArtifact.androidGenSnapshot,
DevelopmentArtifact.androidMaven,
DevelopmentArtifact.androidInternalBuild,
}));
});
testUsingContext('precache --all-platforms gets all artifacts', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(
isWebEnabled: true,
isLinuxEnabled: true,
isMacOSEnabled: true,
isWindowsEnabled: true,
),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--all-platforms',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
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 {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
],
);
verify(cache.platformOverrideArtifacts = <String>{});
});
testUsingContext('precache with explicit artifact options overrides platform filtering', () async {
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',
},
),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--no-ios',
'--no-android',
'--macos',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.macOS,
}));
verify(cache.platformOverrideArtifacts = <String>{'macos'});
});
testUsingContext('precache deletes artifact stampfiles when --force is provided', () async {
when(cache.isUpToDate()).thenReturn(true);
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
featureFlags: TestFeatureFlags(
isMacOSEnabled: true,
),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(const <String>['precache', '--force']);
verify(cache.clearStampFiles()).called(1);
});
}
class MockCache extends Mock implements Cache {}