1 /*
2  *  Copyright (c) 2024, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "common/message.hpp"
30 #include "common/offset_range.hpp"
31 #include "instance/instance.hpp"
32 
33 #include "test_platform.h"
34 #include "test_util.hpp"
35 
36 namespace ot {
37 
TestOffsetRange(void)38 void TestOffsetRange(void)
39 {
40     Instance   *instance;
41     Message    *message;
42     OffsetRange offsetRange;
43 
44     instance = testInitInstance();
45     VerifyOrQuit(instance != nullptr);
46 
47     // Empty `OffsetRange`
48 
49     offsetRange.Clear();
50     VerifyOrQuit(offsetRange.GetOffset() == 0);
51     VerifyOrQuit(offsetRange.GetLength() == 0);
52     VerifyOrQuit(offsetRange.GetEndOffset() == 0);
53     VerifyOrQuit(offsetRange.IsEmpty());
54 
55     offsetRange.ShrinkLength(10);
56     VerifyOrQuit(offsetRange.GetOffset() == 0);
57     VerifyOrQuit(offsetRange.GetLength() == 0);
58     VerifyOrQuit(offsetRange.GetEndOffset() == 0);
59     VerifyOrQuit(offsetRange.IsEmpty());
60 
61     offsetRange.AdvanceOffset(20);
62     VerifyOrQuit(offsetRange.GetOffset() == 0);
63     VerifyOrQuit(offsetRange.GetLength() == 0);
64     VerifyOrQuit(offsetRange.GetEndOffset() == 0);
65     VerifyOrQuit(offsetRange.IsEmpty());
66 
67     // Empty `OffsetRange` with non-zero starting offset
68 
69     offsetRange.Init(100, 0);
70     VerifyOrQuit(offsetRange.GetOffset() == 100);
71     VerifyOrQuit(offsetRange.GetLength() == 0);
72     VerifyOrQuit(offsetRange.GetEndOffset() == 100);
73     VerifyOrQuit(offsetRange.IsEmpty());
74 
75     offsetRange.ShrinkLength(10);
76     VerifyOrQuit(offsetRange.GetOffset() == 100);
77     VerifyOrQuit(offsetRange.GetLength() == 0);
78     VerifyOrQuit(offsetRange.GetEndOffset() == 100);
79     VerifyOrQuit(offsetRange.IsEmpty());
80 
81     offsetRange.AdvanceOffset(20);
82     VerifyOrQuit(offsetRange.GetOffset() == 100);
83     VerifyOrQuit(offsetRange.GetLength() == 0);
84     VerifyOrQuit(offsetRange.GetEndOffset() == 100);
85     VerifyOrQuit(offsetRange.IsEmpty());
86 
87     // Non-empty `OffsetRange`
88 
89     offsetRange.Init(200, 10);
90     VerifyOrQuit(offsetRange.GetOffset() == 200);
91     VerifyOrQuit(offsetRange.GetLength() == 10);
92     VerifyOrQuit(offsetRange.GetEndOffset() == 210);
93     VerifyOrQuit(!offsetRange.IsEmpty());
94     VerifyOrQuit(offsetRange.Contains(10));
95     VerifyOrQuit(!offsetRange.Contains(11));
96 
97     offsetRange.ShrinkLength(10);
98     VerifyOrQuit(offsetRange.GetOffset() == 200);
99     VerifyOrQuit(offsetRange.GetLength() == 10);
100     VerifyOrQuit(offsetRange.GetEndOffset() == 210);
101 
102     offsetRange.ShrinkLength(20);
103     VerifyOrQuit(offsetRange.GetOffset() == 200);
104     VerifyOrQuit(offsetRange.GetLength() == 10);
105     VerifyOrQuit(offsetRange.GetEndOffset() == 210);
106 
107     offsetRange.ShrinkLength(5);
108     VerifyOrQuit(offsetRange.GetOffset() == 200);
109     VerifyOrQuit(offsetRange.GetLength() == 5);
110     VerifyOrQuit(offsetRange.GetEndOffset() == 205);
111     VerifyOrQuit(!offsetRange.Contains(10));
112     VerifyOrQuit(!offsetRange.Contains(6));
113     VerifyOrQuit(offsetRange.Contains(5));
114 
115     offsetRange.AdvanceOffset(4);
116     VerifyOrQuit(offsetRange.GetOffset() == 204);
117     VerifyOrQuit(offsetRange.GetLength() == 1);
118     VerifyOrQuit(offsetRange.GetEndOffset() == 205);
119     VerifyOrQuit(!offsetRange.IsEmpty());
120     VerifyOrQuit(offsetRange.Contains(1));
121     VerifyOrQuit(!offsetRange.Contains(2));
122 
123     offsetRange.AdvanceOffset(1);
124     VerifyOrQuit(offsetRange.GetOffset() == 205);
125     VerifyOrQuit(offsetRange.GetLength() == 0);
126     VerifyOrQuit(offsetRange.GetEndOffset() == 205);
127     VerifyOrQuit(offsetRange.IsEmpty());
128 
129     // `InitFromRange()`
130 
131     offsetRange.InitFromRange(300, 400);
132     VerifyOrQuit(offsetRange.GetOffset() == 300);
133     VerifyOrQuit(offsetRange.GetLength() == 100);
134     VerifyOrQuit(offsetRange.GetEndOffset() == 400);
135     VerifyOrQuit(!offsetRange.IsEmpty());
136     VerifyOrQuit(offsetRange.Contains(100));
137     VerifyOrQuit(!offsetRange.Contains(101));
138 
139     offsetRange.AdvanceOffset(101);
140     VerifyOrQuit(offsetRange.GetOffset() == 400);
141     VerifyOrQuit(offsetRange.GetLength() == 0);
142     VerifyOrQuit(offsetRange.GetEndOffset() == 400);
143     VerifyOrQuit(offsetRange.IsEmpty());
144 
145     // Init from a `Message` from offset or full length
146 
147     message = instance->Get<MessagePool>().Allocate(Message::kTypeOther);
148     VerifyOrQuit(message != nullptr);
149 
150     SuccessOrQuit(message->SetLength(120));
151     VerifyOrQuit(message->GetOffset() == 0);
152 
153     offsetRange.InitFromMessageOffsetToEnd(*message);
154     VerifyOrQuit(offsetRange.GetOffset() == 0);
155     VerifyOrQuit(offsetRange.GetLength() == 120);
156     VerifyOrQuit(offsetRange.GetEndOffset() == 120);
157 
158     offsetRange.InitFromMessageFullLength(*message);
159     VerifyOrQuit(offsetRange.GetOffset() == 0);
160     VerifyOrQuit(offsetRange.GetLength() == 120);
161     VerifyOrQuit(offsetRange.GetEndOffset() == 120);
162 
163     message->SetOffset(40);
164     VerifyOrQuit(message->GetOffset() == 40);
165 
166     offsetRange.InitFromMessageOffsetToEnd(*message);
167     VerifyOrQuit(offsetRange.GetOffset() == 40);
168     VerifyOrQuit(offsetRange.GetLength() == 80);
169     VerifyOrQuit(offsetRange.GetEndOffset() == 120);
170 
171     offsetRange.InitFromMessageFullLength(*message);
172     VerifyOrQuit(offsetRange.GetOffset() == 0);
173     VerifyOrQuit(offsetRange.GetLength() == 120);
174     VerifyOrQuit(offsetRange.GetEndOffset() == 120);
175 
176     message->Free();
177     testFreeInstance(instance);
178 }
179 
180 } // namespace ot
181 
main(void)182 int main(void)
183 {
184     ot::TestOffsetRange();
185     printf("All tests passed\n");
186     return 0;
187 }
188