1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00
gopher-os/kernel/panic_test.go
Achilleas Anagnostopoulos 5fc6ce188e Use go:redirect-from directive to map panic to kernel.Panic
All calls (but one) to kernel.Panic have been replaced by calls to
panic. A call to kernel.Panic is still required to prevent the compiler
from treating kernel.Panic as dead code and eliminating it.
2017-06-25 21:39:56 +01:00

122 lines
2.7 KiB
Go

package kernel
import (
"bytes"
"errors"
"testing"
"unsafe"
"github.com/achilleasa/gopher-os/kernel/cpu"
"github.com/achilleasa/gopher-os/kernel/driver/video/console"
"github.com/achilleasa/gopher-os/kernel/hal"
)
func TestPanic(t *testing.T) {
defer func() {
cpuHaltFn = cpu.Halt
}()
var cpuHaltCalled bool
cpuHaltFn = func() {
cpuHaltCalled = true
}
t.Run("with *kernel.Error", func(t *testing.T) {
cpuHaltCalled = false
fb := mockTTY()
err := &Error{Module: "test", Message: "panic test"}
Panic(err)
exp := "\n-----------------------------------\n[test] unrecoverable error: panic test\n*** kernel panic: system halted ***\n-----------------------------------"
if got := readTTY(fb); got != exp {
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
}
if !cpuHaltCalled {
t.Fatal("expected cpu.Halt() to be called by Panic")
}
})
t.Run("with error", func(t *testing.T) {
cpuHaltCalled = false
fb := mockTTY()
err := errors.New("go error")
Panic(err)
exp := "\n-----------------------------------\n[rt] unrecoverable error: go error\n*** kernel panic: system halted ***\n-----------------------------------"
if got := readTTY(fb); got != exp {
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
}
if !cpuHaltCalled {
t.Fatal("expected cpu.Halt() to be called by Panic")
}
})
t.Run("with string", func(t *testing.T) {
cpuHaltCalled = false
fb := mockTTY()
err := "string error"
Panic(err)
exp := "\n-----------------------------------\n[rt] unrecoverable error: string error\n*** kernel panic: system halted ***\n-----------------------------------"
if got := readTTY(fb); got != exp {
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
}
if !cpuHaltCalled {
t.Fatal("expected cpu.Halt() to be called by Panic")
}
})
t.Run("without error", func(t *testing.T) {
cpuHaltCalled = false
fb := mockTTY()
Panic(nil)
exp := "\n-----------------------------------\n*** kernel panic: system halted ***\n-----------------------------------"
if got := readTTY(fb); got != exp {
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
}
if !cpuHaltCalled {
t.Fatal("expected cpu.Halt() to be called by Panic")
}
})
}
func readTTY(fb []byte) string {
var buf bytes.Buffer
for i := 0; i < len(fb); i += 2 {
ch := fb[i]
if ch == 0 {
if i+2 < len(fb) && fb[i+2] != 0 {
buf.WriteByte('\n')
}
continue
}
buf.WriteByte(ch)
}
return buf.String()
}
func mockTTY() []byte {
// Mock a tty to handle early.Printf output
mockConsoleFb := make([]byte, 160*25)
mockConsole := &console.Ega{}
mockConsole.Init(80, 25, uintptr(unsafe.Pointer(&mockConsoleFb[0])))
hal.ActiveTerminal.AttachTo(mockConsole)
return mockConsoleFb
}