Home | History | Annotate | Download | only in mini_installer_test
      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 "chrome/test/mini_installer_test/installer_path_provider.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/command_line.h"
     10 #include "base/file_util.h"
     11 #include "base/files/file_enumerator.h"
     12 #include "base/path_service.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "chrome/test/mini_installer_test/installer_test_util.h"
     16 #include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace {
     20 
     21 struct FilePathInfo {
     22   base::FileEnumerator::FileInfo info;
     23   base::FilePath path;
     24 };
     25 
     26 bool CompareDate(const FilePathInfo& a, const FilePathInfo& b) {
     27   return a.info.GetLastModifiedTime() > b.info.GetLastModifiedTime();
     28 }
     29 
     30 // Get list of file |type| matching |pattern| in |root|.
     31 // The list is sorted in last modified date order.
     32 // Return true if files/directories are found.
     33 bool FindMatchingFiles(const base::FilePath& root,
     34                        const std::string& pattern,
     35                        base::FileEnumerator::FileType type,
     36                        std::vector<base::FilePath>* paths) {
     37   base::FileEnumerator files(root, false, type,
     38       base::FilePath().AppendASCII(pattern).value());
     39   std::vector<FilePathInfo> matches;
     40   for (base::FilePath current = files.Next(); !current.empty();
     41       current = files.Next()) {
     42     FilePathInfo entry;
     43     entry.info = files.GetInfo();
     44     entry.path = current;
     45     matches.push_back(entry);
     46   }
     47 
     48   if (matches.empty())
     49     return false;
     50 
     51   std::sort(matches.begin(), matches.end(), CompareDate);
     52   std::vector<FilePathInfo>::iterator current;
     53   for (current = matches.begin(); current != matches.end(); ++current) {
     54     paths->push_back(current->path);
     55   }
     56   return true;
     57 }
     58 
     59 bool FindNewestMatchingFile(const base::FilePath& root,
     60                             const std::string& pattern,
     61                             base::FileEnumerator::FileType type,
     62                             base::FilePath* path) {
     63   std::vector<base::FilePath> paths;
     64   if (FindMatchingFiles(root, pattern, type, &paths)) {
     65     *path = paths[0];
     66     return true;
     67   }
     68   return false;
     69 }
     70 
     71 }  // namespace
     72 
     73 namespace installer_test {
     74 
     75 InstallerPathProvider::InstallerPathProvider() {
     76   base::FilePath full_installer, previous_installer;
     77   if (!GetFullInstaller(&full_installer) ||
     78       !GetPreviousInstaller(&previous_installer))
     79     return;
     80   current_build_ =
     81       full_installer.DirName().DirName().BaseName().MaybeAsASCII();
     82   previous_build_ =
     83       previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
     84 }
     85 
     86 InstallerPathProvider::InstallerPathProvider(
     87     const std::string& build_under_test) : current_build_(build_under_test) {
     88   base::FilePath full_installer, previous_installer;
     89   if (!GetFullInstaller(&full_installer) ||
     90       !GetPreviousInstaller(&previous_installer))
     91     return;
     92   previous_build_ =
     93       previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
     94 }
     95 
     96 InstallerPathProvider::~InstallerPathProvider() {}
     97 
     98 bool InstallerPathProvider::GetFullInstaller(base::FilePath* path) {
     99   std::string full_installer_pattern("*_chrome_installer*");
    100   return GetInstaller(full_installer_pattern, path);
    101 }
    102 
    103 bool InstallerPathProvider::GetDiffInstaller(base::FilePath* path) {
    104   std::string diff_installer_pattern("*_from_*");
    105   return GetInstaller(diff_installer_pattern, path);
    106 }
    107 
    108 bool InstallerPathProvider::GetMiniInstaller(base::FilePath* path) {
    109   // Use local copy of installer, else fall back to filer.
    110   base::FilePath mini_installer = PathFromExeDir(
    111       mini_installer_constants::kChromeMiniInstallerExecutable);
    112   if (base::PathExists(mini_installer)) {
    113     *path = mini_installer;
    114     return true;
    115   }
    116   std::string mini_installer_pattern("mini_installer.exe");
    117   return GetInstaller(mini_installer_pattern, path);
    118 }
    119 
    120 bool InstallerPathProvider::GetPreviousInstaller(base::FilePath* path) {
    121   std::string diff_installer_pattern("*_from_*");
    122   std::string full_installer_pattern("*_chrome_installer*");
    123   base::FilePath diff_installer;
    124   if (!GetInstaller(diff_installer_pattern, &diff_installer))
    125     return false;
    126 
    127   base::FilePath previous_installer;
    128   std::vector<std::string> tokenized_name;
    129   Tokenize(diff_installer.BaseName().MaybeAsASCII(),
    130       "_", &tokenized_name);
    131   std::string build_pattern = base::StringPrintf(
    132       "*%s", tokenized_name[2].c_str());
    133   std::vector<base::FilePath> previous_build;
    134   if (FindMatchingFiles(diff_installer.DirName().DirName().DirName(),
    135       build_pattern, base::FileEnumerator::DIRECTORIES,
    136       &previous_build)) {
    137     base::FilePath windir = previous_build.at(0).Append(
    138         mini_installer_constants::kWinFolder);
    139     FindNewestMatchingFile(windir, full_installer_pattern,
    140         base::FileEnumerator::FILES, &previous_installer);
    141   }
    142 
    143   if (previous_installer.empty())
    144     return false;
    145   *path = previous_installer;
    146   return true;
    147 }
    148 
    149 bool InstallerPathProvider::GetStandaloneInstaller(base::FilePath* path) {
    150   // Get standalone installer.
    151   base::FilePath standalone_installer(
    152       mini_installer_constants::kChromeStandAloneInstallerLocation);
    153   // Get the file name.
    154   std::vector<std::string> tokenized_build_number;
    155   if (current_build_.empty())
    156     return false;
    157   Tokenize(current_build_, ".", &tokenized_build_number);
    158   std::string standalone_installer_filename = base::StringPrintf(
    159       "%s%s_%s.exe",
    160       base::FilePath(mini_installer_constants::kUntaggedInstallerPattern)
    161           .MaybeAsASCII().c_str(),
    162       tokenized_build_number[2].c_str(),
    163       tokenized_build_number[3].c_str());
    164   standalone_installer = standalone_installer.AppendASCII(current_build_)
    165       .Append(mini_installer_constants::kWinFolder)
    166       .AppendASCII(standalone_installer_filename);
    167   *path = standalone_installer;
    168   return base::PathExists(standalone_installer);
    169 }
    170 
    171 bool InstallerPathProvider::GetSignedStandaloneInstaller(base::FilePath* path) {
    172   base::FilePath standalone_installer;
    173   if (!GetStandaloneInstaller(&standalone_installer))
    174     return false;
    175   base::FilePath tagged_installer = PathFromExeDir(
    176       mini_installer_constants::kStandaloneInstaller);
    177   CommandLine sign_command = CommandLine::FromString(
    178       base::StringPrintf(L"%ls %ls %ls %ls",
    179       mini_installer_constants::kChromeApplyTagExe,
    180       standalone_installer.value().c_str(),
    181       tagged_installer.value().c_str(),
    182       mini_installer_constants::kChromeApplyTagParameters));
    183 
    184   if (!installer_test::RunAndWaitForCommandToFinish(sign_command))
    185     return false;
    186 
    187   *path = PathFromExeDir(mini_installer_constants::kStandaloneInstaller);
    188   return true;
    189 }
    190 
    191 base::FilePath InstallerPathProvider::PathFromExeDir(
    192     const base::FilePath::StringType& name) {
    193   base::FilePath path;
    194   PathService::Get(base::DIR_EXE, &path);
    195   path = path.Append(name);
    196   return path;
    197 }
    198 
    199 bool InstallerPathProvider::GetInstaller(const std::string& pattern,
    200                                          base::FilePath* path) {
    201   base::FilePath installer;
    202   // Search filer for installer binary.
    203   base::FilePath root(mini_installer_constants::kChromeInstallersLocation);
    204   std::vector<base::FilePath> paths;
    205   if (!FindMatchingFiles(root, current_build_,
    206                          base::FileEnumerator::DIRECTORIES, &paths)) {
    207     return false;
    208   }
    209 
    210   std::vector<base::FilePath>::const_iterator dir;
    211   for (dir = paths.begin(); dir != paths.end(); ++dir) {
    212     base::FilePath windir = dir->Append(
    213         mini_installer_constants::kWinFolder);
    214     if (FindNewestMatchingFile(windir, pattern, base::FileEnumerator::FILES,
    215                                &installer)) {
    216       break;
    217     }
    218   }
    219 
    220   if (installer.empty()) {
    221     LOG(WARNING) << "Failed to find installer with pattern: " << pattern;
    222     return false;
    223   }
    224 
    225   *path = installer;
    226   return true;
    227 }
    228 
    229 std::string InstallerPathProvider::GetCurrentBuild() {
    230   return current_build_;
    231 }
    232 
    233 std::string InstallerPathProvider::GetPreviousBuild() {
    234   return previous_build_;
    235 }
    236 
    237 }  // namespace
    238