forked from lei.chen/myxce
feat: P1-1 handle resource value push via OPCode_notify
Add OPCode_notify handler in go_push_handler top-level switch (not inside handlePush) to receive resource value updates from the controller via xce_notify_data_t/schedUpdateResvals. - Add 8 CGO union accessors for xce_val_t (which, i32, i64, u32, u64, fval, str, bool) since CGO cannot access union fields - Add handleNotifyData() dispatching NotifyData_data_schedUpdateResvals events, iterating xce_resval_list_t and calling cResvalToDistribution - Add cResvalToDistribution in convert.go with 7 separate switch cases for Value_u_* union discriminants (no combining i32/i64) - Add rawResvalData + rawResvalToDistribution pure-Go version in convert_pure.go for testability without CGO - Add 10 TDD tests covering all 7 value types, nil val guard, unknown discriminant, and boolean false - All 42 backend tests passing
This commit is contained in:
parent
dc029a6d14
commit
bc3103a6d5
5 changed files with 365 additions and 23 deletions
|
|
@ -497,6 +497,188 @@ func TestRawHostConfigToModel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_FloatValue(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "r1m",
|
||||
host: "node01",
|
||||
valWhich: 5, // Value_u_fvalue
|
||||
fval: 3.14,
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for fvalue")
|
||||
}
|
||||
if got.ResourceName != "r1m" {
|
||||
t.Errorf("ResourceName: got %q, want %q", got.ResourceName, "r1m")
|
||||
}
|
||||
if got.Location != "node01" {
|
||||
t.Errorf("Location: got %q, want %q", got.Location, "node01")
|
||||
}
|
||||
if !got.IsDynamic {
|
||||
t.Errorf("IsDynamic: got false, want true")
|
||||
}
|
||||
if got.ValueType != int(models.NUMERIC) {
|
||||
t.Errorf("ValueType: got %d, want %d (NUMERIC)", got.ValueType, models.NUMERIC)
|
||||
}
|
||||
if got.NumericValue != 3.14 {
|
||||
t.Errorf("NumericValue: got %f, want 3.14", got.NumericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_StringValue(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "type",
|
||||
host: "node02",
|
||||
valWhich: 4, // Value_u_svalue
|
||||
sval: "LINUX64",
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for svalue")
|
||||
}
|
||||
if got.ValueType != int(models.STRING) {
|
||||
t.Errorf("ValueType: got %d, want %d (STRING)", got.ValueType, models.STRING)
|
||||
}
|
||||
if got.StringValue != "LINUX64" {
|
||||
t.Errorf("StringValue: got %q, want %q", got.StringValue, "LINUX64")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_BooleanValue(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "available",
|
||||
host: "node03",
|
||||
valWhich: 6, // Value_u_bvalue
|
||||
bval: true,
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for bvalue")
|
||||
}
|
||||
if got.ValueType != int(models.BOOLEAN) {
|
||||
t.Errorf("ValueType: got %d, want %d (BOOLEAN)", got.ValueType, models.BOOLEAN)
|
||||
}
|
||||
if !got.BooleanValue {
|
||||
t.Errorf("BooleanValue: got false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_Int32Value(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "slots",
|
||||
host: "node04",
|
||||
valWhich: 0, // Value_u_ivalue32
|
||||
i32: 16,
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for ivalue32")
|
||||
}
|
||||
if got.ValueType != int(models.NUMERIC) {
|
||||
t.Errorf("ValueType: got %d, want %d (NUMERIC)", got.ValueType, models.NUMERIC)
|
||||
}
|
||||
if got.NumericValue != 16 {
|
||||
t.Errorf("NumericValue: got %f, want 16", got.NumericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_Int64Value(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "bigcounter",
|
||||
host: "node05",
|
||||
valWhich: 2, // Value_u_ivalue64
|
||||
i64: 9223372036854775807, // max int64
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for ivalue64")
|
||||
}
|
||||
if got.ValueType != int(models.NUMERIC) {
|
||||
t.Errorf("ValueType: got %d, want %d (NUMERIC)", got.ValueType, models.NUMERIC)
|
||||
}
|
||||
if got.NumericValue != float64(int64(9223372036854775807)) {
|
||||
t.Errorf("NumericValue: got %f, want max int64 as float64", got.NumericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_Uint32Value(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "uint32res",
|
||||
host: "node06",
|
||||
valWhich: 1, // Value_u_uvalue32
|
||||
u32: 4294967295, // max uint32
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for uvalue32")
|
||||
}
|
||||
if got.ValueType != int(models.NUMERIC) {
|
||||
t.Errorf("ValueType: got %d, want %d", got.ValueType, models.NUMERIC)
|
||||
}
|
||||
if got.NumericValue != float64(uint32(4294967295)) {
|
||||
t.Errorf("NumericValue: got %f, want 4294967295", got.NumericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_Uint64Value(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "uint64res",
|
||||
host: "node07",
|
||||
valWhich: 3, // Value_u_uvalue64
|
||||
u64: 18446744073709551615, // max uint64
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for uvalue64")
|
||||
}
|
||||
if got.ValueType != int(models.NUMERIC) {
|
||||
t.Errorf("ValueType: got %d, want %d", got.ValueType, models.NUMERIC)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_NilVal(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "nilres",
|
||||
host: "node08",
|
||||
valNil: true,
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got != nil {
|
||||
t.Errorf("expected nil for nil val, got %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_UnknownDiscriminant(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "unkres",
|
||||
host: "node09",
|
||||
valWhich: 99, // unknown
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got != nil {
|
||||
t.Errorf("expected nil for unknown discriminant, got %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawResvalToDistribution_BooleanFalse(t *testing.T) {
|
||||
r := rawResvalData{
|
||||
name: "available",
|
||||
host: "node10",
|
||||
valWhich: 6, // Value_u_bvalue
|
||||
bval: false,
|
||||
}
|
||||
got := rawResvalToDistribution(r)
|
||||
if got == nil {
|
||||
t.Fatal("expected non-nil result for bvalue false")
|
||||
}
|
||||
if got.ValueType != int(models.BOOLEAN) {
|
||||
t.Errorf("ValueType: got %d, want %d (BOOLEAN)", got.ValueType, models.BOOLEAN)
|
||||
}
|
||||
if got.BooleanValue {
|
||||
t.Errorf("BooleanValue: got true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawClusterToModel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -506,9 +688,9 @@ func TestRawClusterToModel(t *testing.T) {
|
|||
{
|
||||
name: "normal values",
|
||||
raw: rawClusterData{
|
||||
name: "mycluster",
|
||||
heartbeatInterval: 30,
|
||||
vcpus: 16,
|
||||
name: "mycluster",
|
||||
heartbeatInterval: 30,
|
||||
vcpus: 16,
|
||||
inactiveHeartbeatCount: 3,
|
||||
},
|
||||
want: models.ClusterInfo{
|
||||
|
|
@ -536,9 +718,9 @@ func TestRawClusterToModel(t *testing.T) {
|
|||
{
|
||||
name: "built-in fields remain zero",
|
||||
raw: rawClusterData{
|
||||
name: "test",
|
||||
heartbeatInterval: 45,
|
||||
vcpus: 32,
|
||||
name: "test",
|
||||
heartbeatInterval: 45,
|
||||
vcpus: 32,
|
||||
inactiveHeartbeatCount: 2,
|
||||
},
|
||||
want: models.ClusterInfo{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue