Skip to content

Commit

Permalink
CI: add integration test (#56)
Browse files Browse the repository at this point in the history
* CI: add integration test

* README: add info about integration test

* lwip: update the upstream

* CI: not to use timeout
  • Loading branch information
saza-ku authored Mar 18, 2024
1 parent cf44e7b commit 4acfc77
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 32 deletions.
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

0 comments on commit 4acfc77

Please sign in to comment.