1 /*
2  *  Copyright (c) 2020, 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 <openthread/platform/flash.h>
30 
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "utils/flash.hpp"
36 
37 #include "test_platform.h"
38 #include "test_util.h"
39 
40 namespace ot {
41 
TestFlash(void)42 void TestFlash(void)
43 {
44 #if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
45     uint8_t readBuffer[256];
46     uint8_t writeBuffer[256];
47 
48     Instance *instance = testInitInstance();
49     Flash     flash(*instance);
50 
51     for (uint32_t i = 0; i < sizeof(readBuffer); i++)
52     {
53         readBuffer[i] = i & 0xff;
54     }
55 
56     flash.Init();
57 
58     // No records in settings
59 
60     VerifyOrQuit(flash.Delete(0, 0) == kErrorNotFound);
61     VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == kErrorNotFound);
62 
63     // Multiple records with different keys
64 
65     for (uint16_t key = 0; key < 16; key++)
66     {
67         uint16_t length = key;
68 
69         SuccessOrQuit(flash.Add(key, writeBuffer, length));
70     }
71 
72     for (uint16_t key = 0; key < 16; key++)
73     {
74         uint16_t length = key;
75 
76         SuccessOrQuit(flash.Get(key, 0, readBuffer, &length));
77         VerifyOrQuit(length == key, "Get() did not return expected length");
78         VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
79     }
80 
81     for (uint16_t key = 0; key < 16; key++)
82     {
83         SuccessOrQuit(flash.Delete(key, 0));
84     }
85 
86     for (uint16_t key = 0; key < 16; key++)
87     {
88         VerifyOrQuit(flash.Delete(key, 0) == kErrorNotFound);
89         VerifyOrQuit(flash.Get(key, 0, nullptr, nullptr) == kErrorNotFound);
90     }
91 
92     // Multiple records with the same key
93 
94     for (uint16_t index = 0; index < 16; index++)
95     {
96         uint16_t length = index;
97 
98         SuccessOrQuit(flash.Add(0, writeBuffer, length));
99     }
100 
101     for (uint16_t index = 0; index < 16; index++)
102     {
103         uint16_t length = index;
104 
105         SuccessOrQuit(flash.Get(0, index, readBuffer, &length));
106         VerifyOrQuit(length == index, "Get() did not return expected length");
107         VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
108     }
109 
110     for (uint16_t index = 0; index < 16; index++)
111     {
112         SuccessOrQuit(flash.Delete(0, 0));
113     }
114 
115     VerifyOrQuit(flash.Delete(0, 0) == kErrorNotFound);
116     VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == kErrorNotFound);
117 
118     // Multiple records with the same key
119 
120     for (uint16_t index = 0; index < 16; index++)
121     {
122         uint16_t length = index;
123 
124         if ((index % 4) == 0)
125         {
126             SuccessOrQuit(flash.Set(0, writeBuffer, length));
127         }
128         else
129         {
130             SuccessOrQuit(flash.Add(0, writeBuffer, length));
131         }
132     }
133 
134     for (uint16_t index = 0; index < 4; index++)
135     {
136         uint16_t length = index + 12;
137 
138         SuccessOrQuit(flash.Get(0, index, readBuffer, &length));
139         VerifyOrQuit(length == (index + 12), "Get() did not return expected length");
140         VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
141     }
142 
143     for (uint16_t index = 0; index < 4; index++)
144     {
145         SuccessOrQuit(flash.Delete(0, 0));
146     }
147 
148     VerifyOrQuit(flash.Delete(0, 0) == kErrorNotFound);
149     VerifyOrQuit(flash.Get(0, 0, nullptr, nullptr) == kErrorNotFound);
150 
151     // Wipe()
152 
153     for (uint16_t key = 0; key < 16; key++)
154     {
155         uint16_t length = key;
156 
157         SuccessOrQuit(flash.Add(key, writeBuffer, length));
158     }
159 
160     flash.Wipe();
161 
162     for (uint16_t key = 0; key < 16; key++)
163     {
164         VerifyOrQuit(flash.Delete(key, 0) == kErrorNotFound);
165         VerifyOrQuit(flash.Get(key, 0, nullptr, nullptr) == kErrorNotFound);
166     }
167 
168     // Test swap
169 
170     for (uint16_t index = 0; index < 4096; index++)
171     {
172         uint16_t key    = index & 0xf;
173         uint16_t length = index & 0xf;
174 
175         SuccessOrQuit(flash.Set(key, writeBuffer, length));
176     }
177 
178     for (uint16_t key = 0; key < 16; key++)
179     {
180         uint16_t length = key;
181 
182         SuccessOrQuit(flash.Get(key, 0, readBuffer, &length));
183         VerifyOrQuit(length == key, "Get() did not return expected length");
184         VerifyOrQuit(memcmp(readBuffer, writeBuffer, length) == 0, "Get() did not return expected value");
185     }
186 #endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
187 }
188 
189 } // namespace ot
190 
main(void)191 int main(void)
192 {
193     ot::TestFlash();
194     printf("All tests passed\n");
195     return 0;
196 }
197