You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

105 lines
3.3 KiB

package timesocket
import (
"context"
"net"
"path/filepath"
"testing"
"time"
"tera-clone/services/tera-api/internal/systemtime"
)
func TestClientAndServerSyncThroughNarrowProtocol(t *testing.T) {
socketPath := filepath.Join(t.TempDir(), "time.sock")
listener, err := net.Listen("unix", socketPath)
if err != nil {
t.Skipf("unix sockets unavailable: %v", err)
}
server := Server{Controller: systemtime.MockController{}}
done := make(chan error, 1)
go func() { done <- server.Serve(listener) }()
client := NewClient(socketPath)
requested := time.Date(2026, 7, 23, 16, 30, 0, 0, time.FixedZone("KST", 9*60*60))
result, err := client.Sync(context.Background(), systemtime.Request{BrowserTime: requested, Timezone: "Asia/Seoul"})
if err != nil {
t.Fatalf("Sync() error = %v", err)
}
if result.AppliedTime != requested.UTC() || result.Timezone != "Asia/Seoul" {
t.Fatalf("Sync() = %+v, want %s Asia/Seoul", result, requested.UTC())
}
if err := listener.Close(); err != nil {
t.Fatal(err)
}
select {
case err := <-done:
if err != nil {
t.Fatal(err)
}
case <-time.After(time.Second):
t.Fatal("server did not stop")
}
}
func TestClientReportsUnavailableSocket(t *testing.T) {
client := NewClient(filepath.Join(t.TempDir(), "missing.sock"))
_, err := client.Sync(context.Background(), systemtime.Request{})
if !systemtime.IsUnavailable(err) {
t.Fatalf("Sync() error = %v, want unavailable", err)
}
}
func TestClientAndServerSyncNTPThroughNarrowProtocol(t *testing.T) {
socketPath := filepath.Join(t.TempDir(), "time.sock")
listener, err := net.Listen("unix", socketPath)
if err != nil {
t.Skipf("unix sockets unavailable: %v", err)
}
defer listener.Close()
server := Server{Controller: systemtime.MockController{}}
go func() { _ = server.Serve(listener) }()
client := NewClient(socketPath)
result, err := client.SyncNTP(context.Background(), systemtime.NTPRequest{
Servers: []string{"ntp.kriss.re.kr", "time.bora.net"}, Timezone: "Asia/Seoul",
})
if err != nil {
t.Fatalf("SyncNTP() error = %v", err)
}
if result.Timezone != "Asia/Seoul" || len(result.Servers) != 2 || result.Servers[0] != "ntp.kriss.re.kr" {
t.Fatalf("SyncNTP() = %+v", result)
}
}
func TestServerRejectsUnsafeTimezoneWithoutCallingController(t *testing.T) {
socketPath := filepath.Join(t.TempDir(), "time.sock")
listener, err := net.Listen("unix", socketPath)
if err != nil {
t.Skipf("unix sockets unavailable: %v", err)
}
defer listener.Close()
server := Server{Controller: systemtime.MockController{}}
go func() { _ = server.Serve(listener) }()
client := NewClient(socketPath)
_, err = client.Sync(context.Background(), systemtime.Request{
BrowserTime: time.Date(2026, 7, 23, 0, 0, 0, 0, time.UTC),
Timezone: "../../etc/passwd",
})
if err == nil {
t.Fatal("Sync() accepted an unsafe timezone")
}
}
func TestClientConfiguresWithoutClockSync(t *testing.T) {
listener, err := net.Listen("unix", filepath.Join(t.TempDir(), "settings.sock"))
if err != nil {
t.Fatal(err)
}
defer listener.Close()
go func() { _ = (Server{Controller: systemtime.MockController{}}).Serve(listener) }()
client := NewClient(listener.Addr().String())
if err := client.Configure(context.Background(), systemtime.Settings{Timezone: "Asia/Seoul", NTPEnabled: true, Servers: []string{"internal.example"}}); err != nil {
t.Fatal(err)
}
}