blob: 117a1b216d25c494ef28d9cc267e467c8d360980 [file] [log] [blame]
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.android;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.vfs.PathFragment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests {@link AndroidAssets} */
@RunWith(JUnit4.class)
public class AndroidAssetsTest extends ResourceTestBase {
@Test
public void testParseAapt2() throws Exception {
RuleContext ruleContext = getRuleContext();
AndroidAssets assets = getLocalAssets();
ParsedAndroidAssets parsed = assets.parse(AndroidDataContext.forNative(ruleContext));
// Assets should be unchanged
assertThat(parsed.getAssets()).isEqualTo(assets.getAssets());
assertThat(parsed.getAssetRoots()).isEqualTo(assets.getAssetRoots());
// Label should be correct
assertThat(parsed.getLabel()).isEqualTo(ruleContext.getLabel());
// There should be compiled symbols
assertThat(parsed.getCompiledSymbols()).isNotNull();
// Symbols and compiled symbols files should be created from raw assets
assertActionArtifacts(
ruleContext,
/* inputs = */ assets.getAssets(),
/* outputs = */ ImmutableList.of(parsed.getSymbols()));
assertActionArtifacts(
ruleContext,
/* inputs = */ assets.getAssets(),
/* outputs = */ ImmutableList.of(parsed.getCompiledSymbols()));
}
@Test
public void testMergeNoDeps() throws Exception {
RuleContext ruleContext = getRuleContext();
ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext));
MergedAndroidAssets merged = assertMerge(ruleContext, parsed, AssetDependencies.empty());
// The assets can be correctly built into a provider
AndroidAssetsInfo info = merged.toProvider();
assertThat(info.getLabel()).isEqualTo(merged.getLabel());
// The provider just has the local values
assertThat(info.getAssets().toList()).containsExactlyElementsIn(merged.getAssets()).inOrder();
assertThat(info.getSymbols().toList()).containsExactly(merged.getSymbols());
assertThat(info.getDirectParsedAssets().toList()).containsExactly(parsed);
assertThat(info.getTransitiveParsedAssets().toList()).isEmpty();
}
@Test
public void testMergeNeverlink() throws Exception {
RuleContext ruleContext = getRuleContext();
ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext));
AssetDependencies deps = makeDeps(ruleContext, /* neverlink = */ true);
MergedAndroidAssets merged = assertMerge(ruleContext, parsed, deps);
AndroidAssetsInfo info = merged.toProvider();
assertThat(info.getLabel()).isEqualTo(merged.getLabel());
// The provider should be empty because of neverlinking
assertThat(info.getAssets().toList()).isEmpty();
assertThat(info.getSymbols().toList()).isEmpty();
assertThat(info.getDirectParsedAssets().toList()).isEmpty();
assertThat(info.getTransitiveParsedAssets().toList()).isEmpty();
assertThat(info.getCompiledSymbols().toList()).isEmpty();
}
@Test
public void testMergeAapt2() throws Exception {
RuleContext ruleContext = getRuleContext();
ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext));
AssetDependencies deps = makeDeps(ruleContext, /* neverlink = */ false);
MergedAndroidAssets merged = assertMerge(ruleContext, parsed, deps);
AndroidAssetsInfo info = merged.toProvider();
assertThat(info.getLabel()).isEqualTo(merged.getLabel());
// The provider should have transitive and direct deps
assertThat(info.getAssets().toList())
.containsExactlyElementsIn(
Iterables.concat(parsed.getAssets(), deps.getTransitiveAssets().toList()))
.inOrder();
assertThat(info.getSymbols().toList())
.containsExactlyElementsIn(
Iterables.concat(
ImmutableList.of(parsed.getSymbols()), deps.getTransitiveSymbols().toList()))
.inOrder();
assertThat(info.getCompiledSymbols().toList())
.containsExactlyElementsIn(
Iterables.concat(
ImmutableList.of(parsed.getCompiledSymbols()),
deps.getTransitiveCompiledSymbols().toList()));
assertThat(info.getDirectParsedAssets().toList()).containsExactly(parsed).inOrder();
assertThat(info.getTransitiveParsedAssets().toList())
.containsExactlyElementsIn(
Iterables.concat(
deps.getTransitiveParsedAssets().toList(), deps.getDirectParsedAssets().toList()))
.inOrder();
}
private AssetDependencies makeDeps(RuleContext ruleContext, boolean neverlink) {
ParsedAndroidAssets firstDirect = getDependencyAssets(ruleContext, "first_direct");
ParsedAndroidAssets secondDirect = getDependencyAssets(ruleContext, "second_direct");
ParsedAndroidAssets firstTransitive = getDependencyAssets(ruleContext, "first_transitive");
ParsedAndroidAssets secondTransitive = getDependencyAssets(ruleContext, "second_transitive");
return AssetDependencies.of(
neverlink,
NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, firstDirect, secondDirect),
NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, firstTransitive, secondTransitive),
NestedSetBuilder.wrap(
Order.NAIVE_LINK_ORDER,
Iterables.concat(
firstDirect.getAssets(),
secondDirect.getAssets(),
firstTransitive.getAssets(),
secondTransitive.getAssets())),
NestedSetBuilder.wrap(
Order.NAIVE_LINK_ORDER,
ImmutableList.of(
firstDirect.getSymbols(),
secondDirect.getSymbols(),
firstTransitive.getSymbols(),
secondTransitive.getSymbols())),
NestedSetBuilder.wrap(
Order.NAIVE_LINK_ORDER,
ImmutableList.of(
firstDirect.getCompiledSymbols(),
secondDirect.getCompiledSymbols(),
firstTransitive.getCompiledSymbols(),
secondTransitive.getCompiledSymbols())));
}
private MergedAndroidAssets assertMerge(
RuleContext ruleContext, ParsedAndroidAssets parsed, AssetDependencies deps)
throws InterruptedException {
MergedAndroidAssets merged =
MergedAndroidAssets.mergeFrom(AndroidDataContext.forNative(ruleContext), parsed, deps);
// Inherited values should be unchanged
assertThat(new ParsedAndroidAssets(merged)).isEqualTo(parsed);
// The raw assets should be used to merge
assertActionArtifacts(
ruleContext,
/* inputs = */ ImmutableList.<Artifact>builder()
.addAll(merged.getAssets())
.add(merged.getSymbols())
.addAll(deps.getTransitiveAssets().toList())
.addAll(deps.getTransitiveSymbols().toList())
.build(),
/* outputs = */ ImmutableList.of(merged.getMergedAssets()));
return merged;
}
private AndroidAssets getLocalAssets() {
return new AndroidAssets(
ImmutableList.of(getResource("asset_1"), getResource("asset_2")),
ImmutableList.of(PathFragment.create("asset_dir")),
"asset_dir");
}
private ParsedAndroidAssets getDependencyAssets(RuleContext ruleContext, String depName) {
return ParsedAndroidAssets.of(
new AndroidAssets(
ImmutableList.of(getResource(depName + "_asset_1"), getResource(depName + "_asset_2")),
ImmutableList.of(PathFragment.create(depName)),
depName),
getResource("symbols_for_" + depName),
getResource("compiled_symbols_for_" + depName),
ruleContext.getLabel());
}
private RuleContext getRuleContext() throws Exception {
return getRuleContextForActionTesting(
scratchConfiguredTarget("pkg", "r", "android_library(name='r')"));
}
}