Skip to content
This repository was archived by the owner on Apr 12, 2021. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nixpkgs-channels
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b6284fd70f7b
Choose a base ref
...
head repository: NixOS/nixpkgs-channels
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dcf9a77568b8
Choose a head ref
  • 16 commits
  • 15 files changed
  • 7 contributors

Commits on Dec 3, 2019

  1. Copy the full SHA
    e05ae69 View commit details
  2. nixos/pam-oath-login: Port test to python

    Jacek Galowicz committed Dec 3, 2019
    Copy the full SHA
    a166955 View commit details

Commits on Dec 4, 2019

  1. gitlab: 12.5.2 -> 12.5.3

    Milan Pässler committed Dec 4, 2019
    Copy the full SHA
    a43003d View commit details
  2. bazel: improve strict action env context

    - Bazel strict action env set a default PATH to
    `/bin/:/usr/bin:/usr/local/bin`. This was previously changed to disable
    this behavior to improve hermeticity. However the previous change was
    only removing `/bin:/usr/bin`, keeping `/usr/local/bin`, this commit
    also remove this entry.
    guibou committed Dec 4, 2019
    Copy the full SHA
    20752ba View commit details
  3. bazel: add file and zip in the test runner env

    `file` and `zip` are needed for some bazel test and by default the test
    runner take these binaries from the current `PATH` which may not contain
    them
    guibou committed Dec 4, 2019
    Copy the full SHA
    c0a6fc4 View commit details
  4. Merge pull request #73309 from guibou/bazel_fix_env

    bazel: fix strict action env
    flokli authored Dec 4, 2019
    Copy the full SHA
    f4fd6ad View commit details
  5. Merge pull request #74898 from tfc/nixos-test-retry

    nixos/test: Use retry() in all looping functions that need timeouts
    flokli authored Dec 4, 2019
    Copy the full SHA
    746a888 View commit details
  6. nixosTests.ldap: port integration test to python

    Jacek Galowicz committed Dec 4, 2019
    Copy the full SHA
    15f105d View commit details
  7. nixosTests.openldap: port test to python

    Jacek Galowicz committed Dec 4, 2019
    Copy the full SHA
    5d91b29 View commit details
  8. Copy the full SHA
    24a4f45 View commit details
  9. Copy the full SHA
    d674a64 View commit details
  10. Copy the full SHA
    5d0dd4e View commit details
  11. Copy the full SHA
    8ad01c3 View commit details
  12. Copy the full SHA
    0b5dfa5 View commit details
  13. Merge pull request #74851 from tfc/nixos-test-ldap-python

    nixosTests.[open]ldap: port to python
    flokli authored Dec 4, 2019
    Copy the full SHA
    afd8bb3 View commit details
  14. Merge pull request #74972 from nyantec/feature/gitlab-12-5-3

    gitlab: 12.5.2 -> 12.5.3
    flokli authored Dec 4, 2019
    Copy the full SHA
    dcf9a77 View commit details
108 changes: 73 additions & 35 deletions nixos/lib/test-driver/test-driver.py
Original file line number Diff line number Diff line change
@@ -312,8 +312,13 @@ def send_monitor_command(self, command: str) -> str:
self.monitor.send(message)
return self.wait_for_monitor_prompt()

def wait_for_unit(self, unit: str, user: Optional[str] = None) -> bool:
while True:
def wait_for_unit(self, unit: str, user: Optional[str] = None) -> None:
"""Wait for a systemd unit to get into "active" state.
Throws exceptions on "failed" and "inactive" states as well as
after timing out.
"""

def check_active(_: Any) -> bool:
info = self.get_unit_info(unit, user)
state = info["ActiveState"]
if state == "failed":
@@ -329,8 +334,10 @@ def wait_for_unit(self, unit: str, user: Optional[str] = None) -> bool:
'unit "{}" is inactive and there ' "are no pending jobs"
).format(unit)
)
if state == "active":
return True

return state == "active"

retry(check_active)

def get_unit_info(self, unit: str, user: Optional[str] = None) -> Dict[str, str]:
status, lines = self.systemctl('--no-pager show "{}"'.format(unit), user)
@@ -421,18 +428,34 @@ def fail(self, *commands: str) -> None:
)

def wait_until_succeeds(self, command: str) -> str:
"""Wait until a command returns success and return its output.
Throws an exception on timeout.
"""
output = ""

def check_success(_: Any) -> bool:
nonlocal output
status, output = self.execute(command)
return status == 0

with self.nested("waiting for success: {}".format(command)):
while True:
status, output = self.execute(command)
if status == 0:
return output
retry(check_success)
return output

def wait_until_fails(self, command: str) -> str:
"""Wait until a command returns failure.
Throws an exception on timeout.
"""
output = ""

def check_failure(_: Any) -> bool:
nonlocal output
status, output = self.execute(command)
return status != 0

with self.nested("waiting for failure: {}".format(command)):
while True:
status, output = self.execute(command)
if status != 0:
return output
retry(check_failure)
return output

def wait_for_shutdown(self) -> None:
if not self.booted:
@@ -453,25 +476,38 @@ def get_tty_text(self, tty: str) -> str:
)
return output

def wait_until_tty_matches(self, tty: str, regexp: str) -> bool:
def wait_until_tty_matches(self, tty: str, regexp: str) -> None:
"""Wait until the visible output on the chosen TTY matches regular
expression. Throws an exception on timeout.
"""
matcher = re.compile(regexp)

def tty_matches(last: bool) -> bool:
text = self.get_tty_text(tty)
if last:
self.log(
f"Last chance to match /{regexp}/ on TTY{tty}, "
f"which currently contains: {text}"
)
return len(matcher.findall(text)) > 0

with self.nested("waiting for {} to appear on tty {}".format(regexp, tty)):
while True:
text = self.get_tty_text(tty)
if len(matcher.findall(text)) > 0:
return True
retry(tty_matches)

def send_chars(self, chars: List[str]) -> None:
with self.nested("sending keys ‘{}‘".format(chars)):
for char in chars:
self.send_key(char)

def wait_for_file(self, filename: str) -> bool:
def wait_for_file(self, filename: str) -> None:
"""Waits until the file exists in machine's file system."""

def check_file(_: Any) -> bool:
status, _ = self.execute("test -e {}".format(filename))
return status == 0

with self.nested("waiting for file ‘{}‘".format(filename)):
while True:
status, _ = self.execute("test -e {}".format(filename))
if status == 0:
return True
retry(check_file)

def wait_for_open_port(self, port: int) -> None:
def port_is_open(_: Any) -> bool:
@@ -494,8 +530,8 @@ def start_job(self, jobname: str, user: Optional[str] = None) -> Tuple[int, str]
def stop_job(self, jobname: str, user: Optional[str] = None) -> Tuple[int, str]:
return self.systemctl("stop {}".format(jobname), user)

def wait_for_job(self, jobname: str) -> bool:
return self.wait_for_unit(jobname)
def wait_for_job(self, jobname: str) -> None:
self.wait_for_unit(jobname)

def connect(self) -> None:
if self.connected:
@@ -700,18 +736,20 @@ def wait_for_x(self) -> None:
"""Wait until it is possible to connect to the X server. Note that
testing the existence of /tmp/.X11-unix/X0 is insufficient.
"""

def check_x(_: Any) -> bool:
cmd = (
"journalctl -b SYSLOG_IDENTIFIER=systemd | "
+ 'grep "Reached target Current graphical"'
)
status, _ = self.execute(cmd)
if status != 0:
return False
status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
return status == 0

with self.nested("waiting for the X11 server"):
while True:
cmd = (
"journalctl -b SYSLOG_IDENTIFIER=systemd | "
+ 'grep "Reached target Current graphical"'
)
status, _ = self.execute(cmd)
if status != 0:
continue
status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
if status == 0:
return
retry(check_x)

def get_window_names(self) -> List[str]:
return self.succeed(
212 changes: 111 additions & 101 deletions nixos/tests/ldap.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ...} :
import ./make-test-python.nix ({ pkgs, lib, ...} :

let
unlines = lib.concatStringsSep "\n";
@@ -288,108 +288,118 @@ in

client1 = mkClient true; # use nss_pam_ldapd
client2 = mkClient false; # use nss_ldap and pam_ldap

};

testScript = ''
$server->start;
$server->waitForUnit("default.target");
subtest "slapd", sub {
subtest "auth as database admin with SASL and check a POSIX account", sub {
$server->succeed(join ' ', 'test',
'"$(ldapsearch -LLL -H ldapi:// -Y EXTERNAL',
'-b \'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}\' ',
'-s base uidNumber |',
'sed -ne \'s/^uidNumber: \\(.*\\)/\\1/p\' ',
')" -eq ${toString ldapUserId}');
};
subtest "auth as database admin with password and check a POSIX account", sub {
$server->succeed(join ' ', 'test',
'"$(ldapsearch -LLL -H ldap://server',
'-D \'cn=admin,${dbSuffix}\' -w \'${dbAdminPwd}\' ',
'-b \'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}\' ',
'-s base uidNumber |',
'sed -ne \'s/^uidNumber: \\(.*\\)/\\1/p\' ',
')" -eq ${toString ldapUserId}');
};
};
$client1->start;
$client1->waitForUnit("default.target");
subtest "password", sub {
subtest "su with password to a POSIX account", sub {
$client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "${ldapUserPwd}\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
'exit 1' . "'");
};
subtest "change password of a POSIX account as root", sub {
$client1->succeed("chpasswd <<<'${ldapUser}:new-password'");
$client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "new-password\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
'exit 1' . "'");
$client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
};
subtest "change password of a POSIX account from itself", sub {
$client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
$client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
'spawn su --login ${ldapUser} -c passwd',
'expect "Password: "',
'send "${ldapUserPwd}\n"',
'expect "(current) UNIX password: "',
'send "${ldapUserPwd}\n"',
'expect "New password: "',
'send "new-password\n"',
'expect "Retype new password: "',
'send "new-password\n"',
'expect "passwd: password updated successfully" {exit}',
'exit 1' . "'");
$client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "${ldapUserPwd}\n"',
'expect "su: Authentication failure" {exit}',
'exit 1' . "'");
$client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "new-password\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
'exit 1' . "'");
$client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
};
};
$client2->start;
$client2->waitForUnit("default.target");
subtest "NSS", sub {
$client1->succeed("test \"\$(id -u '${ldapUser}')\" -eq ${toString ldapUserId}");
$client1->succeed("test \"\$(id -u -n '${ldapUser}')\" = '${ldapUser}'");
$client1->succeed("test \"\$(id -g '${ldapUser}')\" -eq ${toString ldapGroupId}");
$client1->succeed("test \"\$(id -g -n '${ldapUser}')\" = '${ldapGroup}'");
$client2->succeed("test \"\$(id -u '${ldapUser}')\" -eq ${toString ldapUserId}");
$client2->succeed("test \"\$(id -u -n '${ldapUser}')\" = '${ldapUser}'");
$client2->succeed("test \"\$(id -g '${ldapUser}')\" -eq ${toString ldapGroupId}");
$client2->succeed("test \"\$(id -g -n '${ldapUser}')\" = '${ldapGroup}'");
};
subtest "PAM", sub {
$client1->succeed("echo ${ldapUserPwd} | su -l '${ldapUser}' -c true");
$client2->succeed("echo ${ldapUserPwd} | su -l '${ldapUser}' -c true");
};
def expect_script(*commands):
script = ";".join(commands)
return f"${pkgs.expect}/bin/expect -c '{script}'"
server.start()
server.wait_for_unit("default.target")
with subtest("slapd: auth as database admin with SASL and check a POSIX account"):
server.succeed(
'test "$(ldapsearch -LLL -H ldapi:// -Y EXTERNAL '
+ "-b 'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}' "
+ "-s base uidNumber | "
+ "sed -ne 's/^uidNumber: \\(.*\\)/\\1/p')\" -eq ${toString ldapUserId}"
)
with subtest("slapd: auth as database admin with password and check a POSIX account"):
server.succeed(
"test \"$(ldapsearch -LLL -H ldap://server -D 'cn=admin,${dbSuffix}' "
+ "-w '${dbAdminPwd}' -b 'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}' "
+ "-s base uidNumber | "
+ "sed -ne 's/^uidNumber: \\(.*\\)/\\1/p')\" -eq ${toString ldapUserId}"
)
client1.start()
client1.wait_for_unit("default.target")
with subtest("password: su with password to a POSIX account"):
client1.succeed(
expect_script(
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "${ldapUserPwd}\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
"exit 1",
)
)
with subtest("password: change password of a POSIX account as root"):
client1.succeed(
"chpasswd <<<'${ldapUser}:new-password'",
expect_script(
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "new-password\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
"exit 1",
),
"chpasswd <<<'${ldapUser}:${ldapUserPwd}'",
)
with subtest("password: change password of a POSIX account from itself"):
client1.succeed(
"chpasswd <<<'${ldapUser}:${ldapUserPwd}' ",
expect_script(
"spawn su --login ${ldapUser} -c passwd",
'expect "Password: "',
'send "${ldapUserPwd}\n"',
'expect "(current) UNIX password: "',
'send "${ldapUserPwd}\n"',
'expect "New password: "',
'send "new-password\n"',
'expect "Retype new password: "',
'send "new-password\n"',
'expect "passwd: password updated successfully" {exit}',
"exit 1",
),
expect_script(
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "${ldapUserPwd}\n"',
'expect "su: Authentication failure" {exit}',
"exit 1",
),
expect_script(
'spawn su "${ldapUser}"',
'expect "Password:"',
'send "new-password\n"',
'expect "*"',
'send "whoami\n"',
'expect -ex "${ldapUser}" {exit}',
"exit 1",
),
"chpasswd <<<'${ldapUser}:${ldapUserPwd}'",
)
client2.start()
client2.wait_for_unit("default.target")
with subtest("NSS"):
client1.succeed(
"test \"$(id -u '${ldapUser}')\" -eq ${toString ldapUserId}",
"test \"$(id -u -n '${ldapUser}')\" = '${ldapUser}'",
"test \"$(id -g '${ldapUser}')\" -eq ${toString ldapGroupId}",
"test \"$(id -g -n '${ldapUser}')\" = '${ldapGroup}'",
"test \"$(id -u '${ldapUser}')\" -eq ${toString ldapUserId}",
"test \"$(id -u -n '${ldapUser}')\" = '${ldapUser}'",
"test \"$(id -g '${ldapUser}')\" -eq ${toString ldapGroupId}",
"test \"$(id -g -n '${ldapUser}')\" = '${ldapGroup}'",
)
with subtest("PAM"):
client1.succeed(
"echo ${ldapUserPwd} | su -l '${ldapUser}' -c true",
"echo ${ldapUserPwd} | su -l '${ldapUser}' -c true",
)
'';
})
Loading