aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2017-07-26 02:02:58 -0700
committerDan Willemsen <dwillemsen@google.com>2017-07-26 02:02:58 -0700
commit49104c833dd6bcc805ac544d7a9c96a19ab5264c (patch)
tree8330e18b778ec31d7583fe01dca0ec2193003031
parentbcb31defde3e3fc248a1f11049e7722233003b6f (diff)
parent18ff00f914e7058cd51b4de8480b4a1c5263a39d (diff)
downloadkati-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.yml1
-rw-r--r--find.cc22
-rw-r--r--find_test.cc102
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
diff --git a/find.cc b/find.cc
index 2af242b..c36c468 100644
--- a/find.cc
+++ b/find.cc
@@ -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;
+}