Files
versitygw/rdma/rcserver/rcserver_cgo_linux_test.go
T
Eric EntzelandBen McClelland 3610eddf40 fix: add explicit RDMA build constraints
Gate native RDMA, cuObject, and cuobjclient implementations behind the
rdma build tag while keeping fallback stubs available for standard builds.
Preserve the separate cuobjclient_host configuration, clarify unsupported
platform errors, and update Makefile RDMA targets to pass the required tags
and disable VCS stamping.

Co-authored-by: Ben McClelland <ben.mcclelland@versity.com>
2026-09-15 11:03:51 -07:00

74 lines
2.6 KiB
Go

// Copyright 2026 Versity Software
// Copyright 2026 Gluesys Inc. and Jihyeon Gim
// This file is licensed under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//go:build linux && amd64 && cgo && rdma
package rcserver
import (
"errors"
"strings"
"testing"
"unsafe"
)
// heapSubstring returns a substring whose backing array is heap-allocated
// and whose data pointer is an interior pointer, mirroring how header
// strings reach the binding from the gateway routes.
func heapSubstring(value string) string {
const prefix = "prefix:"
backing := strings.Clone(prefix + value + ":suffix")
return backing[len(prefix) : len(prefix)+len(value)]
}
// TestPrepareHeapStringsReachCValidation calls the real Prepare wrapper
// with heap-backed strings. The request uses an invalid opcode so the C
// entrypoint returns RC_E_ARG from its argument validation before the
// server handle is dereferenced; the dummy handle below is never touched.
// Before the pinnedStrIn fix this call panics at the cgo pointer check;
// after it, the C argument validation runs and the error surfaces.
func TestPrepareHeapStringsReachCValidation(t *testing.T) {
const literalTarget = "/bucket1/obj1"
heapTarget := heapSubstring(literalTarget)
heapToken := heapSubstring(strings.Repeat("0", 88))
for _, tc := range []struct {
name, target, token string
}{
{"literal_control", literalTarget, ""},
{"heap_target", heapTarget, ""},
{"heap_token", literalTarget, heapToken},
{"both_heap", heapTarget, heapToken},
{"empty_control", "", ""},
} {
t.Run(tc.name, func(t *testing.T) {
var svc RCSvc
// Test-only opaque sentinel, not an initialized rc_server.
// Op=255 returns in C argument validation before the
// server pointer is dereferenced.
dummy := new(uint64)
*(*unsafe.Pointer)(unsafe.Pointer(&svc.srv)) = unsafe.Pointer(dummy)
resp, err := svc.Prepare(PrepareRequest{
Op: 255,
Size: 1,
Target: tc.target,
ClientToken: tc.token,
})
if resp != nil || !errors.Is(err, ErrArg) {
t.Fatalf("Prepare = (%v, %v), want (nil, ErrArg)", resp, err)
}
})
}
}