Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
adamws committed Nov 24, 2024
1 parent 198235d commit 101208f
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 55 deletions.
86 changes: 51 additions & 35 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,65 +51,81 @@ jobs:
name: Run functional tests
needs:
- build-and-test
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: klawa-ubuntu-latest
name: klawa-${{ matrix.os }}
path: zig-out/bin
- name: Install dependencies
shell: bash
run: |
pwd
ls -alh zig-out/bin
- if: matrix.os == 'ubuntu-latest'
name: Install dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install ffmpeg xdotool x11-apps xvfb
- if: matrix.os == 'windows-latest'
name: Install dependencies
shell: bash
run: |
choco install autohotkey.portable ffmpeg
- name: Install python dependencies
shell: bash
run: |
cd tests
python -m venv .env
. .env/bin/activate
pip install -r dev-requirements.txt
- name: Run tests
- if: matrix.os == 'ubuntu-latest'
name: Fix executable permisions
shell: bash
run: |
chmod +x zig-out/bin/klawa
- name: Run tests
shell: bash
run: |
# not running with pytest-xdist because renders are way off
# when framerate drops below expected 60fps:
cd tests && . .env/bin/activate && python -m pytest src/
cd tests && python -m pytest src/
- uses: actions/upload-artifact@v4
if: always()
with:
name: report
name: report-${{ matrix.os }}
path: tests/report/
retention-days: 2
if-no-files-found: error

deploy-preview:
name: Deploy tests results
needs:
- run-functional-tests
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./tests
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: report
path: tests/report
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} > url.txt
- name: Add summary
shell: bash
run: |
echo '### Deployed' >> $GITHUB_STEP_SUMMARY
cat url.txt >> $GITHUB_STEP_SUMMARY
# deploy-preview:
# name: Deploy tests results
# needs:
# - run-functional-tests
# runs-on: ubuntu-latest
# defaults:
# run:
# shell: bash
# working-directory: ./tests
# steps:
# - uses: actions/checkout@v4
# - uses: actions/download-artifact@v4
# with:
# name: report
# path: tests/report
# - name: Install Vercel CLI
# run: npm install --global vercel@latest
# - name: Pull Vercel Environment Information
# run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
# - name: Build Project Artifacts
# run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
# - name: Deploy Project Artifacts to Vercel
# run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} > url.txt
# - name: Add summary
# shell: bash
# run: |
# echo '### Deployed' >> $GITHUB_STEP_SUMMARY
# cat url.txt >> $GITHUB_STEP_SUMMARY
9 changes: 8 additions & 1 deletion src/ffmpeg.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const process = std.process;
const Child = process.Child;
const File = std.fs.File;

const builtin = @import("builtin");

pub const Ffmpeg = struct {
child: Child,

Expand All @@ -14,8 +16,13 @@ pub const Ffmpeg = struct {
) !Ffmpeg {
const resolution = try std.fmt.allocPrint(allocator, "{d}x{d}", .{ width, height });
defer allocator.free(resolution);
const exec_name: []const u8 = switch (builtin.target.os.tag) {
.linux => "ffmpeg",
.windows => "ffmpeg.exe",
else => @compileError("unsupported platform"),
};
const args = [_][]const u8{
"ffmpeg", "-y",
exec_name, "-y",
"-f", "rawvideo",
"-framerate", "60",
"-s", resolution,
Expand Down
5 changes: 5 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ pub fn main() !void {
// TODO: is this even needed?
rl.setTargetFPS(60);

std.debug.print("DEBUG1\n", .{});
var renderer: ?Ffmpeg = null;
var pixels: ?[]u8 = null;
if (res.args.render) |dst| {
Expand All @@ -638,6 +639,7 @@ pub fn main() !void {
}
defer if (pixels) |p| allocator.free(p);

std.debug.print("DEBUG2\n", .{});
if (res.args.replay) |replay_file| {
const file = try fs.cwd().openFile(replay_file, .{});
//defer file.close();
Expand All @@ -646,6 +648,7 @@ pub fn main() !void {
key_data_producer = KeyDataProducer.init(reader.any());
}

std.debug.print("DEBUG3\n", .{});
if (res.args.replay == null) {
// TODO: defer when close supported, join on this thread won't work now
_ = try std.Thread.spawn(.{}, backend.listener, .{ &app_state, window_handle });
Expand All @@ -662,6 +665,7 @@ pub fn main() !void {
};
defer rl.unloadTexture(keycap_texture);

std.debug.print("DEBUG4\n", .{});
if (res.args.@"save-atlas") |atlas_file| {
const target = rl.loadRenderTexture(app_state.window_width, app_state.window_height);
defer rl.unloadRenderTexture(target);
Expand Down Expand Up @@ -693,6 +697,7 @@ pub fn main() !void {
const codepoints = try rl.loadCodepoints(all_text);
defer rl.unloadCodepoints(codepoints);

std.debug.print("DEBUG5\n", .{});
std.debug.print("Text contains {} codepoints\n", .{codepoints.len});

// TODO: font should be configurable
Expand Down
1 change: 0 additions & 1 deletion src/textures.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ fn getPositions(sizes: []const rl.Vector2) [keycap_sizes.len]rl.Vector2 {
}

pub fn getPositionBySize(size: rl.Vector2) rl.Vector2 {
std.debug.print("Looking for {d} {d}\n", .{size.x, size.y});
for (keycap_sizes, 0..) |s, i| {
if (size.x == s.x and size.y == s.y) {
return atlas_positions[i];
Expand Down
2 changes: 1 addition & 1 deletion tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[pytest]
addopts =
--html=report/index.html
--app-path=../zig-out/bin/klawa
--app-dir=../zig-out/bin
generate_report_on_test = True
render_collapsed =
log_cli = True
Expand Down
10 changes: 6 additions & 4 deletions tests/src/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import os
import shutil
import sys
from pathlib import Path

import pytest
Expand All @@ -11,18 +12,19 @@

def pytest_addoption(parser) -> None:
parser.addoption(
"--app-path",
"--app-dir",
action="store",
help="Path to klawa executable",
help="Path to directory of klawa executable",
default=False,
)


@pytest.fixture(scope="session")
def app_path(request) -> Path:
app_path = request.config.getoption("--app-path")
app_path = request.config.getoption("--app-dir")
assert app_path, "App path is required"
return Path(os.path.realpath(app_path))
app_name = "klawa.exe" if sys.platform == "win32" else "klawa"
return Path(os.path.realpath(app_path)) / app_name


@pytest.fixture
Expand Down
36 changes: 23 additions & 13 deletions tests/src/test_rendering.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
import os
from os.path import isfile
import signal
import shutil
import subprocess
Expand Down Expand Up @@ -58,7 +57,7 @@ def get_screen_manager():
else:
return HostScreenManager()
else:
pytest.skip(f"Platform '{sys.platform}' is not supported")
return HostScreenManager()


def set_keyboard_layout(lang):
Expand Down Expand Up @@ -91,20 +90,22 @@ def set_keyboard_layout(lang):
def screen_manager():
with get_screen_manager() as _:

# this is a trick to keep one keyboard layout for full display lifetime,
# otherwise server would regenerate layout on last client disconection
# https://stackoverflow.com/questions/75919741/how-to-add-keyboard-layouts-to-xvfb
# 1. run some app in the background for full duration on test
# 2. configure keyboard layout
# 3. test
dummy = subprocess.Popen(["xlogo"])
time.sleep(0.5)
if sys.platform == "linux":
# this is a trick to keep one keyboard layout for full display lifetime,
# otherwise server would regenerate layout on last client disconection
# https://stackoverflow.com/questions/75919741/how-to-add-keyboard-layouts-to-xvfb
# 1. run some app in the background for full duration on test
# 2. configure keyboard layout
# 3. test
dummy = subprocess.Popen(["xlogo"])
time.sleep(0.5)

set_keyboard_layout("pl")
set_keyboard_layout("pl")

yield

dummy.kill()
if sys.platform == "linux":
dummy.kill()


def log_config(tmpdir) -> None:
Expand Down Expand Up @@ -152,6 +153,13 @@ def run_process_capture_logs(command, cwd, name="", process_holder=None) -> None
process.wait()


def run_typing_process(text: str) -> None:
if sys.platform == "win32":
subprocess.run(["AutoHotkey.exe", "/script", f"\"Loop, Parse, '{text}', {{ Send, %A_LoopField% Sleep, 400 }}\""])
else:
subprocess.run(["xdotool", "type", "--delay", "400", text])


def __get_parameters():
texts = [
"The quick brown fox jumps over the lazy dog",
Expand Down Expand Up @@ -192,7 +200,7 @@ def test_record_and_render(app_isolation, text: str, example) -> None:
thread.start()
time.sleep(2)

subprocess.run(["xdotool", "type", "--delay", "400", text])
run_typing_process(text)

process = processes.get("klawa")
if process and process.poll() is None:
Expand All @@ -202,3 +210,5 @@ def test_record_and_render(app_isolation, text: str, example) -> None:

args = [app, "--replay", "events.bin", "--render", "output.webm"]
run_process_capture_logs(args, app_dir)
assert (app_dir / "output.webm").is_file()

0 comments on commit 101208f

Please sign in to comment.