diff options
author | Dan Willemsen <dwillemsen@google.com> | 2017-07-26 02:02:58 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2017-07-26 02:02:58 -0700 |
commit | 49104c833dd6bcc805ac544d7a9c96a19ab5264c (patch) | |
tree | 8330e18b778ec31d7583fe01dca0ec2193003031 | |
parent | bcb31defde3e3fc248a1f11049e7722233003b6f (diff) | |
parent | 18ff00f914e7058cd51b4de8480b4a1c5263a39d (diff) | |
download | kati-o-iot-preview-5.tar.gz |
Merge remote-tracking branch 'aosp/upstream' into masterandroid-o-iot-preview-5o-iot-preview-5
* aosp/upstream:
Fix (cd <symlink>; find .)
Add some simple find unit tests
Bug: 64041576
Test: Compare internal master build-aosp_arm.ninja before/after
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | find.cc | 22 | ||||
-rw-r--r-- | find_test.cc | 102 |
3 files changed, 113 insertions, 12 deletions
diff --git a/.travis.yml b/.travis.yml index 2fd6fa8..3bbe280 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,3 +18,4 @@ script: - ./ninja_test - ./string_piece_test - ./strutil_test + - ./find_test @@ -252,6 +252,8 @@ class DirentDirNode : public DirentNode { return this; size_t index = d.find('/'); const string& p = d.substr(0, index).as_string(); + if (p.empty() || p == ".") + return FindDir(d.substr(index + 1));; for (auto& child : children_) { if (p == child.first) { if (index == string::npos) @@ -827,15 +829,17 @@ class FindEmulatorImpl : public FindEmulator { } } + const DirentNode* root = root_.get(); + if (!fc.chdir.empty()) { if (!CanHandle(fc.chdir)) { LOG("FindEmulator: Cannot handle chdir (%.*s): %s", SPF(fc.chdir), cmd.c_str()); return false; } - bool should_fallback = false; - if (!FindDir(fc.chdir, &should_fallback)) { - if (should_fallback) + root = root->FindDir(fc.chdir); + if (!root) { + if (Exists(fc.chdir)) return false; if (!fc.redirect_to_devnull) { FIND_WARN_LOC(loc, "FindEmulator: cd: %.*s: No such file or directory", @@ -847,18 +851,16 @@ class FindEmulatorImpl : public FindEmulator { vector<string> results; for (const string& finddir : fc.finddirs) { - const string dir = ConcatDir(fc.chdir, finddir); - - if (!CanHandle(dir)) { + if (!CanHandle(finddir)) { LOG("FindEmulator: Cannot handle find dir (%s): %s", - dir.c_str(), cmd.c_str()); + finddir.c_str(), cmd.c_str()); return false; } - bool should_fallback = false; - const DirentNode* base = FindDir(dir, &should_fallback); + const DirentNode* base; + base = root->FindDir(finddir); if (!base) { - if (should_fallback) { + if (Exists(finddir)) { return false; } if (!fc.redirect_to_devnull) { diff --git a/find_test.cc b/find_test.cc index ebdfa98..2ee7e39 100644 --- a/find_test.cc +++ b/find_test.cc @@ -17,13 +17,16 @@ #include "find.h" #include <string> +#include <unistd.h> +#include "fileutil.h" #include "strutil.h" +int FindUnitTests(); + int main(int argc, char* argv[]) { if (argc == 1) { - fprintf(stderr, "TODO: Write unit tests\n"); - return 1; + return FindUnitTests(); } InitFindEmulator(); @@ -48,3 +51,98 @@ int main(int argc, char* argv[]) { printf("%.*s\n", SPF(tok)); } } + +string Run(const string& cmd) { + string s; + int ret = RunCommand("/bin/sh", "-c", cmd, RedirectStderr::NONE, &s); + + if (ret != 0) { + fprintf(stderr, "Failed to run `%s`\n", cmd.c_str()); + exit(ret); + } + + return s; +} + +static bool unit_test_failed = false; + +void CompareFind(const string& cmd) { + string native = Run(cmd); + + FindCommand fc; + if (!fc.Parse(cmd)) { + fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str()); + exit(1); + } + string emulated; + if (!FindEmulator::Get()->HandleFind(cmd, fc, Loc(), &emulated)) { + fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str()); + exit(1); + } + + vector<StringPiece> nativeWords; + vector<StringPiece> emulatedWords; + + WordScanner(native).Split(&nativeWords); + WordScanner(emulated).Split(&emulatedWords); + + if (nativeWords != emulatedWords) { + fprintf(stderr, "Failed to match `%s`:\n", cmd.c_str()); + + auto nativeIter = nativeWords.begin(); + auto emulatedIter = emulatedWords.begin(); + fprintf(stderr, "%-20s %-20s\n", "Native:", "Emulated:"); + while (nativeIter != nativeWords.end() || emulatedIter != emulatedWords.end()) { + fprintf(stderr, " %-20s %-20s\n", + (nativeIter == nativeWords.end()) ? "" : (*nativeIter++).as_string().c_str(), + (emulatedIter == emulatedWords.end()) ? "" : (*emulatedIter++).as_string().c_str()); + } + fprintf(stderr, "------------------------------------------\n"); + unit_test_failed = true; + } +} + +int FindUnitTests() { + Run("rm -rf out/find"); + Run("mkdir -p out/find"); + if (chdir("out/find")) { + perror("Failed to chdir(out/find)"); + return 1; + } + + // Set up files under out/find: + // drwxr-x--- top + // lrwxrwxrwx top/E -> missing + // lrwxrwxrwx top/C -> A + // -rw-r----- top/a + // drwxr-x--- top/A + // lrwxrwxrwx top/A/D -> B + // -rw-r----- top/A/b + // drwxr-x--- top/A/B + // -rw-r----- top/A/B/z + Run("mkdir -p top/A/B"); + Run("cd top && ln -s A C"); + Run("cd top/A && ln -s B D"); + Run("cd top && ln -s missing E"); + Run("touch top/a top/A/b top/A/B/z"); + + InitFindEmulator(); + + CompareFind("find ."); + CompareFind("find -L ."); + + CompareFind("find top/C"); + CompareFind("find top/C/."); + CompareFind("find -L top/C"); + CompareFind("find -L top/C/."); + + CompareFind("cd top && find C"); + CompareFind("cd top && find -L C"); + CompareFind("cd top/C && find ."); + + CompareFind("cd top/C && find D/./z"); + + CompareFind("find .//top"); + + return unit_test_failed ? 1 : 0; +} |