1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #![allow(clippy::unwrap_used)]
16
17 use alloc::boxed::Box;
18
19 use crate::header::VERSION_HEADER_V0_UNENCRYPTED;
20 use crate::legacy::data_elements::actions::{ActionBits, ActionsDataElement};
21 use crate::legacy::serialize::{encode_de_header, AdvBuilder, UnencryptedEncoder};
22 use crate::legacy::Plaintext;
23
24 use super::*;
25
26 #[test]
dynamic_de_works()27 fn dynamic_de_works() {
28 let mut builder = AdvBuilder::new(UnencryptedEncoder);
29
30 let actions: Box<dyn SerializeDataElement<Plaintext>> =
31 Box::new(ActionsDataElement::<Plaintext>::from(ActionBits::default()));
32 builder.add_data_element(DynamicSerializeDataElement::from(actions.as_ref())).unwrap();
33
34 assert_eq!(
35 &[
36 VERSION_HEADER_V0_UNENCRYPTED,
37 encode_de_header(
38 ActionsDataElement::<Plaintext>::DE_TYPE_CODE,
39 DeEncodedLength::from(1),
40 ),
41 0
42 ],
43 builder.into_advertisement().unwrap().as_slice()
44 );
45 }
46
47 pub(in crate::legacy) mod macros {
48 use alloc::vec::Vec;
49
50 use crate::legacy::data_elements::de_type::DataElementType;
51 use crate::legacy::deserialize::{DeIterator, DeserializedDataElement};
52 use crate::legacy::serialize::SerializedDataElement;
53 use crate::legacy::PacketFlavor;
54
55 /// Test method body that creates an array, deserializes it into a DE, serializes it,
56 /// and asserts that the same bytes are produced.
57 ///
58 /// Evaluates to (the deserialized DE, the serialized form of the DE).
59 macro_rules! de_roundtrip_test {
60 ($de_type:ty, $type_variant:ident, $de_variant:ident, $flavor:ty, $bytes:expr) => {{
61 let parsed_de_enum =
62 crate::legacy::data_elements::tests::macros::construct_and_parse_de::<
63 $flavor,
64 >(crate::legacy::data_elements::de_type::DataElementType::$type_variant, &$bytes);
65 if let crate::legacy::deserialize::DeserializedDataElement::$de_variant(de) =
66 parsed_de_enum
67 {
68 // skip DE header byte
69 let expected = <$de_type as crate::legacy::data_elements::DeserializeDataElement>
70 ::deserialize::<$flavor>(&$bytes.as_slice()[1..]).unwrap();
71 assert_eq!(expected, de);
72
73 let serialized = crate::legacy::serialize::tests::serialize::<$flavor, _>(&de);
74 assert_eq!($bytes.as_slice(), serialized.as_slice());
75
76 (de, serialized)
77 } else {
78 panic!("Unexpected variant: {:?}", parsed_de_enum);
79 }
80 }};
81 }
82
83 pub(in crate::legacy) use de_roundtrip_test;
84
85 /// Construct the serialized DE and parse it
construct_and_parse_de<F>( de_type: DataElementType, contents: &SerializedDataElement, ) -> DeserializedDataElement<F> where F: PacketFlavor,86 pub(in crate::legacy) fn construct_and_parse_de<F>(
87 de_type: DataElementType,
88 contents: &SerializedDataElement,
89 ) -> DeserializedDataElement<F>
90 where
91 F: PacketFlavor,
92 {
93 let mut plain_des =
94 DeIterator::new(contents.as_slice()).collect::<Result<Vec<_>, _>>().unwrap();
95 assert_eq!(1, plain_des.len());
96 let de = plain_des.swap_remove(0);
97 assert_eq!(
98 de_type,
99 match de {
100 DeserializedDataElement::Actions(_) => DataElementType::Actions,
101 DeserializedDataElement::TxPower(_) => DataElementType::TxPower,
102 }
103 );
104 de
105 }
106 }
107
108 mod coverage_gaming {
109 use alloc::format;
110
111 use nom::error;
112 use nom::error::ParseError;
113
114 use crate::legacy::data_elements::de_type::DeTypeCode;
115 use crate::legacy::data_elements::{DataElementDeserializeError, DataElementSerializeError};
116
117 #[test]
data_element_serialize_error_debug_eq_clone()118 fn data_element_serialize_error_debug_eq_clone() {
119 let _ = format!("{:?}", DataElementSerializeError::InsufficientSpace.clone());
120 assert_eq!(
121 DataElementSerializeError::InsufficientSpace,
122 DataElementSerializeError::InsufficientSpace
123 );
124 }
125
126 #[test]
data_element_deserialize_error_debug_clone()127 fn data_element_deserialize_error_debug_clone() {
128 let _ = format!("{:?}", DataElementDeserializeError::InvalidStructure.clone());
129 }
130
131 #[test]
data_element_deserialize_error_append()132 fn data_element_deserialize_error_append() {
133 assert_eq!(
134 DataElementDeserializeError::InvalidStructure,
135 DataElementDeserializeError::append(
136 &[0_u8],
137 error::ErrorKind::CrLf,
138 DataElementDeserializeError::InvalidDeType {
139 de_type: DeTypeCode::try_from(10).unwrap()
140 },
141 )
142 );
143 }
144 }
145
146 pub(in crate::legacy) mod test_des {
147 use alloc::vec;
148
149 use rand::distributions;
150 use strum_macros::EnumIter;
151
152 use crate::legacy::data_elements::de_type::{
153 DeActualLength, DeEncodedLength, DeTypeCode, MAX_DE_ENCODED_LEN,
154 };
155 use crate::legacy::data_elements::{
156 DataElementDeserializeError, DataElementSerializationBuffer, DataElementSerializeError,
157 DeserializeDataElement, LengthMapper, SerializeDataElement,
158 };
159 use crate::legacy::deserialize::{DataElementDeserializer, LengthError, RawDataElement};
160 use crate::legacy::serialize::tests::helpers::{LongDataElement, ShortDataElement};
161 use crate::legacy::{PacketFlavor, NP_MAX_DE_CONTENT_LEN};
162 use crate::private::Sealed;
163
164 /// A [DataElementDeserializer] that can deserialize the test stubs [ShortDataElement] and
165 /// [LongDataElement].
166 pub(in crate::legacy) struct TestDeDeserializer;
167
168 impl DataElementDeserializer for TestDeDeserializer {
169 type DeTypeDisambiguator = TestDataElementType;
170 type Deserialized<F: PacketFlavor> = TestDataElement;
171
map_encoded_len_to_actual_len( de_type: DeTypeCode, encoded_len: DeEncodedLength, ) -> Result<(Self::DeTypeDisambiguator, DeActualLength), LengthError>172 fn map_encoded_len_to_actual_len(
173 de_type: DeTypeCode,
174 encoded_len: DeEncodedLength,
175 ) -> Result<(Self::DeTypeDisambiguator, DeActualLength), LengthError> {
176 match de_type {
177 ShortDataElement::DE_TYPE_CODE => {
178 <ShortDataElement as DeserializeDataElement>::LengthMapper::map_encoded_len_to_actual_len(encoded_len)
179 .map(|l| (TestDataElementType::Short, l))
180 .map_err(|e| e.into())
181 }
182 LongDataElement::DE_TYPE_CODE => {
183 <LongDataElement as DeserializeDataElement>::LengthMapper::map_encoded_len_to_actual_len(encoded_len)
184 .map(|l| (TestDataElementType::Long, l))
185 .map_err(|e| e.into())
186 }
187 _ => Err(LengthError::InvalidType),
188 }
189 }
190
deserialize_de<F: PacketFlavor>( raw_de: RawDataElement<Self>, ) -> Result<Self::Deserialized<F>, DataElementDeserializeError>191 fn deserialize_de<F: PacketFlavor>(
192 raw_de: RawDataElement<Self>,
193 ) -> Result<Self::Deserialized<F>, DataElementDeserializeError> {
194 match raw_de.de_type {
195 TestDataElementType::Short => {
196 ShortDataElement::deserialize::<F>(raw_de.contents).map(TestDataElement::Short)
197 }
198 TestDataElementType::Long => {
199 LongDataElement::deserialize::<F>(raw_de.contents).map(TestDataElement::Long)
200 }
201 }
202 }
203 }
204
205 #[derive(EnumIter, Debug, Clone, Copy)]
206 pub(in crate::legacy) enum TestDataElementType {
207 Short,
208 Long,
209 }
210
211 #[derive(Debug, PartialEq, Eq, Clone)]
212 pub(in crate::legacy) enum TestDataElement {
213 Short(ShortDataElement),
214 Long(LongDataElement),
215 }
216
217 impl From<ShortDataElement> for TestDataElement {
from(value: ShortDataElement) -> Self218 fn from(value: ShortDataElement) -> Self {
219 Self::Short(value)
220 }
221 }
222
223 impl From<LongDataElement> for TestDataElement {
from(value: LongDataElement) -> Self224 fn from(value: LongDataElement) -> Self {
225 Self::Long(value)
226 }
227 }
228
229 impl Sealed for TestDataElement {}
230
231 // Not representative of how the main [DeserializedDataElement] would be used, but handy
232 // in tests to be able to directly serialize the deserialized representation
233 impl<F: PacketFlavor> SerializeDataElement<F> for TestDataElement {
de_type_code(&self) -> DeTypeCode234 fn de_type_code(&self) -> DeTypeCode {
235 match self {
236 TestDataElement::Short(s) => {
237 <ShortDataElement as SerializeDataElement<F>>::de_type_code(s)
238 }
239 TestDataElement::Long(l) => {
240 <LongDataElement as SerializeDataElement<F>>::de_type_code(l)
241 }
242 }
243 }
244
map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength245 fn map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength {
246 match self {
247 TestDataElement::Short(s) => {
248 <ShortDataElement as SerializeDataElement<F>>::map_actual_len_to_encoded_len(
249 s, actual_len,
250 )
251 }
252 TestDataElement::Long(l) => {
253 <LongDataElement as SerializeDataElement<F>>::map_actual_len_to_encoded_len(
254 l, actual_len,
255 )
256 }
257 }
258 }
259
serialize_contents( &self, sink: &mut DataElementSerializationBuffer, ) -> Result<(), DataElementSerializeError>260 fn serialize_contents(
261 &self,
262 sink: &mut DataElementSerializationBuffer,
263 ) -> Result<(), DataElementSerializeError> {
264 match self {
265 TestDataElement::Short(s) => {
266 <ShortDataElement as SerializeDataElement<F>>::serialize_contents(s, sink)
267 }
268 TestDataElement::Long(l) => {
269 <LongDataElement as SerializeDataElement<F>>::serialize_contents(l, sink)
270 }
271 }
272 }
273 }
274
275 impl distributions::Distribution<ShortDataElement> for distributions::Standard {
sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> ShortDataElement276 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> ShortDataElement {
277 let len = rng.gen_range(0_usize..MAX_DE_ENCODED_LEN.into());
278 let mut data = vec![0; len];
279 rng.fill(&mut data[..]);
280 ShortDataElement::new(data)
281 }
282 }
283
284 impl distributions::Distribution<LongDataElement> for distributions::Standard {
sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> LongDataElement285 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> LongDataElement {
286 let len = rng.gen_range(LongDataElement::OFFSET..NP_MAX_DE_CONTENT_LEN);
287 let mut data = vec![0; len];
288 rng.fill(&mut data[..]);
289 LongDataElement::new(data)
290 }
291 }
292
293 /// Generate a random instance of the requested de type, or `None` if that type does not support
294 /// plaintext.
random_test_de<R>(de_type: TestDataElementType, rng: &mut R) -> TestDataElement where R: rand::Rng,295 pub(crate) fn random_test_de<R>(de_type: TestDataElementType, rng: &mut R) -> TestDataElement
296 where
297 R: rand::Rng,
298 {
299 match de_type {
300 TestDataElementType::Short => TestDataElement::Short(rng.gen()),
301 TestDataElementType::Long => TestDataElement::Long(rng.gen()),
302 }
303 }
304 }
305