Skip to content

Commit 2ec7bdd

Browse files
Filip JagodzinskiCruz Monrreal II
authored andcommitted
Tests: Stream: Add more test cases
1 parent 1faadae commit 2ec7bdd

File tree

1 file changed

+175
-17
lines changed

1 file changed

+175
-17
lines changed

TESTS/mbed_platform/Stream/main.cpp

Lines changed: 175 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,43 +18,198 @@
1818
#include "utest/utest.h"
1919
#include "unity/unity.h"
2020
#include "mbed.h"
21+
#include "Stream.h"
22+
23+
/* This test suite verifies that write/read/write/read sequence can be
24+
* successfully executed on the Stream objects.
25+
*
26+
* A qute from `man 3 fdopen`:
27+
*
28+
* Reads and writes may be intermixed on read/write streams in any order. Note
29+
* that ANSI C requires that a file positioning function intervene between
30+
* output and input, unless an input operation encounters end-of-file. (If
31+
* this condition is not met, then a read is allowed to return the result
32+
* of writes other than the most recent.) Therefore it is good practice (and
33+
* indeed sometimes necessary under Linux) to put an fseek(3) or fgetpos(3)
34+
* operation between write and read operations on such a stream. This operation
35+
* may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its
36+
* synchronizing side effect).
37+
*/
2138

2239
using utest::v1::Case;
2340

41+
const char FMT[] = "Foo%02ibar.";
42+
const size_t FORMATTED_STR_SIZE = 3 + 2 + 4 + 1;
43+
// The test Stream instance has to be able to store two printf() output strings.
44+
const size_t LOOPBACK_BUFF_SIZE = 2 * FORMATTED_STR_SIZE;
45+
2446
class Loopback : public Stream {
2547
public:
26-
Loopback(const char *name = NULL) : Stream(name) {}
48+
Loopback(const char *name = NULL) : Stream(name)
49+
{
50+
// The `fgets()` stops reading after a newline or EOF.
51+
// Fill the buffer with newlines to simplify fgets() usage in this test.
52+
memset(_buff, '\n', LOOPBACK_BUFF_SIZE);
53+
_p_index = 0;
54+
_g_index = 0;
55+
}
2756

28-
protected:
29-
virtual int _getc()
57+
virtual ~Loopback()
58+
{
59+
}
60+
61+
int test_vprintf(const char *fmt, ...)
3062
{
31-
return _c;
63+
int rc = -1;
64+
std::va_list args;
65+
va_start(args, fmt);
66+
rc = vprintf(fmt, args);
67+
va_end(args);
68+
return rc;
3269
}
70+
71+
int test_vscanf(const char *fmt, ...)
72+
{
73+
int rc = EOF;
74+
std::va_list args;
75+
va_start(args, fmt);
76+
rc = vscanf(fmt, args);
77+
va_end(args);
78+
return rc;
79+
}
80+
81+
protected:
3382
virtual int _putc(int c)
3483
{
35-
_c = c;
84+
if (_p_index >= LOOPBACK_BUFF_SIZE) {
85+
return -1;
86+
}
87+
_buff[_p_index++] = (int8_t)c;
3688
return c;
3789
}
90+
91+
virtual int _getc()
92+
{
93+
if (_g_index >= LOOPBACK_BUFF_SIZE) {
94+
return -1;
95+
}
96+
return _buff[_g_index++];
97+
}
98+
3899
private:
39-
char _c;
100+
int8_t _buff[LOOPBACK_BUFF_SIZE];
101+
size_t _p_index;
102+
size_t _g_index;
40103
};
41104

42-
Loopback loop("loopback");
43-
105+
/* Test intermixed Stream::putc() / Stream::getc().
106+
*
107+
* Given a Stream object,
108+
* when a write/read/write/read sequence is executed
109+
* with the use of Stream::putc() and Stream::getc() methods,
110+
* then all operations succeed.
111+
*/
44112
void test_putc_getc()
45113
{
114+
char char_buff[2] = {'a', 'b'};
115+
Loopback loop("loopback");
46116
int ret;
47-
char char_buf[2] = {'a', 'b'};
48117

49-
ret = loop.putc(char_buf[0]);
50-
TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
118+
ret = loop.putc(char_buff[0]);
119+
TEST_ASSERT_EQUAL_INT(char_buff[0], ret);
51120
ret = loop.getc();
52-
TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
53-
ret = loop.putc(char_buf[1]);
54-
TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
121+
TEST_ASSERT_EQUAL_INT(char_buff[0], ret);
122+
ret = loop.putc(char_buff[1]);
123+
TEST_ASSERT_EQUAL_INT(char_buff[1], ret);
55124
ret = loop.getc();
56-
TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
57-
return;
125+
TEST_ASSERT_EQUAL_INT(char_buff[1], ret);
126+
}
127+
128+
/* Test intermixed Stream::puts() / Stream::gets().
129+
*
130+
* Given a Stream object,
131+
* when a write/read/write/read sequence is executed,
132+
* with the use of Stream::puts() and Stream::gets() methods,
133+
* then all operations succeed.
134+
*/
135+
void test_puts_gets()
136+
{
137+
const size_t STR_LEN = 3;
138+
const size_t STR_SIZE = STR_LEN + 1; // +1 for '\0'
139+
char strings[2][STR_SIZE] = {"Foo", "Bar"};
140+
const size_t GETS_BUFF_SIZE = STR_LEN + 2; // +1 for '\n' (gets() stops AFTER a '\n'), +1 for '\0'
141+
char g_buff[GETS_BUFF_SIZE] = {};
142+
Loopback loop("loopback");
143+
int p_rc;
144+
char *g_rc;
145+
146+
p_rc = loop.puts(strings[0]);
147+
TEST_ASSERT(p_rc >= 0);
148+
g_rc = loop.gets(g_buff, GETS_BUFF_SIZE);
149+
TEST_ASSERT_EQUAL_PTR(g_buff, g_rc);
150+
151+
p_rc = loop.puts(strings[1]);
152+
TEST_ASSERT(p_rc >= 0);
153+
g_rc = loop.gets(g_buff, GETS_BUFF_SIZE);
154+
TEST_ASSERT_EQUAL_PTR(g_buff, g_rc);
155+
}
156+
157+
/* Test intermixed Stream::printf() / Stream::scanf().
158+
*
159+
* Given a Stream object,
160+
* when a write/read/write/read sequence is executed,
161+
* with the use of Stream::printf() and Stream::scanf() methods,
162+
* then all operations succeed.
163+
*/
164+
void test_printf_scanf()
165+
{
166+
Loopback loop("loopback");
167+
int p_val, g_val, rc;
168+
169+
p_val = 42;
170+
g_val = p_val + 1;
171+
rc = loop.printf(FMT, p_val);
172+
TEST_ASSERT(rc > 0);
173+
rc = loop.scanf(FMT, &g_val);
174+
TEST_ASSERT(rc == 1);
175+
TEST_ASSERT_EQUAL_INT(p_val, g_val);
176+
177+
p_val += 5;
178+
g_val = p_val + 1;
179+
rc = loop.printf(FMT, p_val);
180+
TEST_ASSERT(rc > 0);
181+
rc = loop.scanf(FMT, &g_val);
182+
TEST_ASSERT(rc == 1);
183+
TEST_ASSERT_EQUAL_INT(p_val, g_val);
184+
}
185+
186+
/* Test intermixed Stream::vprintf() / Stream::vscanf().
187+
*
188+
* Given a Stream object,
189+
* when a write/read/write/read sequence is executed,
190+
* with the use of Stream::vprintf() and Stream::vscanf() methods,
191+
* then all operations succeed.
192+
*/
193+
void test_vprintf_vscanf()
194+
{
195+
Loopback loop("loopback");
196+
int p_val, g_val, rc;
197+
198+
p_val = 42;
199+
g_val = p_val + 1;
200+
rc = loop.test_vprintf(FMT, p_val);
201+
TEST_ASSERT(rc > 0);
202+
rc = loop.test_vscanf(FMT, &g_val);
203+
TEST_ASSERT(rc == 1);
204+
TEST_ASSERT_EQUAL_INT(p_val, g_val);
205+
206+
p_val += 5;
207+
g_val = p_val + 1;
208+
rc = loop.test_vprintf(FMT, p_val);
209+
TEST_ASSERT(rc > 0);
210+
rc = loop.test_vscanf(FMT, &g_val);
211+
TEST_ASSERT(rc == 1);
212+
TEST_ASSERT_EQUAL_INT(p_val, g_val);
58213
}
59214

60215
utest::v1::status_t test_setup(const size_t number_of_cases)
@@ -64,7 +219,10 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
64219
}
65220

66221
Case cases[] = {
67-
Case("Test putc/getc", test_putc_getc)
222+
Case("Test putc/getc", test_putc_getc),
223+
Case("Test puts/gets", test_puts_gets),
224+
Case("Test printf/scanf", test_printf_scanf),
225+
Case("Test vprintf/vscanf", test_vprintf_vscanf)
68226
};
69227

70228
utest::v1::Specification specification(test_setup, cases);

0 commit comments

Comments
 (0)