kvm/input_rpc_test.go

561 lines
12 KiB
Go

package kvm
import (
"testing"
"github.com/stretchr/testify/assert"
)
// Test validateFloat64Param function
func TestValidateFloat64Param(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
paramName string
methodName string
min float64
max float64
expected float64
expectError bool
}{
{
name: "valid parameter",
params: map[string]interface{}{"test": 50.0},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 50.0,
expectError: false,
},
{
name: "parameter at minimum boundary",
params: map[string]interface{}{"test": 0.0},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 0.0,
expectError: false,
},
{
name: "parameter at maximum boundary",
params: map[string]interface{}{"test": 100.0},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 100.0,
expectError: false,
},
{
name: "parameter below minimum",
params: map[string]interface{}{"test": -1.0},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 0,
expectError: true,
},
{
name: "parameter above maximum",
params: map[string]interface{}{"test": 101.0},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 0,
expectError: true,
},
{
name: "wrong parameter type",
params: map[string]interface{}{"test": "not a number"},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 0,
expectError: true,
},
{
name: "missing parameter",
params: map[string]interface{}{},
paramName: "test",
methodName: "testMethod",
min: 0,
max: 100,
expected: 0,
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := validateFloat64Param(tt.params, tt.paramName, tt.methodName, tt.min, tt.max)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expected, result)
}
})
}
}
// Test validateKeysArray function
func TestValidateKeysArray(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
methodName string
expected []uint8
expectError bool
}{
{
name: "valid keys array",
params: map[string]interface{}{"keys": []interface{}{65.0, 66.0, 67.0}},
methodName: "testMethod",
expected: []uint8{65, 66, 67},
expectError: false,
},
{
name: "empty keys array",
params: map[string]interface{}{"keys": []interface{}{}},
methodName: "testMethod",
expected: []uint8{},
expectError: false,
},
{
name: "maximum keys array",
params: map[string]interface{}{"keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}},
methodName: "testMethod",
expected: []uint8{1, 2, 3, 4, 5, 6},
expectError: false,
},
{
name: "too many keys",
params: map[string]interface{}{"keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}},
methodName: "testMethod",
expected: nil,
expectError: true,
},
{
name: "invalid key type",
params: map[string]interface{}{"keys": []interface{}{"not a number"}},
methodName: "testMethod",
expected: nil,
expectError: true,
},
{
name: "key value out of range (negative)",
params: map[string]interface{}{"keys": []interface{}{-1.0}},
methodName: "testMethod",
expected: nil,
expectError: true,
},
{
name: "key value out of range (too high)",
params: map[string]interface{}{"keys": []interface{}{256.0}},
methodName: "testMethod",
expected: nil,
expectError: true,
},
{
name: "wrong parameter type",
params: map[string]interface{}{"keys": "not an array"},
methodName: "testMethod",
expected: nil,
expectError: true,
},
{
name: "missing keys parameter",
params: map[string]interface{}{},
methodName: "testMethod",
expected: nil,
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := validateKeysArray(tt.params, tt.methodName)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expected, result)
}
})
}
}
// Test handleKeyboardReportDirect function
func TestHandleKeyboardReportDirect(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
expectError bool
}{
{
name: "valid keyboard report",
params: map[string]interface{}{
"modifier": 2.0, // Shift key
"keys": []interface{}{65.0, 66.0}, // A, B keys
},
expectError: false,
},
{
name: "empty keys array",
params: map[string]interface{}{
"modifier": 0.0,
"keys": []interface{}{},
},
expectError: false,
},
{
name: "invalid modifier",
params: map[string]interface{}{
"modifier": 256.0, // Out of range
"keys": []interface{}{65.0},
},
expectError: true,
},
{
name: "invalid keys",
params: map[string]interface{}{
"modifier": 0.0,
"keys": []interface{}{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, // Too many keys
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := handleKeyboardReportDirect(tt.params)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
// Test handleAbsMouseReportDirect function
func TestHandleAbsMouseReportDirect(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
expectError bool
}{
{
name: "valid absolute mouse report",
params: map[string]interface{}{
"x": 1000.0,
"y": 500.0,
"buttons": 1.0, // Left button
},
expectError: false,
},
{
name: "boundary values",
params: map[string]interface{}{
"x": 0.0,
"y": 32767.0,
"buttons": 255.0,
},
expectError: false,
},
{
name: "invalid x coordinate",
params: map[string]interface{}{
"x": -1.0, // Out of range
"y": 500.0,
"buttons": 0.0,
},
expectError: true,
},
{
name: "invalid y coordinate",
params: map[string]interface{}{
"x": 1000.0,
"y": 32768.0, // Out of range
"buttons": 0.0,
},
expectError: true,
},
{
name: "invalid buttons",
params: map[string]interface{}{
"x": 1000.0,
"y": 500.0,
"buttons": 256.0, // Out of range
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := handleAbsMouseReportDirect(tt.params)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
// Test handleRelMouseReportDirect function
func TestHandleRelMouseReportDirect(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
expectError bool
}{
{
name: "valid relative mouse report",
params: map[string]interface{}{
"dx": 10.0,
"dy": -5.0,
"buttons": 2.0, // Right button
},
expectError: false,
},
{
name: "boundary values",
params: map[string]interface{}{
"dx": -127.0,
"dy": 127.0,
"buttons": 0.0,
},
expectError: false,
},
{
name: "invalid dx",
params: map[string]interface{}{
"dx": -128.0, // Out of range
"dy": 0.0,
"buttons": 0.0,
},
expectError: true,
},
{
name: "invalid dy",
params: map[string]interface{}{
"dx": 0.0,
"dy": 128.0, // Out of range
"buttons": 0.0,
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := handleRelMouseReportDirect(tt.params)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
// Test handleWheelReportDirect function
func TestHandleWheelReportDirect(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
expectError bool
}{
{
name: "valid wheel report",
params: map[string]interface{}{
"wheelY": 3.0,
},
expectError: false,
},
{
name: "boundary values",
params: map[string]interface{}{
"wheelY": -127.0,
},
expectError: false,
},
{
name: "invalid wheelY",
params: map[string]interface{}{
"wheelY": 128.0, // Out of range
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := handleWheelReportDirect(tt.params)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
// Test handleInputRPCDirect function
func TestHandleInputRPCDirect(t *testing.T) {
tests := []struct {
name string
method string
params map[string]interface{}
expectError bool
}{
{
name: "keyboard report",
method: "keyboardReport",
params: map[string]interface{}{
"modifier": 0.0,
"keys": []interface{}{65.0},
},
expectError: false,
},
{
name: "absolute mouse report",
method: "absMouseReport",
params: map[string]interface{}{
"x": 1000.0,
"y": 500.0,
"buttons": 1.0,
},
expectError: false,
},
{
name: "relative mouse report",
method: "relMouseReport",
params: map[string]interface{}{
"dx": 10.0,
"dy": -5.0,
"buttons": 2.0,
},
expectError: false,
},
{
name: "wheel report",
method: "wheelReport",
params: map[string]interface{}{
"wheelY": 3.0,
},
expectError: false,
},
{
name: "unknown method",
method: "unknownMethod",
params: map[string]interface{}{},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := handleInputRPCDirect(tt.method, tt.params)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
// Test isInputMethod function
func TestIsInputMethod(t *testing.T) {
tests := []struct {
name string
method string
expected bool
}{
{
name: "keyboard report method",
method: "keyboardReport",
expected: true,
},
{
name: "absolute mouse report method",
method: "absMouseReport",
expected: true,
},
{
name: "relative mouse report method",
method: "relMouseReport",
expected: true,
},
{
name: "wheel report method",
method: "wheelReport",
expected: true,
},
{
name: "non-input method",
method: "someOtherMethod",
expected: false,
},
{
name: "empty method",
method: "",
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := isInputMethod(tt.method)
assert.Equal(t, tt.expected, result)
})
}
}
// Benchmark tests to verify performance improvements
func BenchmarkValidateFloat64Param(b *testing.B) {
params := map[string]interface{}{"test": 50.0}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = validateFloat64Param(params, "test", "benchmarkMethod", 0, 100)
}
}
func BenchmarkValidateKeysArray(b *testing.B) {
params := map[string]interface{}{"keys": []interface{}{65.0, 66.0, 67.0}}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = validateKeysArray(params, "benchmarkMethod")
}
}
func BenchmarkHandleKeyboardReportDirect(b *testing.B) {
params := map[string]interface{}{
"modifier": 2.0,
"keys": []interface{}{65.0, 66.0},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = handleKeyboardReportDirect(params)
}
}
func BenchmarkHandleInputRPCDirect(b *testing.B) {
params := map[string]interface{}{
"modifier": 2.0,
"keys": []interface{}{65.0, 66.0},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = handleInputRPCDirect("keyboardReport", params)
}
}