init

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "greentea-client/test_env.h"
00018 #include "utest/utest.h"
00019 #include "unity/unity.h"
00020 #include "TestFile.h"
00021 #include "mbed.h"
00022 
00023 using utest::v1::Case;
00024 
00025 
00026 /** Test fopen and fclose
00027  *
00028  *  Given a file to be opened
00029  *
00030  *  When the file is open
00031  *  Then returned file descriptor is valid
00032  *
00033  *  When the file is closed
00034  *  Then underneath retargeting layer function is called
00035  *       and the fclose function return with succeed
00036  *
00037  */
00038 void test_fopen_fclose()
00039 {
00040     std::FILE *file;
00041     const uint32_t FS = 5;
00042     TestFile<FS> fh;
00043 
00044     file = fdopen(&fh, "w+");
00045     TEST_ASSERT_NOT_NULL(file);
00046 
00047     TestFile<FS>::resetFunctionCallHistory();
00048     int ret = std::fclose(file);
00049     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnClose));
00050     TEST_ASSERT_EQUAL_INT(0, ret);
00051 }
00052 
00053 
00054 /** Test fwrite and fread
00055  *
00056  *  Given already opened file
00057  *
00058  *  When write some data to file
00059  *  Then underneath retargeting layer write function is called
00060  *       fwrite return number of successfully written elements
00061  *       when not all elements were written stream error is set
00062  *
00063  *  When read previously written data from file
00064  *  Then underneath retargeting layer read function is called
00065  *       fread return number of successfully read elements
00066  *       read data match previously written
00067  *       when read less then expected stream eof is set
00068  *
00069  */
00070 void test_fwrite_fread()
00071 {
00072     std::FILE *file;
00073     const uint32_t FS = 5;
00074     TestFile<FS> fh;
00075     char read_buf[16];
00076     const char *str1 = "abc";
00077     const char *str2 = "def";
00078     const uint32_t str1_size = strlen(str1);
00079     const uint32_t str2_size = strlen(str2);
00080     std::size_t write_ret;
00081     std::size_t read_ret;
00082 
00083     file = fdopen(&fh, "w+");
00084     TEST_ASSERT_NOT_NULL(file);
00085     std::setbuf(file, NULL);
00086 
00087     // write 3; expected written 3
00088     TestFile<FS>::resetFunctionCallHistory();
00089     write_ret = std::fwrite(str1, 1, str1_size, file);
00090     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00091     TEST_ASSERT_EQUAL_INT(str1_size, write_ret);
00092 
00093 #ifndef __ICCARM__ // prevents IAR infinite loop
00094     // write 3; expected written 2
00095     TestFile<FS>::resetFunctionCallHistory();
00096     write_ret = std::fwrite(str2, 1, str2_size, file);
00097     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00098     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00099     std::clearerr(file); // for ARMCC
00100 #ifndef __ARMCC_VERSION
00101     // ARMCC returns 0 here instead of number of elements successfully written
00102     TEST_ASSERT_EQUAL_INT(str2_size - 1, write_ret);
00103 #endif
00104 
00105     // write 3; expected written 0
00106     TestFile<FS>::resetFunctionCallHistory();
00107     write_ret = std::fwrite(str1, 1, str1_size, file);
00108     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00109     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00110     TEST_ASSERT_EQUAL_INT(0, write_ret);
00111 #endif
00112 
00113     std::rewind(file);
00114 
00115     // read 3; expected read 3
00116     TestFile<FS>::resetFunctionCallHistory();
00117     read_ret = std::fread(read_buf, 1, str1_size, file);
00118     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00119     TEST_ASSERT_EQUAL_INT(str1_size, read_ret);
00120     TEST_ASSERT_EQUAL_INT(0, strncmp(str1, read_buf, str1_size));
00121 
00122 #ifndef __ICCARM__
00123     // read 3; expected read 2
00124     TestFile<FS>::resetFunctionCallHistory();
00125     read_ret = std::fread(read_buf, 1, str2_size, file);
00126     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00127     TEST_ASSERT_TRUE(std::feof(file) != 0);
00128     std::clearerr(file); // for ARMCC
00129     TEST_ASSERT_EQUAL_INT(str2_size - 1, read_ret);
00130     TEST_ASSERT_EQUAL_INT(0, strncmp(str2, read_buf, str2_size - 1));
00131 
00132     // read 3; expected read 0
00133     TestFile<FS>::resetFunctionCallHistory();
00134     read_ret = std::fread(read_buf, 1, str2_size, file);
00135     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00136     TEST_ASSERT_TRUE(std::feof(file) != 0);
00137     TEST_ASSERT_EQUAL_INT(0, read_ret);
00138 #endif
00139 
00140     std::fclose(file);
00141 }
00142 
00143 /** Test fputc and fgetc
00144  *
00145  *  Given already opened file
00146  *
00147  *  When write some data to file
00148  *  Then underneath retargeting layer write function is called
00149  *       fputc return written element
00150  *       on failure, returns EOF and stream error is sets
00151  *
00152  *  When read previously written data from file
00153  *  Then underneath retargeting layer read function is called
00154  *       fgetc return read element
00155  *       read data match previously written
00156  *       on failure, returns EOF and stream error/eof is sets respectively
00157  *
00158  */
00159 void test_fputc_fgetc()
00160 {
00161     std::FILE *file;
00162     const uint32_t FS = 3;
00163     TestFile<FS> fh;
00164     char char_buf[3] = {'a', 'b', 'c' };
00165     int ret;
00166 
00167     file = fdopen(&fh, "w+");
00168     TEST_ASSERT_NOT_NULL(file);
00169     std::setbuf(file, NULL);
00170 
00171 
00172     // write 1; expected written 1
00173     TestFile<FS>::resetFunctionCallHistory();
00174     ret = std::fputc(char_buf[0], file);
00175     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00176     TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
00177 
00178     // write 1; expected written 1
00179     TestFile<FS>::resetFunctionCallHistory();
00180     ret = std::fputc(char_buf[1], file);
00181     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00182     TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
00183 
00184     // write 1; expected written 1
00185     TestFile<FS>::resetFunctionCallHistory();
00186     ret = std::fputc(char_buf[2], file);
00187     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00188     TEST_ASSERT_EQUAL_INT(char_buf[2], ret);
00189 
00190 #ifndef __ICCARM__ // prevents IAR infinite loop
00191     // write 1; expected written 0
00192     TestFile<FS>::resetFunctionCallHistory();
00193     ret = std::fputc(char_buf[0], file);
00194     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00195     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00196     TEST_ASSERT_EQUAL_INT(EOF, ret);
00197 #endif
00198 
00199     std::rewind(file);
00200 
00201     // read 1; expected read 1
00202     TestFile<FS>::resetFunctionCallHistory();
00203     ret = std::fgetc(file);
00204     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00205     TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
00206 
00207     // read 1; expected read 1
00208     TestFile<FS>::resetFunctionCallHistory();
00209     ret = std::fgetc(file);
00210 #ifndef __ICCARM__
00211     // IAR optimize reads
00212     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00213 #endif
00214     TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
00215 
00216     // read 1; expected read 1
00217     TestFile<FS>::resetFunctionCallHistory();
00218     ret = std::fgetc(file);
00219 #ifndef __ICCARM__
00220     // IAR optimize reads
00221     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00222 #endif
00223     TEST_ASSERT_EQUAL_INT(char_buf[2], ret);
00224 
00225 #ifndef __ICCARM__
00226     // read 1; expected read 0
00227     TestFile<FS>::resetFunctionCallHistory();
00228     ret = std::fgetc(file);
00229     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00230     TEST_ASSERT_TRUE(std::feof(file) != 0);
00231     TEST_ASSERT_EQUAL_INT(EOF, ret);
00232 #endif
00233 
00234     std::fclose(file);
00235 }
00236 
00237 /** Test fputs and fgets
00238  *
00239  *  Given already opened file
00240  *
00241  *  When write some data to file
00242  *  Then underneath retargeting layer write function is called
00243  *       on success, returns a non-negative value
00244  *       on failure, returns EOF and set stream error
00245  *
00246  *  When read previously written data from file
00247  *  Then underneath retargeting layer read function is called
00248  *       fgets return valid buffer, and read data match previously written
00249  *       when read less then expected stream EOF is set
00250  *       on failure, stream error is sets
00251  *
00252  */
00253 void test_fputs_fgets()
00254 {
00255     std::FILE *file;
00256     const uint32_t FS = 5;
00257     TestFile<FS> fh;
00258     const char *str1 = "abc";
00259     const char *str2 = "def";
00260     const uint32_t str1_size = strlen(str1);
00261     const uint32_t str2_size = strlen(str2);
00262     char read_buf[16];
00263     int fputs_ret;
00264     char *fgets_ret;
00265 
00266     file = fdopen(&fh, "w+");
00267     TEST_ASSERT_NOT_NULL(file);
00268     std::setbuf(file, NULL);
00269 
00270     // write 3; expected written 3
00271     TestFile<FS>::resetFunctionCallHistory();
00272     fputs_ret = std::fputs(str1, file);
00273     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00274     TEST_ASSERT_TRUE(fputs_ret >= 0);
00275 
00276 #ifndef __ICCARM__ // prevents IAR infinite loop
00277     // write 3; expected written 2
00278     TestFile<FS>::resetFunctionCallHistory();
00279     fputs_ret = std::fputs(str2, file);
00280     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00281     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00282     std::clearerr(file); // for ARMCC
00283     TEST_ASSERT_EQUAL_INT(EOF, fputs_ret);
00284 
00285     // write 3; expected written 0
00286     TestFile<FS>::resetFunctionCallHistory();
00287     fputs_ret = std::fputs(str1, file);
00288     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00289     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00290     TEST_ASSERT_EQUAL_INT(EOF, fputs_ret);
00291 #endif
00292 
00293     std::rewind(file);
00294 
00295     // read 3; expected read 3
00296     TestFile<FS>::resetFunctionCallHistory();
00297     fgets_ret = std::fgets(read_buf, str1_size + 1, file);
00298     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00299     TEST_ASSERT_EQUAL_INT(read_buf, fgets_ret);
00300     TEST_ASSERT_EQUAL_INT(0, strncmp(read_buf, str1, str1_size));
00301 
00302 #ifndef __ICCARM__
00303     // read 3; expected read 2
00304     TestFile<FS>::resetFunctionCallHistory();
00305     fgets_ret = std::fgets(read_buf, str2_size + 1, file);
00306     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00307     TEST_ASSERT_TRUE(std::feof(file) != 0);
00308     std::clearerr(file); // for ARMCC
00309     TEST_ASSERT_EQUAL_INT(read_buf, fgets_ret);
00310     TEST_ASSERT_EQUAL_INT(0, strncmp(read_buf, str2, str2_size - 2));
00311 
00312     // read 3; expected read 0
00313     TestFile<FS>::resetFunctionCallHistory();
00314     fgets_ret = std::fgets(read_buf, str2_size + 1, file);
00315     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00316     TEST_ASSERT_TRUE(std::feof(file) != 0);
00317     TEST_ASSERT_EQUAL_INT(NULL, fgets_ret);
00318 #endif
00319 
00320     std::fclose(file);
00321 }
00322 
00323 /** Test fprintf and fscanf
00324  *
00325  *  Given already opened file
00326  *
00327  *  When write some data to file
00328  *  Then underneath retargeting layer write function is called
00329  *       fprintf return number of written components
00330  *       fprintf return negative value if an error occurred and set stream error
00331  *
00332  *  When read previously written data from file
00333  *  Then underneath retargeting layer read function is called
00334  *       fscanf return number of read components, and read data match previously written
00335  *       when read less then expected stream EOF is set
00336  *       on failure, stream error is sets
00337  *
00338  */
00339 void test_fprintf_fscanf()
00340 {
00341     std::FILE *file;
00342     const uint32_t FS = 5;
00343     TestFile<FS> fh;
00344     const char *str1 = "abc";
00345     const char *str2 = "def";
00346     const uint32_t str1_size = strlen(str1);
00347     const uint32_t str2_size = strlen(str2);
00348     char read_buf[16];
00349     int fprintf_ret;
00350     int fscanf_ret;
00351 
00352     file = fdopen(&fh, "w+");
00353     TEST_ASSERT_NOT_NULL(file);
00354     std::setbuf(file, NULL);
00355 
00356     // write 3; expected written 3
00357     TestFile<FS>::resetFunctionCallHistory();
00358     fprintf_ret = fprintf(file, "%s", str1);
00359     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00360     TEST_ASSERT_EQUAL_INT(str1_size, fprintf_ret);
00361 
00362 #ifndef __ICCARM__ // prevents IAR infinite loop
00363     // write 3; expected written 2
00364     TestFile<FS>::resetFunctionCallHistory();
00365     fprintf_ret = fprintf(file, "%s", str2);
00366     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00367     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00368     std::clearerr(file); // for ARMCC
00369     TEST_ASSERT_TRUE(fprintf_ret < 0);
00370 
00371     // write 3; expected written 0
00372     TestFile<FS>::resetFunctionCallHistory();
00373     fprintf_ret = fprintf(file, "%s", str2);
00374     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnWrite));
00375     TEST_ASSERT_TRUE(std::ferror(file) != 0);
00376     TEST_ASSERT_TRUE(fprintf_ret < 0);
00377 #endif
00378 
00379     std::rewind(file);
00380 
00381     // read 3; expected read 3
00382     TestFile<FS>::resetFunctionCallHistory();
00383     fscanf_ret = fscanf(file, "%3s", read_buf);
00384     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00385     TEST_ASSERT_EQUAL_INT(1, fscanf_ret);
00386     TEST_ASSERT_EQUAL_INT(0, strncmp(read_buf, str1, str1_size));
00387 
00388 #ifndef __ICCARM__
00389     // read 3; expected read 2
00390     TestFile<FS>::resetFunctionCallHistory();
00391     fscanf_ret = fscanf(file, "%3s", read_buf);
00392     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00393     TEST_ASSERT_TRUE(std::feof(file) != 0);
00394     std::clearerr(file); // for ARMCC
00395     TEST_ASSERT_EQUAL_INT(1, fscanf_ret);
00396     TEST_ASSERT_EQUAL_INT(0, strncmp(read_buf, str2, str2_size - 1));
00397 
00398     // read 3; expected read 0
00399     TestFile<FS>::resetFunctionCallHistory();
00400     fscanf_ret = fscanf(file, "%3s", read_buf);
00401     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnRead));
00402     TEST_ASSERT_TRUE(std::feof(file) != 0);
00403     TEST_ASSERT_EQUAL_INT(EOF, fscanf_ret);
00404 #endif
00405 
00406     std::fclose(file);
00407 }
00408 
00409 /** Test fseek and ftell
00410  *
00411  *  Given already opened file is empty
00412  *
00413  *  When set the file position indicator via fseek
00414  *  Then underneath retargeting layer seek function is called
00415  *       fseek return with succeed and ftell return already set position
00416  *
00417  *  Given already opened file is not empty
00418  *
00419  *  When set the file position indicator via fseek
00420  *  Then underneath retargeting layer seek function is called
00421  *       fseek return with succeed and ftell return already set position
00422  *
00423  */
00424 void test_fseek_ftell()
00425 {
00426     std::FILE *file;
00427     long ftell_ret;
00428     int fssek_ret;
00429     const uint32_t FS = 128;
00430     TestFile<FS> fh;
00431 
00432     file = fdopen(&fh, "w+");
00433     TEST_ASSERT_NOT_NULL(file);
00434     std::setbuf(file, NULL);
00435 
00436     TestFile<FS>::resetFunctionCallHistory();
00437     ftell_ret = std::ftell(file);
00438     TEST_ASSERT_EQUAL(0, ftell_ret);
00439 
00440     TestFile<FS>::resetFunctionCallHistory();
00441     fssek_ret = std::fseek(file, 0, SEEK_CUR);
00442     TEST_ASSERT_EQUAL(0, fssek_ret);
00443 
00444     TestFile<FS>::resetFunctionCallHistory();
00445     fssek_ret = std::fseek(file, 0, SEEK_SET);
00446     TEST_ASSERT_EQUAL(0, fssek_ret);
00447 
00448     TestFile<FS>::resetFunctionCallHistory();
00449     fssek_ret = std::fseek(file, 0, SEEK_END);
00450     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnSeek));
00451     TEST_ASSERT_EQUAL(0, fssek_ret);
00452 
00453     const char *str = "Hello world";
00454     const std::size_t size = std::strlen(str);
00455 
00456     std::fwrite(str, 1, size, file);
00457 
00458     TestFile<FS>::resetFunctionCallHistory();
00459     ftell_ret = std::ftell(file);
00460     TEST_ASSERT_EQUAL(size, ftell_ret);
00461 
00462     TestFile<FS>::resetFunctionCallHistory();
00463     fssek_ret = std::fseek(file, 5, SEEK_SET);
00464     TEST_ASSERT_EQUAL(0, fssek_ret);
00465     ftell_ret = std::ftell(file);
00466     TEST_ASSERT_EQUAL(5, ftell_ret);
00467 
00468     TestFile<FS>::resetFunctionCallHistory();
00469     fssek_ret = std::fseek(file, -5, SEEK_CUR);
00470     TEST_ASSERT_EQUAL(0, fssek_ret);
00471     ftell_ret = std::ftell(file);
00472     TEST_ASSERT_EQUAL(0, ftell_ret);
00473 
00474     TestFile<FS>::resetFunctionCallHistory();
00475     fssek_ret = std::fseek(file, 0, SEEK_END);
00476     TEST_ASSERT_TRUE(TestFile<FS>::functionCalled(TestFile<FS>::fnSeek));
00477     TEST_ASSERT_EQUAL(0, fssek_ret);
00478     ftell_ret = std::ftell(file);
00479     TEST_ASSERT_EQUAL(size, ftell_ret);
00480 
00481     std::fclose(file);
00482 }
00483 
00484 utest::v1::status_t test_setup(const size_t number_of_cases)
00485 {
00486     GREENTEA_SETUP(10, "default_auto");
00487     return utest::v1::verbose_test_setup_handler(number_of_cases);
00488 }
00489 
00490 Case cases[] = {
00491     Case("Test fopen/fclose", test_fopen_fclose),
00492     Case("Test fwrite/fread", test_fwrite_fread),
00493     Case("Test fputc/fgetc", test_fputc_fgetc),
00494     Case("Test fputs/fgets", test_fputs_fgets),
00495     Case("Test fprintf/fscanf", test_fprintf_fscanf),
00496     Case("Test fseek/ftell", test_fseek_ftell)
00497 };
00498 
00499 utest::v1::Specification specification(test_setup, cases);
00500 
00501 int main()
00502 {
00503     return !utest::v1::Harness::run(specification);
00504 }