LCOV - code coverage report
Current view: top level - test - test-install-root.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 731 734 99.6 %
Date: 2019-08-23 13:36:53 Functions: 14 14 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1393 2376 58.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <unistd.h>
       4                 :            : 
       5                 :            : #include "alloc-util.h"
       6                 :            : #include "fileio.h"
       7                 :            : #include "install.h"
       8                 :            : #include "mkdir.h"
       9                 :            : #include "rm-rf.h"
      10                 :            : #include "special.h"
      11                 :            : #include "string-util.h"
      12                 :            : #include "tests.h"
      13                 :            : 
      14                 :          4 : static void test_basic_mask_and_enable(const char *root) {
      15                 :            :         const char *p;
      16                 :            :         UnitFileState state;
      17                 :          4 :         UnitFileChange *changes = NULL;
      18                 :          4 :         size_t n_changes = 0;
      19                 :            : 
      20                 :          4 :         test_setup_logging(LOG_DEBUG);
      21                 :            : 
      22         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", NULL) == -ENOENT);
      23         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) == -ENOENT);
      24         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) == -ENOENT);
      25         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) == -ENOENT);
      26                 :            : 
      27   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/a.service");
          -  +  -  +  +  
                +  +  - ]
      28         [ -  + ]:          4 :         assert_se(write_string_file(p,
      29                 :            :                                     "[Install]\n"
      30                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
      31                 :            : 
      32         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", NULL) >= 0);
      33   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
      34                 :            : 
      35   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/b.service");
          -  +  -  +  +  
                +  +  - ]
      36         [ -  + ]:          4 :         assert_se(symlink("a.service", p) >= 0);
      37                 :            : 
      38         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) >= 0);
      39   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
      40                 :            : 
      41   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/c.service");
          -  +  -  +  +  
                +  +  - ]
      42         [ -  + ]:          4 :         assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
      43                 :            : 
      44         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) >= 0);
      45   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
      46                 :            : 
      47   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/d.service");
          -  +  -  +  +  
                +  +  - ]
      48         [ -  + ]:          4 :         assert_se(symlink("c.service", p) >= 0);
      49                 :            : 
      50                 :            :         /* This one is interesting, as d follows a relative, then an absolute symlink */
      51         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
      52   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
      53                 :            : 
      54         [ -  + ]:          4 :         assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
      55         [ -  + ]:          4 :         assert_se(n_changes == 1);
      56         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
      57         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/dev/null"));
      58   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service");
          -  +  -  +  +  
                +  +  - ]
      59         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
      60                 :            : 
      61                 :          4 :         unit_file_changes_free(changes, n_changes);
      62                 :          4 :         changes = NULL; n_changes = 0;
      63                 :            : 
      64   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_MASKED);
      65   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_MASKED);
      66   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_MASKED);
      67   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_MASKED);
      68                 :            : 
      69                 :            :         /* Enabling a masked unit should fail! */
      70         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == -ERFKILL);
      71                 :          4 :         unit_file_changes_free(changes, n_changes);
      72                 :          4 :         changes = NULL; n_changes = 0;
      73                 :            : 
      74         [ -  + ]:          4 :         assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
      75         [ -  + ]:          4 :         assert_se(n_changes == 1);
      76         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
      77   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service");
          -  +  -  +  +  
                +  +  - ]
      78         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
      79                 :          4 :         unit_file_changes_free(changes, n_changes);
      80                 :          4 :         changes = NULL; n_changes = 0;
      81                 :            : 
      82         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1);
      83         [ -  + ]:          4 :         assert_se(n_changes == 1);
      84         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
      85         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
      86   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
          -  +  -  +  +  
                +  +  - ]
      87         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
      88                 :          4 :         unit_file_changes_free(changes, n_changes);
      89                 :          4 :         changes = NULL; n_changes = 0;
      90                 :            : 
      91   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
      92   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
      93   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
      94   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
      95                 :            : 
      96                 :            :         /* Enabling it again should succeed but be a NOP */
      97         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
      98         [ -  + ]:          4 :         assert_se(n_changes == 0);
      99                 :          4 :         unit_file_changes_free(changes, n_changes);
     100                 :          4 :         changes = NULL; n_changes = 0;
     101                 :            : 
     102         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
     103         [ -  + ]:          4 :         assert_se(n_changes == 1);
     104         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     105   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
          -  +  -  +  +  
                +  +  - ]
     106         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     107                 :          4 :         unit_file_changes_free(changes, n_changes);
     108                 :          4 :         changes = NULL; n_changes = 0;
     109                 :            : 
     110   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     111   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     112   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     113   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     114                 :            : 
     115                 :            :         /* Disabling a disabled unit must succeed but be a NOP */
     116         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
     117         [ -  + ]:          4 :         assert_se(n_changes == 0);
     118                 :          4 :         unit_file_changes_free(changes, n_changes);
     119                 :          4 :         changes = NULL; n_changes = 0;
     120                 :            : 
     121                 :            :         /* Let's enable this indirectly via a symlink */
     122         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0);
     123         [ -  + ]:          4 :         assert_se(n_changes == 1);
     124         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     125         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
     126   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
          -  +  -  +  +  
                +  +  - ]
     127         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     128                 :          4 :         unit_file_changes_free(changes, n_changes);
     129                 :          4 :         changes = NULL; n_changes = 0;
     130                 :            : 
     131   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     132   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     133   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     134   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     135                 :            : 
     136                 :            :         /* Let's try to reenable */
     137                 :            : 
     138         [ -  + ]:          4 :         assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0);
     139         [ -  + ]:          4 :         assert_se(n_changes == 2);
     140         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     141   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
          -  +  -  +  +  
                +  +  - ]
     142         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     143         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     144         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/a.service"));
     145         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     146                 :          4 :         unit_file_changes_free(changes, n_changes);
     147                 :          4 :         changes = NULL; n_changes = 0;
     148                 :            : 
     149   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     150   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     151   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     152   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     153                 :          4 : }
     154                 :            : 
     155                 :          4 : static void test_linked_units(const char *root) {
     156                 :            :         const char *p, *q;
     157                 :            :         UnitFileState state;
     158                 :          4 :         UnitFileChange *changes = NULL;
     159                 :          4 :         size_t n_changes = 0, i;
     160                 :            : 
     161                 :            :         /*
     162                 :            :          * We'll test three cases here:
     163                 :            :          *
     164                 :            :          * a) a unit file in /opt, that we use "systemctl link" and
     165                 :            :          * "systemctl enable" on to make it available to the system
     166                 :            :          *
     167                 :            :          * b) a unit file in /opt, that is statically linked into
     168                 :            :          * /usr/lib/systemd/system, that "enable" should work on
     169                 :            :          * correctly.
     170                 :            :          *
     171                 :            :          * c) a unit file in /opt, that is linked into
     172                 :            :          * /etc/systemd/system, and where "enable" should result in
     173                 :            :          * -ELOOP, since using information from /etc to generate
     174                 :            :          * information in /etc should not be allowed.
     175                 :            :          */
     176                 :            : 
     177   [ +  +  +  -  :         20 :         p = strjoina(root, "/opt/linked.service");
          -  +  -  +  +  
                +  +  - ]
     178         [ -  + ]:          4 :         assert_se(write_string_file(p,
     179                 :            :                                     "[Install]\n"
     180                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     181                 :            : 
     182   [ +  +  +  -  :         20 :         p = strjoina(root, "/opt/linked2.service");
          -  +  -  +  +  
                +  +  - ]
     183         [ -  + ]:          4 :         assert_se(write_string_file(p,
     184                 :            :                                     "[Install]\n"
     185                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     186                 :            : 
     187   [ +  +  +  -  :         20 :         p = strjoina(root, "/opt/linked3.service");
          -  +  -  +  +  
                +  +  - ]
     188         [ -  + ]:          4 :         assert_se(write_string_file(p,
     189                 :            :                                     "[Install]\n"
     190                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     191                 :            : 
     192         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
     193         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", NULL) == -ENOENT);
     194         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", NULL) == -ENOENT);
     195                 :            : 
     196   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/linked2.service");
          -  +  -  +  +  
                +  +  - ]
     197         [ -  + ]:          4 :         assert_se(symlink("/opt/linked2.service", p) >= 0);
     198                 :            : 
     199   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service");
          -  +  -  +  +  
                +  +  - ]
     200         [ -  + ]:          4 :         assert_se(symlink("/opt/linked3.service", p) >= 0);
     201                 :            : 
     202         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) == -ENOENT);
     203   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     204   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", &state) >= 0 && state == UNIT_FILE_LINKED);
     205                 :            : 
     206                 :            :         /* First, let's link the unit into the search path */
     207         [ -  + ]:          4 :         assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
     208         [ -  + ]:          4 :         assert_se(n_changes == 1);
     209         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     210         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/opt/linked.service"));
     211   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
          -  +  -  +  +  
                +  +  - ]
     212         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     213                 :          4 :         unit_file_changes_free(changes, n_changes);
     214                 :          4 :         changes = NULL; n_changes = 0;
     215                 :            : 
     216   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED);
     217                 :            : 
     218                 :            :         /* Let's unlink it from the search path again */
     219         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
     220         [ -  + ]:          4 :         assert_se(n_changes == 1);
     221         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     222   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
          -  +  -  +  +  
                +  +  - ]
     223         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     224                 :          4 :         unit_file_changes_free(changes, n_changes);
     225                 :          4 :         changes = NULL; n_changes = 0;
     226                 :            : 
     227         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
     228                 :            : 
     229                 :            :         /* Now, let's not just link it, but also enable it */
     230         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
     231         [ -  + ]:          4 :         assert_se(n_changes == 2);
     232   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
          -  +  -  +  +  
                +  +  - ]
     233   [ +  +  +  -  :         20 :         q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
          -  +  -  +  +  
                +  +  - ]
     234         [ +  + ]:         12 :         for (i = 0 ; i < n_changes; i++) {
     235         [ -  + ]:          8 :                 assert_se(changes[i].type == UNIT_FILE_SYMLINK);
     236         [ -  + ]:          8 :                 assert_se(streq(changes[i].source, "/opt/linked.service"));
     237                 :            : 
     238   [ +  +  +  - ]:          8 :                 if (p && streq(changes[i].path, p))
     239                 :          4 :                         p = NULL;
     240   [ +  -  +  - ]:          4 :                 else if (q && streq(changes[i].path, q))
     241                 :          4 :                         q = NULL;
     242                 :            :                 else
     243                 :          0 :                         assert_not_reached("wut?");
     244                 :            :         }
     245   [ +  -  -  + ]:          4 :         assert(!p && !q);
     246                 :          4 :         unit_file_changes_free(changes, n_changes);
     247                 :          4 :         changes = NULL; n_changes = 0;
     248                 :            : 
     249   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     250                 :            : 
     251                 :            :         /* And let's unlink it again */
     252         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
     253         [ -  + ]:          4 :         assert_se(n_changes == 2);
     254   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
          -  +  -  +  +  
                +  +  - ]
     255   [ +  +  +  -  :         20 :         q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
          -  +  -  +  +  
                +  +  - ]
     256         [ +  + ]:         12 :         for (i = 0; i < n_changes; i++) {
     257         [ -  + ]:          8 :                 assert_se(changes[i].type == UNIT_FILE_UNLINK);
     258                 :            : 
     259   [ +  -  +  + ]:          8 :                 if (p && streq(changes[i].path, p))
     260                 :          4 :                         p = NULL;
     261   [ +  -  +  - ]:          4 :                 else if (q && streq(changes[i].path, q))
     262                 :          4 :                         q = NULL;
     263                 :            :                 else
     264                 :          0 :                         assert_not_reached("wut?");
     265                 :            :         }
     266   [ +  -  -  + ]:          4 :         assert(!p && !q);
     267                 :          4 :         unit_file_changes_free(changes, n_changes);
     268                 :          4 :         changes = NULL; n_changes = 0;
     269                 :            : 
     270         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
     271                 :            : 
     272         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0);
     273         [ -  + ]:          4 :         assert_se(n_changes == 2);
     274   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service");
          -  +  -  +  +  
                +  +  - ]
     275   [ +  +  +  -  :         20 :         q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service");
          -  +  -  +  +  
                +  +  - ]
     276         [ +  + ]:         12 :         for (i = 0 ; i < n_changes; i++) {
     277         [ -  + ]:          8 :                 assert_se(changes[i].type == UNIT_FILE_SYMLINK);
     278         [ -  + ]:          8 :                 assert_se(streq(changes[i].source, "/opt/linked2.service"));
     279                 :            : 
     280   [ +  +  +  - ]:          8 :                 if (p && streq(changes[i].path, p))
     281                 :          4 :                         p = NULL;
     282   [ +  -  +  - ]:          4 :                 else if (q && streq(changes[i].path, q))
     283                 :          4 :                         q = NULL;
     284                 :            :                 else
     285                 :          0 :                         assert_not_reached("wut?");
     286                 :            :         }
     287   [ +  -  -  + ]:          4 :         assert(!p && !q);
     288                 :          4 :         unit_file_changes_free(changes, n_changes);
     289                 :          4 :         changes = NULL; n_changes = 0;
     290                 :            : 
     291         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0);
     292         [ -  + ]:          4 :         assert_se(n_changes == 1);
     293         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     294         [ -  + ]:          4 :         assert_se(startswith(changes[0].path, root));
     295         [ -  + ]:          4 :         assert_se(endswith(changes[0].path, "linked3.service"));
     296         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/opt/linked3.service"));
     297                 :          4 :         unit_file_changes_free(changes, n_changes);
     298                 :          4 :         changes = NULL; n_changes = 0;
     299                 :          4 : }
     300                 :            : 
     301                 :          4 : static void test_default(const char *root) {
     302                 :          4 :         _cleanup_free_ char *def = NULL;
     303                 :          4 :         UnitFileChange *changes = NULL;
     304                 :          4 :         size_t n_changes = 0;
     305                 :            :         const char *p;
     306                 :            : 
     307   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/test-default-real.target");
          -  +  -  +  +  
                +  +  - ]
     308         [ -  + ]:          4 :         assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0);
     309                 :            : 
     310   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/test-default.target");
          -  +  -  +  +  
                +  +  - ]
     311         [ -  + ]:          4 :         assert_se(symlink("test-default-real.target", p) >= 0);
     312                 :            : 
     313         [ -  + ]:          4 :         assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
     314                 :            : 
     315         [ -  + ]:          4 :         assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT);
     316         [ -  + ]:          4 :         assert_se(n_changes == 1);
     317         [ -  + ]:          4 :         assert_se(changes[0].type == -ENOENT);
     318         [ -  + ]:          4 :         assert_se(streq_ptr(changes[0].path, "idontexist.target"));
     319                 :          4 :         unit_file_changes_free(changes, n_changes);
     320                 :          4 :         changes = NULL; n_changes = 0;
     321                 :            : 
     322         [ -  + ]:          4 :         assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
     323                 :            : 
     324         [ -  + ]:          4 :         assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0);
     325         [ -  + ]:          4 :         assert_se(n_changes == 1);
     326         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     327         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target"));
     328   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH "/" SPECIAL_DEFAULT_TARGET);
          -  +  -  +  +  
                +  +  - ]
     329         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     330                 :          4 :         unit_file_changes_free(changes, n_changes);
     331                 :          4 :         changes = NULL; n_changes = 0;
     332                 :            : 
     333         [ -  + ]:          4 :         assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) >= 0);
     334         [ -  + ]:          4 :         assert_se(streq_ptr(def, "test-default-real.target"));
     335                 :          4 : }
     336                 :            : 
     337                 :          4 : static void test_add_dependency(const char *root) {
     338                 :          4 :         UnitFileChange *changes = NULL;
     339                 :          4 :         size_t n_changes = 0;
     340                 :            :         const char *p;
     341                 :            : 
     342   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/real-add-dependency-test-target.target");
          -  +  -  +  +  
                +  +  - ]
     343         [ -  + ]:          4 :         assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0);
     344                 :            : 
     345   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/add-dependency-test-target.target");
          -  +  -  +  +  
                +  +  - ]
     346         [ -  + ]:          4 :         assert_se(symlink("real-add-dependency-test-target.target", p) >= 0);
     347                 :            : 
     348   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/real-add-dependency-test-service.service");
          -  +  -  +  +  
                +  +  - ]
     349         [ -  + ]:          4 :         assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0);
     350                 :            : 
     351   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/add-dependency-test-service.service");
          -  +  -  +  +  
                +  +  - ]
     352         [ -  + ]:          4 :         assert_se(symlink("real-add-dependency-test-service.service", p) >= 0);
     353                 :            : 
     354         [ -  + ]:          4 :         assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, &changes, &n_changes) >= 0);
     355         [ -  + ]:          4 :         assert_se(n_changes == 1);
     356         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     357         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
     358   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service");
          -  +  -  +  +  
                +  +  - ]
     359         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     360                 :          4 :         unit_file_changes_free(changes, n_changes);
     361                 :          4 :         changes = NULL; n_changes = 0;
     362                 :          4 : }
     363                 :            : 
     364                 :          4 : static void test_template_enable(const char *root) {
     365                 :          4 :         UnitFileChange *changes = NULL;
     366                 :          4 :         size_t n_changes = 0;
     367                 :            :         UnitFileState state;
     368                 :            :         const char *p;
     369                 :            : 
     370         [ +  - ]:          4 :         log_info("== %s ==", __func__);
     371                 :            : 
     372         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) == -ENOENT);
     373         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) == -ENOENT);
     374         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) == -ENOENT);
     375         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) == -ENOENT);
     376                 :            : 
     377   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/template@.service");
          -  +  -  +  +  
                +  +  - ]
     378         [ -  + ]:          4 :         assert_se(write_string_file(p,
     379                 :            :                                     "[Install]\n"
     380                 :            :                                     "DefaultInstance=def\n"
     381                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     382                 :            : 
     383   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/template-symlink@.service");
          -  +  -  +  +  
                +  +  - ]
     384         [ -  + ]:          4 :         assert_se(symlink("template@.service", p) >= 0);
     385                 :            : 
     386   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     387   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     388   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     389   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     390   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     391   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     392                 :            : 
     393         [ +  - ]:          4 :         log_info("== %s with template@.service enabled ==", __func__);
     394                 :            : 
     395         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
     396         [ -  + ]:          4 :         assert_se(n_changes == 1);
     397         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     398         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
     399   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@def.service");
          -  +  -  +  +  
                +  +  - ]
     400         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     401                 :          4 :         unit_file_changes_free(changes, n_changes);
     402                 :          4 :         changes = NULL; n_changes = 0;
     403                 :            : 
     404   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     405   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     406   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     407   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     408   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     409   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     410                 :            : 
     411         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
     412         [ -  + ]:          4 :         assert_se(n_changes == 1);
     413         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     414         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     415                 :          4 :         unit_file_changes_free(changes, n_changes);
     416                 :          4 :         changes = NULL; n_changes = 0;
     417                 :            : 
     418   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     419   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     420   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     421   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     422   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     423   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     424                 :            : 
     425         [ +  - ]:          4 :         log_info("== %s with template@foo.service enabled ==", __func__);
     426                 :            : 
     427         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
     428         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     429         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
     430   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@foo.service");
          -  +  -  +  +  
                +  +  - ]
     431         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     432                 :          4 :         unit_file_changes_free(changes, n_changes);
     433                 :          4 :         changes = NULL; n_changes = 0;
     434                 :            : 
     435   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     436   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     437   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     438   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     439   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     440   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     441                 :            : 
     442         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
     443         [ -  + ]:          4 :         assert_se(n_changes == 1);
     444         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     445         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     446                 :          4 :         unit_file_changes_free(changes, n_changes);
     447                 :          4 :         changes = NULL; n_changes = 0;
     448                 :            : 
     449   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     450   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     451   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     452   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     453   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     454   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     455   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     456   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     457                 :            : 
     458         [ +  - ]:          4 :         log_info("== %s with template-symlink@quux.service enabled ==", __func__);
     459                 :            : 
     460         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0);
     461         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     462         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
     463   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@quux.service");
          -  +  -  +  +  
                +  +  - ]
     464         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     465                 :          4 :         unit_file_changes_free(changes, n_changes);
     466                 :          4 :         changes = NULL; n_changes = 0;
     467                 :            : 
     468   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     469   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     470   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     471   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     472   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     473   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     474   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     475   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     476                 :          4 : }
     477                 :            : 
     478                 :          4 : static void test_indirect(const char *root) {
     479                 :          4 :         UnitFileChange *changes = NULL;
     480                 :          4 :         size_t n_changes = 0;
     481                 :            :         UnitFileState state;
     482                 :            :         const char *p;
     483                 :            : 
     484         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) == -ENOENT);
     485         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) == -ENOENT);
     486         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) == -ENOENT);
     487                 :            : 
     488   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/indirecta.service");
          -  +  -  +  +  
                +  +  - ]
     489         [ -  + ]:          4 :         assert_se(write_string_file(p,
     490                 :            :                                     "[Install]\n"
     491                 :            :                                     "Also=indirectb.service\n", WRITE_STRING_FILE_CREATE) >= 0);
     492                 :            : 
     493   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/indirectb.service");
          -  +  -  +  +  
                +  +  - ]
     494         [ -  + ]:          4 :         assert_se(write_string_file(p,
     495                 :            :                                     "[Install]\n"
     496                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     497                 :            : 
     498   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/indirectc.service");
          -  +  -  +  +  
                +  +  - ]
     499         [ -  + ]:          4 :         assert_se(symlink("indirecta.service", p) >= 0);
     500                 :            : 
     501   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     502   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     503   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     504                 :            : 
     505         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
     506         [ -  + ]:          4 :         assert_se(n_changes == 1);
     507         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     508         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service"));
     509   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service");
          -  +  -  +  +  
                +  +  - ]
     510         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     511                 :          4 :         unit_file_changes_free(changes, n_changes);
     512                 :          4 :         changes = NULL; n_changes = 0;
     513                 :            : 
     514   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     515   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     516   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
     517                 :            : 
     518         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
     519         [ -  + ]:          4 :         assert_se(n_changes == 1);
     520         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     521   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service");
          -  +  -  +  +  
                +  +  - ]
     522         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     523                 :          4 :         unit_file_changes_free(changes, n_changes);
     524                 :          4 :         changes = NULL; n_changes = 0;
     525                 :          4 : }
     526                 :            : 
     527                 :          4 : static void test_preset_and_list(const char *root) {
     528                 :          4 :         UnitFileChange *changes = NULL;
     529                 :          4 :         size_t n_changes = 0, i;
     530                 :            :         const char *p, *q;
     531                 :            :         UnitFileState state;
     532                 :          4 :         bool got_yes = false, got_no = false;
     533                 :            :         Iterator j;
     534                 :            :         UnitFileList *fl;
     535                 :            :         Hashmap *h;
     536                 :            : 
     537         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) == -ENOENT);
     538         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) == -ENOENT);
     539                 :            : 
     540   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service");
          -  +  -  +  +  
                +  +  - ]
     541         [ -  + ]:          4 :         assert_se(write_string_file(p,
     542                 :            :                                     "[Install]\n"
     543                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     544                 :            : 
     545   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/preset-no.service");
          -  +  -  +  +  
                +  +  - ]
     546         [ -  + ]:          4 :         assert_se(write_string_file(p,
     547                 :            :                                     "[Install]\n"
     548                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     549                 :            : 
     550   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset");
          -  +  -  +  +  
                +  +  - ]
     551         [ -  + ]:          4 :         assert_se(write_string_file(p,
     552                 :            :                                     "enable *-yes.*\n"
     553                 :            :                                     "disable *\n", WRITE_STRING_FILE_CREATE) >= 0);
     554                 :            : 
     555   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     556   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     557                 :            : 
     558         [ -  + ]:          4 :         assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
     559         [ -  + ]:          4 :         assert_se(n_changes == 1);
     560         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     561         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service"));
     562   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
          -  +  -  +  +  
                +  +  - ]
     563         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     564                 :          4 :         unit_file_changes_free(changes, n_changes);
     565                 :          4 :         changes = NULL; n_changes = 0;
     566                 :            : 
     567   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     568   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     569                 :            : 
     570         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
     571         [ -  + ]:          4 :         assert_se(n_changes == 1);
     572         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     573   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
          -  +  -  +  +  
                +  +  - ]
     574         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     575                 :          4 :         unit_file_changes_free(changes, n_changes);
     576                 :          4 :         changes = NULL; n_changes = 0;
     577                 :            : 
     578   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     579   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     580                 :            : 
     581         [ -  + ]:          4 :         assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
     582         [ -  + ]:          4 :         assert_se(n_changes == 0);
     583                 :          4 :         unit_file_changes_free(changes, n_changes);
     584                 :          4 :         changes = NULL; n_changes = 0;
     585                 :            : 
     586   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     587   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     588                 :            : 
     589         [ -  + ]:          4 :         assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
     590                 :            : 
     591         [ -  + ]:          4 :         assert_se(n_changes > 0);
     592                 :            : 
     593   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
          -  +  -  +  +  
                +  +  - ]
     594                 :            : 
     595         [ +  + ]:         40 :         for (i = 0; i < n_changes; i++) {
     596                 :            : 
     597         [ +  + ]:         36 :                 if (changes[i].type == UNIT_FILE_SYMLINK) {
     598         [ -  + ]:          4 :                         assert_se(streq(changes[i].source, "/usr/lib/systemd/system/preset-yes.service"));
     599         [ -  + ]:          4 :                         assert_se(streq(changes[i].path, p));
     600                 :            :                 } else
     601         [ -  + ]:         32 :                         assert_se(changes[i].type == UNIT_FILE_UNLINK);
     602                 :            :         }
     603                 :            : 
     604                 :          4 :         unit_file_changes_free(changes, n_changes);
     605                 :          4 :         changes = NULL; n_changes = 0;
     606                 :            : 
     607   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     608   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     609                 :            : 
     610         [ -  + ]:          4 :         assert_se(h = hashmap_new(&string_hash_ops));
     611         [ -  + ]:          4 :         assert_se(unit_file_get_list(UNIT_FILE_SYSTEM, root, h, NULL, NULL) >= 0);
     612                 :            : 
     613   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service");
          -  +  -  +  +  
                +  +  - ]
     614   [ +  +  +  -  :         20 :         q = strjoina(root, "/usr/lib/systemd/system/preset-no.service");
          -  +  -  +  +  
                +  +  - ]
     615                 :            : 
     616         [ +  + ]:         76 :         HASHMAP_FOREACH(fl, h, j) {
     617         [ -  + ]:         72 :                 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, basename(fl->path), &state) >= 0);
     618         [ -  + ]:         72 :                 assert_se(fl->state == state);
     619                 :            : 
     620         [ +  + ]:         72 :                 if (streq(fl->path, p)) {
     621                 :          4 :                         got_yes = true;
     622         [ -  + ]:          4 :                         assert_se(fl->state == UNIT_FILE_ENABLED);
     623         [ +  + ]:         68 :                 } else if (streq(fl->path, q)) {
     624                 :          4 :                         got_no = true;
     625         [ -  + ]:          4 :                         assert_se(fl->state == UNIT_FILE_DISABLED);
     626                 :            :                 } else
     627   [ +  -  -  + ]:         64 :                         assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT));
     628                 :            :         }
     629                 :            : 
     630                 :          4 :         unit_file_list_free(h);
     631                 :            : 
     632   [ +  -  -  + ]:          4 :         assert_se(got_yes && got_no);
     633                 :          4 : }
     634                 :            : 
     635                 :          4 : static void test_revert(const char *root) {
     636                 :            :         const char *p;
     637                 :            :         UnitFileState state;
     638                 :          4 :         UnitFileChange *changes = NULL;
     639                 :          4 :         size_t n_changes = 0;
     640                 :            : 
     641         [ -  + ]:          4 :         assert(root);
     642                 :            : 
     643         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", NULL) == -ENOENT);
     644         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "yy.service", NULL) == -ENOENT);
     645                 :            : 
     646   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/xx.service");
          -  +  -  +  +  
                +  +  - ]
     647         [ -  + ]:          4 :         assert_se(write_string_file(p, "# Empty\n", WRITE_STRING_FILE_CREATE) >= 0);
     648                 :            : 
     649         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", NULL) >= 0);
     650   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", &state) >= 0 && state == UNIT_FILE_STATIC);
     651                 :            : 
     652                 :            :         /* Initially there's nothing to revert */
     653         [ -  + ]:          4 :         assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
     654         [ -  + ]:          4 :         assert_se(n_changes == 0);
     655                 :          4 :         unit_file_changes_free(changes, n_changes);
     656                 :          4 :         changes = NULL; n_changes = 0;
     657                 :            : 
     658   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service");
          -  +  -  +  +  
                +  +  - ]
     659         [ -  + ]:          4 :         assert_se(write_string_file(p, "# Empty override\n", WRITE_STRING_FILE_CREATE) >= 0);
     660                 :            : 
     661                 :            :         /* Revert the override file */
     662         [ -  + ]:          4 :         assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
     663         [ -  + ]:          4 :         assert_se(n_changes == 1);
     664         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     665         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     666                 :          4 :         unit_file_changes_free(changes, n_changes);
     667                 :          4 :         changes = NULL; n_changes = 0;
     668                 :            : 
     669   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     670         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     671         [ -  + ]:          4 :         assert_se(write_string_file(p, "# Empty dropin\n", WRITE_STRING_FILE_CREATE) >= 0);
     672                 :            : 
     673                 :            :         /* Revert the dropin file */
     674         [ -  + ]:          4 :         assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
     675         [ -  + ]:          4 :         assert_se(n_changes == 2);
     676         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
     677         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     678                 :            : 
     679   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d");
          -  +  -  +  +  
                +  +  - ]
     680         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_UNLINK);
     681         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     682                 :          4 :         unit_file_changes_free(changes, n_changes);
     683                 :          4 :         changes = NULL; n_changes = 0;
     684                 :          4 : }
     685                 :            : 
     686                 :          4 : static void test_preset_order(const char *root) {
     687                 :          4 :         UnitFileChange *changes = NULL;
     688                 :          4 :         size_t n_changes = 0;
     689                 :            :         const char *p;
     690                 :            :         UnitFileState state;
     691                 :            : 
     692         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) == -ENOENT);
     693         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) == -ENOENT);
     694                 :            : 
     695   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/prefix-1.service");
          -  +  -  +  +  
                +  +  - ]
     696         [ -  + ]:          4 :         assert_se(write_string_file(p,
     697                 :            :                                     "[Install]\n"
     698                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     699                 :            : 
     700   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/prefix-2.service");
          -  +  -  +  +  
                +  +  - ]
     701         [ -  + ]:          4 :         assert_se(write_string_file(p,
     702                 :            :                                     "[Install]\n"
     703                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     704                 :            : 
     705   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset");
          -  +  -  +  +  
                +  +  - ]
     706         [ -  + ]:          4 :         assert_se(write_string_file(p,
     707                 :            :                                     "enable prefix-1.service\n"
     708                 :            :                                     "disable prefix-*.service\n"
     709                 :            :                                     "enable prefix-2.service\n", WRITE_STRING_FILE_CREATE) >= 0);
     710                 :            : 
     711   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     712   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     713                 :            : 
     714         [ -  + ]:          4 :         assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
     715         [ -  + ]:          4 :         assert_se(n_changes == 1);
     716         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     717         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service"));
     718   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/prefix-1.service");
          -  +  -  +  +  
                +  +  - ]
     719         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     720                 :          4 :         unit_file_changes_free(changes, n_changes);
     721                 :          4 :         changes = NULL; n_changes = 0;
     722                 :            : 
     723   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     724   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     725                 :            : 
     726         [ -  + ]:          4 :         assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
     727         [ -  + ]:          4 :         assert_se(n_changes == 0);
     728                 :            : 
     729   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     730   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     731                 :          4 : }
     732                 :            : 
     733                 :          4 : static void test_static_instance(const char *root) {
     734                 :            :         UnitFileState state;
     735                 :            :         const char *p;
     736                 :            : 
     737         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) == -ENOENT);
     738         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) == -ENOENT);
     739                 :            : 
     740   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/static-instance@.service");
          -  +  -  +  +  
                +  +  - ]
     741         [ -  + ]:          4 :         assert_se(write_string_file(p,
     742                 :            :                                     "[Install]\n"
     743                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     744                 :            : 
     745   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     746   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     747                 :            : 
     748   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/static-instance@foo.service");
          -  +  -  +  +  
                +  +  - ]
     749         [ -  + ]:          4 :         assert_se(symlink("static-instance@.service", p) >= 0);
     750                 :            : 
     751   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     752   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) >= 0 && state == UNIT_FILE_STATIC);
     753                 :          4 : }
     754                 :            : 
     755                 :          4 : static void test_with_dropin(const char *root) {
     756                 :            :         const char *p;
     757                 :            :         UnitFileState state;
     758                 :          4 :         UnitFileChange *changes = NULL;
     759                 :          4 :         size_t n_changes = 0;
     760                 :            : 
     761         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) == -ENOENT);
     762         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) == -ENOENT);
     763         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) == -ENOENT);
     764         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) == -ENOENT);
     765         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) == -ENOENT);
     766                 :            : 
     767   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1.service");
          -  +  -  +  +  
                +  +  - ]
     768         [ -  + ]:          4 :         assert_se(write_string_file(p,
     769                 :            :                                     "[Install]\n"
     770                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     771                 :            : 
     772   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     773         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     774         [ -  + ]:          4 :         assert_se(write_string_file(p,
     775                 :            :                                     "[Install]\n"
     776                 :            :                                     "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     777                 :            : 
     778   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     779                 :            : 
     780   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service");
          -  +  -  +  +  
                +  +  - ]
     781         [ -  + ]:          4 :         assert_se(write_string_file(p,
     782                 :            :                                     "[Install]\n"
     783                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     784                 :            : 
     785   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     786         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     787         [ -  + ]:          4 :         assert_se(write_string_file(p,
     788                 :            :                                     "[Install]\n"
     789                 :            :                                     "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     790                 :            : 
     791   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     792                 :            : 
     793   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3.service");
          -  +  -  +  +  
                +  +  - ]
     794         [ -  + ]:          4 :         assert_se(write_string_file(p,
     795                 :            :                                     "[Install]\n"
     796                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     797                 :            : 
     798   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-3.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     799         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     800         [ -  + ]:          4 :         assert_se(write_string_file(p,
     801                 :            :                                     "[Install]\n"
     802                 :            :                                     "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     803                 :            : 
     804   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     805                 :            : 
     806   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4a.service");
          -  +  -  +  +  
                +  +  - ]
     807         [ -  + ]:          4 :         assert_se(write_string_file(p,
     808                 :            :                                     "[Install]\n"
     809                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     810                 :            : 
     811   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-4a.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     812         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     813         [ -  + ]:          4 :         assert_se(write_string_file(p,
     814                 :            :                                     "[Install]\n"
     815                 :            :                                     "Also=with-dropin-4b.service\n", WRITE_STRING_FILE_CREATE) >= 0);
     816                 :            : 
     817   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     818                 :            : 
     819   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4b.service");
          -  +  -  +  +  
                +  +  - ]
     820         [ -  + ]:          4 :         assert_se(write_string_file(p,
     821                 :            :                                     "[Install]\n"
     822                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     823                 :            : 
     824   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     825                 :            : 
     826         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1.service"), &changes, &n_changes) == 1);
     827         [ -  + ]:          4 :         assert_se(n_changes == 2);
     828         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     829         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     830         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1.service"));
     831         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1.service"));
     832   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1.service");
          -  +  -  +  +  
                +  +  - ]
     833         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     834   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1.service");
          -  +  -  +  +  
                +  +  - ]
     835         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     836                 :          4 :         unit_file_changes_free(changes, n_changes);
     837                 :          4 :         changes = NULL; n_changes = 0;
     838                 :            : 
     839         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2.service"), &changes, &n_changes) == 1);
     840   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     841         [ -  + ]:          4 :         assert_se(n_changes == 2);
     842         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     843         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     844         [ -  + ]:          4 :         assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"));
     845         [ -  + ]:          4 :         assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"));
     846   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2.service");
          -  +  -  +  +  
                +  +  - ]
     847         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     848   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2.service");
          -  +  -  +  +  
                +  +  - ]
     849         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     850                 :          4 :         unit_file_changes_free(changes, n_changes);
     851                 :          4 :         changes = NULL; n_changes = 0;
     852                 :            : 
     853         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3.service"), &changes, &n_changes) == 1);
     854   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     855         [ -  + ]:          4 :         assert_se(n_changes == 2);
     856         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     857         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     858         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3.service"));
     859         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-3.service"));
     860   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3.service");
          -  +  -  +  +  
                +  +  - ]
     861         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     862   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-3.service");
          -  +  -  +  +  
                +  +  - ]
     863         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     864                 :          4 :         unit_file_changes_free(changes, n_changes);
     865                 :          4 :         changes = NULL; n_changes = 0;
     866                 :            : 
     867         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 2);
     868   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     869         [ -  + ]:          4 :         assert_se(n_changes == 2);
     870         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     871         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     872         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-4a.service"));
     873         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-4b.service"));
     874   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4a.service");
          -  +  -  +  +  
                +  +  - ]
     875         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     876   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4b.service");
          -  +  -  +  +  
                +  +  - ]
     877         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     878                 :          4 :         unit_file_changes_free(changes, n_changes);
     879                 :          4 :         changes = NULL; n_changes = 0;
     880                 :            : 
     881   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     882   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     883   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     884   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     885   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     886                 :          4 : }
     887                 :            : 
     888                 :          4 : static void test_with_dropin_template(const char *root) {
     889                 :            :         const char *p;
     890                 :            :         UnitFileState state;
     891                 :          4 :         UnitFileChange *changes = NULL;
     892                 :          4 :         size_t n_changes = 0;
     893                 :            : 
     894         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@.service", &state) == -ENOENT);
     895         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@.service", &state) == -ENOENT);
     896         [ -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@.service", &state) == -ENOENT);
     897                 :            : 
     898   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1@.service");
          -  +  -  +  +  
                +  +  - ]
     899         [ -  + ]:          4 :         assert_se(write_string_file(p,
     900                 :            :                                     "[Install]\n"
     901                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     902                 :            : 
     903   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1@.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     904         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     905         [ -  + ]:          4 :         assert_se(write_string_file(p,
     906                 :            :                                     "[Install]\n"
     907                 :            :                                     "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     908                 :            : 
     909   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     910                 :            : 
     911   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2@.service");
          -  +  -  +  +  
                +  +  - ]
     912         [ -  + ]:          4 :         assert_se(write_string_file(p,
     913                 :            :                                     "[Install]\n"
     914                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     915                 :            : 
     916   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2@instance-1.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     917         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     918         [ -  + ]:          4 :         assert_se(write_string_file(p,
     919                 :            :                                     "[Install]\n"
     920                 :            :                                     "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     921                 :            : 
     922   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     923                 :            : 
     924   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3@.service");
          -  +  -  +  +  
                +  +  - ]
     925         [ -  + ]:          4 :         assert_se(write_string_file(p,
     926                 :            :                                     "[Install]\n"
     927                 :            :                                     "DefaultInstance=instance-1\n"
     928                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
     929                 :            : 
     930   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3@.service.d/dropin.conf");
          -  +  -  +  +  
                +  +  - ]
     931         [ -  + ]:          4 :         assert_se(mkdir_parents(p, 0755) >= 0);
     932         [ -  + ]:          4 :         assert_se(write_string_file(p,
     933                 :            :                                     "[Install]\n"
     934                 :            :                                     "DefaultInstance=instance-2\n", WRITE_STRING_FILE_CREATE) >= 0);
     935                 :            : 
     936   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     937                 :            : 
     938         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1@instance-1.service"), &changes, &n_changes) == 1);
     939         [ -  + ]:          4 :         assert_se(n_changes == 2);
     940         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     941         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     942         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
     943         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
     944   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1@instance-1.service");
          -  +  -  +  +  
                +  +  - ]
     945         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     946   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1@instance-1.service");
          -  +  -  +  +  
                +  +  - ]
     947         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     948                 :          4 :         unit_file_changes_free(changes, n_changes);
     949                 :          4 :         changes = NULL; n_changes = 0;
     950                 :            : 
     951         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-1.service"), &changes, &n_changes) == 1);
     952         [ -  + ]:          4 :         assert_se(n_changes == 2);
     953         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     954         [ -  + ]:          4 :         assert_se(changes[1].type == UNIT_FILE_SYMLINK);
     955         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
     956         [ -  + ]:          4 :         assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
     957   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-1.service");
          -  +  -  +  +  
                +  +  - ]
     958         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     959   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2@instance-1.service");
          -  +  -  +  +  
                +  +  - ]
     960         [ -  + ]:          4 :         assert_se(streq(changes[1].path, p));
     961                 :          4 :         unit_file_changes_free(changes, n_changes);
     962                 :          4 :         changes = NULL; n_changes = 0;
     963                 :            : 
     964         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-2.service"), &changes, &n_changes) == 1);
     965         [ -  + ]:          4 :         assert_se(n_changes == 1);
     966         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     967         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
     968   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-2.service");
          -  +  -  +  +  
                +  +  - ]
     969         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     970                 :          4 :         unit_file_changes_free(changes, n_changes);
     971                 :          4 :         changes = NULL; n_changes = 0;
     972                 :            : 
     973         [ -  + ]:          4 :         assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3@.service"), &changes, &n_changes) == 1);
     974         [ -  + ]:          4 :         assert_se(n_changes == 1);
     975         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
     976         [ -  + ]:          4 :         assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3@.service"));
     977   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3@instance-2.service");
          -  +  -  +  +  
                +  +  - ]
     978         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
     979                 :          4 :         unit_file_changes_free(changes, n_changes);
     980                 :          4 :         changes = NULL; n_changes = 0;
     981                 :            : 
     982   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@instance-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     983   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@instance-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     984   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     985   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
     986   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
     987                 :          4 : }
     988                 :            : 
     989                 :          4 : static void test_preset_multiple_instances(const char *root) {
     990                 :          4 :         UnitFileChange *changes = NULL;
     991                 :          4 :         size_t n_changes = 0;
     992                 :            :         const char *p;
     993                 :            :         UnitFileState state;
     994                 :            : 
     995                 :            :         /* Set up template service files and preset file */
     996   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/foo@.service");
          -  +  -  +  +  
                +  +  - ]
     997         [ -  + ]:          4 :         assert_se(write_string_file(p,
     998                 :            :                                     "[Install]\n"
     999                 :            :                                     "DefaultInstance=def\n"
    1000                 :            :                                     "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
    1001                 :            : 
    1002   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1003                 :            : 
    1004   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset");
          -  +  -  +  +  
                +  +  - ]
    1005         [ -  + ]:          4 :         assert_se(write_string_file(p,
    1006                 :            :                                     "enable foo@.service bar0 bar1 bartest\n"
    1007                 :            :                                     "enable emptylist@.service\n" /* This line ensures the old functionality for templated unit still works */
    1008                 :            :                                     "disable *\n" , WRITE_STRING_FILE_CREATE) >= 0);
    1009                 :            : 
    1010   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1011                 :            : 
    1012                 :            :         /* Preset a single instantiated unit specified in the list */
    1013         [ -  + ]:          4 :         assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
    1014   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
    1015         [ -  + ]:          4 :         assert_se(n_changes == 1);
    1016         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
    1017   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service");
          -  +  -  +  +  
                +  +  - ]
    1018         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
    1019                 :          4 :         unit_file_changes_free(changes, n_changes);
    1020                 :          4 :         changes = NULL; n_changes = 0;
    1021                 :            : 
    1022         [ -  + ]:          4 :         assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0);
    1023         [ -  + ]:          4 :         assert_se(n_changes == 1);
    1024         [ -  + ]:          4 :         assert_se(changes[0].type == UNIT_FILE_UNLINK);
    1025   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service");
          -  +  -  +  +  
                +  +  - ]
    1026         [ -  + ]:          4 :         assert_se(streq(changes[0].path, p));
    1027                 :          4 :         unit_file_changes_free(changes, n_changes);
    1028                 :          4 :         changes = NULL; n_changes = 0;
    1029                 :            : 
    1030                 :            :         /* Check for preset-all case, only instances on the list should be enabled, not including the default instance */
    1031   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1032   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1033   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1034                 :            : 
    1035         [ -  + ]:          4 :         assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
    1036         [ -  + ]:          4 :         assert_se(n_changes > 0);
    1037                 :            : 
    1038   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
    1039   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
    1040   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
    1041   [ +  -  -  + ]:          4 :         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
    1042                 :            : 
    1043                 :          4 :         unit_file_changes_free(changes, n_changes);
    1044                 :          4 : }
    1045                 :            : 
    1046                 :          4 : int main(int argc, char *argv[]) {
    1047                 :          4 :         char root[] = "/tmp/rootXXXXXX";
    1048                 :            :         const char *p;
    1049                 :            : 
    1050         [ -  + ]:          4 :         assert_se(mkdtemp(root));
    1051                 :            : 
    1052   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system/");
          -  +  -  +  +  
                +  +  - ]
    1053         [ -  + ]:          4 :         assert_se(mkdir_p(p, 0755) >= 0);
    1054                 :            : 
    1055   [ +  +  +  -  :         20 :         p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/");
          -  +  -  +  +  
                +  +  - ]
    1056         [ -  + ]:          4 :         assert_se(mkdir_p(p, 0755) >= 0);
    1057                 :            : 
    1058   [ +  +  +  -  :         20 :         p = strjoina(root, "/run/systemd/system/");
          -  +  -  +  +  
                +  +  - ]
    1059         [ -  + ]:          4 :         assert_se(mkdir_p(p, 0755) >= 0);
    1060                 :            : 
    1061   [ +  +  +  -  :         20 :         p = strjoina(root, "/opt/");
          -  +  -  +  +  
                +  +  - ]
    1062         [ -  + ]:          4 :         assert_se(mkdir_p(p, 0755) >= 0);
    1063                 :            : 
    1064   [ +  +  +  -  :         20 :         p = strjoina(root, "/usr/lib/systemd/system-preset/");
          -  +  -  +  +  
                +  +  - ]
    1065         [ -  + ]:          4 :         assert_se(mkdir_p(p, 0755) >= 0);
    1066                 :            : 
    1067                 :          4 :         test_basic_mask_and_enable(root);
    1068                 :          4 :         test_linked_units(root);
    1069                 :          4 :         test_default(root);
    1070                 :          4 :         test_add_dependency(root);
    1071                 :          4 :         test_template_enable(root);
    1072                 :          4 :         test_indirect(root);
    1073                 :          4 :         test_preset_and_list(root);
    1074                 :          4 :         test_preset_order(root);
    1075                 :          4 :         test_preset_multiple_instances(root);
    1076                 :          4 :         test_revert(root);
    1077                 :          4 :         test_static_instance(root);
    1078                 :          4 :         test_with_dropin(root);
    1079                 :          4 :         test_with_dropin_template(root);
    1080                 :            : 
    1081         [ -  + ]:          4 :         assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
    1082                 :            : 
    1083                 :          4 :         return 0;
    1084                 :            : }

Generated by: LCOV version 1.14