Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <errno.h>
      6 #include <sys/types.h>
      7 #include <sys/xattr.h>
      8 
      9 #include <algorithm>
     10 #include <sstream>
     11 #include <string>
     12 
     13 #include "base/file_util.h"
     14 #include "base/files/file_path.h"
     15 #include "base/files/scoped_temp_dir.h"
     16 #include "base/logging.h"
     17 #include "base/strings/string_split.h"
     18 #include "content/browser/download/file_metadata_linux.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 #include "url/gurl.h"
     21 
     22 namespace content {
     23 namespace {
     24 
     25 using std::istringstream;
     26 using std::string;
     27 using std::vector;
     28 
     29 class FileMetadataLinuxTest : public testing::Test {
     30  public:
     31   FileMetadataLinuxTest()
     32       : source_url_("http://www.source.com"),
     33         referrer_url_("http://www.referrer.com"),
     34         is_xattr_supported_(false) {}
     35 
     36   const base::FilePath& test_file() const {
     37     return test_file_;
     38   }
     39 
     40   const GURL& source_url() const {
     41     return source_url_;
     42   }
     43 
     44   const GURL& referrer_url() const {
     45     return referrer_url_;
     46   }
     47 
     48   bool is_xattr_supported() const {
     49     return is_xattr_supported_;
     50   }
     51 
     52  protected:
     53   virtual void SetUp() OVERRIDE {
     54     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     55     ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &test_file_));
     56     int result = setxattr(test_file_.value().c_str(),
     57                           "user.test", "test", 4, 0);
     58     is_xattr_supported_ = (!result) || (errno != ENOTSUP);
     59     if (!is_xattr_supported_) {
     60       VLOG(0) << "Test will be skipped because extended attributes are not "
     61                 << "supported on this OS/file system.";
     62     }
     63   }
     64 
     65   void CheckExtendedAttributeValue(const string attr_name,
     66                                    const string expected_value) const {
     67     ssize_t len = getxattr(test_file().value().c_str(), attr_name.c_str(),
     68                            NULL, 0);
     69     if (len <= static_cast<ssize_t>(0)) {
     70       FAIL() << "Attribute '" << attr_name << "' does not exist";
     71     }
     72     char* buffer = new char[len];
     73     len = getxattr(test_file().value().c_str(), attr_name.c_str(), buffer, len);
     74     EXPECT_EQ(expected_value.size(), static_cast<size_t>(len));
     75     string real_value(buffer, len);
     76     delete[] buffer;
     77     EXPECT_EQ(expected_value, real_value);
     78   }
     79 
     80   void GetExtendedAttributeNames(vector<string>* attr_names) const {
     81     ssize_t len = listxattr(test_file().value().c_str(), NULL, 0);
     82     if (len <= static_cast<ssize_t>(0)) return;
     83     char* buffer = new char[len];
     84     len = listxattr(test_file().value().c_str(), buffer, len);
     85     attr_names->clear();
     86     base::SplitString(string(buffer, len), '\0', attr_names);
     87     delete[] buffer;
     88   }
     89 
     90   void VerifyAttributesAreSetCorrectly() const {
     91     vector<string> attr_names;
     92     GetExtendedAttributeNames(&attr_names);
     93 
     94     // Check if the attributes are set on the file
     95     vector<string>::const_iterator pos = find(attr_names.begin(),
     96         attr_names.end(), kSourceURLAttrName);
     97     EXPECT_NE(pos, attr_names.end());
     98     pos = find(attr_names.begin(), attr_names.end(), kReferrerURLAttrName);
     99     EXPECT_NE(pos, attr_names.end());
    100 
    101     // Check if the attribute values are set correctly
    102     CheckExtendedAttributeValue(kSourceURLAttrName, source_url().spec());
    103     CheckExtendedAttributeValue(kReferrerURLAttrName, referrer_url().spec());
    104   }
    105 
    106  private:
    107   base::ScopedTempDir temp_dir_;
    108   base::FilePath test_file_;
    109   GURL source_url_;
    110   GURL referrer_url_;
    111   bool is_xattr_supported_;
    112 };
    113 
    114 TEST_F(FileMetadataLinuxTest, CheckMetadataSetCorrectly) {
    115   if (!is_xattr_supported()) return;
    116   AddOriginMetadataToFile(test_file(), source_url(), referrer_url());
    117   VerifyAttributesAreSetCorrectly();
    118 }
    119 
    120 TEST_F(FileMetadataLinuxTest, SetMetadataMultipleTimes) {
    121   if (!is_xattr_supported()) return;
    122   GURL dummy_url("http://www.dummy.com");
    123   AddOriginMetadataToFile(test_file(), dummy_url, dummy_url);
    124   AddOriginMetadataToFile(test_file(), source_url(), referrer_url());
    125   VerifyAttributesAreSetCorrectly();
    126 }
    127 
    128 TEST_F(FileMetadataLinuxTest, InvalidSourceURLTest) {
    129   if (!is_xattr_supported()) return;
    130   GURL invalid_url;
    131   vector<string> attr_names;
    132   AddOriginMetadataToFile(test_file(), invalid_url, referrer_url());
    133   GetExtendedAttributeNames(&attr_names);
    134   EXPECT_EQ(attr_names.end(), find(attr_names.begin(), attr_names.end(),
    135       kSourceURLAttrName));
    136   CheckExtendedAttributeValue(kReferrerURLAttrName, referrer_url().spec());
    137 }
    138 
    139 TEST_F(FileMetadataLinuxTest, InvalidReferrerURLTest) {
    140   if (!is_xattr_supported()) return;
    141   GURL invalid_url;
    142   vector<string> attr_names;
    143   AddOriginMetadataToFile(test_file(), source_url(), invalid_url);
    144   GetExtendedAttributeNames(&attr_names);
    145   EXPECT_EQ(attr_names.end(), find(attr_names.begin(), attr_names.end(),
    146       kReferrerURLAttrName));
    147   CheckExtendedAttributeValue(kSourceURLAttrName, source_url().spec());
    148 }
    149 
    150 TEST_F(FileMetadataLinuxTest, InvalidURLsTest) {
    151   if (!is_xattr_supported()) return;
    152   GURL invalid_url;
    153   vector<string> attr_names;
    154   AddOriginMetadataToFile(test_file(), invalid_url, invalid_url);
    155   GetExtendedAttributeNames(&attr_names);
    156   EXPECT_EQ(attr_names.end(), find(attr_names.begin(), attr_names.end(),
    157       kSourceURLAttrName));
    158   EXPECT_EQ(attr_names.end(), find(attr_names.begin(), attr_names.end(),
    159       kReferrerURLAttrName));
    160 }
    161 
    162 }  // namespace
    163 }  // namespace content
    164