wpkg test coverage results

Coverage test results of the Windows Packager by Made to Order Software Corporation.

LCOV - code coverage report
Current view: top level - tests/unittests - unittest_package.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1169 1192 98.1 %
Date: 2013-06-17 Functions: 36 37 97.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*    unittest_package.cpp
       2             :  *    Copyright (C) 2013  Made to Order Software Corporation
       3             :  *
       4             :  *    This program is free software; you can redistribute it and/or modify
       5             :  *    it under the terms of the GNU General Public License as published by
       6             :  *    the Free Software Foundation; either version 2 of the License, or
       7             :  *    (at your option) any later version.
       8             :  *
       9             :  *    This program is distributed in the hope that it will be useful,
      10             :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  *    GNU General Public License for more details.
      13             :  *
      14             :  *    You should have received a copy of the GNU General Public License along
      15             :  *    with this program; if not, write to the Free Software Foundation, Inc.,
      16             :  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  *
      18             :  *    Authors
      19             :  *    Alexis Wilke   alexis@m2osw.com
      20             :  */
      21             : 
      22             : #include "unittest_package.h"
      23             : #include "unittest_main.h"
      24             : #include "libdebpackages/debian_packages.h"
      25             : #include "libdebpackages/wpkg_control.h"
      26             : #include <stdexcept>
      27             : #include <cstring>
      28             : 
      29             : // for the WEXITSTATUS()
      30             : #ifdef __GNUC__
      31             : #       pragma GCC diagnostic ignored "-Wold-style-cast"
      32             : #endif
      33             : 
      34           1 : CPPUNIT_TEST_SUITE_REGISTRATION( PackageUnitTests );
      35             : 
      36          17 : void PackageUnitTests::setUp()
      37             : {
      38             :     // make sure that the temporary directory is not empty, may be relative
      39          17 :     if(unittest::tmp_dir.empty())
      40             :     {
      41           0 :         fprintf(stderr, "\nerror:unittest_package: a temporary directory is required to run the package unit tests.\n");
      42           0 :         throw std::runtime_error("--tmp <directory> missing");
      43             :     }
      44             : 
      45             :     // path to the wpkg tool must not be empty either, may be relative
      46          17 :     if(unittest::wpkg_tool.empty())
      47             :     {
      48           0 :         fprintf(stderr, "\nerror:unittest_package: the path to the wpkg tool is required; we do not use chdir() so a relative path will do.\n");
      49           0 :         throw std::runtime_error("--wpkg <path-to-wpkg> missing");
      50             :     }
      51             : 
      52             :     // delete everything before running ANY ONE TEST
      53             :     // (i.e. the setUp() function is called before any test)
      54          17 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
      55             :     try
      56             :     {
      57          17 :         memfile::memory_file::unlink_rf(root);
      58             :     }
      59           0 :     catch(const memfile::memfile_exception_io&)
      60             :     {
      61             : #ifdef MO_WINDOWS
      62             :         // at times MS-Windows needs a little pause...
      63             :         fprintf(stderr, "\n+++ Pause Between Package Tests +++\n");
      64             :         Sleep(200);
      65             :         memfile::memory_file::unlink_rf(root);
      66             : #else
      67             :         // otherwise just rethrow
      68           0 :         throw;
      69             : #endif
      70             :     }
      71             : 
      72          17 :     printf("\n");
      73          17 : }
      74             : 
      75             : ///////////////////////////////////////////////////////////////////////////
      76             : ///////////////////////////////////////////////////////////////////////////
      77             : //                                                                       //
      78             : //     MANY FUNCTIONS USED TO FACILITATE THE DEVELOPMENT OF TESTS        //
      79             : //                                                                       //
      80             : ///////////////////////////////////////////////////////////////////////////
      81             : ///////////////////////////////////////////////////////////////////////////
      82             : 
      83             : namespace
      84             : {
      85             : typedef std::vector<std::string> string_list;
      86             : 
      87             : /** \brief create a standard control file
      88             :  *
      89             :  * This function allocates a control file and creates 4 of the 5
      90             :  * mandatory fields. It does not create the Package field because
      91             :  * that's set when you want to create the package.
      92             :  *
      93             :  * \param[in] test_name  The name of the test, to recognize the package as coming from that specific test.
      94             :  */
      95         396 : std::tr1::shared_ptr<wpkg_control::control_file> get_new_control_file(const std::string& test_name)
      96             : {
      97         396 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl(new wpkg_control::control_file);
      98             : 
      99             :     //ctrl->set_field("Package", ...); -- this is set by the create_package() call
     100         396 :     ctrl->set_field("Description", "Test " + test_name);
     101         396 :     ctrl->set_field("Architecture", debian_packages_architecture());
     102         396 :     ctrl->set_field("Maintainer", "Alexis Wilke <alexis@m2osw.com>");
     103         396 :     ctrl->set_field("Version", "1.0");
     104             : 
     105         396 :     return ctrl;
     106             : }
     107             : 
     108             : /** \brief Create a randomized file.
     109             :  *
     110             :  * To fill packages with actual files, we create them with random data
     111             :  * so they look real enough. These can then be used to check that the
     112             :  * --install, --unpack commands indeed install the files as expected.
     113             :  * We can also test that they do get removed too.
     114             :  *
     115             :  * The function makes use of the size as specified in the \p files
     116             :  * parameter list. If the size is zero ("undefined") then a random
     117             :  * size is choosen between 0 and 0x3FFFF (262143 bytes).
     118             :  *
     119             :  * Note that path is the directory name of the package, not the
     120             :  * exact path where the file is saved. This is because the \p files
     121             :  * filename may include a path too (i.e. /usr/share/doc/t1/copyright).
     122             :  *
     123             :  * \param[in] files  The list of files that we want created.
     124             :  * \param[in] idx  The index of the file to create on this call.
     125             :  * \param[in] path  The output directory where the file is to be saved.
     126             :  */
     127         849 : void create_file(wpkg_control::file_list_t& files, wpkg_control::file_list_t::size_type idx, wpkg_filename::uri_filename path)
     128             : {
     129         849 :     std::string filename(files[idx].get_filename());
     130         849 :     size_t size(files[idx].get_size());
     131         849 :     if(size == 0)
     132             :     {
     133         849 :         size = rand() & 0x3FFFF;
     134         849 :         files[idx].set_size(size);
     135             :     }
     136         849 :     memfile::memory_file file;
     137         849 :     file.create(memfile::memory_file::file_format_other);
     138   109637598 :     for(size_t i(0); i < size; ++i)
     139             :     {
     140   109636749 :         char c(rand() & 255);
     141   109636749 :         file.write(&c, static_cast<int>(i), static_cast<int>(sizeof(c)));
     142             :     }
     143         849 :     file.write_file(path.append_child(filename), true);
     144             : 
     145         849 :     files[idx].set_checksum(file.md5sum());
     146         849 : }
     147             : 
     148             : /** \brief Create (i.e. --build) a package.
     149             :  *
     150             :  * This function creates a package environment, randomized files, and
     151             :  * then build a package with the wpkg command line tool.
     152             :  *
     153             :  * The control file passed down will always have its Package field set
     154             :  * to the specified \p name parameter. It is also expected to have a
     155             :  * Files field, it is used to create all the files added to that package.
     156             :  * It also makes use of a few variables to add command line options to
     157             :  * the command:
     158             :  *
     159             :  * \li BUILD_PREOPTIONS -- command line options added before the --build
     160             :  * \li BUILD_POSTOPTIONS -- command line options added after the --build
     161             :  *
     162             :  * \param[in] name  The name of the of the package.
     163             :  * \param[in] ctrl  The control file for that package.
     164             :  */
     165         282 : void create_package(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl, bool reset_wpkg_dir = true)
     166             : {
     167         282 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     168         282 :     wpkg_filename::uri_filename build_path(root.append_child(name));
     169         282 :     wpkg_filename::uri_filename wpkg_path(build_path.append_child("WPKG"));
     170             : 
     171             :     // clean up the directory
     172         282 :     if(reset_wpkg_dir)
     173             :     {
     174         276 :         memfile::memory_file::unlink_rf(build_path);
     175             :     }
     176             : 
     177         282 :     ctrl->set_field("Package", name);
     178             : 
     179             :     // handle the files before saving the control file so we can fix the md5sum
     180         282 :     wpkg_control::file_list_t files(ctrl->get_files("Files"));
     181         282 :     wpkg_control::file_list_t::size_type max(files.size());
     182        1131 :     for(wpkg_control::file_list_t::size_type i(0); i < max; ++i)
     183             :     {
     184         849 :         create_file(files, i, build_path);
     185             :     }
     186         282 :     ctrl->set_field("Files", wpkg_control::to_string(files));
     187             : 
     188         282 :     if(ctrl->field_is_defined("Conffiles"))
     189             :     {
     190         150 :         wpkg_control::file_list_t conffiles(ctrl->get_files("Conffiles"));
     191         150 :         memfile::memory_file conffiles_output;
     192         150 :         conffiles_output.create(memfile::memory_file::file_format_other);
     193         150 :         conffiles_output.printf("%s\n", wpkg_control::to_string(conffiles, wpkg_control::file_item::format_list, false).c_str());
     194         150 :         wpkg_filename::uri_filename conffiles_filename(wpkg_path.append_child("conffiles"));
     195         150 :         conffiles_output.write_file(conffiles_filename, true);
     196         150 :         ctrl->delete_field("Conffiles");
     197             :     }
     198             : 
     199         282 :     memfile::memory_file ctrl_output;
     200         282 :     ctrl->write(ctrl_output);
     201         282 :     ctrl_output.write_file(wpkg_path.append_child("control"), true);
     202             : 
     203         282 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
     204         282 :     repository.os_mkdir_p();
     205             : 
     206         282 :     std::string cmd(unittest::wpkg_tool);
     207         282 :     if(ctrl->variable_is_defined("BUILD_PREOPTIONS"))
     208             :     {
     209           0 :         cmd += " " + ctrl->get_variable("BUILD_PREOPTIONS");
     210             :     }
     211         282 :     cmd += " --output-dir " + repository.path_only();
     212         282 :     cmd += " --build " + build_path.path_only();
     213         282 :     if(ctrl->variable_is_defined("BUILD_POSTOPTIONS"))
     214             :     {
     215           0 :         cmd += " " + ctrl->get_variable("BUILD_POSTOPTIONS");
     216             :     }
     217         282 :     printf("Build Command: \"%s\"\n", cmd.c_str());
     218         282 :     fflush(stdout);
     219         282 :     CPPUNIT_ASSERT(system(cmd.c_str()) == 0);
     220         282 : }
     221             : 
     222             : /** \brief Install a package that you previously created.
     223             :  *
     224             :  * This function runs wpkg --install to install a .deb file as
     225             :  * generated by the create_package() function. The .deb is
     226             :  * expected to be in the repository and have a version and
     227             :  * architecture specification (TODO: check if architecture
     228             :  * is "src"/"source" and do not add it in that case.)
     229             :  *
     230             :  * We take the control file as a parameter so we can make use
     231             :  * of some variables:
     232             :  *
     233             :  * \li INSTALL_PREOPTIONS -- command line options added before the --install
     234             :  * \li INSTALL_POSTOPTIONS -- command line options added after the --install
     235             :  *
     236             :  * \param[in] name  The name of the package as passed to create_package().
     237             :  * \param[in] ctrl  The control file as passed to create_package().
     238             :  */
     239         293 : void install_package(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl, int expected_return_value = 0)
     240             : {
     241         293 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     242         293 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     243         293 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
     244             : 
     245         293 :     if(!target_path.is_dir() || !target_path.append_child("var/lib/wpkg/core").exists())
     246             :     {
     247          16 :         target_path.os_mkdir_p();
     248          16 :         wpkg_filename::uri_filename core_ctrl_filename(repository.append_child("core.ctrl"));
     249          16 :         memfile::memory_file core_ctrl;
     250          16 :         core_ctrl.create(memfile::memory_file::file_format_other);
     251          16 :         core_ctrl.printf("Architecture: %s\nMaintainer: Alexis Wilke <alexis@m2osw.com>\n", debian_packages_architecture());
     252          16 :         if(ctrl->variable_is_defined("INSTALL_EXTRACOREFIELDS"))
     253             :         {
     254           0 :             core_ctrl.printf("%s", ctrl->get_variable("INSTALL_EXTRACOREFIELDS").c_str());
     255             :         }
     256          16 :         core_ctrl.write_file(core_ctrl_filename);
     257          16 :         std::string core_cmd(unittest::wpkg_tool + " --root " + target_path.path_only() + " --create-admindir " + core_ctrl_filename.path_only());
     258          16 :         printf("Create AdminDir Command: \"%s\"\n", core_cmd.c_str());
     259          16 :         fflush(stdout);
     260          16 :         CPPUNIT_ASSERT(system(core_cmd.c_str()) == 0);
     261             :     }
     262             : 
     263         293 :     std::string cmd(unittest::wpkg_tool);
     264         293 :     if(ctrl->variable_is_defined("INSTALL_PREOPTIONS"))
     265             :     {
     266         130 :         cmd += " " + ctrl->get_variable("INSTALL_PREOPTIONS");
     267             :     }
     268         293 :     if(!ctrl->variable_is_defined("INSTALL_NOROOT"))
     269             :     {
     270         288 :         cmd += " --root " + target_path.path_only();
     271             :     }
     272         293 :     cmd += " --install " + repository.append_child("/" + name + "_" + ctrl->get_field("Version") + "_" + ctrl->get_field("Architecture") + ".deb").path_only();
     273         293 :     if(ctrl->variable_is_defined("INSTALL_POSTOPTIONS"))
     274             :     {
     275         135 :         cmd += " " + ctrl->get_variable("INSTALL_POSTOPTIONS");
     276             :     }
     277         293 :     printf("Install Command: \"%s\"\n", cmd.c_str());
     278         293 :     fflush(stdout);
     279         293 :     int r(system(cmd.c_str()));
     280         293 :     printf("  Install result = %d (expected %d)\n", WEXITSTATUS(r), expected_return_value);
     281         293 :     CPPUNIT_ASSERT(WEXITSTATUS(r) == expected_return_value);
     282         293 : }
     283             : 
     284             : /** \brief Remove a package as the --remove command does.
     285             :  *
     286             :  * This function runs the wpkg --remove command with the specified package
     287             :  * name. The result should be the module removed from the target.
     288             :  *
     289             :  * \param[in] name  The name of the package to remove.
     290             :  * \param[in] ctrl  The control file fields.
     291             :  */
     292          18 : void remove_package(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl, int expected_return_value = 0)
     293             : {
     294          18 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     295          18 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     296             : 
     297          18 :     std::string cmd(unittest::wpkg_tool);
     298          18 :     if(ctrl->variable_is_defined("REMOVE_PREOPTIONS"))
     299             :     {
     300           5 :         cmd += " " + ctrl->get_variable("REMOVE_PREOPTIONS");
     301             :     }
     302          18 :     if(!ctrl->variable_is_defined("REMOVE_NOROOT"))
     303             :     {
     304          16 :         cmd += " --root " + target_path.path_only();
     305             :     }
     306          18 :     cmd += " --remove " + name;
     307          18 :     if(ctrl->variable_is_defined("REMOVE_POSTOPTIONS"))
     308             :     {
     309           1 :         cmd += " " + ctrl->get_variable("REMOVE_POSTOPTIONS");
     310             :     }
     311          18 :     printf("Remove Command: \"%s\"\n", cmd.c_str());
     312          18 :     fflush(stdout);
     313          18 :     int r(system(cmd.c_str()));
     314          18 :     printf("  Remove result = %d (expected %d)\n", WEXITSTATUS(r), expected_return_value);
     315          18 :     CPPUNIT_ASSERT(WEXITSTATUS(r) == expected_return_value);
     316          18 : }
     317             : 
     318             : /** \brief Purge a package as the --purge command does.
     319             :  *
     320             :  * This function runs the wpkg --purge command with the specified package
     321             :  * name. The result should be the module completely from the target (i.e.
     322             :  * all the files including the configuration files.)
     323             :  *
     324             :  * \param[in] name  The name of the package to remove.
     325             :  * \param[in] ctrl  The control file fields.
     326             :  */
     327          20 : void purge_package(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl, int expected_return_value = 0)
     328             : {
     329          20 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     330          20 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     331             : 
     332          20 :     std::string cmd(unittest::wpkg_tool);
     333          20 :     if(ctrl->variable_is_defined("PURGE_PREOPTIONS"))
     334             :     {
     335           4 :         cmd += " " + ctrl->get_variable("PURGE_PREOPTIONS");
     336             :     }
     337          20 :     if(!ctrl->variable_is_defined("PURGE_NOROOT"))
     338             :     {
     339          17 :         cmd += " --root " + target_path.path_only();
     340             :     }
     341          20 :     cmd += " --purge " + name;
     342          20 :     if(ctrl->variable_is_defined("PURGE_POSTOPTIONS"))
     343             :     {
     344           0 :         cmd += " " + ctrl->get_variable("PURGE_POSTOPTIONS");
     345             :     }
     346          20 :     printf("Purge Command: \"%s\"\n", cmd.c_str());
     347          20 :     fflush(stdout);
     348          20 :     int r(system(cmd.c_str()));
     349          20 :     printf("  Purge result = %d (expected %d)\n", WEXITSTATUS(r), expected_return_value);
     350          20 :     CPPUNIT_ASSERT(WEXITSTATUS(r) == expected_return_value);
     351          20 : }
     352             : 
     353             : /** \brief Compare files from the build directories with those from the target.
     354             :  *
     355             :  * This function compares the files that were used to create a .deb
     356             :  * against those that were installed from that .deb in a target. It
     357             :  * ensures that the files are binary equal to each other (as they
     358             :  * should be as we do not process files at all.)
     359             :  *
     360             :  * This process works as long as the source package directory did
     361             :  * not get replaced (i.e. newer version replacing the older version
     362             :  * to test an upgrade, etc.)
     363             :  *
     364             :  * \param[in] name  The name of the package to check.
     365             :  */
     366          51 : void verify_installed_files(const std::string& name)
     367             : {
     368          51 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     369          51 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     370          51 :     wpkg_filename::uri_filename build_path(root.append_child(name));
     371          51 :     memfile::memory_file dir;
     372          51 :     dir.dir_rewind(build_path);
     373        1508 :     for(;;)
     374             :     {
     375        1559 :         memfile::memory_file::file_info info;
     376        1559 :         memfile::memory_file data;
     377        1559 :         if(!dir.dir_next(info, &data))
     378             :         {
     379             :             break;
     380             :         }
     381        3273 :         if(info.get_file_type() == memfile::memory_file::file_info::regular_file
     382        1765 :         && strstr(info.get_filename().c_str(), "/WPKG/") == NULL)
     383             :         {
     384         165 :             wpkg_filename::uri_filename installed_name(info.get_uri());
     385         165 :             installed_name = installed_name.remove_common_segments(build_path);
     386         165 :             installed_name = target_path.append_child(installed_name.path_only());
     387         165 :             memfile::memory_file target_data;
     388         165 :             target_data.read_file(installed_name);
     389        1508 :             CPPUNIT_ASSERT_MESSAGE(installed_name.original_filename(), target_data.compare(data) == 0);
     390             :         }
     391        1559 :     }
     392          51 : }
     393             : 
     394             : 
     395         164 : struct verify_file_t
     396             : {
     397             :     enum verify_modes
     398             :     {
     399             :         verify_deleted,
     400             :         verify_exists,
     401             :         verify_content,
     402             :         verify_text
     403             :     };
     404             :     typedef controlled_vars::limited_auto_init<verify_modes, verify_deleted, verify_text, verify_exists> verify_mode_t;
     405           3 :     void clear()
     406             :     {
     407           3 :         f_mode = static_cast<int>(verify_exists); // FIXME cast
     408           3 :         f_filename = "";
     409           3 :         f_data = "";
     410           3 :     }
     411             : 
     412             :     verify_mode_t               f_mode;
     413             :     std::string                 f_filename;
     414             :     std::string                 f_data;
     415             : };
     416             : typedef std::vector<verify_file_t> verify_file_vector_t;
     417             : 
     418             : /** \brief Compare files that scripts were expected to generate/delete.
     419             :  *
     420             :  * This function checks whether certain files are there or not there depending
     421             :  * on what the scripts are expected to do.
     422             :  *
     423             :  * The function accepts an array of verify_file_t structure. Each entry
     424             :  * has a relative filename starting at the root of the installation target.
     425             :  * The mode defines how the file will be tested:
     426             :  *
     427             :  * \li verify_deleted -- the file must not exist
     428             :  * \li verify_exists -- the file must exist
     429             :  * \li verify_content -- the file must exist and its content match one to one
     430             :  * \li verify_text -- the file must exist and its text content must match;
     431             :  *                    since this is viewed as text, new lines and carriage
     432             :  *                    returns are all checked as \n (so \n, \r\n, and \r
     433             :  *                    are all viewed as one \n.)
     434             :  *
     435             :  * The f_data parameter is a string (verify_text) or a binary buffer
     436             :  * (verify_content). In the former case, the string is taken as binary
     437             :  * and thus the size is used to determine the end of the content (i.e.
     438             :  * the buffer can include '\0'.)
     439             :  *
     440             :  * \param[in] name  The name of the package to check.
     441             :  */
     442          10 : void verify_generated_files(const verify_file_vector_t& files)
     443             : {
     444          10 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     445          10 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     446             : 
     447          59 :     for(verify_file_vector_t::const_iterator it(files.begin()); it != files.end(); ++it)
     448             :     {
     449          49 :         wpkg_filename::uri_filename filename(target_path.append_child(it->f_filename));
     450          49 :         switch(it->f_mode)
     451             :         {
     452             :         case verify_file_t::verify_deleted:
     453          35 :             CPPUNIT_ASSERT_MESSAGE("file is not expected to exist \"" + filename.original_filename() + "\"", !filename.exists());
     454          35 :             break;
     455             : 
     456             :         case verify_file_t::verify_exists:
     457           0 :             CPPUNIT_ASSERT_MESSAGE("file is expected to exist \"" + filename.original_filename() + "\"", filename.exists());
     458           0 :             break;
     459             : 
     460             :         case verify_file_t::verify_content:
     461           0 :             CPPUNIT_ASSERT_MESSAGE("file is expected to exist \"" + filename.original_filename() + "\"", filename.exists());
     462             :             {
     463           0 :                 memfile::memory_file disk_data;
     464           0 :                 disk_data.read_file(filename);
     465           0 :                 CPPUNIT_ASSERT_MESSAGE("file content size does not match \"" + filename.original_filename() + "\"", static_cast<size_t>(disk_data.size()) == it->f_data.size());
     466           0 :                 memfile::memory_file test_data;
     467           0 :                 test_data.create(memfile::memory_file::file_format_other);
     468           0 :                 test_data.write(it->f_data.c_str(), 0, it->f_data.size());
     469           0 :                 CPPUNIT_ASSERT_MESSAGE("file content does not match \"" + filename.original_filename() + "\"", disk_data.compare(test_data) == 0);
     470             :             }
     471           0 :             break;
     472             : 
     473             :         case verify_file_t::verify_text:
     474          14 :             CPPUNIT_ASSERT_MESSAGE("file is expected to exist " + filename.original_filename(), filename.exists());
     475             :             {
     476          14 :                 memfile::memory_file disk_data;
     477          14 :                 disk_data.read_file(filename);
     478          14 :                 memfile::memory_file test_data;
     479          14 :                 test_data.create(memfile::memory_file::file_format_other);
     480          14 :                 test_data.write(it->f_data.c_str(), 0, it->f_data.size());
     481             : 
     482          14 :                 std::string disk_line, test_line;
     483          14 :                 int disk_offset(0), test_offset(0);
     484          28 :                 for(;;)
     485             :                 {
     486          42 :                     bool disk_result(disk_data.read_line(disk_offset, disk_line));
     487          42 :                     bool test_result(test_data.read_line(test_offset, test_line));
     488          42 :                     CPPUNIT_ASSERT_MESSAGE("file content does not match \"" + filename.original_filename() + "\" (early EOF on one of the files)", disk_result == test_result);
     489          42 :                     if(!disk_result)
     490             :                     {
     491          14 :                         break;
     492             :                     }
     493          28 :                     CPPUNIT_ASSERT_MESSAGE("file lines \"" + disk_line + "\" and \"" + test_line + "\" do not match for \"" + filename.original_filename() + "\" (lines are invalid)", disk_line == test_line);
     494          14 :                 }
     495             :             }
     496          14 :             break;
     497             : 
     498             :         }
     499          49 :         switch(it->f_mode)
     500             :         {
     501             :         case verify_file_t::verify_deleted:
     502          35 :             break;
     503             : 
     504             :         default:
     505          14 :             filename.os_unlink();
     506          14 :             break;
     507             : 
     508             :         }
     509          59 :     }
     510          10 : }
     511             : 
     512             : /** \brief Check that a package was properly removed.
     513             :  *
     514             :  * The name of the package that got removed.
     515             :  *
     516             :  * This function skips the package configuration files since a remove does
     517             :  * not delete those. It checks all the other files though. The \p ctrl object
     518             :  * is used to gather the list of configuration files. Remember that the list
     519             :  * of configuration files is removed when we create (--build) the package.
     520             :  * So before calling this function you have to redefine the field.
     521             :  *
     522             :  * \param[in] name  The name of the package that was purged.
     523             :  * \param[in] ctrl  The control file with fields.
     524             :  */
     525          15 : void verify_removed_files(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl)
     526             : {
     527          15 :     wpkg_control::file_list_t conffiles;
     528          15 :     if(ctrl->field_is_defined("Conffiles"))
     529             :     {
     530           7 :         conffiles = ctrl->get_files("Conffiles");
     531             :     }
     532          15 :     wpkg_control::file_list_t::size_type max(conffiles.size());
     533          15 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     534          15 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     535          15 :     wpkg_filename::uri_filename build_path(root.append_child(name));
     536          15 :     memfile::memory_file dir;
     537          15 :     dir.dir_rewind(build_path);
     538         436 :     for(;;)
     539             :     {
     540         451 :         memfile::memory_file::file_info info;
     541         451 :         if(!dir.dir_next(info, NULL))
     542             :         {
     543             :             break;
     544             :         }
     545         948 :         if(info.get_file_type() == memfile::memory_file::file_info::regular_file
     546         512 :         && strstr(info.get_filename().c_str(), "/WPKG/") == NULL)
     547             :         {
     548          47 :             wpkg_filename::uri_filename installed_name(info.get_uri());
     549          47 :             installed_name = installed_name.remove_common_segments(build_path);
     550          47 :             std::string absolute_filename(installed_name.path_only());
     551          47 :             if(!installed_name.is_absolute())
     552             :             {
     553          47 :                 absolute_filename = "/" + absolute_filename;
     554             :             }
     555          47 :             bool found(false);
     556          64 :             for(wpkg_control::file_list_t::size_type i(0); i < max; ++i)
     557             :             {
     558          23 :                 std::string conf(conffiles[i].get_filename().c_str());
     559             : 
     560          23 :                 std::string conf_filename(conffiles[i].get_filename());
     561          23 :                 if(!conf_filename.empty() && conf_filename[0] != '/')
     562             :                 {
     563          16 :                     conf_filename = "/" + conf_filename;
     564             :                 }
     565          23 :                 if(conf_filename == absolute_filename)
     566             :                 {
     567          23 :                     found = true;
     568             :                     break;
     569             :                 }
     570          23 :             }
     571          47 :             if(!found)
     572             :             {
     573             :                 // not found as one of the configuration file so it must have
     574             :                 // been deleted, verify
     575          41 :                 installed_name = target_path.append_child(installed_name.path_only());
     576          41 :                 if(installed_name.exists())
     577             :                 {
     578           0 :                     fprintf(stderr, "error: file \"%s\" was expected to be removed, it is still present.\n", installed_name.path_only().c_str());
     579           0 :                     CPPUNIT_ASSERT(!"removed file still exists!?");
     580             :                 }
     581         436 :             }
     582             :         }
     583         451 :     }
     584          15 : }
     585             : 
     586             : /** \brief Check that a package was properly purged.
     587             :  *
     588             :  * The name of the package that got purged.
     589             :  *
     590             :  * This function checks the package configuration files and all are removed
     591             :  * (i.e. the .wpkg-new, .wkpg-old, and .wpkg-user extensions are checked too.)
     592             :  *
     593             :  * The list of exceptions are paths to files that will not have been purged,
     594             :  * as expected. This happens when we try to install and it fails because
     595             :  * of files that would otherwise get overwritten.
     596             :  *
     597             :  * \param[in] name  The name of the package that was purged.
     598             :  * \param[in] ctrl  The control file with fields.
     599             :  * \param[in] exceptions  List of exceptions; files that are still there
     600             :  */
     601          35 : void verify_purged_files(const std::string& name, std::tr1::shared_ptr<wpkg_control::control_file> ctrl, string_list exceptions = string_list())
     602             : {
     603          35 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     604          35 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     605          35 :     wpkg_filename::uri_filename build_path(root.append_child(name));
     606          35 :     memfile::memory_file dir;
     607          35 :     dir.dir_rewind(build_path);
     608        1066 :     for(;;)
     609             :     {
     610        1101 :         memfile::memory_file::file_info info;
     611        1101 :         if(!dir.dir_next(info, NULL))
     612             :         {
     613             :             break;
     614             :         }
     615        2306 :         if(info.get_file_type() == memfile::memory_file::file_info::regular_file
     616        1240 :         && strstr(info.get_filename().c_str(), "/WPKG/") == NULL)
     617             :         {
     618             :             // in this case all files must be gone
     619         118 :             wpkg_filename::uri_filename installed_name(info.get_uri());
     620         118 :             installed_name = installed_name.remove_common_segments(build_path);
     621         118 :             bool found(false);
     622         128 :             for(string_list::size_type i(0); i < exceptions.size(); ++i)
     623             :             {
     624          12 :                 if(installed_name.path_only() == exceptions[i])
     625             :                 {
     626           2 :                     found = true;
     627           2 :                     break;
     628             :                 }
     629             :             }
     630         118 :             installed_name = target_path.append_child(installed_name.path_only());
     631         118 :             if(found)
     632             :             {
     633             :                 // exceptions happen when we test overwrite problems
     634           2 :                 CPPUNIT_ASSERT(installed_name.exists());
     635             :             }
     636             :             else
     637             :             {
     638             : // this print useful if you're wondering why an exception fails (i.e. did you use an absolute path?)
     639             : //fprintf(stderr, "checking [%s]\n", installed_name.path_only().c_str());
     640         116 :                 CPPUNIT_ASSERT(!installed_name.exists());
     641        1066 :             }
     642             :         }
     643        1101 :     }
     644             : 
     645          35 :     wpkg_control::file_list_t conffiles;
     646          35 :     if(ctrl->field_is_defined("Conffiles"))
     647             :     {
     648          20 :         conffiles = ctrl->get_files("Conffiles");
     649          20 :         wpkg_control::file_list_t::size_type max(conffiles.size());
     650          40 :         for(wpkg_control::file_list_t::size_type i(0); i < max; ++i)
     651             :         {
     652          20 :             wpkg_filename::uri_filename conffile(target_path.append_child(conffiles[i].get_filename()));
     653             :             // assuming that the package was properly built, the next test is a repeat from the previous loop
     654          20 :             CPPUNIT_ASSERT(!conffile.exists());
     655             : 
     656             :             // different extensions
     657          20 :             wpkg_filename::uri_filename with_ext(conffile.path_only() + ".wpkg-new");
     658          20 :             CPPUNIT_ASSERT(!with_ext.exists());
     659          20 :             with_ext.set_filename(conffile.path_only() + ".wpkg-old");
     660          20 :             CPPUNIT_ASSERT(!with_ext.exists());
     661          20 :             with_ext.set_filename(conffile.path_only() + ".wpkg-user");
     662          20 :             CPPUNIT_ASSERT(!with_ext.exists());
     663          20 :         }
     664          35 :     }
     665          35 : }
     666             : 
     667             : } // noname namespace
     668             : 
     669             : 
     670             : 
     671             : ///////////////////////////////////////////////////////////////////////////
     672             : ///////////////////////////////////////////////////////////////////////////
     673             : //                                                                       //
     674             : //        ACTUAL TEST START HERE                                         //
     675             : //                                                                       //
     676             : ///////////////////////////////////////////////////////////////////////////
     677             : ///////////////////////////////////////////////////////////////////////////
     678             : 
     679             : 
     680             : 
     681           1 : void PackageUnitTests::simple_package()
     682             : {
     683             :     // IMPORTANT: remember that all files are deleted between tests
     684             : 
     685           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
     686             :     ctrl->set_field("Files", "conffiles\n"
     687             :         "/etc/t1.conf 0123456789abcdef0123456789abcdef\n"
     688             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
     689             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     690           1 :     );
     691           1 :     create_package("t1", ctrl);
     692             : 
     693           1 :     install_package("t1", ctrl);        // --install + --remove
     694           1 :     verify_installed_files("t1");
     695           1 :     remove_package("t1", ctrl);
     696           1 :     verify_removed_files("t1", ctrl);
     697             : 
     698           1 :     install_package("t1", ctrl);        // --install + --purge
     699           1 :     verify_installed_files("t1");
     700           1 :     purge_package("t1", ctrl);
     701           1 :     verify_purged_files("t1", ctrl);
     702             : 
     703           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     704             :     //wpkg_filename::uri_filename target_path(root.append_child("target"));
     705           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
     706             : 
     707           1 :     ctrl->set_variable("INSTALL_POSTOPTIONS", repository.append_child("/t1_" + ctrl->get_field("Version") + "_" + ctrl->get_field("Architecture") + ".deb").path_only());
     708           1 :     install_package("t1", ctrl);        // --install + --remove + --purge
     709           1 :     verify_installed_files("t1");
     710           1 :     remove_package("t1", ctrl);
     711           1 :     verify_removed_files("t1", ctrl);
     712           1 :     purge_package("t1", ctrl);
     713           1 :     verify_purged_files("t1", ctrl);
     714             : 
     715           1 :     install_package("t1", ctrl);        // --install + --install ("restore") + --purge
     716           1 :     verify_installed_files("t1");
     717           1 :     install_package("t1", ctrl);
     718           1 :     verify_installed_files("t1");
     719           1 :     purge_package("t1", ctrl);
     720           1 :     verify_purged_files("t1", ctrl);
     721           1 : }
     722             : 
     723           1 : void PackageUnitTests::admindir_package()
     724             : {
     725             :     // IMPORTANT: remember that all files are deleted between tests
     726             : 
     727           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
     728             :     ctrl->set_field("Files", "conffiles\n"
     729             :         "/etc/t1.conf 0123456789abcdef0123456789abcdef\n"
     730             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
     731             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     732           1 :     );
     733           1 :     create_package("t1", ctrl);
     734             : 
     735             :     // in this special case we want to create the target directory to avoid
     736             :     // the --create-admindir in it; then create and run --create-admindir
     737             :     // in the separate administration directory
     738           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     739           1 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     740           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
     741           1 :     wpkg_filename::uri_filename admindir(root.append_child("admin"));
     742           1 :     target_path.os_mkdir_p();
     743           1 :     admindir.os_mkdir_p();
     744           1 :     wpkg_filename::uri_filename core_ctrl_filename(repository.append_child("core.ctrl"));
     745           1 :     memfile::memory_file core_ctrl;
     746           1 :     core_ctrl.create(memfile::memory_file::file_format_other);
     747           1 :     core_ctrl.printf("Architecture: %s\nMaintainer: Alexis Wilke <alexis@m2osw.com>\n", debian_packages_architecture());
     748           1 :     core_ctrl.write_file(core_ctrl_filename);
     749           1 :     std::string core_cmd(unittest::wpkg_tool + " --admindir " + admindir.os_real_path().full_path() + " --create-admindir " + core_ctrl_filename.path_only());
     750           1 :     printf("  Specilized Create AdminDir Command: \"%s\"  ", core_cmd.c_str());
     751           1 :     fflush(stdout);
     752           1 :     CPPUNIT_ASSERT(system(core_cmd.c_str()) == 0);
     753           1 :     ctrl->set_variable("INSTALL_NOROOT", "Yes");
     754           1 :     ctrl->set_variable("INSTALL_PREOPTIONS", "--admindir " + admindir.os_real_path().full_path() + " --instdir " + target_path.os_real_path().full_path());
     755           1 :     ctrl->set_variable("REMOVE_NOROOT", "Yes");
     756           1 :     ctrl->set_variable("REMOVE_PREOPTIONS", "--admindir " + admindir.os_real_path().full_path() + " --instdir " + target_path.os_real_path().full_path());
     757           1 :     ctrl->set_variable("PURGE_NOROOT", "Yes");
     758           1 :     ctrl->set_variable("PURGE_PREOPTIONS", "--admindir " + admindir.os_real_path().full_path() + " --instdir " + target_path.os_real_path().full_path());
     759             : 
     760           1 :     install_package("t1", ctrl);        // --install + --remove
     761           1 :     verify_installed_files("t1");
     762           1 :     remove_package("t1", ctrl);
     763           1 :     verify_removed_files("t1", ctrl);
     764             : 
     765           1 :     install_package("t1", ctrl);        // --install + --purge
     766           1 :     verify_installed_files("t1");
     767           1 :     purge_package("t1", ctrl);
     768           1 :     verify_purged_files("t1", ctrl);
     769             : 
     770           1 :     install_package("t1", ctrl);        // --install + --remove + --purge
     771           1 :     verify_installed_files("t1");
     772           1 :     remove_package("t1", ctrl);
     773           1 :     verify_removed_files("t1", ctrl);
     774           1 :     purge_package("t1", ctrl);
     775           1 :     verify_purged_files("t1", ctrl);
     776             : 
     777           1 :     install_package("t1", ctrl);        // --install + --install ("restore") + --purge
     778           1 :     verify_installed_files("t1");
     779           1 :     install_package("t1", ctrl);
     780           1 :     verify_installed_files("t1");
     781           1 :     purge_package("t1", ctrl);
     782           1 :     verify_purged_files("t1", ctrl);
     783           1 : }
     784             : 
     785           1 : void PackageUnitTests::upgrade_package()
     786             : {
     787             :     // IMPORTANT: remember that all files are deleted between tests
     788             : 
     789           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
     790             :     ctrl->set_field("Files", "conffiles\n"
     791             :         "/etc/t1.conf 0123456789abcdef0123456789abcdef\n"
     792             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
     793             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     794           1 :     );
     795           1 :     create_package("t1", ctrl);
     796             : 
     797           1 :     install_package("t1", ctrl);        // --install
     798           1 :     verify_installed_files("t1");
     799             : 
     800             :     // replace /usr/bin/t1 with /usr/bin/t1-new
     801           1 :     ctrl->set_field("Version", "1.1");
     802             :     ctrl->set_field("Files", "conffiles\n"
     803             :         "/etc/t1.conf 0123456789abcdef0123456789abcdef\n"
     804             :         "/usr/bin/t1-new 0123456789abcdef0123456789abcdef\n"
     805             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     806           1 :     );
     807           1 :     create_package("t1", ctrl);
     808             : 
     809           1 :     install_package("t1", ctrl);        // --install ("upgrade")
     810           1 :     verify_installed_files("t1");
     811             : 
     812             :     // make sure that /usr/bin/t1 was removed
     813           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     814           1 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
     815           1 :     CPPUNIT_ASSERT(!target_path.append_child("usr/bin/t1").exists());
     816             : 
     817           1 :     root.append_child("t1").os_rename(root.append_child("t1-save"));
     818             : 
     819             :     // now test a downgrade
     820           1 :     ctrl->set_field("Version", "0.9");
     821             :     ctrl->set_field("Files", "conffiles\n"
     822             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
     823             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     824           1 :     );
     825           1 :     create_package("t1", ctrl);
     826             : 
     827           1 :     install_package("t1", ctrl, 1);        // --install ("upgrade")
     828             : 
     829             :     // restore the original t1 so we can verify that its files weren't modified
     830           1 :     memfile::memory_file::unlink_rf(root.append_child("t1"));
     831           1 :     root.append_child("t1-save").os_rename(root.append_child("t1"));
     832           1 :     verify_installed_files("t1");
     833           1 : }
     834             : 
     835           1 : void PackageUnitTests::depends_with_simple_packages()
     836             : {
     837             :     // IMPORTANT: remember that all files are deleted between tests
     838             : 
     839           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
     840             :     ctrl_t2->set_field("Files", "conffiles\n"
     841             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef\n"
     842             :         "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
     843             :         "/usr/bin/t2b 0123456789abcdef0123456789abcdef\n"
     844             :         "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
     845           1 :     );
     846           1 :     create_package("t2", ctrl_t2);
     847             :     ctrl_t2->set_variable("INSTALL_POSTOPTIONS",
     848             : #ifdef MO_WINDOWS
     849             :         // here we assume that you're running with cmd.exe which system() does
     850             :         // we have to duplicate all the double quotes
     851             :         "--validate-fields \"getfield(\"\"Version\"\") > \"\"0.9\"\"\""
     852             : #else
     853             :         "--validate-fields 'getfield(\"Version\") > \"0.9\"'"
     854             : #endif
     855           1 :     );
     856           1 :     install_package("t2", ctrl_t2);
     857           1 :     verify_installed_files("t2");
     858             : 
     859           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t3(get_new_control_file(__FUNCTION__));
     860             :     // Conffiles
     861             :     ctrl_t3->set_field("Conffiles", "\n"
     862             :         "/etc/t3/setup.conf 0123456789abcdef0123456789abcdef"
     863           1 :     );
     864             :     ctrl_t3->set_field("Files", "conffiles\n"
     865             :         "/etc/t3/setup.conf 0123456789abcdef0123456789abcdef\n"
     866             :         "/usr/bin/t3 0123456789abcdef0123456789abcdef\n"
     867             :         "/usr/share/doc/t3/copyright 0123456789abcdef0123456789abcdef\n"
     868           1 :     );
     869           1 :     ctrl_t3->set_field("Depends", "t2");
     870           1 :     create_package("t3", ctrl_t3);
     871             :     // Conffiles -- the create_package deletes this field
     872             :     ctrl_t3->set_field("Conffiles", "\n"
     873             :         "etc/t3/setup.conf 0123456789abcdef0123456789abcdef"
     874           1 :     );
     875           1 :     install_package("t3", ctrl_t3);
     876           1 :     verify_installed_files("t3");
     877           1 :     remove_package("t3", ctrl_t3);
     878           1 :     verify_removed_files("t3", ctrl_t3);
     879             : 
     880             :     // we couldn't have removed t2, t3 were still installed!
     881           1 :     remove_package("t2", ctrl_t3);
     882           1 :     verify_removed_files("t2", ctrl_t3);
     883             : 
     884             :     // now we can reinstall t2 and t3
     885           1 :     install_package("t2", ctrl_t2);
     886           1 :     verify_installed_files("t2");
     887             : 
     888           1 :     install_package("t3", ctrl_t3);
     889           1 :     verify_installed_files("t3");
     890             : 
     891           1 :     purge_package("t3", ctrl_t3);
     892           1 :     verify_purged_files("t3", ctrl_t3);
     893             : 
     894           1 :     purge_package("t2", ctrl_t2);
     895           1 :     verify_purged_files("t2", ctrl_t2);
     896             : 
     897             :     // test with the --repository option
     898           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
     899           1 :     wpkg_filename::uri_filename build_path_t2(root.append_child("t2"));
     900           1 :     wpkg_filename::uri_filename wpkg_path_t2(build_path_t2.append_child("WPKG"));
     901           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
     902           1 :     ctrl_t3->set_variable("INSTALL_PREOPTIONS", "--repository " + repository.path_only());
     903             : 
     904           1 :     install_package("t3", ctrl_t3);
     905           1 :     verify_installed_files("t3");
     906           1 :     verify_installed_files("t2"); // t2 was auto-installed, we can check that!
     907           1 :     remove_package("t3", ctrl_t3);
     908           1 :     verify_removed_files("t3", ctrl_t3);
     909             : 
     910           1 :     purge_package("t3", ctrl_t3);
     911           1 :     verify_purged_files("t3", ctrl_t3);
     912             : 
     913           1 :     purge_package("t2", ctrl_t2);
     914           1 :     verify_purged_files("t2", ctrl_t2);
     915             : 
     916             :     // the next test checks that t2 gets installed before t3 even though t2
     917             :     // is specified first on the command line; to do so, we add a simple
     918             :     // shell script that checks whether t3's files exist just before t2
     919             :     // gets unpacked
     920           1 :     memfile::memory_file preinst;
     921           1 :     preinst.create(memfile::memory_file::file_format_other);
     922             : #ifdef MO_WINDOWS
     923             :     preinst.printf(
     924             :         "REM Test whether t3 is installed\n"
     925             :         "ECHO Running preinst of t2 package\n"
     926             :         "IF EXIST usr\\bin\\t3 (\n"
     927             :         "  ECHO t3 file already exists, order was not respected\n"
     928             :         "  EXIT 1\n"
     929             :         ") ELSE (\n"
     930             :         "  ECHO t3 file not present, test passed\n"
     931             :         "  EXIT 0\n"
     932             :         ")\n"
     933             :     );
     934             :     preinst.write_file(wpkg_path_t2.append_child("preinst.bat"));
     935             : #else
     936             :     preinst.printf(
     937             :         "#!/bin/sh\n"
     938             :         "# Test whether t3 is installed\n"
     939             :         "echo \"Running preinst of t2 package\"\n"
     940             :         "if test -f usr/bin/t3\n"
     941             :         "then\n"
     942             :         " echo \"t3 file already exists, order was not respected\"\n"
     943             :         " exit 1\n"
     944             :         "else\n"
     945             :         " echo \"t3 file not present, test passed\"\n"
     946             :         " exit 0\n"
     947             :         "fi\n"
     948           1 :     );
     949           1 :     preinst.write_file(wpkg_path_t2.append_child("preinst"));
     950             : #endif
     951           1 :     create_package("t2", ctrl_t2, false);
     952             : 
     953             :     ctrl_t3->set_variable("INSTALL_POSTOPTIONS",
     954             :         repository.append_child("t2_" + ctrl_t2->get_field("Version") + "_" + ctrl_t2->get_field("Architecture") + ".deb").path_only()
     955             :         + " -D 077777 "
     956             : #ifdef MO_WINDOWS
     957             :         // here we assume that you're running with cmd.exe which system() does
     958             :         // we have to duplicate all the double quotes
     959             :         "--validate-fields \"getfield(\"\"Version\"\") == \"\"1.0\"\"\""
     960             : #else
     961             :         "--validate-fields 'getfield(\"Version\") == \"1.0\"'"
     962             : #endif
     963           1 :     );
     964           1 :     install_package("t3", ctrl_t3);
     965           1 :     verify_installed_files("t3");
     966           1 :     verify_installed_files("t2"); // t2 was explicitly installed in this case
     967             : 
     968           1 :     purge_package("t3", ctrl_t3);
     969           1 :     verify_purged_files("t3", ctrl_t3);
     970             : 
     971           1 :     purge_package("t2", ctrl_t2);
     972           1 :     verify_purged_files("t2", ctrl_t2);
     973             : 
     974             :     // add t1 as a dependency of t2
     975           1 :     ctrl_t2->set_field("Depends", "t1");
     976           1 :     create_package("t2", ctrl_t2);
     977             : 
     978             :     // the test a circular dependency now: t1 -> t3 -> t2 -> t1
     979           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
     980             :     ctrl_t1->set_field("Files", "conffiles\n"
     981             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
     982             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
     983             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
     984           1 :     );
     985           1 :     ctrl_t1->set_field("Depends", "t3");
     986           1 :     create_package("t1", ctrl_t1);
     987             :     ctrl_t1->set_variable("INSTALL_POSTOPTIONS",
     988             :             repository.append_child("t2_" + ctrl_t2->get_field("Version") + "_" + ctrl_t2->get_field("Architecture") + ".deb").path_only()
     989             :             + " " +
     990             :             repository.append_child("t3_" + ctrl_t3->get_field("Version") + "_" + ctrl_t3->get_field("Architecture") + ".deb").path_only()
     991           1 :         );
     992           1 :     install_package("t1", ctrl_t1, 1);
     993           1 :     verify_purged_files("t1", ctrl_t1);
     994           1 :     verify_purged_files("t2", ctrl_t2);
     995           1 :     verify_purged_files("t3", ctrl_t3);
     996             : 
     997           1 : }
     998             : 
     999           1 : void PackageUnitTests::essential_package()
    1000             : {
    1001             :     // IMPORTANT: remember that all files are deleted between tests
    1002             : 
    1003           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1004             :     ctrl_t1->set_field("Files", "conffiles\n"
    1005             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1006             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1007             :         "/usr/bin/t1b 0123456789abcdef0123456789abcdef\n"
    1008             :         "/usr/bin/t1c 0123456789abcdef0123456789abcdef\n"
    1009             :         "/usr/bin/t1d 0123456789abcdef0123456789abcdef\n"
    1010             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1011           1 :     );
    1012           1 :     ctrl_t1->set_field("Essential", "Yes");
    1013           1 :     create_package("t1", ctrl_t1);
    1014           1 :     install_package("t1", ctrl_t1);
    1015           1 :     verify_installed_files("t1");
    1016             : 
    1017             :     // remove as is fails because essential package cannot be removed by default
    1018           1 :     remove_package("t1", ctrl_t1, 1);
    1019           1 :     verify_installed_files("t1");
    1020           1 :     purge_package("t1", ctrl_t1, 1);
    1021           1 :     verify_installed_files("t1");
    1022             : 
    1023             :     // remove as is fails because essential package cannot be removed by default
    1024           1 :     ctrl_t1->set_variable("REMOVE_PREOPTIONS", "--force-remove-essential");
    1025           1 :     remove_package("t1", ctrl_t1);
    1026           1 :     verify_removed_files("t1", ctrl_t1);
    1027           1 :     ctrl_t1->set_variable("PURGE_PREOPTIONS", "--force-remove-essential");
    1028           1 :     purge_package("t1", ctrl_t1);
    1029           1 :     verify_purged_files("t1", ctrl_t1);
    1030             : 
    1031             :     // now test that overwriting of an essential file is not possible
    1032             :     // re-install t1
    1033           1 :     install_package("t1", ctrl_t1);
    1034           1 :     verify_installed_files("t1");
    1035             : 
    1036             :     // then create t2 which a file that will overwrite on in t1
    1037           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
    1038             :     ctrl_t2->set_field("Files", "conffiles\n"
    1039             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef\n"
    1040             :         "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    1041             :         "/usr/bin/t1b 0123456789abcdef0123456789abcdef\n" // same as t1 file!
    1042             :         "/usr/bin/t2c 0123456789abcdef0123456789abcdef\n"
    1043             :         "/usr/bin/t2d 0123456789abcdef0123456789abcdef\n"
    1044             :         "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    1045           1 :     );
    1046           1 :     create_package("t2", ctrl_t2);
    1047             : 
    1048             :     // TBD -- how do we know that we are getting the correct errors?
    1049           1 :     install_package("t2", ctrl_t2, 1); // simple overwrite error
    1050           1 :     string_list exceptions;
    1051           1 :     exceptions.push_back("usr/bin/t1b"); // exceptions are checked against relative paths
    1052           1 :     verify_purged_files("t2", ctrl_t2, exceptions);
    1053             : 
    1054             :     // check with --force-overwrite and it fails again
    1055           1 :     ctrl_t2->set_variable("INSTALL_PREOPTIONS", "--force-overwrite");
    1056           1 :     install_package("t2", ctrl_t2, 1); // simple overwrite error
    1057           1 :     verify_purged_files("t2", ctrl_t2, exceptions);
    1058           1 : }
    1059             : 
    1060           1 : void PackageUnitTests::file_exists_in_admindir()
    1061             : {
    1062             :     // IMPORTANT: remember that all files are deleted between tests
    1063             : 
    1064           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1065             :     ctrl_t1->set_field("Files", "conffiles\n"
    1066             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1067             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1068             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1069           1 :     );
    1070           1 :     create_package("t1", ctrl_t1);
    1071             : 
    1072             :     // create a file named "t1" in the admindir to prevent installation
    1073           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    1074           1 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
    1075           1 :     wpkg_filename::uri_filename t1_file(target_path.append_child("var/lib/wpkg/t1"));
    1076           1 :     memfile::memory_file t1_data;
    1077           1 :     t1_data.create(memfile::memory_file::file_format_other);
    1078           1 :     t1_data.printf("Some random data\n");
    1079           1 :     t1_data.write_file(t1_file, true);
    1080             : 
    1081             :     // there should be no other reason why installing t1 would fail, try!
    1082           1 :     install_package("t1", ctrl_t1, 1);
    1083           1 :     verify_purged_files("t1", ctrl_t1);
    1084           1 : }
    1085             : 
    1086             : //void PackageUnitTests::depends_distribution_packages()
    1087             : //{
    1088             : //    // IMPORTANT: remember that all files are deleted between tests
    1089             : //
    1090             : //    // first attempt to create a package without a Distribution field
    1091             : //    // we expect the installation to fail
    1092             : //    std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1093             : //    ctrl_t1->set_field("Conffiles", "\n"
    1094             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1095             : //    );
    1096             : //    ctrl_t1->set_field("Files", "conffiles\n"
    1097             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1098             : //        "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1099             : //        "/usr/bin/t1b 0123456789abcdef0123456789abcdef\n"
    1100             : //        "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1101             : //    );
    1102             : //    create_package("t1", ctrl_t1);
    1103             : //    ctrl_t1->set_field("Conffiles", "\n"
    1104             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1105             : //    );
    1106             : //    ctrl_t1->set_variable("INSTALL_EXTRACOREFIELDS", "Distribution: m2osw\n");
    1107             : //    install_package("t1", ctrl_t1, 1);
    1108             : //    verify_purged_files("t1", ctrl_t1);
    1109             : //
    1110             : //    // re-create that same package, this time with the Distribution field,
    1111             : //    // but not the right distribution name
    1112             : //    ctrl_t1->set_field("Distribution", "wrong-name");
    1113             : //    create_package("t1", ctrl_t1);
    1114             : //    ctrl_t1->set_field("Conffiles", "\n"
    1115             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1116             : //    );
    1117             : //    install_package("t1", ctrl_t1, 1);
    1118             : //    verify_purged_files("t1", ctrl_t1);
    1119             : //
    1120             : //    // okay, re-create with the correct distribution name this time
    1121             : //    ctrl_t1->set_field("Distribution", "m2osw");
    1122             : //    create_package("t1", ctrl_t1);
    1123             : //    ctrl_t1->set_field("Conffiles", "\n"
    1124             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1125             : //    );
    1126             : //    install_package("t1", ctrl_t1);
    1127             : //    verify_installed_files("t1");
    1128             : //
    1129             : //    std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
    1130             : //    // Conffiles
    1131             : //    ctrl_t2->set_field("Conffiles", "\n"
    1132             : //        "/etc/t2/setup.conf 0123456789abcdef0123456789abcdef"
    1133             : //    );
    1134             : //    ctrl_t2->set_field("Files", "conffiles\n"
    1135             : //        "/etc/t2/setup.conf 0123456789abcdef0123456789abcdef\n"
    1136             : //        "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    1137             : //        "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    1138             : //    );
    1139             : //    ctrl_t2->set_field("Depends", "t1 (<= 1.0)");
    1140             : //    ctrl_t2->set_field("Distribution", "m2osw");
    1141             : //    create_package("t2", ctrl_t2);
    1142             : //    // Conffiles -- the create_package deletes this field
    1143             : //    ctrl_t2->set_field("Conffiles", "\n"
    1144             : //        "etc/t2/setup.conf 0123456789abcdef0123456789abcdef"
    1145             : //    );
    1146             : //    install_package("t2", ctrl_t2);
    1147             : //    verify_installed_files("t2");
    1148             : //    remove_package("t2", ctrl_t2);
    1149             : //    verify_removed_files("t2", ctrl_t2);
    1150             : //
    1151             : //    // we couldn't have removed t1, t2 were still installed!
    1152             : //    remove_package("t1", ctrl_t1);
    1153             : //    verify_removed_files("t1", ctrl_t1);
    1154             : //
    1155             : //    // now we can reinstall t1 and t2
    1156             : //    install_package("t1", ctrl_t1);
    1157             : //    verify_installed_files("t1");
    1158             : //
    1159             : //    install_package("t2", ctrl_t2);
    1160             : //    verify_installed_files("t2");
    1161             : //
    1162             : //    purge_package("t2", ctrl_t2);
    1163             : //    verify_purged_files("t2", ctrl_t2);
    1164             : //
    1165             : //    purge_package("t1", ctrl_t1);
    1166             : //    verify_purged_files("t1", ctrl_t1);
    1167             : //
    1168             : //    ctrl_t1->set_variable("INSTALL_POSTOPTIONS",
    1169             : //#ifdef MO_WINDOWS
    1170             : //        // here we assume that you're running with cmd.exe which system() does
    1171             : //        // we have to duplicate all the double quotes
    1172             : //        "--validate-fields \"getfield(\"\"Package\"\") == \"\"t1\"\"\""
    1173             : //#else
    1174             : //        "--validate-fields 'getfield(\"Package\") == \"t1\"'"
    1175             : //#endif
    1176             : //    );
    1177             : //    ctrl_t2->set_variable("INSTALL_POSTOPTIONS",
    1178             : //#ifdef MO_WINDOWS
    1179             : //        // here we assume that you're running with cmd.exe which system() does
    1180             : //        // we have to duplicate all the double quotes
    1181             : //        "--validate-fields \"getfield(\"\"Package\"\") >= \"\"t1\"\"\""
    1182             : //#else
    1183             : //        "--validate-fields 'getfield(\"Package\") >= \"t1\"'"
    1184             : //#endif
    1185             : //    );
    1186             : //
    1187             : //    // test with the --repository option
    1188             : //    wpkg_filename::uri_filename root(unittest::tmp_dir);
    1189             : //    wpkg_filename::uri_filename repository(root.append_child("repository"));
    1190             : //    ctrl_t2->set_variable("INSTALL_PREOPTIONS", "--repository " + repository.path_only());
    1191             : //
    1192             : //    install_package("t2", ctrl_t2);
    1193             : //    verify_installed_files("t2");
    1194             : //    verify_installed_files("t1");
    1195             : //
    1196             : //    purge_package("t2", ctrl_t2);
    1197             : //    verify_purged_files("t2", ctrl_t2);
    1198             : //
    1199             : //    purge_package("t1", ctrl_t1);
    1200             : //    verify_purged_files("t1", ctrl_t1);
    1201             : //
    1202             : //    // now try the --repository with the wrong distribution
    1203             : //    ctrl_t1->set_field("Distribution", "wong-name-again");
    1204             : //    create_package("t1", ctrl_t1);
    1205             : //    ctrl_t1->set_field("Conffiles", "\n"
    1206             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1207             : //    );
    1208             : //
    1209             : //    // ?!?! WORKS WITH THE WRONG DISTRIBUTION ?!?!
    1210             : //    // This is because there is an index and all the validations count on the
    1211             : //    // index to be valid! (here we have a sync. problem too!)
    1212             : //    install_package("t2", ctrl_t2);
    1213             : //    verify_installed_files("t2");
    1214             : //    verify_installed_files("t1");
    1215             : //
    1216             : //    purge_package("t2", ctrl_t2);
    1217             : //    verify_purged_files("t2", ctrl_t2);
    1218             : //
    1219             : //    purge_package("t1", ctrl_t1);
    1220             : //    verify_purged_files("t1", ctrl_t1);
    1221             : //
    1222             : //    // So now we reset the index and try again
    1223             : //    wpkg_filename::uri_filename index(repository.append_child("index.tar.gz"));
    1224             : //    index.os_unlink();
    1225             : //
    1226             : //    install_package("t2", ctrl_t2, 1);
    1227             : //    verify_purged_files("t2", ctrl_t2);
    1228             : //    verify_purged_files("t1", ctrl_t1);
    1229             : //
    1230             : //    // --force-any-distribution works even on implicit packages
    1231             : //    ctrl_t2->set_variable("INSTALL_POSTOPTIONS", "--force-any-distribution");
    1232             : //    install_package("t2", ctrl_t2);
    1233             : //    verify_installed_files("t2");
    1234             : //    verify_installed_files("t1");
    1235             : //
    1236             : //    // cannot purge (or remove) because t2 depends on it
    1237             : //    purge_package("t1", ctrl_t1, 1);
    1238             : //    verify_installed_files("t1");
    1239             : //
    1240             : //    // reset slate to test a Pre-Depends instead
    1241             : //    purge_package("t2", ctrl_t2);
    1242             : //    verify_purged_files("t2", ctrl_t2);
    1243             : //
    1244             : //    purge_package("t1", ctrl_t1);
    1245             : //    verify_purged_files("t1", ctrl_t1);
    1246             : //
    1247             : //    // when we change the architecture we get a new name,
    1248             : //    // make sure the old .deb is removed
    1249             : //    // we also have to delete the index because it still has a
    1250             : //    // reference to that old .deb file (and not the new file)
    1251             : //    {
    1252             : //        wpkg_filename::uri_filename t1(repository.append_child("/t1_" + ctrl_t1->get_field("Version") + "_" + ctrl_t1->get_field("Architecture") + ".deb"));
    1253             : //        t1.os_unlink();
    1254             : //    }
    1255             : //    index.os_unlink();
    1256             : //
    1257             : //    // fix distribution + wrong architecture
    1258             : //    ctrl_t1->set_field("Distribution", "m2osw");
    1259             : //    ctrl_t1->set_field("Architecture", strcmp(debian_packages_architecture(), "win32-i386") == 0 ? "win64-amd64" : "win32-i386");
    1260             : //    create_package("t1", ctrl_t1);
    1261             : //    ctrl_t1->set_field("Conffiles", "\n"
    1262             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1263             : //    );
    1264             : //
    1265             : //    install_package("t2", ctrl_t2, 1);
    1266             : //    verify_purged_files("t2", ctrl_t2);
    1267             : //    verify_purged_files("t1", ctrl_t1);
    1268             : //
    1269             : //    // reset architecture
    1270             : //    ctrl_t1->set_field("Architecture", debian_packages_architecture());
    1271             : //    create_package("t1", ctrl_t1);
    1272             : //    ctrl_t1->set_field("Conffiles", "\n"
    1273             : //        "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1274             : //    );
    1275             : //
    1276             : //    // replace the Depends with a Pre-Depends
    1277             : //    ctrl_t2->delete_field("Depends");
    1278             : //    ctrl_t2->set_field("Pre-Depends", "t1 (>> 0.9)");
    1279             : //    create_package("t2", ctrl_t2);
    1280             : //    ctrl_t2->set_field("Conffiles", "\n"
    1281             : //        "etc/t2/setup.conf 0123456789abcdef0123456789abcdef"
    1282             : //    );
    1283             : //    ctrl_t2->delete_variable("INSTALL_POSTOPTIONS");
    1284             : //
    1285             : //    // fails because t1 is a Pre-dependency
    1286             : //    install_package("t2", ctrl_t2, 1);
    1287             : //    verify_purged_files("t2", ctrl_t2);
    1288             : //    verify_purged_files("t1", ctrl_t1);
    1289             : //
    1290             : //    install_package("t1", ctrl_t1);
    1291             : //    verify_installed_files("t1");
    1292             : //    install_package("t2", ctrl_t2);
    1293             : //    verify_installed_files("t2");
    1294             : //}
    1295             : 
    1296           1 : void PackageUnitTests::conflicting_packages()
    1297             : {
    1298             :     // IMPORTANT: remember that all files are deleted between tests
    1299             : 
    1300             :     // create & install a package that doesn't like the other
    1301           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1302             :     ctrl_t1->set_field("Conffiles", "\n"
    1303             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1304           1 :     );
    1305             :     ctrl_t1->set_field("Files", "conffiles\n"
    1306             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1307             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1308             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1309           1 :     );
    1310           1 :     ctrl_t1->set_field("Conflicts", "t2");
    1311           1 :     create_package("t1", ctrl_t1);
    1312             :     // Conffiles -- the create_package deletes this field
    1313             :     ctrl_t1->set_field("Conffiles", "\n"
    1314             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1315           1 :     );
    1316           1 :     install_package("t1", ctrl_t1);
    1317           1 :     verify_installed_files("t1");
    1318             : 
    1319             :     // create that other package
    1320           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
    1321             :     ctrl_t2->set_field("Conffiles", "\n"
    1322             :         "/etc/t2/setup.conf 0123456789abcdef0123456789abcdef"
    1323           1 :     );
    1324             :     ctrl_t2->set_field("Files", "conffiles\n"
    1325             :         "/etc/t2/setup.conf 0123456789abcdef0123456789abcdef\n"
    1326             :         "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    1327             :         "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    1328           1 :     );
    1329           1 :     create_package("t2", ctrl_t2);
    1330             :     ctrl_t2->set_field("Conffiles", "\n"
    1331             :         "etc/t2/setup.conf 0123456789abcdef0123456789abcdef"
    1332           1 :     );
    1333           1 :     install_package("t2", ctrl_t2, 1);
    1334           1 :     verify_purged_files("t2", ctrl_t2);
    1335             : 
    1336             :     // try again with the force flag
    1337           1 :     ctrl_t2->set_variable("INSTALL_POSTOPTIONS", "--force-conflicts");
    1338           1 :     install_package("t2", ctrl_t2);
    1339           1 :     verify_installed_files("t2");
    1340           1 :     remove_package("t2", ctrl_t2);
    1341           1 :     verify_removed_files("t2", ctrl_t2);
    1342             : 
    1343           1 :     purge_package("t2", ctrl_t2);
    1344           1 :     verify_purged_files("t2", ctrl_t2);
    1345             : 
    1346           1 :     purge_package("t1", ctrl_t1);
    1347           1 :     verify_purged_files("t1", ctrl_t1);
    1348             : 
    1349             :     // replace with a break which when packages are installed has the same effect
    1350           1 :     ctrl_t1->delete_field("Conflicts");
    1351           1 :     ctrl_t1->set_field("Breaks", "t2");
    1352           1 :     create_package("t1", ctrl_t1);
    1353             :     // Conffiles -- the create_package deletes this field
    1354             :     ctrl_t1->set_field("Conffiles", "\n"
    1355             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1356           1 :     );
    1357           1 :     install_package("t1", ctrl_t1);
    1358           1 :     verify_installed_files("t1");
    1359             : 
    1360             :     // t2 already exists so we can just try to install, it fails because of the Breaks
    1361           1 :     ctrl_t2->delete_variable("INSTALL_POSTOPTIONS");
    1362           1 :     install_package("t2", ctrl_t2, 1);
    1363           1 :     verify_purged_files("t2", ctrl_t2);
    1364             : 
    1365             :     // try again with a force, this time it is expected to work
    1366           1 :     ctrl_t2->set_variable("INSTALL_POSTOPTIONS", "--force-breaks");
    1367           1 :     install_package("t2", ctrl_t2);
    1368           1 :     verify_installed_files("t2");
    1369           1 :     remove_package("t2", ctrl_t2);
    1370           1 :     verify_removed_files("t2", ctrl_t2);
    1371             : 
    1372           1 :     purge_package("t2", ctrl_t2);
    1373           1 :     verify_purged_files("t2", ctrl_t2);
    1374             : 
    1375           1 :     purge_package("t1", ctrl_t1);
    1376           1 :     verify_purged_files("t1", ctrl_t1);
    1377           1 : }
    1378             : 
    1379           2 : void PackageUnitTests::sorted_packages_run(int precreate_index)
    1380             : {
    1381             :     // IMPORTANT: remember that all files are deleted between tests
    1382             : 
    1383           2 :     wpkg_filename::uri_filename const root(unittest::tmp_dir);
    1384           2 :     wpkg_filename::uri_filename const repository(root.append_child("repository"));
    1385             : 
    1386             :     // *** CREATION ***
    1387             :     // create 50 to 70 packages and install them in random order
    1388             :     // then upgrade different packages in a random order
    1389           2 :     const int max_packages = rand() % 21 + 50;
    1390           2 :     std::vector<bool> has_conf;
    1391           2 :     has_conf.resize(max_packages + 1);
    1392           2 :     std::vector<bool> has_dependents;
    1393           2 :     has_dependents.resize(max_packages + 1);
    1394           2 :     std::vector<int> order;
    1395           2 :     order.resize(max_packages + 1);
    1396         121 :     for(int i = 1; i <= max_packages; ++i)
    1397             :     {
    1398         119 :         order[i] = i;
    1399         119 :         std::stringstream strname;
    1400         119 :         strname << "t" << i;
    1401         119 :         std::string name(strname.str());
    1402         119 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
    1403         119 :         has_conf[i] = (rand() & 1) != 0;
    1404         119 :         if(has_conf[i])
    1405             :         {
    1406             :             ctrl->set_field("Conffiles", "\n"
    1407             :                 "/etc/" + name + "/" + name + ".conf 0123456789abcdef0123456789abcdef"
    1408          63 :             );
    1409             :         }
    1410             :         ctrl->set_field("Files", "conffiles\n"
    1411             :             "/etc/" + name + "/" + name + ".conf 0123456789abcdef0123456789abcdef\n"
    1412             :             "/usr/bin/" + name + " 0123456789abcdef0123456789abcdef\n"
    1413             :             "/usr/share/doc/" + name + "/copyright 0123456789abcdef0123456789abcdef\n"
    1414         119 :         );
    1415         119 :         int depend(rand() % (max_packages * 2) + 1);
    1416         119 :         if(depend <= max_packages && depend != i && !has_dependents[depend])
    1417             :         {
    1418          48 :             std::stringstream strdepend;
    1419          48 :             strdepend << "t" << depend;
    1420          48 :             ctrl->set_field("Depends", strdepend.str());
    1421          48 :             has_dependents[i] = true;
    1422             :         }
    1423         119 :         create_package(name, ctrl);
    1424         119 :         if(has_conf[i])
    1425             :         {
    1426             :             ctrl->set_field("Conffiles", "\n"
    1427             :                 "/etc/" + name + "/" + name + ".conf 0123456789abcdef0123456789abcdef"
    1428          63 :             );
    1429             :         }
    1430         119 :     }
    1431             : 
    1432             :     // the installation will automatically create the index, however,
    1433             :     // if we let it do that we miss on the potential to test validation
    1434             :     // against field only; however, we want to test the automatic
    1435             :     // mechanism too once in a while so we randomize the use of that
    1436           2 :     if(precreate_index)
    1437             :     {
    1438           1 :         std::string cmd(unittest::wpkg_tool);
    1439           1 :         cmd += " --create-index " + repository.full_path() + "/index.tar.gz --repository " + repository.full_path();
    1440           1 :         printf("Create packages index: \"%s\"\n", cmd.c_str());
    1441           1 :         fflush(stdout);
    1442           1 :         CPPUNIT_ASSERT(system(cmd.c_str()) == 0);
    1443             :     }
    1444             : 
    1445             :     // *** INSTALLATION ***
    1446             :     // randomize the order in which we'll be installing these
    1447         121 :     for(int i = 1; i <= max_packages; ++i)
    1448             :     {
    1449         119 :         const int j = rand() % max_packages + 1;
    1450         119 :         std::swap(order[i], order[j]);
    1451             :     }
    1452         121 :     for(int i = 1; i <= max_packages; ++i)
    1453             :     {
    1454             :         // some random control file is required
    1455             :         // we need the proper architecture and version which we have not changed from the default
    1456         119 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
    1457         119 :         std::stringstream strname;
    1458         119 :         strname << "t" << order[i];
    1459         119 :         ctrl->set_variable("INSTALL_PREOPTIONS", "--repository " + repository.path_only());
    1460             :         ctrl->set_variable("INSTALL_POSTOPTIONS",
    1461             : #ifdef MO_WINDOWS
    1462             :                 // here we assume that you're running with cmd.exe which system() does
    1463             :                 // we have to duplicate all the double quotes
    1464             :                 "--validate-fields \"getfield(\"\"Version\"\") >= \"\"0.9\"\"\""
    1465             : #else
    1466             :                 "--validate-fields 'getfield(\"Version\") >= \"0.9\"'"
    1467             : #endif
    1468         119 :             );
    1469         119 :         install_package(strname.str(), ctrl);
    1470         119 :     }
    1471             : 
    1472             :     // *** UPGRADE ***
    1473             :     // randomize the order in which we'll be upgrading these
    1474         121 :     for(int i = 1; i <= max_packages; ++i)
    1475             :     {
    1476         119 :         const int j = rand() % max_packages + 1;
    1477         119 :         std::swap(order[i], order[j]);
    1478             :     }
    1479           2 :     std::vector<int> version;
    1480           2 :     version.resize(max_packages + 1);
    1481         121 :     for(int i = 1; i <= max_packages; ++i)
    1482             :     {
    1483             :         // recreate a valid control file
    1484         119 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl(get_new_control_file(__FUNCTION__));
    1485         119 :         std::stringstream strname;
    1486         119 :         strname << "t" << order[i];
    1487         119 :         std::string name(strname.str());
    1488         119 :         if(has_conf[order[i]])
    1489             :         {
    1490             :             ctrl->set_field("Conffiles", "\n"
    1491             :                 "/etc/" + name + "/" + name + ".conf 0123456789abcdef0123456789abcdef"
    1492          63 :             );
    1493             :         }
    1494             :         ctrl->set_field("Files", "conffiles\n"
    1495             :             "/etc/" + name + "/" + name + ".conf 0123456789abcdef0123456789abcdef\n"
    1496             :             "/usr/bin/" + name + " 0123456789abcdef0123456789abcdef\n"
    1497             :             "/usr/share/doc/" + name + "/copyright 0123456789abcdef0123456789abcdef\n"
    1498         119 :         );
    1499             :         // bump version up (or not, one in 20 will still be 1.0)
    1500         119 :         version[order[i]] = rand() % 20;
    1501         119 :         std::stringstream strversion;
    1502         119 :         strversion << "1." << version[order[i]];
    1503         119 :         ctrl->set_field("Version", strversion.str());
    1504         119 :         create_package(name, ctrl);
    1505             :         // no need to recreate the Conffiles field here
    1506         119 :         install_package(name, ctrl);
    1507         119 :     }
    1508             : 
    1509             :     // *** REFRESH ***
    1510             :     // randomize the order in which we'll be refreshing these
    1511         121 :     for(int i = 1; i <= max_packages; ++i)
    1512             :     {
    1513         119 :         const int j = rand() % max_packages + 1;
    1514         119 :         std::swap(order[i], order[j]);
    1515             :     }
    1516           2 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_refresh(get_new_control_file(__FUNCTION__));
    1517           2 :     std::stringstream name_list;
    1518         119 :     for(int i = 2; i <= max_packages; ++i)
    1519             :     {
    1520         117 :         name_list << " " << repository.path_only() << "/t" << order[i] << "_1." << version[order[i]] << "_" << debian_packages_architecture() << ".deb";
    1521             :     }
    1522           2 :     std::stringstream strfirst_version;
    1523           2 :     strfirst_version << "1." << version[order[1]];
    1524           2 :     ctrl_refresh->set_field("Version", strfirst_version.str());
    1525           2 :     ctrl_refresh->set_variable("INSTALL_POSTOPTIONS", name_list.str());
    1526           2 :     std::stringstream name_refresh;
    1527           2 :     name_refresh << "t" << order[1];
    1528           2 :     install_package(name_refresh.str(), ctrl_refresh);
    1529             : 
    1530             :     // with all those .deb files, we can create an impressive md5sums.txt file
    1531             :     // so let's do that and then run a check
    1532             :     {
    1533           2 :         std::string cmd(unittest::wpkg_tool);
    1534           2 :         cmd += " --md5sums " + repository.full_path() + "/*.deb >" + root.full_path() + "/md5sums.txt -v";
    1535           2 :         printf("Create md5sums: \"%s\"\n", cmd.c_str());
    1536           2 :         fflush(stdout);
    1537           2 :         CPPUNIT_ASSERT(system(cmd.c_str()) == 0);
    1538             :     }
    1539             :     {
    1540           2 :         std::string cmd(unittest::wpkg_tool);
    1541           2 :         cmd += " --md5sums-check " + root.full_path() + "/md5sums.txt " + repository.full_path() + "/*.deb -v";
    1542           2 :         printf("  check valid md5sums: \"%s\"\n", cmd.c_str());
    1543           2 :         fflush(stdout);
    1544           2 :         CPPUNIT_ASSERT(system(cmd.c_str()) == 0);
    1545             :     }
    1546             :     {
    1547             :         // modify an md5 checksum
    1548           2 :         FILE *f(fopen((root.full_path() + "/md5sums.txt").c_str(), "r+"));
    1549           2 :         CPPUNIT_ASSERT(f != NULL);
    1550             :         char o;
    1551             : #ifdef __GNUC__
    1552             : #   pragma GCC diagnostic push
    1553             : #   pragma GCC diagnostic ignored "-Wunused-result"
    1554             : #endif
    1555           2 :         fseek(f, 0, SEEK_SET);
    1556           2 :         fread(&o, 1, 1, f);
    1557           2 :         char c(o == 'f' ? 'a' : 'f');
    1558           2 :         fseek(f, 0, SEEK_SET);
    1559           2 :         fwrite(&c, 1, 1, f);
    1560           2 :         fclose(f);
    1561             : #ifdef __GNUC__
    1562             : #   pragma GCC diagnostic pop
    1563             : #endif
    1564             :         // try again and this time we MUST get an error
    1565           2 :         std::string cmd(unittest::wpkg_tool);
    1566           2 :         cmd += " --md5sums-check " + root.full_path() + "/md5sums.txt " + repository.full_path() + "/*.deb -v";
    1567           2 :         printf("  check invalid md5sums: \"%s\"\n", cmd.c_str());
    1568           2 :         fflush(stdout);
    1569           2 :         int r(system(cmd.c_str()));
    1570           2 :         CPPUNIT_ASSERT(WEXITSTATUS(r) == 1);
    1571           2 :     }
    1572           2 : }
    1573             : 
    1574           1 : void PackageUnitTests::sorted_packages_auto_index()
    1575             : {
    1576           1 :     sorted_packages_run(false);
    1577           1 : }
    1578             : 
    1579           1 : void PackageUnitTests::sorted_packages_ready_index()
    1580             : {
    1581           1 :     sorted_packages_run(true);
    1582           1 : }
    1583             : 
    1584             : 
    1585           1 : void PackageUnitTests::choices_packages()
    1586             : {
    1587             :     // IMPORTANT: remember that all files are deleted between tests
    1588             : 
    1589           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    1590           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    1591             : 
    1592             :     // Failing tree because pb and pc require two different versions of pd
    1593             :     // pa: pb pc
    1594             :     // pb: pd1
    1595             :     // pc: pd2
    1596             :     // pd1: pe
    1597             :     // pd2: pe pf
    1598             :     // pe:
    1599             :     // pf:
    1600             : 
    1601             :     // package pa
    1602           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pa(get_new_control_file(__FUNCTION__));
    1603             :     ctrl_pa->set_field("Conffiles", "\n"
    1604             :         "/etc/pa/pa.conf 0123456789abcdef0123456789abcdef"
    1605           1 :     );
    1606             :     ctrl_pa->set_field("Files", "conffiles\n"
    1607             :         "/etc/pa/pa.conf 0123456789abcdef0123456789abcdef\n"
    1608             :         "/usr/bin/pa 0123456789abcdef0123456789abcdef\n"
    1609             :         "/usr/share/doc/pa/copyright 0123456789abcdef0123456789abcdef\n"
    1610           1 :     );
    1611           1 :     ctrl_pa->set_field("Depends", "pb, pc");
    1612           1 :     create_package("pa", ctrl_pa);
    1613             :     ctrl_pa->set_field("Conffiles", "\n"
    1614             :         "/etc/pa/pa.conf 0123456789abcdef0123456789abcdef"
    1615           1 :     );
    1616             : 
    1617             :     // package pb
    1618           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pb(get_new_control_file(__FUNCTION__));
    1619             :     ctrl_pb->set_field("Conffiles", "\n"
    1620             :         "/etc/pb/pb.conf 0123456789abcdef0123456789abcdef"
    1621           1 :     );
    1622             :     ctrl_pb->set_field("Files", "conffiles\n"
    1623             :         "/etc/pb/pb.conf 0123456789abcdef0123456789abcdef\n"
    1624             :         "/usr/bin/pb 0123456789abcdef0123456789abcdef\n"
    1625             :         "/usr/share/doc/pb/copyright 0123456789abcdef0123456789abcdef\n"
    1626           1 :     );
    1627           1 :     ctrl_pb->set_field("Depends", "pd (= 1.0)");
    1628           1 :     create_package("pb", ctrl_pb);
    1629             :     ctrl_pb->set_field("Conffiles", "\n"
    1630             :         "/etc/pb/pb.conf 0123456789abcdef0123456789abcdef"
    1631           1 :     );
    1632             : 
    1633             :     // package pc
    1634           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pc(get_new_control_file(__FUNCTION__));
    1635             :     ctrl_pc->set_field("Conffiles", "\n"
    1636             :         "/etc/pc/pc.conf 0123456789abcdef0123456789abcdef"
    1637           1 :     );
    1638             :     ctrl_pc->set_field("Files", "conffiles\n"
    1639             :         "/etc/pc/pc.conf 0123456789abcdef0123456789abcdef\n"
    1640             :         "/usr/bin/pc 0123456789abcdef0123456789abcdef\n"
    1641             :         "/usr/share/doc/pc/copyright 0123456789abcdef0123456789abcdef\n"
    1642           1 :     );
    1643           1 :     ctrl_pc->set_field("Depends", "pd (= 2.0)");
    1644           1 :     create_package("pc", ctrl_pc);
    1645             :     ctrl_pc->set_field("Conffiles", "\n"
    1646             :         "/etc/pc/pc.conf 0123456789abcdef0123456789abcdef"
    1647           1 :     );
    1648             : 
    1649             :     // package pd1 (version 1.0)
    1650           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pd1(get_new_control_file(__FUNCTION__));
    1651             :     ctrl_pd1->set_field("Conffiles", "\n"
    1652             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef"
    1653           1 :     );
    1654             :     ctrl_pd1->set_field("Files", "conffiles\n"
    1655             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef\n"
    1656             :         "/usr/bin/pd 0123456789abcdef0123456789abcdef\n"
    1657             :         "/usr/share/doc/pd/copyright 0123456789abcdef0123456789abcdef\n"
    1658           1 :     );
    1659           1 :     ctrl_pd1->set_field("Depends", "pe");
    1660           1 :     create_package("pd", ctrl_pd1);
    1661             :     ctrl_pd1->set_field("Conffiles", "\n"
    1662             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef"
    1663           1 :     );
    1664             : 
    1665             :     // package pd2 (version 2.0)
    1666           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pd2(get_new_control_file(__FUNCTION__));
    1667           1 :     ctrl_pd2->set_field("Version", "2.0");
    1668             :     ctrl_pd2->set_field("Conffiles", "\n"
    1669             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef"
    1670           1 :     );
    1671             :     ctrl_pd2->set_field("Files", "conffiles\n"
    1672             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef\n"
    1673             :         "/usr/bin/pd 0123456789abcdef0123456789abcdef\n"
    1674             :         "/usr/share/doc/pd/copyright 0123456789abcdef0123456789abcdef\n"
    1675           1 :     );
    1676           1 :     ctrl_pd2->set_field("Depends", "pe, pf");
    1677           1 :     create_package("pd", ctrl_pd2);
    1678             :     ctrl_pd2->set_field("Conffiles", "\n"
    1679             :         "/etc/pd/pd.conf 0123456789abcdef0123456789abcdef"
    1680           1 :     );
    1681             : 
    1682             :     // package pe
    1683           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pe(get_new_control_file(__FUNCTION__));
    1684             :     ctrl_pe->set_field("Conffiles", "\n"
    1685             :         "/etc/pe/pe.conf 0123456789abcdef0123456789abcdef"
    1686           1 :     );
    1687             :     ctrl_pe->set_field("Files", "conffiles\n"
    1688             :         "/etc/pe/pe.conf 0123456789abcdef0123456789abcdef\n"
    1689             :         "/usr/bin/pe 0123456789abcdef0123456789abcdef\n"
    1690             :         "/usr/share/doc/pe/copyright 0123456789abcdef0123456789abcdef\n"
    1691           1 :     );
    1692           1 :     create_package("pe", ctrl_pe);
    1693             :     ctrl_pe->set_field("Conffiles", "\n"
    1694             :         "/etc/pe/pe.conf 0123456789abcdef0123456789abcdef"
    1695           1 :     );
    1696             : 
    1697             :     // package pf
    1698           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_pf(get_new_control_file(__FUNCTION__));
    1699             :     ctrl_pf->set_field("Conffiles", "\n"
    1700             :         "/etc/pf/pf.conf 0123456789abcdef0123456789abcdef"
    1701           1 :     );
    1702             :     ctrl_pf->set_field("Files", "conffiles\n"
    1703             :         "/etc/pf/pf.conf 0123456789abcdef0123456789abcdef\n"
    1704             :         "/usr/bin/pf 0123456789abcdef0123456789abcdef\n"
    1705             :         "/usr/share/doc/pf/copyright 0123456789abcdef0123456789abcdef\n"
    1706           1 :     );
    1707           1 :     create_package("pf", ctrl_pf);
    1708             :     ctrl_pf->set_field("Conffiles", "\n"
    1709             :         "/etc/pf/pf.conf 0123456789abcdef0123456789abcdef"
    1710           1 :     );
    1711             : 
    1712             : 
    1713             : 
    1714             : 
    1715           1 :     ctrl_pa->set_variable("INSTALL_PREOPTIONS", "--repository " + repository.path_only());
    1716           1 :     install_package("pa", ctrl_pa, 1);
    1717             : 
    1718           1 :     verify_purged_files("pa", ctrl_pa);
    1719           1 :     verify_purged_files("pb", ctrl_pb);
    1720           1 :     verify_purged_files("pc", ctrl_pc);
    1721             :     //verify_purged_files("pd", ctrl_pd1); -- this was overwritten by pd2
    1722           1 :     verify_purged_files("pd", ctrl_pd2);
    1723           1 :     verify_purged_files("pe", ctrl_pe);
    1724           1 :     verify_purged_files("pf", ctrl_pf);
    1725           1 : }
    1726             : 
    1727             : 
    1728           1 : void PackageUnitTests::same_package_two_places_errors()
    1729             : {
    1730             :     // IMPORTANT: remember that all files are deleted between tests
    1731             : 
    1732           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    1733           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    1734           1 :     wpkg_filename::uri_filename rep2(root.append_child("rep2"));
    1735           1 :     rep2.os_mkdir_p();
    1736             : 
    1737             :     // create two packages with the exact same name (in two different directories)
    1738           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1739             :     ctrl_t1->set_field("Conffiles", "\n"
    1740             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1741           1 :     );
    1742             :     ctrl_t1->set_field("Files", "conffiles\n"
    1743             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1744             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1745             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1746           1 :     );
    1747           1 :     create_package("t1", ctrl_t1);
    1748             :     // Conffiles -- the create_package deletes this field
    1749             :     ctrl_t1->set_field("Conffiles", "\n"
    1750             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1751           1 :     );
    1752             : 
    1753             :     // move t1 to rep2
    1754           1 :     wpkg_filename::uri_filename t1_filename(repository.append_child("/t1_" + ctrl_t1->get_field("Version") + "_" + ctrl_t1->get_field("Architecture") + ".deb"));
    1755           1 :     wpkg_filename::uri_filename t1_file2(rep2.append_child("/t1_" + ctrl_t1->get_field("Version") + "_" + ctrl_t1->get_field("Architecture") + ".deb"));
    1756           1 :     t1_filename.os_rename(t1_file2);
    1757             : 
    1758             :     // create another t1 (t1b variables) in repository
    1759           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1b(get_new_control_file(__FUNCTION__));
    1760             :     ctrl_t1b->set_field("Conffiles", "\n"
    1761             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1762           1 :     );
    1763             :     ctrl_t1b->set_field("Files", "conffiles\n"
    1764             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    1765             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1766             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1767           1 :     );
    1768           1 :     create_package("t1", ctrl_t1b);
    1769             :     // Conffiles -- the create_package deletes this field
    1770             :     ctrl_t1b->set_field("Conffiles", "\n"
    1771             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    1772           1 :     );
    1773             : 
    1774           1 :     ctrl_t1->set_variable("INSTALL_POSTOPTIONS", rep2.append_child("/t1_" + ctrl_t1->get_field("Version") + "_" + ctrl_t1->get_field("Architecture") + ".deb").path_only());
    1775           1 :     install_package("t1", ctrl_t1, 1);
    1776             : 
    1777           1 :     verify_purged_files("t1", ctrl_t1);
    1778           1 : }
    1779             : 
    1780             : 
    1781             : 
    1782           1 : void PackageUnitTests::self_upgrade()
    1783             : {
    1784             :     // IMPORTANT: remember that all files are deleted between tests
    1785             : 
    1786             :     // create a package with the name "wpkg"
    1787           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_wpkg(get_new_control_file(__FUNCTION__));
    1788           1 :     ctrl_wpkg->set_field("Priority", "required");
    1789             :     ctrl_wpkg->set_field("Conffiles", "\n"
    1790             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef"
    1791           1 :     );
    1792             :     ctrl_wpkg->set_field("Files", "conffiles\n"
    1793             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef\n"
    1794             :         "/usr/bin/wpkg 0123456789abcdef0123456789abcdef\n"
    1795             :         "/usr/share/doc/wpkg/copyright 0123456789abcdef0123456789abcdef\n"
    1796           1 :     );
    1797           1 :     create_package("wpkg", ctrl_wpkg);
    1798             :     // Conffiles -- the create_package deletes this field
    1799             :     ctrl_wpkg->set_field("Conffiles", "\n"
    1800             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef"
    1801           1 :     );
    1802             : 
    1803             :     // the first install call is expected to work as is, not problem
    1804           1 :     install_package("wpkg", ctrl_wpkg, 0);
    1805           1 :     verify_installed_files("wpkg");
    1806             : 
    1807             :     // the second install works too, only this time we were upgrading
    1808             :     // (IMPORTANT NOTE: Under MS-Windows we lose control and the 2nd instance
    1809             :     // of wpkg.exe may generate errors and we won't know it!)
    1810           1 :     install_package("wpkg", ctrl_wpkg, 0);
    1811           1 :     verify_installed_files("wpkg");
    1812             : 
    1813             :     // wpkg does not allow removal (i.e. we marked it as required)
    1814           1 :     remove_package("wpkg", ctrl_wpkg, 1);
    1815           1 :     verify_installed_files("wpkg");
    1816           1 :     purge_package("wpkg", ctrl_wpkg, 1);
    1817           1 :     verify_installed_files("wpkg");
    1818             : 
    1819             : 
    1820             :     // try again, this time we remove the Priority field...
    1821           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_wpkg2(get_new_control_file(__FUNCTION__));
    1822           1 :     ctrl_wpkg2->set_field("Version", "1.4.3");
    1823             :     ctrl_wpkg2->set_field("Conffiles", "\n"
    1824             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef"
    1825           1 :     );
    1826             :     ctrl_wpkg2->set_field("Files", "conffiles\n"
    1827             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef\n"
    1828             :         "/usr/bin/wpkg 0123456789abcdef0123456789abcdef\n"
    1829             :         "/usr/share/doc/wpkg/copyright 0123456789abcdef0123456789abcdef\n"
    1830           1 :     );
    1831           1 :     create_package("wpkg", ctrl_wpkg2);
    1832             :     // Conffiles -- the create_package deletes this field
    1833             :     ctrl_wpkg2->set_field("Conffiles", "\n"
    1834             :         "/etc/wpkg/wpkg.conf 0123456789abcdef0123456789abcdef"
    1835           1 :     );
    1836             : 
    1837             :     // the first install call is expected to work as is, not problem
    1838           1 :     install_package("wpkg", ctrl_wpkg2, 0);
    1839           1 :     verify_installed_files("wpkg");
    1840             : 
    1841             :     // the second install works too, only this time we were upgrading
    1842             :     // (IMPORTANT NOTE: Under MS-Windows we lose control and the 2nd instance
    1843             :     // of wpkg.exe may generate errors and we won't know it!)
    1844           1 :     install_package("wpkg", ctrl_wpkg2, 0);
    1845           1 :     verify_installed_files("wpkg");
    1846             : 
    1847             :     // wpkg does not allow removal (i.e. we marked it as required)
    1848           1 :     remove_package("wpkg", ctrl_wpkg2, 1);
    1849           1 :     verify_installed_files("wpkg");
    1850           1 :     purge_package("wpkg", ctrl_wpkg2, 1);
    1851           1 :     verify_installed_files("wpkg");
    1852           1 : }
    1853             : 
    1854           1 : void PackageUnitTests::scripts_order()
    1855             : {
    1856             :     // IMPORTANT: remember that all files are deleted between tests
    1857             : 
    1858           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    1859           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    1860             : 
    1861             : ////////////////////// t1 -- upgrade from full scripts to full scripts
    1862           1 :     wpkg_filename::uri_filename build_path_t1(root.append_child("t1"));
    1863           1 :     wpkg_filename::uri_filename wpkg_path_t1(build_path_t1.append_child("WPKG"));
    1864             : 
    1865             :     // create a first version of the package
    1866             :     {
    1867           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    1868             :         ctrl_t1->set_field("Files", "conffiles\n"
    1869             :             "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    1870             :             "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    1871           1 :         );
    1872             : 
    1873           1 :         memfile::memory_file preinst;
    1874           1 :         preinst.create(memfile::memory_file::file_format_other);
    1875           1 :         memfile::memory_file postinst;
    1876           1 :         postinst.create(memfile::memory_file::file_format_other);
    1877           1 :         memfile::memory_file prerm;
    1878           1 :         prerm.create(memfile::memory_file::file_format_other);
    1879           1 :         memfile::memory_file postrm;
    1880           1 :         postrm.create(memfile::memory_file::file_format_other);
    1881             : 
    1882             : #ifdef MO_WINDOWS
    1883             :         preinst.printf(
    1884             :             "REM Test to know that t1 preinst ran\n"
    1885             :             "ECHO preinst: called with: [%*]\"\n"
    1886             :             "ECHO pre-inst ctrl_t1 > preinst.txt\n"
    1887             :             "ECHO arguments: [%*] >> preinst.txt\n"
    1888             :         );
    1889             :         preinst.write_file(wpkg_path_t1.append_child("preinst.bat"), true);
    1890             :         postinst.printf(
    1891             :             "REM Test to know that t1 postinst ran\n"
    1892             :             "ECHO postinst: called with: [%*]\"\n"
    1893             :             "ECHO post-inst ctrl_t1 > postinst.txt\n"
    1894             :             "ECHO arguments: [%*] >> postinst.txt\n"
    1895             :             "IF EXIST preinst.txt (\n"
    1896             :             "  ECHO t1 preinst ran as expected\n"
    1897             :             "  EXIT 0\n"
    1898             :             ") ELSE (\n"
    1899             :             "  ECHO t1 preinst file not present, test failed\n"
    1900             :             "  EXIT 1\n"
    1901             :             ")\n"
    1902             :         );
    1903             :         postinst.write_file(wpkg_path_t1.append_child("postinst.bat"), true);
    1904             :         prerm.printf(
    1905             :             "REM Test to know that t1 prerm ran\n"
    1906             :             "ECHO pre-rm: called with: [%*]\"\n"
    1907             :             "ECHO pre-rm ctrl_t1 > prerm.txt\n"
    1908             :         );
    1909             :         prerm.write_file(wpkg_path_t1.append_child("prerm.bat"), true);
    1910             :         postrm.printf(
    1911             :             "REM Test to know that t1 postrm ran\n"
    1912             :             "ECHO post-rm: called with: [%*]\"\n"
    1913             :             "ECHO post-rm ctrl_t1 > postrm.txt\n"
    1914             :         );
    1915             :         postrm.write_file(wpkg_path_t1.append_child("postrm.bat"), true);
    1916             : #else
    1917             :         preinst.printf(
    1918             :             "#!/bin/sh -e\n"
    1919             :             "# Test to know that t1 preinst ran\n"
    1920             :             "echo \"preinst: called with: [$*]\"\n"
    1921             :             "if test -f *.txt\n"
    1922             :             "then\n"
    1923             :             "  echo \"  preinst: t1 preinst found unexpected .txt files\"\n"
    1924             :             "  exit 1\n"
    1925             :             "fi\n"
    1926             :             "echo \"pre-inst ctrl_t1\" > preinst.txt\n"
    1927             :             "echo \"arguments: [$*]\" >> preinst.txt\n"
    1928           1 :         );
    1929           1 :         preinst.write_file(wpkg_path_t1.append_child("preinst"), true);
    1930             :         postinst.printf(
    1931             :             "#!/bin/sh -e\n"
    1932             :             "# Test to know that t1 postinst ran\n"
    1933             :             "echo \"postinst: called with: [$*]\"\n"
    1934             :             "echo \"post-inst ctrl_t1\" > postinst.txt\n"
    1935             :             "echo \"arguments: [$*]\" >> postinst.txt\n"
    1936             :             "if test -f preinst.txt\n"
    1937             :             "then\n"
    1938             :             "  echo \"  postinst: t1 preinst ran as expected\"\n"
    1939             :             "  exit 0\n"
    1940             :             "else\n"
    1941             :             "  echo \"  postinst: t1 preinst file not present, test failed\"\n"
    1942             :             "  exit 1\n"
    1943             :             "fi\n"
    1944           1 :         );
    1945           1 :         postinst.write_file(wpkg_path_t1.append_child("postinst"), true);
    1946             :         prerm.printf(
    1947             :             "#!/bin/sh -e\n"
    1948             :             "# Test to know that t1 prerm ran\n"
    1949             :             "echo \"prerm: called with: [$*]\"\n"
    1950             :             "if test -f *.txt\n"
    1951             :             "then\n"
    1952             :             "  echo \"  prerm: t1 prerm found unexpected .txt files\"\n"
    1953             :             "  exit 1\n"
    1954             :             "fi\n"
    1955             :             "echo \"pre-rm ctrl_t1\" > prerm.txt\n"
    1956             :             "echo \"arguments: [$*]\" >> prerm.txt\n"
    1957           1 :         );
    1958           1 :         prerm.write_file(wpkg_path_t1.append_child("prerm"), true);
    1959             :         postrm.printf(
    1960             :             "#!/bin/sh -e\n"
    1961             :             "# Test to know that t1 postrm ran\n"
    1962             :             "echo \"postrm: called with: [$*]\"\n"
    1963             :             "echo \"post-rm ctrl_t1\" > postrm.txt\n"
    1964             :             "echo \"arguments: [$*]\" >> postrm.txt\n"
    1965             :             "if test -f preinst-b.txt -a -f prerm.txt\n"
    1966             :             "then\n"
    1967             :             "  echo \"  postinst: t1 preinst ran as expected\"\n"
    1968             :             "  exit 0\n"
    1969             :             "else\n"
    1970             :             "  echo \"  postinst: t1 preinst file not present, test failed\"\n"
    1971             :             "  exit 1\n"
    1972             :             "fi\n"
    1973           1 :         );
    1974           1 :         postrm.write_file(wpkg_path_t1.append_child("postrm"), true);
    1975             : #endif
    1976           1 :         create_package("t1", ctrl_t1, false);
    1977           1 :         install_package("t1", ctrl_t1);
    1978           1 :         verify_installed_files("t1");
    1979             : 
    1980             :         // verify that each script created the file we expect
    1981           1 :         verify_file_vector_t files;
    1982           1 :         verify_file_t f;
    1983           1 :         f.f_filename = "preinst.txt";
    1984           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    1985             :         f.f_data = "pre-inst ctrl_t1\n"
    1986           1 :                    "arguments: [install]";
    1987           1 :         files.push_back(f);
    1988           1 :         f.f_filename = "postinst.txt";
    1989           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    1990             :         f.f_data = "post-inst ctrl_t1\n"
    1991           1 :                    "arguments: [configure 1.0]";
    1992           1 :         files.push_back(f);
    1993           1 :         f.f_filename = "prerm.txt";
    1994           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    1995           1 :         files.push_back(f);
    1996           1 :         f.f_filename = "postrm.txt";
    1997           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    1998           1 :         files.push_back(f);
    1999           1 :         verify_generated_files(files);
    2000             :     }
    2001             : 
    2002             :     // create an upgrade
    2003             :     {
    2004           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__));
    2005           1 :         ctrl_t1->set_field("Version", "1.1");
    2006             :         ctrl_t1->set_field("Files", "conffiles\n"
    2007             :             "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    2008             :             "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    2009           1 :         );
    2010             :         // destroy the previous version
    2011           1 :         create_package("t1", ctrl_t1);
    2012             : 
    2013           1 :         memfile::memory_file preinst;
    2014           1 :         preinst.create(memfile::memory_file::file_format_other);
    2015           1 :         memfile::memory_file postinst;
    2016           1 :         postinst.create(memfile::memory_file::file_format_other);
    2017           1 :         memfile::memory_file prerm;
    2018           1 :         prerm.create(memfile::memory_file::file_format_other);
    2019           1 :         memfile::memory_file postrm;
    2020           1 :         postrm.create(memfile::memory_file::file_format_other);
    2021             : 
    2022             : #ifdef MO_WINDOWS
    2023             :         preinst.printf(
    2024             :             "REM Test to know whether t1(b) preinst ran\n"
    2025             :             "ECHO preinst(b): called with: [$*]\n"
    2026             :             "ECHO pre-inst ctrl_t1 (b) > preinst.txt\n"
    2027             :             "ECHO arguments: [%*] >> preinst.txt\n"
    2028             :         );
    2029             :         preinst.write_file(wpkg_path_t1.append_child("preinst.bat"), true);
    2030             :         postinst.printf(
    2031             :             "REM Test to know that t1 postinst ran\n"
    2032             :             "ECHO postinst(b): called with: [$*]\n"
    2033             :             "ECHO post-inst ctrl_t1 (b) > postinst.txt\n"
    2034             :             "ECHO arguments: [%*] >> postinst.txt\n"
    2035             :             "IF EXIST preinst.txt (\n"
    2036             :             "  ECHO t1(b) preinst ran as expected\n"
    2037             :             "  EXIT 0\n"
    2038             :             ") ELSE (\n"
    2039             :             "  ECHO t1 preinst file not present, test failed\n"
    2040             :             "  EXIT 1\n"
    2041             :             ")\n"
    2042             :         );
    2043             :         postinst.write_file(wpkg_path_t1.append_child("postinst.bat"), true);
    2044             :         prerm.printf(
    2045             :             "REM Test to know that t1 prerm ran\n"
    2046             :             "ECHO prerm(b): called with: [$*]\n"
    2047             :             "ECHO pre-rm ctrl_t1 (b) > prerm.txt\n"
    2048             :             "ECHO arguments: [%*] (b) >> prerm.txt\n"
    2049             :         );
    2050             :         prerm.write_file(wpkg_path_t1.append_child("prerm.bat"), true);
    2051             :         postrm.printf(
    2052             :             "REM Test to know that t1 postrm ran\n"
    2053             :             "ECHO postrm(b): called with: [$*]\n"
    2054             :             "ECHO post-rm ctrl_t1 (b) > postrm.txt\n"
    2055             :             "ECHO arguments: [%*] (b) >> prerm.txt\n"
    2056             :         );
    2057             :         postrm.write_file(wpkg_path_t1.append_child("postrm.bat"), true);
    2058             : #else
    2059             :         preinst.printf(
    2060             :             "#!/bin/sh -e\n"
    2061             :             "# Test to know that t1 (b) preinst ran\n"
    2062             :             "echo \"preinst(b): called with: [$*]\"\n"
    2063             :             "echo \"pre-inst ctrl_t1 (b)\" > preinst-b.txt\n"
    2064             :             "echo \"arguments: [$*]\" >> preinst-b.txt\n"
    2065             :             "if test -f prerm.txt\n"
    2066             :             "then\n"
    2067             :             "  echo \"  preinst(b): t1 prerm ran as expected\"\n"
    2068             :             "  exit 0\n"
    2069             :             "else\n"
    2070             :             "  echo \"  preinst(b): t1 prerm.txt file not present, test failed\"\n"
    2071             :             "  exit 1\n"
    2072             :             "fi\n"
    2073           1 :         );
    2074           1 :         preinst.write_file(wpkg_path_t1.append_child("preinst"), true);
    2075             :         postinst.printf(
    2076             :             "#!/bin/sh -e\n"
    2077             :             "# Test to know that t1 postinst ran\n"
    2078             :             "echo \"postinst(b): called with: [$*]\"\n"
    2079             :             "echo \"post-inst ctrl_t1 (b)\" > postinst-b.txt\n"
    2080             :             "echo \"arguments: [$*]\" >> postinst-b.txt\n"
    2081             :             "if test -f preinst-b.txt\n"
    2082             :             "then\n"
    2083             :             "  echo \"  postinst: t1(b) preinst ran as expected\"\n"
    2084             :             "  exit 0\n"
    2085             :             "else\n"
    2086             :             "  echo \"  postinst: t1(b) preinst file not present, test failed\"\n"
    2087             :             "  exit 1\n"
    2088             :             "fi\n"
    2089           1 :         );
    2090           1 :         postinst.write_file(wpkg_path_t1.append_child("postinst"), true);
    2091             :         prerm.printf(
    2092             :             "#!/bin/sh -e\n"
    2093             :             "# Test to know that t1(b) prerm ran\n"
    2094             :             "echo \"prerm(b): called with: [$*]\"\n"
    2095             :             "if test -f *.txt\n"
    2096             :             "then\n"
    2097             :             "  echo \"  prerm: t1(b) prerm found unexpected .txt files\"\n"
    2098             :             "  exit 1\n"
    2099             :             "fi\n"
    2100             :             "echo \"pre-rm ctrl_t1 (b)\" > prerm-b.txt\n"
    2101             :             "echo \"arguments: [$*]\" >> prerm-b.txt\n"
    2102           1 :         );
    2103           1 :         prerm.write_file(wpkg_path_t1.append_child("prerm"), true);
    2104             :         postrm.printf(
    2105             :             "#!/bin/sh -e\n"
    2106             :             "# Test to know that t1(b) postrm ran\n"
    2107             :             "echo \"postrm(b): called with: [$*]\"\n"
    2108             :             "echo \"post-rm ctrl_t1 (b)\" > postrm-b.txt\n"
    2109             :             "echo \"arguments: [$*]\" >> postrm-b.txt\n"
    2110             :             "if test -f prerm-b.txt\n"
    2111             :             "then\n"
    2112             :             "  echo \"  postrm: t1(b) prerm ran as expected\"\n"
    2113             :             "  exit 0\n"
    2114             :             "else\n"
    2115             :             "  echo \"  postrm: t1(b) prerm file not present, test failed\"\n"
    2116             :             "  exit 1\n"
    2117             :             "fi\n"
    2118           1 :         );
    2119           1 :         postrm.write_file(wpkg_path_t1.append_child("postrm"), true);
    2120             : #endif
    2121           1 :         create_package("t1", ctrl_t1, false);
    2122           1 :         install_package("t1", ctrl_t1);
    2123           1 :         verify_installed_files("t1");
    2124             : 
    2125             :         // verify that each script created the file we expect
    2126           1 :         verify_file_vector_t files;
    2127           1 :         verify_file_t f;
    2128           1 :         f.f_filename = "preinst.txt";
    2129           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2130           1 :         files.push_back(f);
    2131           1 :         f.f_filename = "postinst.txt";
    2132           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2133           1 :         files.push_back(f);
    2134           1 :         f.f_filename = "preinst-b.txt";
    2135           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2136             :         f.f_data = "pre-inst ctrl_t1 (b)\n"
    2137           1 :                    "arguments: [upgrade 1.0]";
    2138           1 :         files.push_back(f);
    2139           1 :         f.f_filename = "postinst-b.txt";
    2140           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2141             :         f.f_data = "post-inst ctrl_t1 (b)\n"
    2142           1 :                    "arguments: [configure 1.1]";
    2143           1 :         files.push_back(f);
    2144           1 :         f.f_filename = "prerm.txt";
    2145           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2146             :         f.f_data = "pre-rm ctrl_t1\n"
    2147           1 :                    "arguments: [upgrade 1.1]";
    2148           1 :         files.push_back(f);
    2149           1 :         f.f_filename = "postrm.txt";
    2150           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2151             :         f.f_data = "post-rm ctrl_t1\n"
    2152           1 :                    "arguments: [upgrade 1.1]";
    2153           1 :         files.push_back(f);
    2154           1 :         verify_generated_files(files);
    2155             : 
    2156             :         // remove the result
    2157           1 :         remove_package("t1", ctrl_t1);
    2158           1 :         verify_removed_files("t1", ctrl_t1);
    2159             : 
    2160             :         // verify that each script created the file we expect
    2161           1 :         files.clear();
    2162           1 :         f.clear();
    2163           1 :         f.f_filename = "preinst.txt";
    2164           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2165           1 :         files.push_back(f);
    2166           1 :         f.f_filename = "postinst.txt";
    2167           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2168           1 :         files.push_back(f);
    2169           1 :         f.f_filename = "prerm.txt";
    2170           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2171           1 :         files.push_back(f);
    2172           1 :         f.f_filename = "postrm.txt";
    2173           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2174           1 :         files.push_back(f);
    2175           1 :         f.f_filename = "preinst-b.txt";
    2176           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2177           1 :         files.push_back(f);
    2178           1 :         f.f_filename = "postinst-b.txt";
    2179           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2180           1 :         files.push_back(f);
    2181             : 
    2182           1 :         f.f_filename = "prerm-b.txt";
    2183           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2184             :         f.f_data = "pre-rm ctrl_t1 (b)\n"
    2185           1 :                    "arguments: [remove]";
    2186           1 :         files.push_back(f);
    2187           1 :         f.f_filename = "postrm-b.txt";
    2188           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2189             :         f.f_data = "post-rm ctrl_t1 (b)\n"
    2190           1 :                    "arguments: [remove]";
    2191           1 :         files.push_back(f);
    2192           1 :         verify_generated_files(files);
    2193             :     }
    2194             : 
    2195             : ////////////////////// t2 -- upgrade from a package without any scripts to a package with full scripts
    2196           1 :     wpkg_filename::uri_filename build_path_t2(root.append_child("t2"));
    2197           1 :     wpkg_filename::uri_filename wpkg_path_t2(build_path_t2.append_child("WPKG"));
    2198             : 
    2199             :     // create a first version of the package
    2200             :     {
    2201           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
    2202           1 :         ctrl_t2->set_field("Version", "2.0");
    2203             :         ctrl_t2->set_field("Files", "conffiles\n"
    2204             :             "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    2205             :             "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    2206           1 :         );
    2207             : 
    2208           1 :         create_package("t2", ctrl_t2, false);
    2209           1 :         install_package("t2", ctrl_t2);
    2210           1 :         verify_installed_files("t2");
    2211             : 
    2212             :         // verify that each script created the file we expect
    2213           1 :         verify_file_vector_t files;
    2214           1 :         verify_file_t f;
    2215           1 :         f.f_filename = "preinst.txt";
    2216           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2217           1 :         files.push_back(f);
    2218           1 :         f.f_filename = "postinst.txt";
    2219           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2220           1 :         files.push_back(f);
    2221           1 :         f.f_filename = "prerm.txt";
    2222           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2223           1 :         files.push_back(f);
    2224           1 :         f.f_filename = "postrm.txt";
    2225           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2226           1 :         files.push_back(f);
    2227           1 :         verify_generated_files(files);
    2228             :     }
    2229             : 
    2230             :     // create an upgrade
    2231             :     {
    2232           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__));
    2233           1 :         ctrl_t2->set_field("Version", "2.1");
    2234             :         ctrl_t2->set_field("Files", "conffiles\n"
    2235             :             "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    2236             :             "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    2237           1 :         );
    2238             :         // destroy the previous version
    2239           1 :         create_package("t2", ctrl_t2);
    2240             : 
    2241           1 :         memfile::memory_file preinst;
    2242           1 :         preinst.create(memfile::memory_file::file_format_other);
    2243           1 :         memfile::memory_file postinst;
    2244           1 :         postinst.create(memfile::memory_file::file_format_other);
    2245           1 :         memfile::memory_file prerm;
    2246           1 :         prerm.create(memfile::memory_file::file_format_other);
    2247           1 :         memfile::memory_file postrm;
    2248           1 :         postrm.create(memfile::memory_file::file_format_other);
    2249             : 
    2250             : #ifdef MO_WINDOWS
    2251             :         preinst.printf(
    2252             :             "REM Test to know whether t2(b) preinst ran\n"
    2253             :             "ECHO preinst(b): called with: [$*]\n"
    2254             :             "ECHO pre-inst ctrl_t2 (b) > preinst.txt\n"
    2255             :             "ECHO arguments: [%*] >> preinst.txt\n"
    2256             :         );
    2257             :         preinst.write_file(wpkg_path_t2.append_child("preinst.bat"), true);
    2258             :         postinst.printf(
    2259             :             "REM Test to know that t2 postinst ran\n"
    2260             :             "ECHO postinst(b): called with: [$*]\n"
    2261             :             "ECHO post-inst ctrl_t2 (b) > postinst.txt\n"
    2262             :             "ECHO arguments: [%*] >> postinst.txt\n"
    2263             :             "IF EXIST preinst.txt (\n"
    2264             :             "  ECHO t2(b) preinst ran as expected\n"
    2265             :             "  EXIT 0\n"
    2266             :             ") ELSE (\n"
    2267             :             "  ECHO t2 preinst file not present, test failed\n"
    2268             :             "  EXIT 1\n"
    2269             :             ")\n"
    2270             :         );
    2271             :         postinst.write_file(wpkg_path_t2.append_child("postinst.bat"), true);
    2272             :         prerm.printf(
    2273             :             "REM Test to know that t2 prerm ran\n"
    2274             :             "ECHO prerm(b): called with: [$*]\n"
    2275             :             "ECHO pre-rm ctrl_t2 (b) > prerm.txt\n"
    2276             :             "ECHO arguments: [%*] (b) >> prerm.txt\n"
    2277             :         );
    2278             :         prerm.write_file(wpkg_path_t2.append_child("prerm.bat"), true);
    2279             :         postrm.printf(
    2280             :             "REM Test to know that t2 postrm ran\n"
    2281             :             "ECHO postrm(b): called with: [$*]\n"
    2282             :             "ECHO post-rm ctrl_t2 (b) > postrm.txt\n"
    2283             :             "ECHO arguments: [%*] (b) >> prerm.txt\n"
    2284             :         );
    2285             :         postrm.write_file(wpkg_path_t2.append_child("postrm.bat"), true);
    2286             : #else
    2287             :         preinst.printf(
    2288             :             "#!/bin/sh -e\n"
    2289             :             "# Test to know that t2 (b) preinst ran\n"
    2290             :             "echo \"preinst(b): t2 called with: [$*]\"\n"
    2291             :             "if test -f *.txt\n"
    2292             :             "then\n"
    2293             :             "  echo \"  preinst(b): t2 preinst file detected other unexpected files\"\n"
    2294             :             "  exit 1\n"
    2295             :             "else\n"
    2296             :             "  echo \"  preinst(b): t2 preinst ran first as expected\"\n"
    2297             :             "fi\n"
    2298             :             "echo \"pre-inst ctrl_t2 (b)\" > preinst-b.txt\n"
    2299             :             "echo \"arguments: [$*]\" >> preinst-b.txt\n"
    2300           1 :         );
    2301           1 :         preinst.write_file(wpkg_path_t2.append_child("preinst"), true);
    2302             :         postinst.printf(
    2303             :             "#!/bin/sh -e\n"
    2304             :             "# Test to know that t2 postinst ran\n"
    2305             :             "echo \"postinst(b): called with: [$*]\"\n"
    2306             :             "echo \"post-inst ctrl_t2 (b)\" > postinst-b.txt\n"
    2307             :             "echo \"arguments: [$*]\" >> postinst-b.txt\n"
    2308             :             "if test -f preinst-b.txt\n"
    2309             :             "then\n"
    2310             :             "  echo \"  postinst: t2(b) preinst ran as expected\"\n"
    2311             :             "  exit 0\n"
    2312             :             "else\n"
    2313             :             "  echo \"  postinst: t2(b) preinst file not present, test failed\"\n"
    2314             :             "  exit 1\n"
    2315             :             "fi\n"
    2316           1 :         );
    2317           1 :         postinst.write_file(wpkg_path_t2.append_child("postinst"), true);
    2318             :         prerm.printf(
    2319             :             "#!/bin/sh -e\n"
    2320             :             "# Test to know that t2(b) prerm ran\n"
    2321             :             "echo \"prerm(b): called with: [$*]\"\n"
    2322             :             "if test -f *.txt\n"
    2323             :             "then\n"
    2324             :             "  echo \"  prerm: t2(b) prerm found unexpected .txt files\"\n"
    2325             :             "  exit 1\n"
    2326             :             "fi\n"
    2327             :             "echo \"pre-rm ctrl_t2 (b)\" > prerm-b.txt\n"
    2328             :             "echo \"arguments: [$*]\" >> prerm-b.txt\n"
    2329           1 :         );
    2330           1 :         prerm.write_file(wpkg_path_t2.append_child("prerm"), true);
    2331             :         postrm.printf(
    2332             :             "#!/bin/sh -e\n"
    2333             :             "# Test to know that t2(b) postrm ran\n"
    2334             :             "echo \"postrm(b): called with: [$*]\"\n"
    2335             :             "echo \"post-rm ctrl_t2 (b)\" > postrm-b.txt\n"
    2336             :             "echo \"arguments: [$*]\" >> postrm-b.txt\n"
    2337             :             "if test -f prerm-b.txt\n"
    2338             :             "then\n"
    2339             :             "  echo \"  postrm: t2(b) prerm ran as expected\"\n"
    2340             :             "  exit 0\n"
    2341             :             "else\n"
    2342             :             "  echo \"  postrm: t2(b) prerm file not present, test failed\"\n"
    2343             :             "  exit 1\n"
    2344             :             "fi\n"
    2345           1 :         );
    2346           1 :         postrm.write_file(wpkg_path_t2.append_child("postrm"), true);
    2347             : #endif
    2348           1 :         create_package("t2", ctrl_t2, false);
    2349           1 :         install_package("t2", ctrl_t2);
    2350           1 :         verify_installed_files("t2");
    2351             : 
    2352             :         // verify that each script created the file we expect
    2353           1 :         verify_file_vector_t files;
    2354           1 :         verify_file_t f;
    2355           1 :         f.f_filename = "preinst.txt";
    2356           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2357           1 :         files.push_back(f);
    2358           1 :         f.f_filename = "postinst.txt";
    2359           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2360           1 :         files.push_back(f);
    2361           1 :         f.f_filename = "preinst-b.txt";
    2362           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2363             :         f.f_data = "pre-inst ctrl_t2 (b)\n"
    2364           1 :                    "arguments: [upgrade 2.0]";
    2365           1 :         files.push_back(f);
    2366           1 :         f.f_filename = "postinst-b.txt";
    2367           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2368             :         f.f_data = "post-inst ctrl_t2 (b)\n"
    2369           1 :                    "arguments: [configure 2.1]";
    2370           1 :         files.push_back(f);
    2371           1 :         f.f_filename = "prerm.txt";
    2372           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2373           1 :         files.push_back(f);
    2374           1 :         f.f_filename = "postrm.txt";
    2375           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2376           1 :         files.push_back(f);
    2377           1 :         verify_generated_files(files);
    2378             : 
    2379             :         // remove the result
    2380           1 :         remove_package("t2", ctrl_t2);
    2381           1 :         verify_removed_files("t2", ctrl_t2);
    2382             : 
    2383             :         // verify that each script created the file we expect
    2384           1 :         files.clear();
    2385           1 :         f.clear();
    2386           1 :         f.f_filename = "preinst.txt";
    2387           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2388           1 :         files.push_back(f);
    2389           1 :         f.f_filename = "postinst.txt";
    2390           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2391           1 :         files.push_back(f);
    2392           1 :         f.f_filename = "prerm.txt";
    2393           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2394           1 :         files.push_back(f);
    2395           1 :         f.f_filename = "postrm.txt";
    2396           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2397           1 :         files.push_back(f);
    2398           1 :         f.f_filename = "preinst-b.txt";
    2399           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2400           1 :         files.push_back(f);
    2401           1 :         f.f_filename = "postinst-b.txt";
    2402           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2403           1 :         files.push_back(f);
    2404             : 
    2405           1 :         f.f_filename = "prerm-b.txt";
    2406           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2407             :         f.f_data = "pre-rm ctrl_t2 (b)\n"
    2408           1 :                    "arguments: [remove]";
    2409           1 :         files.push_back(f);
    2410           1 :         f.f_filename = "postrm-b.txt";
    2411           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2412             :         f.f_data = "post-rm ctrl_t2 (b)\n"
    2413           1 :                    "arguments: [remove]";
    2414           1 :         files.push_back(f);
    2415           1 :         verify_generated_files(files);
    2416             :     }
    2417             : 
    2418             : ////////////////////// t3 -- upgrade from a package without any scripts to a package with full scripts
    2419           1 :     wpkg_filename::uri_filename build_path_t3(root.append_child("t3"));
    2420           1 :     wpkg_filename::uri_filename wpkg_path_t3(build_path_t3.append_child("WPKG"));
    2421             : 
    2422             :     // create a first version of the package
    2423             :     {
    2424           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t3(get_new_control_file(__FUNCTION__));
    2425           1 :         ctrl_t3->set_field("Version", "3.0");
    2426             :         ctrl_t3->set_field("Files", "conffiles\n"
    2427             :             "/usr/bin/t3 0123456789abcdef0123456789abcdef\n"
    2428             :             "/usr/share/doc/t3/copyright 0123456789abcdef0123456789abcdef\n"
    2429           1 :         );
    2430             : 
    2431           1 :         memfile::memory_file preinst;
    2432           1 :         preinst.create(memfile::memory_file::file_format_other);
    2433           1 :         memfile::memory_file postinst;
    2434           1 :         postinst.create(memfile::memory_file::file_format_other);
    2435           1 :         memfile::memory_file prerm;
    2436           1 :         prerm.create(memfile::memory_file::file_format_other);
    2437           1 :         memfile::memory_file postrm;
    2438           1 :         postrm.create(memfile::memory_file::file_format_other);
    2439             : 
    2440             : #ifdef MO_WINDOWS
    2441             :         preinst.printf(
    2442             :             "REM Test to know whether t3 preinst ran\n"
    2443             :             "ECHO preinst: called with: [$*]\n"
    2444             :             "ECHO pre-inst ctrl_t3 > preinst.txt\n"
    2445             :             "ECHO arguments: [%*] >> preinst.txt\n"
    2446             :         );
    2447             :         preinst.write_file(wpkg_path_t3.append_child("preinst.bat"), true);
    2448             :         postinst.printf(
    2449             :             "REM Test to know that t3 postinst ran\n"
    2450             :             "ECHO postinst: called with: [$*]\n"
    2451             :             "ECHO post-inst ctrl_t3 > postinst.txt\n"
    2452             :             "ECHO arguments: [%*] >> postinst.txt\n"
    2453             :             "IF EXIST preinst.txt (\n"
    2454             :             "  ECHO t3 preinst ran as expected\n"
    2455             :             "  EXIT 0\n"
    2456             :             ") ELSE (\n"
    2457             :             "  ECHO t3 preinst file not present, test failed\n"
    2458             :             "  EXIT 1\n"
    2459             :             ")\n"
    2460             :         );
    2461             :         postinst.write_file(wpkg_path_t3.append_child("postinst.bat"), true);
    2462             :         prerm.printf(
    2463             :             "REM Test to know that t3 prerm ran\n"
    2464             :             "ECHO prerm: called with: [$*]\n"
    2465             :             "ECHO pre-rm ctrl_t3 > prerm.txt\n"
    2466             :             "ECHO arguments: [%*] >> prerm.txt\n"
    2467             :         );
    2468             :         prerm.write_file(wpkg_path_t3.append_child("prerm.bat"), true);
    2469             :         postrm.printf(
    2470             :             "REM Test to know that t3 postrm ran\n"
    2471             :             "ECHO postrm: called with: [$*]\n"
    2472             :             "ECHO post-rm ctrl_t3 > postrm.txt\n"
    2473             :             "ECHO arguments: [%*] >> prerm.txt\n"
    2474             :         );
    2475             :         postrm.write_file(wpkg_path_t3.append_child("postrm.bat"), true);
    2476             : #else
    2477             :         preinst.printf(
    2478             :             "#!/bin/sh -e\n"
    2479             :             "# Test to know that t3 preinst ran\n"
    2480             :             "echo \"preinst: t3 called with: [$*]\"\n"
    2481             :             "if test -f *.txt\n"
    2482             :             "then\n"
    2483             :             "  echo \"  preinst: t3 preinst file detected other unexpected files\"\n"
    2484             :             "  exit 1\n"
    2485             :             "else\n"
    2486             :             "  echo \"  preinst: t3 preinst ran first as expected\"\n"
    2487             :             "fi\n"
    2488             :             "echo \"pre-inst ctrl_t3\" > preinst.txt\n"
    2489             :             "echo \"arguments: [$*]\" >> preinst.txt\n"
    2490           1 :         );
    2491           1 :         preinst.write_file(wpkg_path_t3.append_child("preinst"), true);
    2492             :         postinst.printf(
    2493             :             "#!/bin/sh -e\n"
    2494             :             "# Test to know that t3 postinst ran\n"
    2495             :             "echo \"postinst: called with: [$*]\"\n"
    2496             :             "echo \"post-inst ctrl_t3\" > postinst.txt\n"
    2497             :             "echo \"arguments: [$*]\" >> postinst.txt\n"
    2498             :             "if test -f preinst.txt\n"
    2499             :             "then\n"
    2500             :             "  echo \"  postinst: t3 preinst ran as expected\"\n"
    2501             :             "  exit 0\n"
    2502             :             "else\n"
    2503             :             "  echo \"  postinst: t3 preinst file not present, test failed\"\n"
    2504             :             "  exit 1\n"
    2505             :             "fi\n"
    2506           1 :         );
    2507           1 :         postinst.write_file(wpkg_path_t3.append_child("postinst"), true);
    2508             :         prerm.printf(
    2509             :             "#!/bin/sh -e\n"
    2510             :             "# Test to know that t3 prerm ran\n"
    2511             :             "echo \"prerm: called with: [$*]\"\n"
    2512             :             "if test -f *.txt\n"
    2513             :             "then\n"
    2514             :             "  echo \"  prerm: t3 prerm found unexpected .txt files\"\n"
    2515             :             "  exit 1\n"
    2516             :             "fi\n"
    2517             :             "echo \"pre-rm ctrl_t3\" > prerm-b.txt\n"
    2518             :             "echo \"arguments: [$*]\" >> prerm-b.txt\n"
    2519           1 :         );
    2520           1 :         prerm.write_file(wpkg_path_t3.append_child("prerm"), true);
    2521             :         postrm.printf(
    2522             :             "#!/bin/sh -e\n"
    2523             :             "# Test to know that t3 postrm ran\n"
    2524             :             "echo \"postrm: called with: [$*]\"\n"
    2525             :             "echo \"post-rm ctrl_t3\" > postrm-b.txt\n"
    2526             :             "echo \"arguments: [$*]\" >> postrm-b.txt\n"
    2527             :             "if test -f prerm-b.txt\n"
    2528             :             "then\n"
    2529             :             "  echo \"  postrm: t3 prerm ran as expected\"\n"
    2530             :             "  exit 0\n"
    2531             :             "else\n"
    2532             :             "  echo \"  postrm: t3 prerm file not present, test failed\"\n"
    2533             :             "  exit 1\n"
    2534             :             "fi\n"
    2535           1 :         );
    2536           1 :         postrm.write_file(wpkg_path_t3.append_child("postrm"), true);
    2537             : #endif
    2538           1 :         create_package("t3", ctrl_t3, false);
    2539           1 :         install_package("t3", ctrl_t3);
    2540           1 :         verify_installed_files("t3");
    2541             : 
    2542             :         // verify that each script created the file we expect
    2543           1 :         verify_file_vector_t files;
    2544           1 :         verify_file_t f;
    2545           1 :         f.f_filename = "preinst.txt";
    2546           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2547             :         f.f_data = "pre-inst ctrl_t3\n"
    2548           1 :                    "arguments: [install]";
    2549           1 :         files.push_back(f);
    2550           1 :         f.f_filename = "postinst.txt";
    2551           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_text); // FIXME cast
    2552             :         f.f_data = "post-inst ctrl_t3\n"
    2553           1 :                    "arguments: [configure 3.0]";
    2554           1 :         files.push_back(f);
    2555           1 :         f.f_filename = "prerm.txt";
    2556           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2557           1 :         files.push_back(f);
    2558           1 :         f.f_filename = "postrm.txt";
    2559           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2560           1 :         files.push_back(f);
    2561           1 :         verify_generated_files(files);
    2562             :     }
    2563             : 
    2564             :     // create an upgrade
    2565             :     {
    2566           1 :         std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t3(get_new_control_file(__FUNCTION__));
    2567           1 :         ctrl_t3->set_field("Version", "3.1");
    2568             :         ctrl_t3->set_field("Files", "conffiles\n"
    2569             :             "/usr/bin/t3 0123456789abcdef0123456789abcdef\n"
    2570             :             "/usr/share/doc/t3/copyright 0123456789abcdef0123456789abcdef\n"
    2571           1 :         );
    2572             :         // destroy the previous version
    2573           1 :         create_package("t3", ctrl_t3);
    2574           1 :         install_package("t3", ctrl_t3);
    2575           1 :         verify_installed_files("t3");
    2576             : 
    2577             :         // verify that each script created the file we expect
    2578           1 :         verify_file_vector_t files;
    2579           1 :         verify_file_t f;
    2580           1 :         f.f_filename = "preinst.txt";
    2581           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2582           1 :         files.push_back(f);
    2583           1 :         f.f_filename = "postinst.txt";
    2584           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2585           1 :         files.push_back(f);
    2586           1 :         f.f_filename = "prerm.txt";
    2587           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2588           1 :         files.push_back(f);
    2589           1 :         f.f_filename = "postrm.txt";
    2590           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2591           1 :         files.push_back(f);
    2592           1 :         verify_generated_files(files);
    2593             : 
    2594             :         // remove the result
    2595           1 :         remove_package("t3", ctrl_t3);
    2596           1 :         verify_removed_files("t3", ctrl_t3);
    2597             : 
    2598             :         // verify that each script created the file we expect
    2599           1 :         files.clear();
    2600           1 :         f.clear();
    2601           1 :         f.f_filename = "preinst.txt";
    2602           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2603           1 :         files.push_back(f);
    2604           1 :         f.f_filename = "postinst.txt";
    2605           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2606           1 :         files.push_back(f);
    2607           1 :         f.f_filename = "prerm.txt";
    2608           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2609           1 :         files.push_back(f);
    2610           1 :         f.f_filename = "postrm.txt";
    2611           1 :         f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2612           1 :         files.push_back(f);
    2613           1 :         verify_generated_files(files);
    2614           1 :     }
    2615           1 : }
    2616             : 
    2617             : 
    2618           1 : void PackageUnitTests::compare_versions()
    2619             : {
    2620             :     struct version_t
    2621             :     {
    2622             :         const char * const  f_left;
    2623             :         const char * const  f_right;
    2624             :         int                 f_results[10];
    2625             :     };
    2626             :     const version_t versions[] = {
    2627             :         //    l         r        << -nl  <= -nl  ==  !=  >= -nl  >> -nl
    2628             :         { "",          "",      { 1,  1,  0,  0,  0,  1,  0,  0,  1,  1 } },
    2629             :         { "",       "0.9",      { 0,  1,  0,  1,  1,  0,  1,  0,  1,  0 } },
    2630             :         { "1.0",       "",      { 1,  0,  1,  0,  1,  0,  0,  1,  0,  1 } },
    2631             :         { "1.0",    "0.9",      { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2632             :         { "0.9",    "1.0",      { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2633             :         { "1.0",    "1.0",      { 1,  1,  0,  0,  0,  1,  0,  0,  1,  1 } },
    2634             :         { "1b",     "1a",       { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2635             :         { "1a",     "1b",       { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2636             :         { "1a~",    "1a~",      { 1,  1,  0,  0,  0,  1,  0,  0,  1,  1 } },
    2637             :         { "1a",     "1a~",      { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2638             :         { "1a~",    "1a",       { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2639             :         { "1.0",    "1.a",      { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2640             :         { "1.0",    "1.+",      { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2641             :         { "1.0",    "1.--0",    { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2642             :         { "1.+",    "1.--0",    { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2643             :         { "1+",     "1--0",     { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2644             :         { "1.3a+",  "1.3a--0",  { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2645             :         { "3.5-10", "3.5-5",    { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2646             :         { "3.5-20", "3.5-15",   { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2647             :         { "3.5-2",  "3.5-15",   { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2648             :         { "3:5.2",  "3:5.02",   { 1,  1,  0,  0,  0,  1,  0,  0,  1,  1 } },
    2649             :         { "3:5.9",  "3:5.09",   { 1,  1,  0,  0,  0,  1,  0,  0,  1,  1 } },
    2650             :         { "2:5.9",  "3:5.09",   { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2651             :         { "4:5.9",  "3:5.09",   { 1,  1,  1,  1,  1,  0,  0,  0,  0,  0 } },
    2652             :         { "7:5.9",  "7:5:9",    { 0,  0,  0,  0,  1,  0,  1,  1,  1,  1 } },
    2653           1 :     };
    2654           1 :     const size_t versions_size = sizeof(versions) / sizeof(versions[0]);
    2655             :     const char *ops[3][10] = {
    2656             :         { "<<", "lt-nl", "<=", "le-nl",  "=", "!=", ">=", "ge-nl", ">>", "gt-nl" },
    2657             :         { "lt", "lt-nl", "le", "le-nl", "eq", "ne", "ge", "ge-nl", "gt", "gt-nl" },
    2658             :         {  "<", "lt-nl", "<=", "le-nl", "==", "<>", ">=", "ge-nl",  ">", "gt-nl" }
    2659           1 :     };
    2660             : 
    2661          26 :     for(size_t i(0); i < versions_size; ++i)
    2662             :     {
    2663         100 :         for(size_t j(0); j < 3; ++j)
    2664             :         {
    2665         825 :             for(size_t k(0); k < 10; ++k)
    2666             :             {
    2667         750 :                 std::string cmd(unittest::wpkg_tool);
    2668         750 :                 cmd += " --compare-versions ";
    2669         750 :                 if(*versions[i].f_left == '\0')
    2670             :                 {
    2671          60 :                     cmd += "''";
    2672             :                 }
    2673             :                 else
    2674             :                 {
    2675         690 :                     cmd += versions[i].f_left;
    2676             :                 }
    2677         750 :                 cmd += " '";
    2678         750 :                 cmd += ops[j][k];
    2679         750 :                 cmd += "' ";
    2680         750 :                 if(*versions[i].f_right == '\0')
    2681             :                 {
    2682          60 :                     cmd += "''";
    2683             :                 }
    2684             :                 else
    2685             :                 {
    2686         690 :                     cmd += versions[i].f_right;
    2687             :                 }
    2688             : 
    2689         750 :                 int r(system(cmd.c_str()));
    2690         750 :                 int result(WEXITSTATUS(r));
    2691         750 :                 CPPUNIT_ASSERT_MESSAGE(cmd + " completely failed", result == 0 || result == 1);
    2692         750 :                 std::stringstream msg;
    2693         750 :                 msg << cmd << " result: " << result << " (expected: " << versions[i].f_results[k] << ")";
    2694         750 :                 CPPUNIT_ASSERT_MESSAGE(msg.str(), versions[i].f_results[k] == result);
    2695         750 :             }
    2696             :         }
    2697             :     }
    2698           1 : }
    2699             : 
    2700             : 
    2701             : 
    2702             : 
    2703           1 : void PackageUnitTests::auto_upgrade()
    2704             : {
    2705             :     // IMPORTANT: remember that all files are deleted between tests
    2706             : 
    2707           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    2708             :     //wpkg_filename::uri_filename target_path(root.append_child("target"));
    2709           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    2710             : 
    2711             :     // create a package that will be auto-upgraded
    2712           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__ + std::string(" t1")));
    2713             :     ctrl_t1->set_field("Conffiles", "\n"
    2714             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2715           1 :     );
    2716             :     ctrl_t1->set_field("Files", "conffiles\n"
    2717             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    2718             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    2719             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    2720           1 :     );
    2721           1 :     create_package("t1", ctrl_t1);
    2722             :     // Conffiles -- the create_package deletes this field
    2723             :     ctrl_t1->set_field("Conffiles", "\n"
    2724             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2725           1 :     );
    2726             : 
    2727             :     // the first install call is expected to work as is, not problem
    2728           1 :     install_package("t1", ctrl_t1, 0);
    2729           1 :     verify_installed_files("t1");
    2730             : 
    2731             :     // create a package that we'll mark for hold
    2732           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1_15(get_new_control_file(__FUNCTION__ + std::string(" t1 v1.5")));
    2733           1 :     ctrl_t1_15->set_field("Version", "1.5");
    2734             :     ctrl_t1_15->set_field("Conffiles", "\n"
    2735             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2736           1 :     );
    2737             :     ctrl_t1_15->set_field("Files", "conffiles\n"
    2738             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    2739             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    2740             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    2741             :         "/usr/share/doc/t1/changes_in_15 0123456789abcdef0123456789abcdef\n"
    2742           1 :     );
    2743           1 :     create_package("t1", ctrl_t1_15);
    2744             :     // Conffiles -- the create_package deletes this field
    2745             :     ctrl_t1_15->set_field("Conffiles", "\n"
    2746             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2747           1 :     );
    2748             : 
    2749             :     // Now create t2 with t1 as a dependency that needs to be auto-upgraded
    2750           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__ + std::string(" t2")));
    2751           1 :     ctrl_t2->set_field("Depends", "t1 (= 1.5)");
    2752             :     ctrl_t2->set_field("Conffiles", "\n"
    2753             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef"
    2754           1 :     );
    2755             :     ctrl_t2->set_field("Files", "conffiles\n"
    2756             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef\n"
    2757             :         "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    2758             :         "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    2759           1 :     );
    2760           1 :     create_package("t2", ctrl_t2);
    2761             :     // Conffiles -- the create_package deletes this field
    2762             :     ctrl_t2->set_field("Conffiles", "\n"
    2763             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef"
    2764           1 :     );
    2765             : 
    2766             :     // the first install call is expected to work as is, not problem
    2767           1 :     ctrl_t2->set_variable("INSTALL_POSTOPTIONS", "--repository " + repository.path_only());
    2768           1 :     install_package("t2", ctrl_t2, 0);
    2769           1 :     verify_installed_files("t2");
    2770           1 : }
    2771             : 
    2772             : 
    2773           1 : void PackageUnitTests::auto_downgrade()
    2774             : {
    2775             :     // IMPORTANT: remember that all files are deleted between tests
    2776             : 
    2777           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    2778             :     //wpkg_filename::uri_filename target_path(root.append_child("target"));
    2779           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    2780             : 
    2781             :     // create a package that will be viewed as an auto-downgrad
    2782           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1(get_new_control_file(__FUNCTION__ + std::string(" t1")));
    2783           1 :     ctrl_t1->set_field("Version", "1.9");
    2784             :     ctrl_t1->set_field("Conffiles", "\n"
    2785             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2786           1 :     );
    2787             :     ctrl_t1->set_field("Files", "conffiles\n"
    2788             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    2789             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    2790             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    2791           1 :     );
    2792           1 :     create_package("t1", ctrl_t1);
    2793             :     // Conffiles -- the create_package deletes this field
    2794             :     ctrl_t1->set_field("Conffiles", "\n"
    2795             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2796           1 :     );
    2797             : 
    2798             :     // the first install call is expected to work as is, not problem
    2799           1 :     install_package("t1", ctrl_t1, 0);
    2800           1 :     verify_installed_files("t1");
    2801             : 
    2802             :     // create a package that we'll mark for hold
    2803           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t1_12(get_new_control_file(__FUNCTION__ + std::string(" t1 v1.2")));
    2804           1 :     ctrl_t1_12->set_field("Version", "1.2");
    2805             :     ctrl_t1_12->set_field("Conffiles", "\n"
    2806             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2807           1 :     );
    2808             :     ctrl_t1_12->set_field("Files", "conffiles\n"
    2809             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef\n"
    2810             :         "/usr/bin/t1 0123456789abcdef0123456789abcdef\n"
    2811             :         "/usr/share/doc/t1/copyright 0123456789abcdef0123456789abcdef\n"
    2812             :         "/usr/share/doc/t1/changes_in_15 0123456789abcdef0123456789abcdef\n"
    2813           1 :     );
    2814           1 :     create_package("t1", ctrl_t1_12);
    2815             :     // Conffiles -- the create_package deletes this field
    2816             :     ctrl_t1_12->set_field("Conffiles", "\n"
    2817             :         "/etc/t1/t1.conf 0123456789abcdef0123456789abcdef"
    2818           1 :     );
    2819             : 
    2820             :     // Now create t2 with t1 as a dependency that needs to be auto-upgraded
    2821           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_t2(get_new_control_file(__FUNCTION__ + std::string(" t2")));
    2822           1 :     ctrl_t2->set_field("Depends", "t1 (= 1.2)");
    2823             :     ctrl_t2->set_field("Conffiles", "\n"
    2824             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef"
    2825           1 :     );
    2826             :     ctrl_t2->set_field("Files", "conffiles\n"
    2827             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef\n"
    2828             :         "/usr/bin/t2 0123456789abcdef0123456789abcdef\n"
    2829             :         "/usr/share/doc/t2/copyright 0123456789abcdef0123456789abcdef\n"
    2830           1 :     );
    2831           1 :     create_package("t2", ctrl_t2);
    2832             :     // Conffiles -- the create_package deletes this field
    2833             :     ctrl_t2->set_field("Conffiles", "\n"
    2834             :         "/etc/t2/t2.conf 0123456789abcdef0123456789abcdef"
    2835           1 :     );
    2836             : 
    2837             :     // the first install call is expected to work as is, not problem
    2838           1 :     ctrl_t2->set_variable("INSTALL_POSTOPTIONS", "--repository " + repository.path_only());
    2839           1 :     install_package("t2", ctrl_t2, 1);
    2840           1 :     verify_purged_files("t2", ctrl_t2);
    2841           1 : }
    2842             : 
    2843             : 
    2844           1 : void PackageUnitTests::test_hold()
    2845             : {
    2846             :     // IMPORTANT: remember that all files are deleted between tests
    2847             : 
    2848           1 :     wpkg_filename::uri_filename root(unittest::tmp_dir);
    2849           1 :     wpkg_filename::uri_filename target_path(root.append_child("target"));
    2850           1 :     wpkg_filename::uri_filename repository(root.append_child("repository"));
    2851             : 
    2852             :     // create a package that we'll mark for hold
    2853           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_held(get_new_control_file(__FUNCTION__));
    2854             :     ctrl_held->set_field("Conffiles", "\n"
    2855             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef"
    2856           1 :     );
    2857             :     ctrl_held->set_field("Files", "conffiles\n"
    2858             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef\n"
    2859             :         "/usr/bin/held 0123456789abcdef0123456789abcdef\n"
    2860             :         "/usr/share/doc/held/copyright 0123456789abcdef0123456789abcdef\n"
    2861           1 :     );
    2862           1 :     create_package("held", ctrl_held);
    2863             :     // Conffiles -- the create_package deletes this field
    2864             :     ctrl_held->set_field("Conffiles", "\n"
    2865             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef"
    2866           1 :     );
    2867             : 
    2868             :     // the first install call is expected to work as is, not problem
    2869           1 :     install_package("held", ctrl_held, 0);
    2870           1 :     verify_installed_files("held");
    2871             : 
    2872             :     // now we want to mark the package for hold
    2873           1 :     std::string cmd(unittest::wpkg_tool);
    2874           1 :     cmd += " --root " + target_path.path_only();
    2875           1 :     cmd += " --set-selection hold held";
    2876           1 :     printf("Set Selection Command: \"%s\"\n", cmd.c_str());
    2877           1 :     fflush(stdout);
    2878           1 :     int r(system(cmd.c_str()));
    2879           1 :     printf("  Set selection result = %d (expected 0)\n", WEXITSTATUS(r));
    2880           1 :     CPPUNIT_ASSERT(WEXITSTATUS(r) == 0);
    2881             : 
    2882             :     // create a package that we'll mark for hold
    2883           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_held15(get_new_control_file(__FUNCTION__));
    2884           1 :     ctrl_held15->set_field("Version", "1.5");
    2885             :     ctrl_held15->set_field("Conffiles", "\n"
    2886             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef"
    2887           1 :     );
    2888             :     ctrl_held15->set_field("Files", "conffiles\n"
    2889             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef\n"
    2890             :         "/usr/bin/held 0123456789abcdef0123456789abcdef\n"
    2891             :         "/usr/share/doc/held/copyright 0123456789abcdef0123456789abcdef\n"
    2892             :         "/usr/share/doc/held/changes_in_15 0123456789abcdef0123456789abcdef\n"
    2893           1 :     );
    2894           1 :     create_package("held", ctrl_held15);
    2895             :     // Conffiles -- the create_package deletes this field
    2896             :     ctrl_held15->set_field("Conffiles", "\n"
    2897             :         "/etc/held/held.conf 0123456789abcdef0123456789abcdef"
    2898           1 :     );
    2899             : 
    2900             :     // the first install call is expected to work as is, not problem
    2901           1 :     install_package("held", ctrl_held15, 1);
    2902             : 
    2903             :     //verify_installed_files("held"); -- the install of 1.5 fails, but the
    2904             :     // files of 1.0 are still installed... instead we use the
    2905             :     // verify_generated_files() since it has not side effects over
    2906             :     // non-existing files:
    2907           1 :     verify_file_vector_t files;
    2908           1 :     verify_file_t f;
    2909           1 :     f.f_filename = "usr/share/doc/held/changes_in_15";
    2910           1 :     f.f_mode = static_cast<int>(verify_file_t::verify_deleted); // FIXME cast
    2911           1 :     files.push_back(f);
    2912           1 :     verify_generated_files(files);
    2913             : 
    2914             :     // Now try again with held 1.5 as an implicit package
    2915           1 :     std::tr1::shared_ptr<wpkg_control::control_file> ctrl_friend(get_new_control_file(__FUNCTION__));
    2916           1 :     ctrl_friend->set_field("Depends", "held (= 1.5)");
    2917             :     ctrl_friend->set_field("Conffiles", "\n"
    2918             :         "/etc/friend/friend.conf 0123456789abcdef0123456789abcdef"
    2919           1 :     );
    2920             :     ctrl_friend->set_field("Files", "conffiles\n"
    2921             :         "/etc/friend/friend.conf 0123456789abcdef0123456789abcdef\n"
    2922             :         "/usr/bin/friend 0123456789abcdef0123456789abcdef\n"
    2923             :         "/usr/share/doc/friend/copyright 0123456789abcdef0123456789abcdef\n"
    2924           1 :     );
    2925           1 :     create_package("friend", ctrl_friend);
    2926             :     // Conffiles -- the create_package deletes this field
    2927             :     ctrl_friend->set_field("Conffiles", "\n"
    2928             :         "/etc/friend/friend.conf 0123456789abcdef0123456789abcdef"
    2929           1 :     );
    2930             : 
    2931             :     // this install does not work because of the selection that's on Hold
    2932           1 :     ctrl_friend->set_variable("INSTALL_POSTOPTIONS", "--repository " + repository.path_only());
    2933           1 :     install_package("friend", ctrl_friend, 1);
    2934           1 :     verify_purged_files("friend", ctrl_friend);
    2935             : 
    2936             :     // the --force-hold does NOT help installing friend because the problem
    2937             :     // is with the implicit dependency
    2938           1 :     ctrl_friend->set_variable("INSTALL_PREOPTIONS", "--force-hold");
    2939           1 :     install_package("friend", ctrl_friend, 1);
    2940           1 :     verify_purged_files("friend", ctrl_friend);
    2941             : 
    2942             :     // the --force-hold on the held package itself works, however
    2943           1 :     ctrl_held15->set_variable("INSTALL_PREOPTIONS", "--force-hold");
    2944           1 :     install_package("held", ctrl_held15, 0);
    2945           1 :     verify_installed_files("held");
    2946             : 
    2947             :     // now we can install friend without any addition parameters
    2948           1 :     ctrl_friend->delete_variable("INSTALL_PREOPTIONS");
    2949           1 :     ctrl_friend->delete_variable("INSTALL_POSTOPTIONS");
    2950           1 :     install_package("friend", ctrl_friend, 0);
    2951           1 :     verify_installed_files("friend");
    2952             : 
    2953             :     // now we can do a recursive remove,
    2954             :     // but without the --force-hold it will fail
    2955           1 :     ctrl_held15->set_variable("REMOVE_PREOPTIONS", "--recursive");
    2956           1 :     remove_package("held", ctrl_held15, 1);
    2957           1 :     verify_installed_files("held");
    2958           1 :     verify_installed_files("friend");
    2959             : 
    2960             :     // try again with the --force-hold
    2961           1 :     ctrl_held15->set_variable("REMOVE_POSTOPTIONS", "--force-hold");
    2962           1 :     remove_package("held", ctrl_held15, 0);
    2963           1 :     verify_removed_files("held", ctrl_held15);
    2964           1 :     verify_removed_files("friend", ctrl_friend);
    2965           4 : }
    2966             : 
    2967             : 
    2968             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9

The wpkg tool is an open source tool created by Made to Order Software Corporation.