diff options
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/util/DependencySetTest.java')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/util/DependencySetTest.java | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/util/DependencySetTest.java b/src/test/java/com/google/devtools/build/lib/util/DependencySetTest.java new file mode 100644 index 0000000000..40edf36b03 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/util/DependencySetTest.java @@ -0,0 +1,230 @@ +// Copyright 2014 Google Inc. 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.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.google.common.collect.Sets; +import com.google.devtools.build.lib.testutil.MoreAsserts; +import com.google.devtools.build.lib.vfs.FileSystemUtils; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.util.FsApparatus; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.Collection; + +@RunWith(JUnit4.class) +public class DependencySetTest { + + private FsApparatus scratch = FsApparatus.newInMemory(); + + private DependencySet newDependencySet() { + return new DependencySet(scratch.fs().getRootDirectory()); + } + + @Test + public void dotDParser_simple() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + filename + ": \\", + " " + file1 + " \\", + " " + file2 + " "); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_simple_crlf() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + filename + ": \\\r", + " " + file1 + " \\\r", + " " + file2 + " "); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_simple_cr() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + filename + ": \\\r" + + " " + file1 + " \\\r" + + " " + file2 + " "); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_leading_crlf() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + "\r\n" + filename + ": \\\r\n" + + " " + file1 + " \\\r\n" + + " " + file2 + " "); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_oddFormatting() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + PathFragment file3 = new PathFragment("/usr/local/blah/blah/genhello/other.h"); + PathFragment file4 = new PathFragment("/usr/local/blah/blah/genhello/onemore.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + filename + ": " + file1 + " \\", + " " + file2 + "\\", + " " + file3 + " " + file4); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2, file3, file4), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_relativeFilenames() throws Exception { + PathFragment file1 = new PathFragment("hello.cc"); + PathFragment file2 = new PathFragment("hello.h"); + String filename = "hello.o"; + Path dotd = scratch.file("/tmp/foo.d", + filename + ": \\", + " " + file1 + " \\", + " " + file2 + " "); + DependencySet depset = newDependencySet().read(dotd); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + depset.getDependencies()); + assertEquals(depset.getOutputFileName(), filename); + } + + @Test + public void dotDParser_emptyFile() throws Exception { + Path dotd = scratch.file("/tmp/empty.d"); + DependencySet depset = newDependencySet().read(dotd); + Collection<PathFragment> headers = depset.getDependencies(); + if (!headers.isEmpty()) { + fail("Not empty: " + headers.size() + " " + headers); + } + assertEquals(depset.getOutputFileName(), null); + } + + @Test + public void dotDParser_multipleTargets() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + Path dotd = scratch.file("/tmp/foo.d", + "hello.o: \\", + " " + file1, + "hello2.o: \\", + " " + file2); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2), + newDependencySet().read(dotd).getDependencies()); + } + + /* + * Regression test: if gcc fails to execute remotely, and we retry locally, then the behavior + * of gcc's DEPENDENCIES_OUTPUT option is to append, not overwrite, the .d file. As a result, + * during retry, a second stanza is written to the file. + * + * We handle this by merging all of the stanzas. + */ + @Test + public void dotDParser_duplicateStanza() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + PathFragment file3 = new PathFragment("/usr/local/blah/blah/genhello/other.h"); + Path dotd = scratch.file("/tmp/foo.d", + "hello.o: \\", + " " + file1 + " \\", + " " + file2 + " ", + "hello.o: \\", + " " + file1 + " \\", + " " + file3 + " "); + MoreAsserts.assertSameContents(Sets.newHashSet(file1, file2, file3), + newDependencySet().read(dotd).getDependencies()); + } + + @Test + public void writeSet() throws Exception { + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + PathFragment file3 = new PathFragment("/usr/local/blah/blah/genhello/other.h"); + String filename = "/usr/local/blah/blah/genhello/hello.o"; + + DependencySet depSet1 = newDependencySet(); + depSet1.addDependency(file1); + depSet1.addDependency(file2); + depSet1.addDependency(file3); + depSet1.setOutputFileName(filename); + + Path outfile = scratch.path(filename); + Path dotd = scratch.path("/usr/local/blah/blah/genhello/hello.d"); + FileSystemUtils.createDirectoryAndParents(dotd.getParentDirectory()); + depSet1.write(outfile, ".d"); + + String dotdContents = new String(FileSystemUtils.readContentAsLatin1(dotd)); + String expected = + "usr/local/blah/blah/genhello/hello.o: \\\n" + + " /usr/local/blah/blah/genhello/hello.cc \\\n" + + " /usr/local/blah/blah/genhello/hello.h \\\n" + + " /usr/local/blah/blah/genhello/other.h\n"; + assertEquals(expected, dotdContents); + assertEquals(filename, depSet1.getOutputFileName()); + } + + @Test + public void writeReadSet() throws Exception { + String filename = "/usr/local/blah/blah/genhello/hello.d"; + PathFragment file1 = new PathFragment("/usr/local/blah/blah/genhello/hello.cc"); + PathFragment file2 = new PathFragment("/usr/local/blah/blah/genhello/hello.h"); + PathFragment file3 = new PathFragment("/usr/local/blah/blah/genhello/other.h"); + DependencySet depSet1 = newDependencySet(); + depSet1.addDependency(file1); + depSet1.addDependency(file2); + depSet1.addDependency(file3); + depSet1.setOutputFileName(filename); + + Path dotd = scratch.path(filename); + FileSystemUtils.createDirectoryAndParents(dotd.getParentDirectory()); + depSet1.write(dotd, ".d"); + + DependencySet depSet2 = newDependencySet().read(dotd); + assertEquals(depSet1, depSet2); + // due to how pic.d files are written, absolute paths are changed into relatives + assertEquals(depSet1.getOutputFileName(), "/" + depSet2.getOutputFileName()); + } + +} |