@Test public void testGetBuildTargetForAlias() throws IOException, NoSuchBuildTargetException { BuildTargetParser parser = EasyMock.createMock(BuildTargetParser.class); EasyMock.expect(parser.parse("//java/com/example:foo", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:foo")); EasyMock.expect(parser.parse("//java/com/example:bar", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:bar")); EasyMock.replay(parser); Reader reader = new StringReader( Joiner.on('\n') .join("[alias]", "foo = //java/com/example:foo", "bar = //java/com/example:bar")); BuckConfig config = createWithDefaultFilesystem(reader, parser); assertEquals("//java/com/example:foo", config.getBuildTargetForAlias("foo")); assertEquals("//java/com/example:bar", config.getBuildTargetForAlias("bar")); assertNull( "Invalid alias names, such as build targets, should be tolerated by this method.", config.getBuildTargetForAlias("//java/com/example:foo")); assertNull(config.getBuildTargetForAlias("baz")); Reader noAliasesReader = new StringReader(""); BuckConfig noAliasesConfig = createWithDefaultFilesystem(noAliasesReader, parser); assertNull(noAliasesConfig.getBuildTargetForAlias("foo")); assertNull(noAliasesConfig.getBuildTargetForAlias("bar")); assertNull(noAliasesConfig.getBuildTargetForAlias("baz")); EasyMock.verify(parser); }
@Test public void testReferentialAliases() throws IOException, NoSuchBuildTargetException { BuildTargetParser parser = EasyMock.createMock(BuildTargetParser.class); EasyMock.expect(parser.parse("//java/com/example:foo", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:foo")); EasyMock.expect(parser.parse("//java/com/example:bar", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:bar")); EasyMock.replay(parser); Reader reader = new StringReader( Joiner.on('\n') .join( "[alias]", "foo = //java/com/example:foo", "bar = //java/com/example:bar", "foo_codename = foo", "", "# Do not delete these: automation builds require these aliases to exist!", "automation_foo = foo_codename", "automation_bar = bar")); BuckConfig config = createWithDefaultFilesystem(reader, parser); assertEquals("//java/com/example:foo", config.getBuildTargetForAlias("foo")); assertEquals("//java/com/example:bar", config.getBuildTargetForAlias("bar")); assertEquals("//java/com/example:foo", config.getBuildTargetForAlias("foo_codename")); assertEquals("//java/com/example:foo", config.getBuildTargetForAlias("automation_foo")); assertEquals("//java/com/example:bar", config.getBuildTargetForAlias("automation_bar")); assertNull(config.getBuildTargetForAlias("baz")); EasyMock.verify(parser); }
/** * Ensure that whichever alias is listed first in the file is the one used in the reverse map if * the value appears multiple times. */ @Test public void testGetBasePathToAliasMap() throws IOException, NoSuchBuildTargetException { BuildTargetParser parser = EasyMock.createMock(BuildTargetParser.class); EasyMock.expect(parser.parse("//java/com/example:fbandroid", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:fbandroid")) .anyTimes(); EasyMock.replay(parser); Reader reader1 = new StringReader( Joiner.on('\n') .join( "[alias]", "fb4a = //java/com/example:fbandroid", "katana = //java/com/example:fbandroid")); BuckConfig config1 = createWithDefaultFilesystem(reader1, parser); assertEquals(ImmutableMap.of("java/com/example", "fb4a"), config1.getBasePathToAliasMap()); assertEquals( ImmutableMap.of( "fb4a", "//java/com/example:fbandroid", "katana", "//java/com/example:fbandroid"), config1.getEntriesForSection("alias")); Reader reader2 = new StringReader( Joiner.on('\n') .join( "[alias]", "katana = //java/com/example:fbandroid", "fb4a = //java/com/example:fbandroid")); BuckConfig config2 = createWithDefaultFilesystem(reader2, parser); assertEquals(ImmutableMap.of("java/com/example", "katana"), config2.getBasePathToAliasMap()); assertEquals( ImmutableMap.of( "fb4a", "//java/com/example:fbandroid", "katana", "//java/com/example:fbandroid"), config2.getEntriesForSection("alias")); Reader noAliasesReader = new StringReader(""); BuckConfig noAliasesConfig = createWithDefaultFilesystem(noAliasesReader, parser); assertEquals(ImmutableMap.of(), noAliasesConfig.getBasePathToAliasMap()); assertEquals(ImmutableMap.of(), noAliasesConfig.getEntriesForSection("alias")); EasyMock.verify(parser); }
@Test public void testUnresolvedAliasThrows() throws IOException, NoSuchBuildTargetException { BuildTargetParser parser = EasyMock.createMock(BuildTargetParser.class); EasyMock.expect(parser.parse("//java/com/example:foo", ParseContext.fullyQualified())) .andReturn(BuildTargetFactory.newInstance("//java/com/example:foo")); EasyMock.replay(parser); Reader reader = new StringReader( Joiner.on('\n').join("[alias]", "foo = //java/com/example:foo", "bar = food")); try { createWithDefaultFilesystem(reader, parser); fail("Should have thrown HumanReadableException."); } catch (HumanReadableException e) { assertEquals("No alias for: food.", e.getHumanReadableErrorMessage()); } EasyMock.verify(parser); }
@Test public void testCreateAndRunGenrule() throws IOException, NoSuchBuildTargetException { /* * Programmatically build up a Genrule that corresponds to: * * genrule( * name = 'katana_manifest', * srcs = [ * 'convert_to_katana.py', * 'AndroidManifest.xml', * ], * cmd = 'python $SRCDIR/* > $OUT', * out = 'AndroidManifest.xml', * ) */ BuildRuleResolver ruleResolver = new BuildRuleResolver(); createSampleJavaBinaryRule(ruleResolver); Map<String, ?> instance = ImmutableMap.of( "name", "katana_manifest", "srcs", ImmutableList.<String>of("convert_to_katana.py", "AndroidManifest.xml"), "cmd", "python convert_to_katana.py AndroidManifest.xml > $OUT", "out", "AndroidManifest.xml", "deps", ImmutableList.<String>of("//java/com/facebook/util:util")); // From the Python object, create a GenruleBuildRuleFactory to create a Genrule.Builder // that builds a Genrule from the Python object. BuildTargetParser parser = EasyMock.createNiceMock(BuildTargetParser.class); EasyMock.expect( parser.parse( EasyMock.eq("//java/com/facebook/util:util"), EasyMock.anyObject(ParseContext.class))) .andStubReturn(BuildTargetFactory.newInstance("//java/com/facebook/util:util")); EasyMock.replay(parser); BuildTarget buildTarget = new BuildTarget("//src/com/facebook/katana", "katana_manifest"); BuildRuleFactoryParams params = NonCheckingBuildRuleFactoryParams.createNonCheckingBuildRuleFactoryParams( instance, parser, buildTarget); GenruleBuildRuleFactory factory = new GenruleBuildRuleFactory(); Builder builder = factory.newInstance(params); builder.setRelativeToAbsolutePathFunctionForTesting(relativeToAbsolutePathFunction); Genrule genrule = ruleResolver.buildAndAddToIndex(builder); // Verify all of the observers of the Genrule. assertEquals(BuildRuleType.GENRULE, genrule.getType()); assertEquals( GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml", genrule.getPathToOutputFile()); assertEquals( getAbsolutePathInBase(GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml").toString(), genrule.getAbsoluteOutputFilePath()); BuildContext buildContext = null; // unused since there are no deps ImmutableSortedSet<String> inputsToCompareToOutputs = ImmutableSortedSet.of( "src/com/facebook/katana/convert_to_katana.py", "src/com/facebook/katana/AndroidManifest.xml"); assertEquals(inputsToCompareToOutputs, genrule.getInputsToCompareToOutput()); // Verify that the shell commands that the genrule produces are correct. List<Step> steps = genrule.getBuildSteps(buildContext, new FakeBuildableContext()); assertEquals(7, steps.size()); Step firstStep = steps.get(0); assertTrue(firstStep instanceof RmStep); RmStep rmCommand = (RmStep) firstStep; ExecutionContext executionContext = newEmptyExecutionContext(); assertEquals( "First command should delete the output file to be written by the genrule.", ImmutableList.of("rm", "-f", GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml"), rmCommand.getShellCommand(executionContext)); Step secondStep = steps.get(1); assertTrue(secondStep instanceof MkdirStep); MkdirStep mkdirCommand = (MkdirStep) secondStep; assertEquals( "Second command should make sure the output directory exists.", Paths.get(GEN_DIR + "/src/com/facebook/katana"), mkdirCommand.getPath(executionContext)); Step mkTmpDir = steps.get(2); assertTrue(mkTmpDir instanceof MakeCleanDirectoryStep); MakeCleanDirectoryStep secondMkdirCommand = (MakeCleanDirectoryStep) mkTmpDir; String pathToTmpDir = GEN_DIR + "/src/com/facebook/katana/katana_manifest__tmp"; assertEquals( "Third command should create the temp directory to be written by the genrule.", pathToTmpDir, secondMkdirCommand.getPath()); Step mkSrcDir = steps.get(3); assertTrue(mkSrcDir instanceof MakeCleanDirectoryStep); MakeCleanDirectoryStep thirdMkdirCommand = (MakeCleanDirectoryStep) mkTmpDir; String pathToSrcDir = GEN_DIR + "/src/com/facebook/katana/katana_manifest__srcs"; assertEquals( "Fourth command should create the temp source directory to be written by the genrule.", pathToTmpDir, thirdMkdirCommand.getPath()); MkdirAndSymlinkFileStep linkSource1 = (MkdirAndSymlinkFileStep) steps.get(4); assertEquals("src/com/facebook/katana/convert_to_katana.py", linkSource1.getSource()); assertEquals(pathToSrcDir + "/convert_to_katana.py", linkSource1.getTarget()); MkdirAndSymlinkFileStep linkSource2 = (MkdirAndSymlinkFileStep) steps.get(5); assertEquals("src/com/facebook/katana/AndroidManifest.xml", linkSource2.getSource()); assertEquals(pathToSrcDir + "/AndroidManifest.xml", linkSource2.getTarget()); Step sixthStep = steps.get(6); assertTrue(sixthStep instanceof ShellStep); ShellStep genruleCommand = (ShellStep) sixthStep; assertEquals("genrule", genruleCommand.getShortName()); assertEquals( ImmutableMap.<String, String>builder() .put( "OUT", getAbsolutePathInBase(GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml") .toString()) .build(), genruleCommand.getEnvironmentVariables(executionContext)); assertEquals( ImmutableList.of( "/bin/bash", "-e", "-c", "python convert_to_katana.py AndroidManifest.xml > $OUT"), genruleCommand.getShellCommand(executionContext)); }