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
58 changes: 58 additions & 0 deletions .github/workflows/itf-qnx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
name: ITF QNX QEMU Tests
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
itf-qnx-qemu-tests-build-all:
runs-on: ubuntu-latest
environment: workflow-approval
permissions:
contents: read
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.2
- name: Setup Bazel
uses: bazel-contrib/setup-bazel@0.14.0
- name: Setup QNX License
env:
SCORE_QNX_LICENSE: ${{ secrets.SCORE_QNX_LICENSE }}
run: |
mkdir -p /opt/score_qnx/license
echo "${SCORE_QNX_LICENSE}" | base64 --decode > /opt/score_qnx/license/licenses
- name: Install qemu
run: |
sudo apt-get update
sudo apt-get install -y qemu-system
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Allow unprivileged user namespaces
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
- name: Build and test
env:
SCORE_QNX_USER: ${{ secrets.SCORE_QNX_USER }}
SCORE_QNX_PASSWORD: ${{ secrets.SCORE_QNX_PASSWORD }}
run: |
bazel test --config=qemu-integration //test:qnx_qemu_tests \
--credential_helper=*.qnx.com=${{ github.workspace }}/tools/qnx_credential_helper.py
- name: Cleanup QNX License
if: always()
run: |
rm -rf /opt/score_qnx
rm -rf "${HOME}/.cache/bazel"
16 changes: 13 additions & 3 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ py_itf_test(
"//score/itf/plugins:dlt_plugin",
],
tags = [
"local",
"manual",
],
)
Expand All @@ -141,7 +140,6 @@ py_itf_test(
"//score/itf/plugins:qemu_plugin",
],
tags = [
"local",
"manual",
],
)
Expand All @@ -164,11 +162,23 @@ py_itf_test(
"//score/itf/plugins:dlt_plugin",
],
tags = [
"local",
"manual",
],
)

test_suite(
name = "qnx_qemu_tests",
tags = [
"manual",
],
tests = [
":test_qemu_bridge_network",
":test_qemu_bridge_network_no_dlt",
":test_qemu_port_forwarding",
":test_ssh_configurable",
],
)

py_itf_test(
name = "test_ping",
srcs = [
Expand Down
79 changes: 79 additions & 0 deletions tools/qnx_credential_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env python3

# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

import http.cookiejar
import json
import netrc
import os
import sys
import urllib.parse
import urllib.request


def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)


if __name__ == "__main__":
data = json.load(sys.stdin)

if "qnx.com" not in data["uri"]:
eprint("Unsupported domain")
sys.exit(1)

if "SCORE_QNX_USER" in os.environ and "SCORE_QNX_PASSWORD" in os.environ:
login = os.environ["SCORE_QNX_USER"]
password = os.environ["SCORE_QNX_PASSWORD"]
else:
try:
nrc = netrc.netrc()
auth = nrc.authenticators("qnx.com")
if auth:
login, _, password = auth
else:
raise Exception("No credential found for QNX")
except Exception as excp:
eprint(excp)
eprint("Failed getting credentials from .netrc")
sys.exit(1)

data = urllib.parse.urlencode({"userlogin": login, "password": password, "UseCookie": "1"})
data = data.encode("ascii")

cookie_jar = http.cookiejar.CookieJar()
cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)
opener = urllib.request.build_opener(cookie_processor)
urllib.request.install_opener(opener)

r = urllib.request.urlopen("https://www.qnx.com/account/login.html", data)
if r.status != 200:
eprint("Failed to login to QNX")
sys.exit(1)

cookies = {c.name: c.value for c in list(cookie_jar)}
if not "myQNX" in cookies:
eprint("Failed to get myQNX cookie from login page")
sys.exit(1)

myQNX = cookies["myQNX"]
print(
json.dumps(
{
"headers": {
"Cookie": [f"myQNX={myQNX}"],
}
}
)
)