Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions .github/workflows/openbsd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
name: OpenBSD

# spell-checker:ignore sshfs usesh vmactions taiki Swatinem esac fdescfs fdesc sccache nextest copyback logind bindgen libclang

env:
# * style job configuration
STYLE_FAIL_ON_FAULT: true ## (bool) fail the build if a style job contains a fault (error or warning); may be overridden on a per-job basis

on:
pull_request:
push:
branches:
- '*'

permissions:
contents: read # to fetch code (actions/checkout)

# End the current execution if there is a new changeset in the PR.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
style:
name: Style and Lint
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
job:
- { features: unix }
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Prepare, build and test
uses: vmactions/openbsd-vm@v1
with:
usesh: true
sync: rsync
copyback: false
mem: 4096
# We need jq and GNU coreutils to run show-utils.sh and bash to use inline shell string replacement
# Use sudo-- to get the default sudo package without ambiguity
# Install rust and cargo from OpenBSD packages
prepare: pkg_add curl sudo-- jq coreutils bash rust rust-clippy rust-rustfmt llvm--
run: |
## Prepare, build, and test
# implementation modelled after ref: <https://github.com/rust-lang/rustup/pull/2783>
# * NOTE: All steps need to be run in this block, otherwise, we are operating back on the mac host
set -e
#
TEST_USER=tester
REPO_NAME=${GITHUB_WORKSPACE##*/}
WORKSPACE_PARENT="/home/runner/work/${REPO_NAME}"
WORKSPACE="${WORKSPACE_PARENT}/${REPO_NAME}"
#
useradd -m -G wheel ${TEST_USER}
chown -R ${TEST_USER}:wheel /root/ "${WORKSPACE_PARENT}"/
whoami
#
# Further work needs to be done in a sudo as we are changing users
sudo -i -u ${TEST_USER} bash << EOF
set -e
whoami
# Rust is installed from packages, no need for rustup
# Set up PATH for cargo
export PATH="/usr/local/bin:$PATH"
## VARs setup
cd "${WORKSPACE}"
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
*) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;;
esac;
FAULT_PREFIX=\$(echo "\${FAULT_TYPE}" | tr '[:lower:]' '[:upper:]')
# * determine sub-crate utility list
UTILITY_LIST="\$(./util/show-utils.sh --features ${{ matrix.job.features }})"
CARGO_UTILITY_LIST_OPTIONS="\$(for u in \${UTILITY_LIST}; do echo -n "-puu_\${u} "; done;)"
## Info
# environment
echo "## environment"
echo "CI='${CI}'"
echo "REPO_NAME='${REPO_NAME}'"
echo "TEST_USER='${TEST_USER}'"
echo "WORKSPACE_PARENT='${WORKSPACE_PARENT}'"
echo "WORKSPACE='${WORKSPACE}'"
echo "FAULT_PREFIX='\${FAULT_PREFIX}'"
echo "UTILITY_LIST='\${UTILITY_LIST}'"
env | sort
# tooling info
echo "## tooling info"
cargo -V
rustc -V
#
# To ensure that files are cleaned up, we don't want to exit on error
set +e
unset FAULT
## cargo fmt testing
echo "## cargo fmt testing"
# * convert any errors/warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
S=\$(cargo fmt -- --check) && printf "%s\n" "\$S" || { printf "%s\n" "\$S" ; printf "%s\n" "\$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+\${PWD//\//\\\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*\$/::\${FAULT_TYPE} file=\1,line=\2::\${FAULT_PREFIX}: \\\`cargo fmt\\\`: style violation (file:'\1', line:\2; use \\\`cargo fmt -- \"\1\"\\\`)/p" ; FAULT=true ; }
## cargo clippy lint testing
if [ -z "\${FAULT}" ]; then
echo "## cargo clippy lint testing"
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
S=\$(cargo clippy --all-targets \${CARGO_UTILITY_LIST_OPTIONS} -- -D warnings 2>&1) && printf "%s\n" "\$S" || { printf "%s\n" "\$S" ; printf "%s" "\$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*\$/::\${FAULT_TYPE} file=\2,line=\3,col=\4::\${FAULT_PREFIX}: \\\`cargo clippy\\\`: \1 (file:'\2', line:\3)/p;" -e '}' ; FAULT=true ; }
fi
# Clean to avoid to rsync back the files
cargo clean
if [ -n "\${FAIL_ON_FAULT}" ] && [ -n "\${FAULT}" ]; then exit 1 ; fi
EOF

test:
name: Tests
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
job:
- { features: unix }
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Prepare, build and test
uses: vmactions/openbsd-vm@v1
with:
usesh: true
sync: rsync
copyback: false
mem: 4096
# Install rust and build dependencies from OpenBSD packages (llvm provides libclang for bindgen)
prepare: pkg_add curl gmake sudo-- jq rust llvm--
run: |
## Prepare, build, and test
# implementation modelled after ref: <https://github.com/rust-lang/rustup/pull/2783>
# * NOTE: All steps need to be run in this block, otherwise, we are operating back on the mac host
set -e
#
TEST_USER=tester
REPO_NAME=${GITHUB_WORKSPACE##*/}
WORKSPACE_PARENT="/home/runner/work/${REPO_NAME}"
WORKSPACE="${WORKSPACE_PARENT}/${REPO_NAME}"
#
useradd -m -G wheel ${TEST_USER}
chown -R ${TEST_USER}:wheel /root/ "${WORKSPACE_PARENT}"/
whoami
#
# Further work needs to be done in a sudo as we are changing users
sudo -i -u ${TEST_USER} sh << EOF
set -e
whoami
# Rust is installed from packages, no need for rustup
# Set up PATH for cargo
export PATH="/usr/local/bin:$PATH"
# Install nextest
mkdir -p ~/.cargo/bin
# Note: nextest might not have OpenBSD builds, so we'll use regular cargo test
## Info
# environment
echo "## environment"
echo "CI='${CI}'"
echo "REPO_NAME='${REPO_NAME}'"
echo "TEST_USER='${TEST_USER}'"
echo "WORKSPACE_PARENT='${WORKSPACE_PARENT}'"
echo "WORKSPACE='${WORKSPACE}'"
env | sort
# tooling info
echo "## tooling info"
cargo -V
rustc -V
#
# To ensure that files are cleaned up, we don't want to exit on error
set +e
cd "${WORKSPACE}"
unset FAULT
cargo build || FAULT=1
export PATH=~/.cargo/bin:${PATH}
export RUST_BACKTRACE=1
export CARGO_TERM_COLOR=always
# Use cargo test since nextest might not support OpenBSD
if (test -z "\$FAULT"); then cargo test --features '${{ matrix.job.features }}' || FAULT=1 ; fi
# There is no systemd-logind on OpenBSD, so test all features except feat_systemd_logind
if (test -z "\$FAULT"); then
UUCORE_FEATURES=\$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.name == "uucore") | .features | keys | .[]' | grep -v "feat_systemd_logind" | paste -s -d "," -)
cargo test --features "\$UUCORE_FEATURES" -p uucore || FAULT=1
fi
# Test building with make
if (test -z "\$FAULT"); then make PROFILE=ci || FAULT=1 ; fi
# Clean to avoid to rsync back the files
cargo clean
if (test -n "\$FAULT"); then exit 1 ; fi
EOF
22 changes: 11 additions & 11 deletions tests/by-util/test_cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static TEST_NONEXISTENT_FILE: &str = "nonexistent_file.txt";
use uutests::util::compare_xattrs;

/// Assert that mode, ownership, and permissions of two metadata objects match.
#[cfg(all(not(windows), not(target_os = "freebsd")))]
#[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))]
macro_rules! assert_metadata_eq {
($m1:expr, $m2:expr) => {{
assert_eq!($m1.mode(), $m2.mode(), "mode is different");
Expand Down Expand Up @@ -1553,7 +1553,7 @@ fn test_cp_parents_with_permissions_copy_file() {
.arg(dir)
.succeeds();

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
let p1_metadata = at.metadata("p1");
let p2_metadata = at.metadata("p1/p2");
Expand Down Expand Up @@ -1596,7 +1596,7 @@ fn test_cp_parents_with_permissions_copy_dir() {
.arg(dir1)
.succeeds();

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
let p1_metadata = at.metadata("p1");
let p2_metadata = at.metadata("p1/p2");
Expand Down Expand Up @@ -1641,7 +1641,7 @@ fn test_cp_preserve_no_args() {
.arg("--preserve")
.succeeds();

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
// Assert that the mode, ownership, and timestamps are preserved
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
Expand Down Expand Up @@ -1669,7 +1669,7 @@ fn test_cp_preserve_no_args_before_opts() {
.arg(dst_file)
.succeeds();

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
// Assert that the mode, ownership, and timestamps are preserved
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
Expand All @@ -1695,7 +1695,7 @@ fn test_cp_preserve_all() {
// Copy
ucmd.arg(src_file).arg(dst_file).arg(argument).succeeds();

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
// Assert that the mode, ownership, and timestamps are preserved
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
Expand Down Expand Up @@ -3028,7 +3028,7 @@ fn test_copy_through_dangling_symlink_no_dereference_permissions() {
assert!(at.symlink_exists("d2"), "symlink wasn't created");

// `-p` means `--preserve=mode,ownership,timestamps`
#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
let metadata1 = at.symlink_metadata("dangle");
let metadata2 = at.symlink_metadata("d2");
Expand Down Expand Up @@ -3749,7 +3749,7 @@ fn test_preserve_hardlink_attributes_in_directory() {
//
// A hard link should have the same inode as the target file.
at.file_exists("dest/src/link");
#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
assert_eq!(
at.metadata("dest/src/f").ino(),
at.metadata("dest/src/link").ino()
Expand All @@ -3765,7 +3765,7 @@ fn test_hard_link_file() {
ucmd.args(&["-f", "--link", "src", "dest"])
.succeeds()
.no_output();
#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
assert_eq!(at.metadata("src").ino(), at.metadata("dest").ino());
}

Expand Down Expand Up @@ -4069,7 +4069,7 @@ fn test_cp_dest_no_permissions() {
}

#[test]
#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
fn test_cp_attributes_only() {
let (at, mut ucmd) = at_and_ucmd!();
let a = "file_a";
Expand Down Expand Up @@ -6537,7 +6537,7 @@ fn test_cp_preserve_selinux() {
selinux_perm_dest
);

#[cfg(all(unix, not(target_os = "freebsd")))]
#[cfg(all(unix, not(target_os = "freebsd"), not(target_os = "openbsd")))]
{
// Assert that the mode, ownership, and timestamps are preserved
// NOTICE: the ownership is not modified on the src file, because that requires root permissions
Expand Down
4 changes: 2 additions & 2 deletions tests/by-util/test_hostname.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ fn test_hostname() {
assert!(ls_default_res.stdout().len() >= ls_domain_res.stdout().len());
}

// FixME: fails for "MacOS" => "failed to lookup address information"
#[cfg(not(target_os = "macos"))]
// FixME: fails for "MacOS" and "OpenBSD" => "failed to lookup address information"
#[cfg(not(any(target_os = "macos", target_os = "openbsd")))]
#[test]
fn test_hostname_ip() {
let result = new_ucmd!().arg("-i").succeeds();
Expand Down
Loading