blob: 85c26326e6795800ddeea9b0ea178270e6ebedaf [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/ddk/driver.h>
#include <zxtest/zxtest.h>
#include "binding_internal.h"
#include "coordinator.h"
#include "src/devices/lib/bind/ffi_bindings.h"
// Tests for matching device properties to the new bytecode.
bool match_bind_rules(const uint8_t* bytecode, const zx_device_prop_t* props,
const StrProperty* str_props, size_t bytecode_sz, size_t props_sz,
size_t str_props_sz, uint32_t protocol_id, bool autobind) {
auto driver = Driver();
driver.bytecode_version = 2;
driver.binding_size = bytecode_sz;
auto bytecode_arr = std::make_unique<uint8_t[]>(bytecode_sz);
if (bytecode) {
memcpy(bytecode_arr.get(), bytecode, bytecode_sz * sizeof(bytecode[0]));
}
driver.binding = std::unique_ptr<uint8_t[]>(bytecode_arr.release());
fbl::Array<zx_device_prop_t> properties(new zx_device_prop_t[props_sz], props_sz);
if (props) {
memcpy(properties.data(), props, sizeof(props[0]) * props_sz);
}
fbl::Array<StrProperty> str_properties(new StrProperty[str_props_sz], str_props_sz);
if (str_props) {
memcpy(str_properties.data(), str_props, sizeof(str_props[0]) * str_props_sz);
}
return can_driver_bind(&driver, protocol_id, std::move(properties), std::move(str_properties),
autobind);
}
TEST(BindingV2Test, SingleAbortInstruction) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x01, 0x0, 0x0, 0x0, // Instruction header
0x30 // Abort instruction
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), 0, 5, false));
}
TEST(BindingV2Test, NoBindRules) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0, 0x0, 0x0, 0x0 // Instruction header
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), 0, 5, false));
}
TEST(BindingV2Test, MatchDeviceProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{4, 0, 3}, zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), 0, 5, false));
}
TEST(BindingV2Test, MismatchDeviceProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 20}};
const StrProperty kStrProperties[] = {};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), 0, 5, false));
}
TEST(BindingV2Test, NoDevicePropertiesWithMismatchProtocolId) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x01, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {};
const StrProperty kStrProperties[] = {};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode), 0, 0,
5, false));
}
TEST(BindingV2Test, NoDevicePropertiesWithMatchingProtocolId) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x01, 0x0, 0x0, 0x0, 0x01, 0x05, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {};
const StrProperty kStrProperties[] = {};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode), 0, 0,
5, false));
}
TEST(BindingV2Test, NoDevicePropertiesWithMismatchAutobind) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x02, 0x0, 0x0, 0x0, 0x01, 0x01, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {};
const StrProperty kStrProperties[] = {};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode), 0, 0,
5, false));
}
TEST(BindingV2Test, NoDevicePropertiesWithMatchingAutobind) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x02, 0x0, 0x0, 0x0, 0x01, 0x01, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {};
const StrProperty kStrProperties[] = {};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode), 0, 0,
5, true));
}
TEST(BindingV2Test, MatchDeviceStringProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x36, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x03, 0x0, 0x0, 0x0, // "coot" symbol key (3)
0x63, 0x6F, 0x6F, 0x74, 0x0, // "coot" string literal
0x04, 0x0, 0x0, 0x0, // "ibis" symbol key (4)
0x69, 0x62, 0x69, 0x73, 0x0, // "ibis" string literal
0x05, 0x0, 0x0, 0x0, // "crow" symbol key (5)
0x63, 0x72, 0x6F, 0x77, 0x0, // "crow" string literal
0x06, 0x0, 0x0, 0x0, // "hawk" symbol key (6)
0x68, 0x61, 0x77, 0x6B, 0x0, // "hawk" string literal
0x49, 0x4E, 0x53, 0x54, 0x2C, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x02, 0x02, 0x0, 0x0, 0x0, // "rail" == "ruff"
0x01, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x01, 0x0, 0x0, 0x0, // "ibis" == true
0x01, 0x0, 0x03, 0x0, 0x0, 0x0, 0x01, 0x08, 0x0, 0x0, 0x0, // "coot" == 8
0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x04, 0x06, 0x0, 0x0, 0x0, // "crow" == "hawk"
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {
StrProperty{
.key = "woodpecker",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "sapsucker"}},
StrProperty{.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "ruff"}},
StrProperty{.key = "coot", .value = static_cast<uint32_t>(8)},
StrProperty{.key = "ibis", .value = true},
StrProperty{.key = "crow",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::Enum>, "hawk"}},
};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MismatchDeviceStringPropertyWStringValue) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x02, 0x02, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {StrProperty{
.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "coot"}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MismatchDeviceStringPropertyWIntValue) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x01, 0x08, 0x0, 0x0, 0x0, // "rail" == 8
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {
StrProperty{.key = "rail", .value = static_cast<uint32_t>(5)}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MismatchDeviceStringPropertyWBoolValue) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x03, 0x08, 0x0, 0x0, 0x0, // "ruff" == true
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {StrProperty{.key = "ruff", .value = false}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MismatchDeviceStringPropertyWEnumValue) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x04, 0x02, 0x0, 0x0, 0x0, // Equal instruction
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {
StrProperty{.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::Enum>, "coot"}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MatchDevicePropertyAndStringProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x36, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x03, 0x0, 0x0, 0x0, // "coot" symbol key (3)
0x63, 0x6F, 0x6F, 0x74, 0x0, // "coot" string literal
0x04, 0x0, 0x0, 0x0, // "ibis" symbol key (4)
0x69, 0x62, 0x69, 0x73, 0x0, // "ibis" string literal
0x05, 0x0, 0x0, 0x0, // "crow" symbol key (5)
0x63, 0x72, 0x6F, 0x77, 0x0, // "crow" string literal
0x06, 0x0, 0x0, 0x0, // "hawk" symbol key (6)
0x68, 0x61, 0x77, 0x6B, 0x0, // "hawk" string literal
0x49, 0x4E, 0x53, 0x54, 0x37, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x02, 0x02, 0x0, 0x0, 0x0, // "rail" == "ruff"
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // 5 == 2
0x01, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x01, 0x0, 0x0, 0x0, // "ibis" == true
0x01, 0x0, 0x03, 0x0, 0x0, 0x0, 0x01, 0x08, 0x0, 0x0, 0x0, // "coot" == 8
0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x04, 0x06, 0x0, 0x0, 0x0, // "crow" == "hawk"
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {
StrProperty{
.key = "woodpecker",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "sapsucker"}},
StrProperty{.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "ruff"}},
StrProperty{.key = "coot", .value = static_cast<uint32_t>(8)},
StrProperty{.key = "ibis", .value = true},
StrProperty{.key = "crow",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::Enum>, "hawk"}},
};
ASSERT_TRUE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MatchDevicePropertyMismatchStringProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x16, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x02, 0x02, 0x0, 0x0, 0x0, // "rail" == "ruff"
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // 5 == 2
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
const StrProperty kStrProperties[] = {StrProperty{
.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "coot"}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, MismatchDevicePropertyMatchStringProperty) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x12, 0x0, 0x0, 0x0, // Symbol table header
0x01, 0x0, 0x0, 0x0, // "rail" symbol key (1)
0x72, 0x61, 0x69, 0x6c, 0x0, // "rail" string literal
0x02, 0x0, 0x0, 0x0, // "ruff" symbol key (2)
0x72, 0x75, 0x66, 0x66, 0x0, // "ruff" string literal
0x49, 0x4E, 0x53, 0x54, 0x16, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x0, 0x01, 0x0, 0x0, 0x0, 0x02, 0x02, 0x0, 0x0, 0x0, // "rail" == "ruff"
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // 5 == 2
};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 3}};
const StrProperty kStrProperties[] = {StrProperty{
.key = "rail",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "ruff"}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kStrProperties), 5, false));
}
TEST(BindingV2Test, StringPropertyNotInUnicode) {
const uint8_t kBytecode[] = {
0x42, 0x49, 0x4E, 0x44, 0x02, 0x0, 0x0, 0x0, // Bind header
0x53, 0x59, 0x4E, 0x42, 0x0, 0x0, 0x0, 0x0, // Symbol table header
0x49, 0x4E, 0x53, 0x54, 0x0B, 0x0, 0x0, 0x0, // Instruction header
0x01, 0x01, 0x05, 0x0, 0x0, 0x0, 0x01, 0x02, 0x0, 0x0, 0x0, // 5 == 2
};
// The device properties match the equal instruction.
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 2}};
// String properties containing invalid unicode characters in the key.
const char kInvalidKey[] = {static_cast<char>(0xC0), 0};
const StrProperty kInvalidStrProperties[] = {StrProperty{
.key = kInvalidKey,
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, "honeyeater"}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kInvalidStrProperties, std::size(kBytecode),
std::size(kProperties), std::size(kInvalidStrProperties), 5,
false));
// String properties containing invalid unicode characters in the value.
const char kInvalidValue[] = {static_cast<char>(0xFF), 0};
const StrProperty kInvalidStrProperties2[] = {StrProperty{
.key = "wattlebird",
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, kInvalidValue}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kInvalidStrProperties2,
std::size(kBytecode), std::size(kProperties),
std::size(kInvalidStrProperties2), 5, false));
// String properties containing invalid unicode characters in the key and value.
const StrProperty kInvalidStrProperties3[] = {StrProperty{
.key = kInvalidKey,
.value = StrPropertyValue{std::in_place_index<StrPropValueType::String>, kInvalidValue}}};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kInvalidStrProperties3,
std::size(kBytecode), std::size(kProperties),
std::size(kInvalidStrProperties3), 5, false));
}
TEST(BindingV2Test, EmptyBytecode) {
const uint8_t kBytecode[] = {};
const zx_device_prop_t kProperties[] = {zx_device_prop_t{5, 0, 20}};
const StrProperty kStrProperties[] = {};
ASSERT_FALSE(match_bind_rules(kBytecode, kProperties, kStrProperties, 0, std::size(kProperties),
0, 5, false));
}