• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fadeevab / cocoon / 166589197

pending completion
166589197

push

github

Alexander Fadeev
Add deserialize_from and incorrect header tests

131 of 291 branches covered (45.02%)

Branch coverage included in aggregate %.

24 of 24 new or added lines in 1 file covered. (100.0%)

488 of 525 relevant lines covered (92.95%)

15.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.33
/src/format.rs
1
#[cfg(feature = "std")]
2
use std::io::Read;
3

4
use super::{
5
    error::Error,
6
    header::{CocoonHeader, CocoonVersion},
7
};
8

9
const HEADER_SIZE: usize = CocoonHeader::SIZE;
10
const TAG_SIZE: usize = 16;
11
const MAX_SIZE: usize = HEADER_SIZE + TAG_SIZE;
12

13
pub struct FormatPrefix {
14
    header: CocoonHeader,
15
    raw: [u8; MAX_SIZE],
16
    size: usize,
17
}
18

19
impl FormatPrefix {
20
    pub const SERIALIZE_SIZE: usize = MAX_SIZE;
21

22
    // The idea is that having additional extensions we shell put them in the constructor.
23
    // Meanwhile `tag` will be calculated later and it appears right on serialization.
24
    // Also parameters are moved into the object to evade additional copying.
25
    pub fn new(header: CocoonHeader) -> Self {
22✔
26
        let mut raw = [0u8; MAX_SIZE];
22✔
27
        let size;
28

29
        match header.version() {
22✔
30
            CocoonVersion::Version1 => {
31
                header.serialize_into(&mut raw);
22✔
32
                size = HEADER_SIZE + TAG_SIZE;
22✔
33
            }
34
        };
35

36
        FormatPrefix { header, raw, size }
22✔
37
    }
22✔
38

39
    pub fn serialize(mut self, tag: &[u8; TAG_SIZE]) -> [u8; Self::SERIALIZE_SIZE] {
22✔
40
        match self.header().version() {
22✔
41
            CocoonVersion::Version1 => (),
42
            // _ => panic!("Prefix can be serialized into the latest version only!"),
43
        }
44

45
        self.raw[HEADER_SIZE..HEADER_SIZE + TAG_SIZE].copy_from_slice(tag);
22✔
46
        self.raw
22✔
47
    }
22✔
48

49
    pub fn deserialize(start: &[u8]) -> Result<Self, Error> {
17✔
50
        let header = CocoonHeader::deserialize(&start)?;
18!
51

52
        let mut raw = [0u8; MAX_SIZE];
15✔
53
        let size: usize;
54

55
        match header.version() {
15✔
56
            CocoonVersion::Version1 => {
57
                if start.len() < HEADER_SIZE + TAG_SIZE {
15✔
58
                    return Err(Error::UnrecognizedFormat);
1✔
59
                }
60

61
                raw[..HEADER_SIZE].copy_from_slice(&start[..HEADER_SIZE]);
14✔
62
                raw[HEADER_SIZE..HEADER_SIZE + TAG_SIZE]
28✔
63
                    .copy_from_slice(&start[HEADER_SIZE..HEADER_SIZE + TAG_SIZE]);
14✔
64

65
                size = HEADER_SIZE + TAG_SIZE;
14✔
66
            }
67
        }
68

69
        Ok(FormatPrefix { header, raw, size })
14✔
70
    }
17✔
71

72
    #[cfg(feature = "std")]
73
    pub fn deserialize_from(reader: &mut impl Read) -> Result<Self, Error> {
63✔
74
        let mut raw = [0u8; MAX_SIZE];
63✔
75
        let size: usize;
76

77
        reader.read_exact(&mut raw[..HEADER_SIZE])?;
79!
78
        let header = CocoonHeader::deserialize(&raw)?;
33!
79

80
        match header.version() {
17✔
81
            CocoonVersion::Version1 => {
82
                reader.read_exact(&mut raw[HEADER_SIZE..HEADER_SIZE + TAG_SIZE])?;
17!
83
                size = HEADER_SIZE + TAG_SIZE;
2✔
84
            }
85
        }
86

87
        Ok(FormatPrefix { header, raw, size })
2✔
88
    }
63✔
89

90
    pub fn header(&self) -> &CocoonHeader {
46✔
91
        &self.header
46✔
92
    }
46✔
93

94
    pub fn prefix(&self) -> &[u8] {
35✔
95
        &self.raw[..HEADER_SIZE]
35✔
96
    }
35✔
97

98
    pub fn tag(&self) -> &[u8] {
14✔
99
        &self.raw[HEADER_SIZE..HEADER_SIZE + TAG_SIZE]
14✔
100
    }
14✔
101

102
    pub fn size(&self) -> usize {
20✔
103
        self.size
20✔
104
    }
20✔
105
}
106

107
#[cfg(test)]
108
mod test {
109
    use super::*;
110

111
    use std::io::Cursor;
112

113
    use crate::{CocoonConfig, CocoonHeader};
114

115
    #[test]
116
    fn format_prefix_good() {
2✔
117
        const RANDOM_ADD: usize = 12;
118
        let mut raw = [1u8; FormatPrefix::SERIALIZE_SIZE + RANDOM_ADD];
1✔
119

120
        CocoonHeader::new(CocoonConfig::default(), [0; 16], [0; 12], 0).serialize_into(&mut raw);
1✔
121

122
        let prefix = FormatPrefix::deserialize(&raw).expect("Deserialized container's prefix");
1✔
123

124
        assert_eq!(&raw[..HEADER_SIZE], prefix.prefix());
1!
125
        assert_eq!(&raw[HEADER_SIZE..HEADER_SIZE + TAG_SIZE], prefix.tag());
1!
126
        assert_eq!(prefix.size(), FormatPrefix::SERIALIZE_SIZE);
1!
127
    }
2✔
128

129
    #[test]
130
    fn format_prefix_short() {
2✔
131
        let mut raw = [1u8; FormatPrefix::SERIALIZE_SIZE];
1✔
132

133
        CocoonHeader::new(CocoonConfig::default(), [0; 16], [0; 12], 0).serialize_into(&mut raw);
1✔
134

135
        FormatPrefix::deserialize(&raw).expect("Deserialized container's prefix");
1✔
136

137
        match FormatPrefix::deserialize(&raw[0..FormatPrefix::SERIALIZE_SIZE - 1]) {
1✔
138
            Err(err) => match err {
1!
139
                Error::UnrecognizedFormat => (),
1!
140
                _ => panic!("Invalid error"),
×
141
            },
1✔
142
            Ok(_) => panic!("Cocoon prefix has not to be parsed"),
×
143
        };
144
    }
2✔
145

146
    #[test]
147
    fn format_version1() {
2✔
148
        assert_eq!(44 + 16, FormatPrefix::SERIALIZE_SIZE);
1✔
149

150
        let header = CocoonHeader::new(CocoonConfig::default(), [1; 16], [2; 12], 50);
1✔
151
        let prefix = FormatPrefix::new(header);
1✔
152
        let tag = [3; 16];
1✔
153

154
        assert_eq!(
1!
155
            [
1✔
156
                127, 192, 10, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
157
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 50, 3, 3, 3, 3, 3, 3, 3, 3, 3,
158
                3, 3, 3, 3, 3, 3, 3
159
            ][..],
160
            prefix.serialize(&tag)[..]
1✔
161
        );
162
    }
2✔
163

164
    #[test]
165
    fn format_prefix_deserialize_from() {
2✔
166
        let mut raw = [1u8; FormatPrefix::SERIALIZE_SIZE];
1✔
167

168
        CocoonHeader::new(CocoonConfig::default(), [0; 16], [0; 12], 0).serialize_into(&mut raw);
1✔
169

170
        let mut file = Cursor::new(&raw[..]);
1✔
171

172
        FormatPrefix::deserialize_from(&mut file).expect("Deserialized prefix");
1✔
173

174
        for i in 0..raw.len() - 1 {
60!
175
            let mut file = Cursor::new(&raw[0..i]);
59✔
176
            match FormatPrefix::deserialize_from(&mut file) {
59✔
177
                Err(_) => (),
59!
178
                _ => panic!("Short file cannot be deserialized"),
×
179
            }
180
        }
59✔
181
    }
2✔
182

183
    #[test]
184
    fn format_prefix_bad_prefix() {
2✔
185
        let raw = [1u8; FormatPrefix::SERIALIZE_SIZE];
1✔
186

187
        match FormatPrefix::deserialize(&raw) {
1✔
188
            Err(_) => (),
1!
189
            _ => panic!("Bad prefix is expected"),
×
190
        }
1✔
191

192
        let mut file = Cursor::new(&raw[..]);
1✔
193

194
        match FormatPrefix::deserialize_from(&mut file) {
1✔
195
            Err(_) => (),
1!
196
            _ => panic!("Bad prefix is expected"),
×
197
        }
198
    }
2✔
199
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2024 Coveralls, Inc