Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: add integration test #56

Merged
merged 4 commits into from
Mar 18, 2024
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/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: CI

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

jobs:
run-integration-test:
runs-on: ubuntu-latest
steps:
- name: Checkout mewz
uses: actions/checkout@v3
with:
repository: mewz-project/mewz
submodules: true

- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.12.0-dev.926+3be8490d8
cache: true

- name: Install packages for running tests
uses: awalsh128/[email protected]
with:
packages: qemu-system mtools

- name: Cache mewz
uses: actions/cache@v2
with:
path:
zig-cache
key: ${{ runner.os }}-mewz

- name: Cache Newlib
uses: actions/cache@v2
with:
path:
build/newlib
key: ${{ runner.os }}-mewz-newlib

- name: Cache lwIP
uses: actions/cache@v2
with:
path:
build/lwip
key: ${{ runner.os }}-mewz-lwip

- name: Build Mewz
run: zig build -Dtest=true -Doptimize=ReleaseFast

- name: Run tests
run: |
zig build -Dtest=true -Doptimize=ReleaseFast run
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ To use file systems, specify the directory by `-Ddir=<path to dir>`. See [exampl
> [!NOTE]
> QEMU's port 1234 is mapped to localhost:1234.

## Run integration tests

```sh
zig bulid -Dtest=true run
```

### Current Status


Expand Down
116 changes: 85 additions & 31 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,80 @@ const Target = @import("std").Target;
const CrossTarget = @import("std").zig.CrossTarget;
const Feature = @import("std").Target.Cpu.Feature;

pub fn build(b: *Build) !void {
const kernel_options = b.addOptions();

const obj_path_option = b.option([]const u8, "app-obj", "object file of application");
if (obj_path_option) |_| {
kernel_options.addOption(bool, "has_wasm", true);
} else {
kernel_options.addOption(bool, "has_wasm", false);
const TEST_DIR_PATH = "build/test";

const BuildParams = struct {
obj_path: ?[]const u8 = undefined,
dir_path: ?[]const u8 = undefined,
is_test: bool = undefined,
log_level: []const u8 = undefined,

const Self = @This();

fn new(b: *Build) Self {
var params = BuildParams{};

const test_option = b.option(bool, "test", "run tests");
if (test_option) |t| {
params.is_test = t;
if (t) {
createTestDir() catch unreachable;
params.dir_path = TEST_DIR_PATH;
}
} else {
params.is_test = false;
}

const obj_path_option = b.option([]const u8, "app-obj", "object file of application");
if (obj_path_option) |p| {
params.obj_path = p;
} else {
params.obj_path = null;
}

const log_level_option = b.option([]const u8, "log-level", "log level");
if (log_level_option) |l| {
params.log_level = l;
} else {
params.log_level = "fatal";
}

const dir_path_option = b.option([]const u8, "dir", "path to directory");
if (dir_path_option) |p| {
std.debug.print("building fs: {s}\n", .{p});
params.dir_path = p;
} else {
params.dir_path = null;
}

return params;
}

const test_option = b.option(bool, "test", "run tests");
if (test_option) |t| {
kernel_options.addOption(bool, "is_test", t);
} else {
kernel_options.addOption(bool, "is_test", false);
}
fn setOptions(self: *const Self, b: *Build) *Build.Step.Options {
const options = b.addOptions();

const log_level_option = b.option([]const u8, "log-level", "log level");
if (log_level_option) |l| {
kernel_options.addOption([]const u8, "log_level", l);
} else {
kernel_options.addOption([]const u8, "log_level", "fatal");
}
options.addOption(bool, "is_test", self.is_test);
options.addOption([]const u8, "log_level", self.log_level);

if (self.obj_path) |_| {
options.addOption(bool, "has_wasm", true);
} else {
options.addOption(bool, "has_wasm", false);
}

const fs_path_option = b.option([]const u8, "dir", "path to filesystem");
if (fs_path_option) |p| {
std.debug.print("building fs: {s}\n", .{p});
kernel_options.addOption(bool, "has_fs", true);
} else {
kernel_options.addOption(bool, "has_fs", false);
if (self.dir_path) |_| {
options.addOption(bool, "has_fs", true);
} else {
options.addOption(bool, "has_fs", false);
}

return options;
}
};

pub fn build(b: *Build) !void {
const params = BuildParams.new(b);
const options = params.setOptions(b);

const features = Target.x86.Feature;

Expand Down Expand Up @@ -72,19 +115,19 @@ pub fn build(b: *Build) !void {
kernel.addObjectFile(Build.LazyPath{ .path = "build/lwip/liblwipallapps.a" });
kernel.addCSourceFile(Build.Step.Compile.CSourceFile{ .file = Build.LazyPath{ .path = "src/c/newlib_support.c" }, .flags = &[_][]const u8{ "-I", "submodules/newlib/newlib/libc/include" } });
kernel.addCSourceFile(Build.Step.Compile.CSourceFile{ .file = Build.LazyPath{ .path = "src/c/lwip_support.c" }, .flags = &[_][]const u8{ "-I", "submodules/newlib/newlib/libc/include" } });
if (obj_path_option) |p| {
if (params.obj_path) |p| {
kernel.addObjectFile(Build.LazyPath{ .path = p });
}
if (fs_path_option) |_| {
if (params.dir_path) |_| {
kernel.addObjectFile(Build.LazyPath{ .path = "build/disk.o" });
}
kernel.addOptions("options", kernel_options);
kernel.addOptions("options", options);
b.installArtifact(kernel);

const kernel_step = b.step("kernel", "Build the kernel");
kernel.step.dependOn(&newlib_build_cmd.step);
kernel.step.dependOn(&lwip_build_cmd.step);
if (fs_path_option) |p| {
if (params.dir_path) |p| {
const fs_build_cmd = b.addSystemCommand(&[_][]const u8{ "./scripts/build-fs.sh", p });
kernel.step.dependOn(&fs_build_cmd.step);
}
Expand All @@ -93,7 +136,10 @@ pub fn build(b: *Build) !void {
const rewrite_kernel_cmd = b.addSystemCommand(&[_][]const u8{"./scripts/rewrite-kernel.sh"});
rewrite_kernel_cmd.step.dependOn(b.getInstallStep());

const run_cmd_str = [_][]const u8{"./scripts/run-qemu.sh"};
const run_cmd_str = if (params.is_test)
[_][]const u8{"./scripts/integration-test.sh"}
else
[_][]const u8{"./scripts/run-qemu.sh"};

const run_cmd = b.addSystemCommand(&run_cmd_str);
run_cmd.step.dependOn(&rewrite_kernel_cmd.step);
Expand All @@ -111,3 +157,11 @@ pub fn build(b: *Build) !void {
const debug_step = b.step("debug", "Debug the kernel");
debug_step.dependOn(&debug_cmd.step);
}

fn createTestDir() !void {
const cwd = std.fs.cwd();
const test_dir = try cwd.makeOpenPath(TEST_DIR_PATH, std.fs.Dir.OpenDirOptions{});
const file = try test_dir.createFile("test.txt", std.fs.File.CreateFlags{});
defer file.close();
_ = try file.write("fd_read test\n");
}
8 changes: 8 additions & 0 deletions scripts/create-test-dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -ex

REPO_ROOT=$(git rev-parse --show-toplevel)
cd $REPO_ROOT

mkdir -p build/test
echo "fd_read test" > build/test/hogehoge.txt
19 changes: 19 additions & 0 deletions scripts/integration-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
set -ex

REPO_ROOT=$(git rev-parse --show-toplevel)
cd $REPO_ROOT

mkdir -p build/test
(stty -echo; sleep 4; (sleep 0.5; echo q) | telnet localhost 1234) &
(sleep 2; curl localhost:1234) &
./scripts/run-qemu.sh > build/test/output.txt

if ! grep -q "Integration test passed" build/test/output.txt; then
echo "Integration Test FAILED!!"
echo "output:"
cat build/test/output.txt
exit 1
fi

echo -e "\nIntegration Test PASSED!!"
2 changes: 1 addition & 1 deletion submodules/lwip
Submodule lwip updated from b413b0 to d0efd9
Loading