tests+kernel+init: Run tests automatically in a headless way
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
bcfee628cb
commit
cd6bf745a7
@ -7,15 +7,15 @@ platform:
|
||||
os: linux
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
- name: build-and-test
|
||||
image: ubuntu
|
||||
commands:
|
||||
- apt update
|
||||
- apt install build-essential cmake ninja-build wget nasm genext2fs -y
|
||||
- apt install build-essential cmake ninja-build wget nasm genext2fs qemu -y
|
||||
- wget https://pub.cloudapio.eu/luna/toolchains/ci-toolchain-arm64.tar.gz --quiet
|
||||
- tar xf ci-toolchain-arm64.tar.gz
|
||||
- rm ci-toolchain-arm64.tar.gz
|
||||
- tools/rebuild-iso.sh
|
||||
- tools/run-tests.sh
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <os/Directory.h>
|
||||
#include <os/File.h>
|
||||
#include <os/Process.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -18,6 +19,18 @@
|
||||
|
||||
FILE* g_init_log = nullptr;
|
||||
|
||||
// Request a successful exit from the system (for tests)
|
||||
void sigterm_handler(int)
|
||||
{
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
// Request a failure exit from the system (for tests)
|
||||
void sigquit_handler(int)
|
||||
{
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
struct Service
|
||||
{
|
||||
String name;
|
||||
@ -315,11 +328,14 @@ int main()
|
||||
|
||||
umask(022);
|
||||
|
||||
g_init_log = fopen("/tmp/init.log", "w+");
|
||||
g_init_log = fopen("/dev/uart0", "w+");
|
||||
fcntl(fileno(g_init_log), F_SETFD, FD_CLOEXEC);
|
||||
|
||||
set_hostname();
|
||||
|
||||
if (signal(SIGTERM, sigterm_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGTERM");
|
||||
if (signal(SIGQUIT, sigquit_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGQUIT");
|
||||
|
||||
start_services();
|
||||
|
||||
while (1)
|
||||
|
@ -56,6 +56,7 @@ set(SOURCES
|
||||
src/fs/devices/FullDevice.cpp
|
||||
src/fs/devices/ConsoleDevice.cpp
|
||||
src/fs/devices/FramebufferDevice.cpp
|
||||
src/fs/devices/UARTDevice.cpp
|
||||
src/fs/InitRD.cpp
|
||||
src/thread/ELF.cpp
|
||||
)
|
||||
@ -111,6 +112,10 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/config.cmake)
|
||||
include(config.cmake)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
target_compile_definitions(moon PRIVATE MOON_ENABLE_TESTING_FEATURES)
|
||||
endif()
|
||||
|
||||
target_link_options(moon PRIVATE -lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mcmodel=kernel)
|
||||
|
||||
set_target_properties(moon PROPERTIES CXX_STANDARD 20)
|
||||
|
@ -35,5 +35,9 @@ namespace CPU
|
||||
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
|
||||
void sync_interrupts();
|
||||
|
||||
#ifdef MOON_ENABLE_TESTING_FEATURES
|
||||
void magic_exit(int status);
|
||||
#endif
|
||||
|
||||
void pause();
|
||||
}
|
||||
|
@ -417,6 +417,17 @@ namespace CPU
|
||||
change_pic_masks(pic1_mask, pic2_mask);
|
||||
CPU::restore_interrupts(val);
|
||||
}
|
||||
|
||||
#ifdef MOON_ENABLE_TESTING_FEATURES
|
||||
// For tests! Must run QEMU with -device isa-debug-exit,iobase=0xf4,iosize=0x04.
|
||||
void magic_exit(int status)
|
||||
{
|
||||
IO::outl(0xf4,
|
||||
status ? 0x2 : 0x1); // QEMU exits with (status << 1) | 1. Zero would map to 0b11 (3), non-zero would
|
||||
// map to 0b101 (5).
|
||||
__builtin_unreachable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// called by kernel_yield
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "fs/devices/FramebufferDevice.h"
|
||||
#include "fs/devices/FullDevice.h"
|
||||
#include "fs/devices/NullDevice.h"
|
||||
#include "fs/devices/UARTDevice.h"
|
||||
#include "fs/devices/ZeroDevice.h"
|
||||
#include "fs/tmpfs/FileSystem.h"
|
||||
#include "thread/Thread.h"
|
||||
@ -69,6 +70,7 @@ namespace DeviceRegistry
|
||||
FullDevice::create();
|
||||
ConsoleDevice::create();
|
||||
FramebufferDevice::create();
|
||||
UARTDevice::create();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace DeviceRegistry
|
||||
Framebuffer = 3,
|
||||
Disk = 4,
|
||||
DiskPartition = 5,
|
||||
Serial = 6,
|
||||
};
|
||||
|
||||
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor);
|
||||
|
14
kernel/src/fs/devices/UARTDevice.cpp
Normal file
14
kernel/src/fs/devices/UARTDevice.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "fs/devices/UARTDevice.h"
|
||||
#include "arch/Serial.h"
|
||||
|
||||
Result<void> UARTDevice::create()
|
||||
{
|
||||
auto device = (SharedPtr<Device>)TRY(make_shared<UARTDevice>());
|
||||
return DeviceRegistry::register_special_device(DeviceRegistry::Serial, 0, device, 0222);
|
||||
}
|
||||
|
||||
Result<usize> UARTDevice::write(const u8* buf, usize, usize length)
|
||||
{
|
||||
Serial::write((const char*)buf, length);
|
||||
return length;
|
||||
}
|
28
kernel/src/fs/devices/UARTDevice.h
Normal file
28
kernel/src/fs/devices/UARTDevice.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "fs/devices/DeviceRegistry.h"
|
||||
|
||||
class UARTDevice : public Device
|
||||
{
|
||||
public:
|
||||
// Initializer for DeviceRegistry.
|
||||
static Result<void> create();
|
||||
|
||||
Result<usize> read(u8*, usize, usize) const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result<usize> write(const u8*, usize, usize) override;
|
||||
|
||||
bool blocking() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StringView device_path() const override
|
||||
{
|
||||
return "uart0";
|
||||
}
|
||||
|
||||
virtual ~UARTDevice() = default;
|
||||
};
|
@ -38,9 +38,6 @@ Result<u64> sys_sigaction(Registers*, SyscallArgs args)
|
||||
if (!MemoryManager::copy_from_user_typed(act, &kact)) return err(EFAULT);
|
||||
kact.__sa_sigreturn = sigreturn;
|
||||
|
||||
kinfoln("sigaction: installing signal handler for signo=%d: handler=%p, sigreturn=%p", signo,
|
||||
(void*)kact.sa_handler, sigreturn);
|
||||
|
||||
current->signal_handlers[signo - 1] = kact;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "thread/Thread.h"
|
||||
#include "Log.h"
|
||||
#include "arch/CPU.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "thread/Scheduler.h"
|
||||
#include <bits/atfile.h>
|
||||
@ -79,7 +80,11 @@ Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& pa
|
||||
|
||||
[[noreturn]] void Thread::exit_and_signal_parent(int _status)
|
||||
{
|
||||
#ifndef MOON_ENABLE_TESTING_FEATURES
|
||||
if (this->id == 1) fail("the init process exited");
|
||||
#else
|
||||
if (this->id == 1) CPU::magic_exit(_status);
|
||||
#endif
|
||||
if (is_kernel) state = ThreadState::Dying;
|
||||
else
|
||||
{
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/Directory.h>
|
||||
#include <os/File.h>
|
||||
#include <os/Process.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@ -23,10 +25,16 @@ Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
auto command = TRY(String::format("%s/%s"_sv, test_dir.chars(), program.chars()));
|
||||
int status = system(command.chars());
|
||||
if (WEXITSTATUS(status) != 0) return WEXITSTATUS(status);
|
||||
if (WEXITSTATUS(status) != 0)
|
||||
{
|
||||
os::Process::kill(1, SIGQUIT); // Tell init to report a failed test run.
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
os::println("All tests passed.");
|
||||
|
||||
os::Process::kill(1, SIGTERM); // Tell init to report a successful test run.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,14 +16,27 @@ cmake --build $LUNA_BUILD_DIR
|
||||
|
||||
rm base/etc/init/*
|
||||
|
||||
printf "Name=test\nCommand=/bin/run-tests\nWait=true\n" > base/etc/init/00-tests
|
||||
printf "Name=test\nCommand=/bin/run-tests\nWait=true\nStandardOutput=/dev/uart0\nStandardError=/dev/uart0\n" > base/etc/init/00-tests
|
||||
|
||||
tools/make-iso.sh
|
||||
|
||||
set +e
|
||||
tools/fast-run.sh
|
||||
tools/fast-run.sh -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
|
||||
EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
rm base/etc/init/00-tests
|
||||
|
||||
git checkout base/etc/init/
|
||||
|
||||
if [ "$EXIT_CODE" -eq "3" ]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$EXIT_CODE" -eq "5" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit $EXIT_CODE
|
||||
|
Loading…
Reference in New Issue
Block a user