Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <assert.h>
     18 #include <stdint.h>
     19 #include <stdbool.h>
     20 #include <gtest/gtest.h>
     21 
     22 #include <trusty/lib/storage.h>
     23 
     24 #define TRUSTY_DEVICE_NAME "/dev/trusty-ipc-dev0"
     25 
     26 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
     27 
     28 static inline bool is_32bit_aligned(size_t sz)
     29 {
     30     return ((sz & 0x3) == 0);
     31 }
     32 
     33 static inline bool is_valid_size(size_t sz) {
     34     return (sz > 0) && is_32bit_aligned(sz);
     35 }
     36 
     37 static bool is_valid_offset(storage_off_t off)
     38 {
     39     return (off & 0x3) == 0ULL;
     40 }
     41 
     42 static void fill_pattern32(uint32_t *buf, size_t len, storage_off_t off)
     43 {
     44     size_t cnt = len / sizeof(uint32_t);
     45     uint32_t pattern = (uint32_t)(off / sizeof(uint32_t));
     46     while (cnt--) {
     47         *buf++ = pattern++;
     48     }
     49 }
     50 
     51 static bool check_pattern32(const uint32_t *buf, size_t len, storage_off_t off)
     52 {
     53     size_t cnt = len / sizeof(uint32_t);
     54     uint32_t pattern = (uint32_t)(off / sizeof(uint32_t));
     55     while (cnt--) {
     56         if (*buf != pattern)
     57             return false;
     58         buf++;
     59         pattern++;
     60     }
     61     return true;
     62 }
     63 
     64 static bool check_value32(const uint32_t *buf, size_t len, uint32_t val)
     65 {
     66     size_t cnt = len / sizeof(uint32_t);
     67     while (cnt--) {
     68         if (*buf != val)
     69             return false;
     70         buf++;
     71     }
     72     return true;
     73 }
     74 
     75 using testing::TestWithParam;
     76 
     77 class StorageServiceTest : public virtual TestWithParam<const char *> {
     78 public:
     79     StorageServiceTest() {}
     80     virtual ~StorageServiceTest() {}
     81 
     82     virtual void SetUp() {
     83         port_ = GetParam();
     84         test_buf_ = NULL;
     85         aux_session_ = STORAGE_INVALID_SESSION;
     86         int rc = storage_open_session(TRUSTY_DEVICE_NAME, &session_, port_);
     87         ASSERT_EQ(0, rc);
     88     }
     89 
     90     virtual void TearDown() {
     91         if (test_buf_) {
     92             delete[] test_buf_;
     93             test_buf_ = NULL;
     94         }
     95         storage_close_session(session_);
     96 
     97         if (aux_session_ != STORAGE_INVALID_SESSION) {
     98             storage_close_session(aux_session_);
     99             aux_session_ = STORAGE_INVALID_SESSION;
    100         }
    101     }
    102 
    103     void WriteReadAtOffsetHelper(file_handle_t handle, size_t blk, size_t cnt, bool complete);
    104 
    105     void WriteZeroChunk(file_handle_t handle, storage_off_t off, size_t chunk_len, bool complete );
    106     void WritePatternChunk(file_handle_t handle, storage_off_t off, size_t chunk_len, bool complete);
    107     void WritePattern(file_handle_t handle, storage_off_t off, size_t data_len, size_t chunk_len, bool complete);
    108 
    109     void ReadChunk(file_handle_t handle, storage_off_t off, size_t chunk_len,
    110                    size_t head_len, size_t pattern_len, size_t tail_len);
    111     void ReadPattern(file_handle_t handle, storage_off_t off, size_t data_len, size_t chunk_len);
    112     void ReadPatternEOF(file_handle_t handle, storage_off_t off, size_t chunk_len, size_t exp_len);
    113 
    114 protected:
    115     const char *port_;
    116     uint32_t *test_buf_;
    117     storage_session_t session_;
    118     storage_session_t aux_session_;
    119 };
    120 
    121 INSTANTIATE_TEST_CASE_P(SS_TD_Tests, StorageServiceTest,   ::testing::Values(STORAGE_CLIENT_TD_PORT));
    122 INSTANTIATE_TEST_CASE_P(SS_TDEA_Tests, StorageServiceTest, ::testing::Values(STORAGE_CLIENT_TDEA_PORT));
    123 INSTANTIATE_TEST_CASE_P(SS_TP_Tests, StorageServiceTest,   ::testing::Values(STORAGE_CLIENT_TP_PORT));
    124 
    125 
    126 void StorageServiceTest::WriteZeroChunk(file_handle_t handle, storage_off_t off,
    127                                        size_t chunk_len, bool complete)
    128 {
    129     int rc;
    130     uint32_t data_buf[chunk_len/sizeof(uint32_t)];
    131 
    132     ASSERT_PRED1(is_valid_size, chunk_len);
    133     ASSERT_PRED1(is_valid_offset, off);
    134 
    135     memset(data_buf, 0, chunk_len);
    136 
    137     rc = storage_write(handle, off, data_buf, sizeof(data_buf),
    138                        complete ? STORAGE_OP_COMPLETE : 0);
    139     ASSERT_EQ((int)chunk_len, rc);
    140 }
    141 
    142 void StorageServiceTest::WritePatternChunk(file_handle_t handle, storage_off_t off,
    143                                            size_t chunk_len, bool complete)
    144 {
    145     int rc;
    146     uint32_t data_buf[chunk_len/sizeof(uint32_t)];
    147 
    148     ASSERT_PRED1(is_valid_size, chunk_len);
    149     ASSERT_PRED1(is_valid_offset, off);
    150 
    151     fill_pattern32(data_buf, chunk_len, off);
    152 
    153     rc = storage_write(handle, off, data_buf, sizeof(data_buf),
    154                        complete ? STORAGE_OP_COMPLETE : 0);
    155     ASSERT_EQ((int)chunk_len, rc);
    156 }
    157 
    158 void StorageServiceTest::WritePattern(file_handle_t handle, storage_off_t off,
    159                                       size_t data_len, size_t chunk_len, bool complete)
    160 {
    161     ASSERT_PRED1(is_valid_size, data_len);
    162     ASSERT_PRED1(is_valid_size, chunk_len);
    163 
    164     while (data_len) {
    165         if (data_len < chunk_len)
    166             chunk_len = data_len;
    167         WritePatternChunk(handle, off, chunk_len, (chunk_len == data_len) && complete);
    168         ASSERT_FALSE(HasFatalFailure());
    169         off += chunk_len;
    170         data_len -= chunk_len;
    171     }
    172 }
    173 
    174 void StorageServiceTest::ReadChunk(file_handle_t handle,
    175                                    storage_off_t off, size_t chunk_len,
    176                                    size_t head_len, size_t pattern_len,
    177                                    size_t tail_len)
    178 {
    179     int rc;
    180     uint32_t data_buf[chunk_len/sizeof(uint32_t)];
    181     uint8_t *data_ptr = (uint8_t *)data_buf;
    182 
    183     ASSERT_PRED1(is_valid_size, chunk_len);
    184     ASSERT_PRED1(is_valid_offset, off);
    185     ASSERT_EQ(head_len + pattern_len + tail_len, chunk_len);
    186 
    187     rc = storage_read(handle, off, data_buf, chunk_len);
    188     ASSERT_EQ((int)chunk_len, rc);
    189 
    190     if (head_len) {
    191         ASSERT_TRUE(check_value32((const uint32_t *)data_ptr, head_len, 0));
    192         data_ptr += head_len;
    193         off += head_len;
    194     }
    195 
    196     if (pattern_len) {
    197         ASSERT_TRUE(check_pattern32((const uint32_t *)data_ptr, pattern_len, off));
    198         data_ptr += pattern_len;
    199     }
    200 
    201     if (tail_len) {
    202         ASSERT_TRUE(check_value32((const uint32_t *)data_ptr, tail_len, 0));
    203     }
    204 }
    205 
    206 void StorageServiceTest::ReadPattern(file_handle_t handle, storage_off_t off,
    207                                      size_t data_len, size_t chunk_len)
    208 {
    209     int rc;
    210     uint32_t data_buf[chunk_len/sizeof(uint32_t)];
    211 
    212     ASSERT_PRED1(is_valid_size, chunk_len);
    213     ASSERT_PRED1(is_valid_size, data_len);
    214     ASSERT_PRED1(is_valid_offset, off);
    215 
    216     while (data_len) {
    217         if (chunk_len > data_len)
    218             chunk_len = data_len;
    219         rc = storage_read(handle, off, data_buf, sizeof(data_buf));
    220         ASSERT_EQ((int)chunk_len, rc);
    221         ASSERT_TRUE(check_pattern32(data_buf, chunk_len, off));
    222         off += chunk_len;
    223         data_len -= chunk_len;
    224     }
    225 }
    226 
    227 void StorageServiceTest::ReadPatternEOF(file_handle_t handle, storage_off_t off,
    228                                         size_t chunk_len, size_t exp_len)
    229 {
    230     int rc;
    231     size_t bytes_read = 0;
    232     uint32_t data_buf[chunk_len/sizeof(uint32_t)];
    233 
    234     ASSERT_PRED1(is_valid_size, chunk_len);
    235     ASSERT_PRED1(is_32bit_aligned, exp_len);
    236 
    237     while (true) {
    238          rc = storage_read(handle, off, data_buf, sizeof(data_buf));
    239          ASSERT_GE(rc, 0);
    240          if (rc == 0)
    241              break; // end of file reached
    242          ASSERT_PRED1(is_valid_size, (size_t)rc);
    243          ASSERT_TRUE(check_pattern32(data_buf, rc, off));
    244          off += rc;
    245          bytes_read += rc;
    246     }
    247     ASSERT_EQ(bytes_read, exp_len);
    248 }
    249 
    250 TEST_P(StorageServiceTest, CreateDelete) {
    251     int rc;
    252     file_handle_t handle;
    253     const char *fname = "test_create_delete_file";
    254 
    255     // make sure test file does not exist (expect success or -ENOENT)
    256     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    257     rc = (rc == -ENOENT) ? 0 : rc;
    258     ASSERT_EQ(0, rc);
    259 
    260     // one more time (expect -ENOENT only)
    261     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    262     ASSERT_EQ(-ENOENT, rc);
    263 
    264     // create file (expect 0)
    265     rc = storage_open_file(session_, &handle, fname,
    266                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    267                            STORAGE_OP_COMPLETE);
    268     ASSERT_EQ(0, rc);
    269 
    270     // try to create it again while it is still opened (expect -EEXIST)
    271     rc = storage_open_file(session_, &handle, fname,
    272                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    273                            STORAGE_OP_COMPLETE);
    274     ASSERT_EQ(-EEXIST, rc);
    275 
    276     // close it
    277     storage_close_file(handle);
    278 
    279     // try to create it again while it is closed (expect -EEXIST)
    280     rc = storage_open_file(session_, &handle, fname,
    281                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    282                            STORAGE_OP_COMPLETE);
    283     ASSERT_EQ(-EEXIST, rc);
    284 
    285     // delete file (expect 0)
    286     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    287     ASSERT_EQ(0, rc);
    288 
    289     // one more time (expect -ENOENT)
    290     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    291     ASSERT_EQ(-ENOENT, rc);
    292 }
    293 
    294 
    295 TEST_P(StorageServiceTest, DeleteOpened) {
    296     int rc;
    297     file_handle_t handle;
    298     const char *fname = "delete_opened_test_file";
    299 
    300     // make sure test file does not exist (expect success or -ENOENT)
    301     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    302     rc = (rc == -ENOENT) ? 0 : rc;
    303     ASSERT_EQ(0, rc);
    304 
    305     // one more time (expect -ENOENT)
    306     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    307     ASSERT_EQ(-ENOENT, rc);
    308 
    309     // open/create file (expect 0)
    310     rc = storage_open_file(session_, &handle, fname,
    311                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    312                            STORAGE_OP_COMPLETE);
    313     ASSERT_EQ(0, rc);
    314 
    315     // delete opened file (expect 0)
    316     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    317     ASSERT_EQ(0, rc);
    318 
    319     // one more time (expect -ENOENT)
    320     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    321     ASSERT_EQ(-ENOENT, rc);
    322 
    323     // close file
    324     storage_close_file(handle);
    325 
    326     // one more time (expect -ENOENT)
    327     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    328     ASSERT_EQ(-ENOENT, rc);
    329 }
    330 
    331 
    332 TEST_P(StorageServiceTest, OpenNoCreate) {
    333     int rc;
    334     file_handle_t handle;
    335     const char *fname = "test_open_no_create_file";
    336 
    337     // make sure test file does not exist (expect success or -ENOENT)
    338     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    339     rc = (rc == -ENOENT) ? 0 : rc;
    340     ASSERT_EQ(0, rc);
    341 
    342     // open non-existing file (expect -ENOENT)
    343     rc = storage_open_file(session_, &handle, fname, 0, 0);
    344     ASSERT_EQ(-ENOENT, rc);
    345 
    346     // create file (expect 0)
    347     rc = storage_open_file(session_, &handle, fname,
    348                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    349                            STORAGE_OP_COMPLETE);
    350     ASSERT_EQ(0, rc);
    351     storage_close_file(handle);
    352 
    353     // open existing file (expect 0)
    354     rc = storage_open_file(session_, &handle, fname, 0, 0);
    355     ASSERT_EQ(0, rc);
    356 
    357     // close it
    358     storage_close_file(handle);
    359 
    360     // delete file (expect 0)
    361     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    362     ASSERT_EQ(0, rc);
    363 }
    364 
    365 
    366 TEST_P(StorageServiceTest, OpenOrCreate) {
    367     int rc;
    368     file_handle_t handle;
    369     const char *fname = "test_open_create_file";
    370 
    371     // make sure test file does not exist (expect success or -ENOENT)
    372     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    373     rc = (rc == -ENOENT) ? 0 : rc;
    374     ASSERT_EQ(0, rc);
    375 
    376     // open/create a non-existing file (expect 0)
    377     rc = storage_open_file(session_, &handle, fname,
    378                            STORAGE_FILE_OPEN_CREATE, STORAGE_OP_COMPLETE);
    379     ASSERT_EQ(0, rc);
    380     storage_close_file(handle);
    381 
    382     // open/create an existing file (expect 0)
    383     rc = storage_open_file(session_, &handle, fname,
    384                            STORAGE_FILE_OPEN_CREATE, STORAGE_OP_COMPLETE);
    385     ASSERT_EQ(0, rc);
    386     storage_close_file(handle);
    387 
    388     // delete file (expect 0)
    389     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    390     ASSERT_EQ(0, rc);
    391 }
    392 
    393 
    394 TEST_P(StorageServiceTest, OpenCreateDeleteCharset) {
    395     int rc;
    396     file_handle_t handle;
    397     const char *fname = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz_01234.56789";
    398 
    399     // open/create file (expect 0)
    400     rc = storage_open_file(session_, &handle, fname,
    401                            STORAGE_FILE_OPEN_CREATE, STORAGE_OP_COMPLETE);
    402     ASSERT_EQ(0, rc);
    403     storage_close_file(handle);
    404 
    405     // open/create an existing file (expect 0)
    406     rc = storage_open_file(session_, &handle, fname, 0, 0);
    407     ASSERT_EQ(0, rc);
    408     storage_close_file(handle);
    409 
    410     // delete file (expect 0)
    411     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    412     ASSERT_EQ(0, rc);
    413 
    414     // open again
    415     rc = storage_open_file(session_, &handle, fname, 0, 0);
    416     ASSERT_EQ(-ENOENT, rc);
    417 }
    418 
    419 
    420 TEST_P(StorageServiceTest, WriteReadSequential) {
    421     int rc;
    422     size_t blk = 2048;
    423     file_handle_t handle;
    424     const char *fname = "test_write_read_sequential";
    425 
    426     // make sure test file does not exist (expect success or -ENOENT)
    427     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    428     rc = (rc == -ENOENT) ? 0 : rc;
    429     ASSERT_EQ(0, rc);
    430 
    431     // create file.
    432     rc = storage_open_file(session_, &handle, fname,
    433                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    434                            STORAGE_OP_COMPLETE);
    435     ASSERT_EQ(0, rc);
    436 
    437     // write a bunch of blocks (sequentially)
    438     WritePattern(handle, 0, 32 * blk, blk, true);
    439     ASSERT_FALSE(HasFatalFailure());
    440 
    441     ReadPattern(handle, 0, 32 * blk, blk);
    442     ASSERT_FALSE(HasFatalFailure());
    443 
    444     // close file
    445     storage_close_file(handle);
    446 
    447     // open the same file again
    448     rc = storage_open_file(session_, &handle, fname, 0, 0);
    449     ASSERT_EQ(0, rc);
    450 
    451     // read data back (sequentially) and check pattern again
    452     ReadPattern(handle, 0, 32 * blk, blk);
    453     ASSERT_FALSE(HasFatalFailure());
    454 
    455     // cleanup
    456     storage_close_file(handle);
    457     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    458 }
    459 
    460 
    461 TEST_P(StorageServiceTest, OpenTruncate) {
    462     int rc;
    463     uint32_t val;
    464     size_t blk = 2048;
    465     file_handle_t handle;
    466     const char *fname = "test_open_truncate";
    467 
    468     // make sure test file does not exist (expect success or -ENOENT)
    469     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    470     rc = (rc == -ENOENT) ? 0 : rc;
    471     ASSERT_EQ(0, rc);
    472 
    473     // create file.
    474     rc = storage_open_file(session_, &handle, fname,
    475                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
    476                            STORAGE_OP_COMPLETE);
    477     ASSERT_EQ(0, rc);
    478 
    479     // write some data and read it back
    480     WritePatternChunk(handle, 0, blk, true);
    481     ASSERT_FALSE(HasFatalFailure());
    482 
    483     ReadPattern(handle, 0, blk, blk);
    484     ASSERT_FALSE(HasFatalFailure());
    485 
    486      // close file
    487     storage_close_file(handle);
    488 
    489     // reopen with truncate
    490     rc = storage_open_file(session_, &handle, fname,
    491                            STORAGE_FILE_OPEN_TRUNCATE, STORAGE_OP_COMPLETE);
    492     ASSERT_EQ(0, rc);
    493 
    494     /* try to read data back (expect no data) */
    495     rc = storage_read(handle, 0LL, &val, sizeof(val));
    496     ASSERT_EQ(0, rc);
    497 
    498     // cleanup
    499     storage_close_file(handle);
    500     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    501 }
    502 
    503 
    504 TEST_P(StorageServiceTest, OpenSame) {
    505     int rc;
    506     file_handle_t handle1;
    507     file_handle_t handle2;
    508     file_handle_t handle3;
    509     const char *fname = "test_open_same_file";
    510 
    511     // open/create file (expect 0)
    512     rc = storage_open_file(session_, &handle1, fname, STORAGE_FILE_OPEN_CREATE,
    513                            STORAGE_OP_COMPLETE);
    514     ASSERT_EQ(0, rc);
    515     storage_close_file(handle1);
    516 
    517     // open an existing file first time (expect 0)
    518     rc = storage_open_file(session_, &handle1, fname, 0, 0);
    519     ASSERT_EQ(0, rc);
    520 
    521     // open the same file second time (expect error)
    522     rc = storage_open_file(session_, &handle2, fname, 0, 0);
    523     ASSERT_NE(0, rc);
    524 
    525     storage_close_file(handle1);
    526 
    527     // delete file (expect 0)
    528     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    529     ASSERT_EQ(0, rc);
    530 
    531     // open deleted file (expect -ENOENT)
    532     rc = storage_open_file(session_, &handle3, fname, 0, 0);
    533     ASSERT_EQ(-ENOENT, rc);
    534 }
    535 
    536 
    537 TEST_P(StorageServiceTest, OpenMany) {
    538     int rc;
    539     file_handle_t handles[10];
    540     char filename[10];
    541     const char *fname_fmt = "mf%d";
    542 
    543     // open or create a bunch of files (expect 0)
    544     for (uint i = 0; i < ARRAY_SIZE(handles); ++i) {
    545         snprintf(filename, sizeof(filename), fname_fmt, i);
    546         rc = storage_open_file(session_, &handles[i], filename,
    547                                STORAGE_FILE_OPEN_CREATE, STORAGE_OP_COMPLETE);
    548         ASSERT_EQ(0, rc);
    549     }
    550 
    551     // check that all handles are different
    552     for (uint i = 0; i < ARRAY_SIZE(handles)-1; i++) {
    553         for (uint j = i+1; j < ARRAY_SIZE(handles); j++) {
    554             ASSERT_NE(handles[i], handles[j]);
    555         }
    556     }
    557 
    558     // close them all
    559     for (uint i = 0; i < ARRAY_SIZE(handles); ++i) {
    560         storage_close_file(handles[i]);
    561     }
    562 
    563     // open all files without CREATE flags (expect 0)
    564     for (uint i = 0; i < ARRAY_SIZE(handles); ++i) {
    565         snprintf(filename, sizeof(filename), fname_fmt, i);
    566         rc = storage_open_file(session_, &handles[i], filename, 0, 0);
    567         ASSERT_EQ(0, rc);
    568     }
    569 
    570     // check that all handles are different
    571     for (uint i = 0; i < ARRAY_SIZE(handles)-1; i++) {
    572         for (uint j = i+1; j < ARRAY_SIZE(handles); j++) {
    573             ASSERT_NE(handles[i], handles[j]);
    574         }
    575     }
    576 
    577     // close and remove all test files
    578     for (uint i = 0; i < ARRAY_SIZE(handles); ++i) {
    579         storage_close_file(handles[i]);
    580         snprintf(filename, sizeof(filename), fname_fmt, i);
    581         rc = storage_delete_file(session_, filename, STORAGE_OP_COMPLETE);
    582         ASSERT_EQ(0, rc);
    583     }
    584 }
    585 
    586 
    587 TEST_P(StorageServiceTest, ReadAtEOF) {
    588     int rc;
    589     uint32_t val;
    590     size_t blk = 2048;
    591     file_handle_t handle;
    592     const char *fname = "test_read_eof";
    593 
    594     // open/create/truncate file
    595     rc = storage_open_file(session_, &handle, fname,
    596                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    597                            STORAGE_OP_COMPLETE);
    598     ASSERT_EQ(0, rc);
    599 
    600     // write block at offset 0
    601     WritePatternChunk(handle, 0, blk, true);
    602     ASSERT_FALSE(HasFatalFailure());
    603 
    604     // close file
    605     storage_close_file(handle);
    606 
    607     // open same file again
    608     rc = storage_open_file(session_, &handle, fname, 0, 0);
    609     ASSERT_EQ(0, rc);
    610 
    611     // read the whole block back and check pattern again
    612     ReadPattern(handle, 0, blk, blk);
    613     ASSERT_FALSE(HasFatalFailure());
    614 
    615     // read at end of file (expected 0 bytes)
    616     rc = storage_read(handle, blk, &val, sizeof(val));
    617     ASSERT_EQ(0, rc);
    618 
    619     // partial read at end of the file (expected partial data)
    620     ReadPatternEOF(handle, blk/2, blk, blk/2);
    621     ASSERT_FALSE(HasFatalFailure());
    622 
    623     // read past end of file
    624     rc = storage_read(handle, blk + 2, &val, sizeof(val));
    625     ASSERT_EQ(-EINVAL, rc);
    626 
    627     // cleanup
    628     storage_close_file(handle);
    629     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    630 }
    631 
    632 
    633 TEST_P(StorageServiceTest, GetFileSize) {
    634     int rc;
    635     size_t blk = 2048;
    636     storage_off_t size;
    637     file_handle_t handle;
    638     const char *fname = "test_get_file_size";
    639 
    640     // open/create/truncate file.
    641     rc = storage_open_file(session_, &handle, fname,
    642                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    643                            STORAGE_OP_COMPLETE);
    644     ASSERT_EQ(0, rc);
    645 
    646     // check file size (expect success and size == 0)
    647     size = 1;
    648     rc = storage_get_file_size(handle, &size);
    649     ASSERT_EQ(0, rc);
    650     ASSERT_EQ((storage_off_t)0, size);
    651 
    652     // write block
    653     WritePatternChunk(handle, 0, blk, true);
    654     ASSERT_FALSE(HasFatalFailure());
    655 
    656     // check size
    657     rc = storage_get_file_size(handle, &size);
    658     ASSERT_EQ(0, rc);
    659     ASSERT_EQ(blk, size);
    660 
    661     // write another block
    662     WritePatternChunk(handle, blk, blk, true);
    663     ASSERT_FALSE(HasFatalFailure());
    664 
    665     // check size again
    666     rc = storage_get_file_size(handle, &size);
    667     ASSERT_EQ(0, rc);
    668     ASSERT_EQ(blk*2, size);
    669 
    670     // cleanup
    671     storage_close_file(handle);
    672     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    673 }
    674 
    675 
    676 TEST_P(StorageServiceTest, SetFileSize) {
    677     int rc;
    678     size_t blk = 2048;
    679     storage_off_t size;
    680     file_handle_t handle;
    681     const char *fname = "test_set_file_size";
    682 
    683     // open/create/truncate file.
    684     rc = storage_open_file(session_, &handle, fname,
    685                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    686                            STORAGE_OP_COMPLETE);
    687     ASSERT_EQ(0, rc);
    688 
    689     // check file size (expect success and size == 0)
    690     size = 1;
    691     rc = storage_get_file_size(handle, &size);
    692     ASSERT_EQ(0, rc);
    693     ASSERT_EQ((storage_off_t)0, size);
    694 
    695     // write block
    696     WritePatternChunk(handle, 0, blk, true);
    697     ASSERT_FALSE(HasFatalFailure());
    698 
    699     // check size
    700     rc = storage_get_file_size(handle, &size);
    701     ASSERT_EQ(0, rc);
    702     ASSERT_EQ(blk, size);
    703 
    704     storage_close_file(handle);
    705 
    706     // reopen normally
    707     rc = storage_open_file(session_, &handle, fname, 0, 0);
    708     ASSERT_EQ(0, rc);
    709 
    710     // check size again
    711     rc = storage_get_file_size(handle, &size);
    712     ASSERT_EQ(0, rc);
    713     ASSERT_EQ(blk, size);
    714 
    715     // set file size to half
    716     rc = storage_set_file_size(handle, blk/2, STORAGE_OP_COMPLETE);
    717     ASSERT_EQ(0, rc);
    718 
    719     // check size again (should be half of original size)
    720     rc = storage_get_file_size(handle, &size);
    721     ASSERT_EQ(0, rc);
    722     ASSERT_EQ(blk/2, size);
    723 
    724     // read data back
    725     ReadPatternEOF(handle, 0, blk, blk/2);
    726     ASSERT_FALSE(HasFatalFailure());
    727 
    728     // set file size to 0
    729     rc = storage_set_file_size(handle, 0, STORAGE_OP_COMPLETE);
    730     ASSERT_EQ(0, rc);
    731 
    732     // check size again (should be 0)
    733     rc = storage_get_file_size(handle, &size);
    734     ASSERT_EQ(0, rc);
    735     ASSERT_EQ((storage_off_t)0LL, size);
    736 
    737     // try to read again
    738     ReadPatternEOF(handle, 0, blk, 0);
    739     ASSERT_FALSE(HasFatalFailure());
    740 
    741     // cleanup
    742     storage_close_file(handle);
    743     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    744 }
    745 
    746 
    747 void StorageServiceTest::WriteReadAtOffsetHelper(file_handle_t handle, size_t blk, size_t cnt, bool complete)
    748 {
    749     storage_off_t off1 = blk;
    750     storage_off_t off2 = blk * (cnt-1);
    751 
    752     // write known pattern data at non-zero offset1
    753     WritePatternChunk(handle, off1, blk, complete);
    754     ASSERT_FALSE(HasFatalFailure());
    755 
    756     // write known pattern data at non-zero offset2
    757     WritePatternChunk(handle, off2, blk, complete);
    758     ASSERT_FALSE(HasFatalFailure());
    759 
    760     // read data back at offset1
    761     ReadPattern(handle, off1, blk, blk);
    762     ASSERT_FALSE(HasFatalFailure());
    763 
    764     // read data back at offset2
    765     ReadPattern(handle, off2, blk, blk);
    766     ASSERT_FALSE(HasFatalFailure());
    767 
    768     // read partially written data at end of file(expect to get data only, no padding)
    769     ReadPatternEOF(handle, off2 + blk/2, blk, blk/2);
    770     ASSERT_FALSE(HasFatalFailure());
    771 
    772     // read data at offset 0 (expect success and zero data)
    773     ReadChunk(handle, 0, blk, blk, 0, 0);
    774     ASSERT_FALSE(HasFatalFailure());
    775 
    776     // read data from gap (expect success and zero data)
    777     ReadChunk(handle, off1 + blk, blk, blk, 0, 0);
    778     ASSERT_FALSE(HasFatalFailure());
    779 
    780     // read partially written data (start pointing within written data)
    781     // (expect to get written data back and zeroes at the end)
    782     ReadChunk(handle, off1 + blk/2, blk, 0, blk/2, blk/2);
    783     ASSERT_FALSE(HasFatalFailure());
    784 
    785     // read partially written data (start pointing withing unwritten data)
    786     // expect to get zeroes at the beginning and proper data at the end
    787     ReadChunk(handle, off1 - blk/2, blk, blk/2, blk/2, 0);
    788     ASSERT_FALSE(HasFatalFailure());
    789 }
    790 
    791 
    792 TEST_P(StorageServiceTest, WriteReadAtOffset) {
    793     int rc;
    794     file_handle_t handle;
    795     size_t blk = 2048;
    796     size_t blk_cnt = 32;
    797     const char *fname = "test_write_at_offset";
    798 
    799     // create/truncate file.
    800     rc = storage_open_file(session_, &handle, fname,
    801                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    802                            STORAGE_OP_COMPLETE);
    803     ASSERT_EQ(0, rc);
    804 
    805     // write a bunch of blocks filled with zeroes
    806     for (uint i = 0; i < blk_cnt; i++) {
    807         WriteZeroChunk(handle, i * blk, blk, true);
    808         ASSERT_FALSE(HasFatalFailure());
    809     }
    810 
    811     WriteReadAtOffsetHelper(handle, blk, blk_cnt, true);
    812     ASSERT_FALSE(HasFatalFailure());
    813 
    814     // cleanup
    815     storage_close_file(handle);
    816     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    817 }
    818 
    819 
    820 TEST_P(StorageServiceTest, WriteSparse) {
    821     int rc;
    822     file_handle_t handle;
    823     const char *fname = "test_write_sparse";
    824 
    825     // open/create/truncate file.
    826     rc = storage_open_file(session_, &handle, fname,
    827                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    828                            STORAGE_OP_COMPLETE);
    829     ASSERT_EQ(0, rc);
    830 
    831     // write value past en of file
    832     uint32_t val = 0xDEADBEEF;
    833     rc = storage_write(handle, 1, &val, sizeof(val), STORAGE_OP_COMPLETE);
    834     ASSERT_EQ(-EINVAL, rc);
    835 
    836     // cleanup
    837     storage_close_file(handle);
    838     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    839 }
    840 
    841 // Persistent 32k
    842 
    843 TEST_P(StorageServiceTest, CreatePersistent32K) {
    844     int rc;
    845     file_handle_t handle;
    846     size_t blk = 2048;
    847     size_t file_size = 32768;
    848     const char *fname = "test_persistent_32K_file";
    849 
    850     // create/truncate file.
    851     rc = storage_open_file(session_, &handle, fname,
    852                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    853                            STORAGE_OP_COMPLETE);
    854     ASSERT_EQ(0, rc);
    855 
    856     // write a bunch of blocks filled with pattern
    857     WritePattern(handle, 0, file_size, blk, true);
    858     ASSERT_FALSE(HasFatalFailure());
    859 
    860     // close but do not delete file
    861     storage_close_file(handle);
    862 }
    863 
    864 TEST_P(StorageServiceTest, ReadPersistent32k) {
    865     int rc;
    866     file_handle_t handle;
    867     size_t exp_len = 32 * 1024;
    868     const char *fname = "test_persistent_32K_file";
    869 
    870     // create/truncate file.
    871     rc = storage_open_file(session_, &handle, fname, 0, 0);
    872     ASSERT_EQ(0, rc);
    873 
    874     ReadPatternEOF(handle, 0, 2048, exp_len);
    875     ASSERT_FALSE(HasFatalFailure());
    876 
    877     ReadPatternEOF(handle, 0, 1024, exp_len);
    878     ASSERT_FALSE(HasFatalFailure());
    879 
    880     ReadPatternEOF(handle, 0,  332, exp_len);
    881     ASSERT_FALSE(HasFatalFailure());
    882 
    883     // close but do not delete file
    884     storage_close_file(handle);
    885 }
    886 
    887 TEST_P(StorageServiceTest, CleanUpPersistent32K) {
    888     int rc;
    889     const char *fname = "test_persistent_32K_file";
    890     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
    891     rc = (rc == -ENOENT) ? 0 : rc;
    892     ASSERT_EQ(0, rc);
    893 }
    894 
    895 // Persistent 1M
    896 TEST_P(StorageServiceTest, CreatePersistent1M_4040) {
    897     int rc;
    898     file_handle_t handle;
    899     size_t file_size = 1024 * 1024;
    900     const char *fname = "test_persistent_1M_file";
    901 
    902     // create/truncate file.
    903     rc = storage_open_file(session_, &handle, fname,
    904                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    905                            STORAGE_OP_COMPLETE);
    906     ASSERT_EQ(0, rc);
    907 
    908     // write a bunch of blocks filled with pattern
    909     WritePattern(handle, 0, file_size, 4040, true);
    910     ASSERT_FALSE(HasFatalFailure());
    911 
    912     // close but do not delete file
    913     storage_close_file(handle);
    914 }
    915 
    916 TEST_P(StorageServiceTest, CreatePersistent1M_2032) {
    917     int rc;
    918     file_handle_t handle;
    919     size_t file_size = 1024 * 1024;
    920     const char *fname = "test_persistent_1M_file";
    921 
    922     // create/truncate file.
    923     rc = storage_open_file(session_, &handle, fname,
    924                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    925                            STORAGE_OP_COMPLETE);
    926     ASSERT_EQ(0, rc);
    927 
    928     // write a bunch of blocks filled with pattern
    929     WritePattern(handle, 0, file_size, 2032, true);
    930     ASSERT_FALSE(HasFatalFailure());
    931 
    932     // close but do not delete file
    933     storage_close_file(handle);
    934 }
    935 
    936 
    937 TEST_P(StorageServiceTest, CreatePersistent1M_496) {
    938     int rc;
    939     file_handle_t handle;
    940     size_t file_size = 1024 * 1024;
    941     const char *fname = "test_persistent_1M_file";
    942 
    943     // create/truncate file.
    944     rc = storage_open_file(session_, &handle, fname,
    945                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    946                            STORAGE_OP_COMPLETE);
    947     ASSERT_EQ(0, rc);
    948 
    949     // write a bunch of blocks filled with pattern
    950     WritePattern(handle, 0, file_size, 496, true);
    951     ASSERT_FALSE(HasFatalFailure());
    952 
    953     // close but do not delete file
    954     storage_close_file(handle);
    955 }
    956 
    957 TEST_P(StorageServiceTest, CreatePersistent1M_240) {
    958     int rc;
    959     file_handle_t handle;
    960     size_t file_size = 1024 * 1024;
    961     const char *fname = "test_persistent_1M_file";
    962 
    963     // create/truncate file.
    964     rc = storage_open_file(session_, &handle, fname,
    965                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
    966                            STORAGE_OP_COMPLETE);
    967     ASSERT_EQ(0, rc);
    968 
    969     // write a bunch of blocks filled with pattern
    970     WritePattern(handle, 0, file_size, 240, true);
    971     ASSERT_FALSE(HasFatalFailure());
    972 
    973     // close but do not delete file
    974     storage_close_file(handle);
    975 }
    976 
    977 TEST_P(StorageServiceTest, ReadPersistent1M_4040) {
    978     int rc;
    979     file_handle_t handle;
    980     size_t exp_len = 1024 * 1024;
    981     const char *fname = "test_persistent_1M_file";
    982 
    983     // create/truncate file.
    984     rc = storage_open_file(session_, &handle, fname, 0, 0);
    985     ASSERT_EQ(0, rc);
    986 
    987     ReadPatternEOF(handle, 0, 4040, exp_len);
    988     ASSERT_FALSE(HasFatalFailure());
    989 
    990     // close but do not delete file
    991     storage_close_file(handle);
    992 }
    993 
    994 TEST_P(StorageServiceTest, ReadPersistent1M_2032) {
    995     int rc;
    996     file_handle_t handle;
    997     size_t exp_len = 1024 * 1024;
    998     const char *fname = "test_persistent_1M_file";
    999 
   1000     // create/truncate file.
   1001     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1002     ASSERT_EQ(0, rc);
   1003 
   1004     ReadPatternEOF(handle, 0, 2032, exp_len);
   1005     ASSERT_FALSE(HasFatalFailure());
   1006 
   1007     // close but do not delete file
   1008     storage_close_file(handle);
   1009 }
   1010 
   1011 TEST_P(StorageServiceTest, ReadPersistent1M_496) {
   1012     int rc;
   1013     file_handle_t handle;
   1014     size_t exp_len = 1024 * 1024;
   1015     const char *fname = "test_persistent_1M_file";
   1016 
   1017     // create/truncate file.
   1018     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1019     ASSERT_EQ(0, rc);
   1020 
   1021     ReadPatternEOF(handle, 0, 496, exp_len);
   1022     ASSERT_FALSE(HasFatalFailure());
   1023 
   1024     // close but do not delete file
   1025     storage_close_file(handle);
   1026 }
   1027 
   1028 TEST_P(StorageServiceTest, ReadPersistent1M_240) {
   1029     int rc;
   1030     file_handle_t handle;
   1031     size_t exp_len = 1024 * 1024;
   1032     const char *fname = "test_persistent_1M_file";
   1033 
   1034     // create/truncate file.
   1035     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1036     ASSERT_EQ(0, rc);
   1037 
   1038     ReadPatternEOF(handle, 0, 240, exp_len);
   1039     ASSERT_FALSE(HasFatalFailure());
   1040 
   1041     // close but do not delete file
   1042     storage_close_file(handle);
   1043 }
   1044 
   1045 TEST_P(StorageServiceTest, CleanUpPersistent1M) {
   1046     int rc;
   1047     const char *fname = "test_persistent_1M_file";
   1048     rc = storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1049     rc = (rc == -ENOENT) ? 0 : rc;
   1050     ASSERT_EQ(0, rc);
   1051 }
   1052 
   1053 TEST_P(StorageServiceTest, WriteReadLong) {
   1054     int rc;
   1055     file_handle_t handle;
   1056     size_t wc = 10000;
   1057     const char *fname = "test_write_read_long";
   1058 
   1059     rc = storage_open_file(session_, &handle, fname,
   1060                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1061                            STORAGE_OP_COMPLETE);
   1062     ASSERT_EQ(0, rc);
   1063 
   1064     test_buf_ = new uint32_t[wc];
   1065     fill_pattern32(test_buf_, wc * sizeof(uint32_t), 0);
   1066     rc = storage_write(handle, 0, test_buf_, wc * sizeof(uint32_t), STORAGE_OP_COMPLETE);
   1067     ASSERT_EQ((int)(wc * sizeof(uint32_t)), rc);
   1068 
   1069     rc = storage_read(handle, 0, test_buf_, wc * sizeof(uint32_t));
   1070     ASSERT_EQ((int)(wc * sizeof(uint32_t)), rc);
   1071     ASSERT_TRUE(check_pattern32(test_buf_, wc * sizeof(uint32_t), 0));
   1072 
   1073     // cleanup
   1074     storage_close_file(handle);
   1075     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1076 }
   1077 
   1078 // Negative tests
   1079 
   1080 TEST_P(StorageServiceTest, OpenInvalidFileName) {
   1081     int rc;
   1082     file_handle_t handle;
   1083     const char *fname1 = "";
   1084     const char *fname2 = "ffff$ffff";
   1085     const char *fname3 = "ffff\\ffff";
   1086     char max_name[STORAGE_MAX_NAME_LENGTH_BYTES+1];
   1087 
   1088     rc = storage_open_file(session_, &handle, fname1,
   1089                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1090                            STORAGE_OP_COMPLETE);
   1091     ASSERT_EQ(-EINVAL, rc);
   1092 
   1093     rc = storage_open_file(session_, &handle, fname2,
   1094                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1095                            STORAGE_OP_COMPLETE);
   1096     ASSERT_EQ(-EINVAL, rc);
   1097 
   1098     rc = storage_open_file(session_, &handle, fname3,
   1099                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1100                            STORAGE_OP_COMPLETE);
   1101     ASSERT_EQ(-EINVAL, rc);
   1102 
   1103     /* max name */
   1104     memset(max_name, 'a', sizeof(max_name));
   1105     max_name[sizeof(max_name)-1] = 0;
   1106 
   1107     rc = storage_open_file(session_, &handle, max_name,
   1108                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1109                            STORAGE_OP_COMPLETE);
   1110     ASSERT_EQ(-EINVAL, rc);
   1111 
   1112     max_name[sizeof(max_name)-2] = 0;
   1113     rc = storage_open_file(session_, &handle, max_name,
   1114                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1115                            STORAGE_OP_COMPLETE);
   1116     ASSERT_EQ(0, rc);
   1117 
   1118     storage_close_file(handle);
   1119     storage_delete_file(session_, max_name, STORAGE_OP_COMPLETE);
   1120 }
   1121 
   1122 
   1123 TEST_P(StorageServiceTest, BadFileHnadle) {
   1124     int rc;
   1125     file_handle_t handle;
   1126     file_handle_t handle1;
   1127     const char *fname = "test_invalid_file_handle";
   1128 
   1129     rc = storage_open_file(session_, &handle, fname,
   1130                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1131                            STORAGE_OP_COMPLETE);
   1132     ASSERT_EQ(0, rc);
   1133 
   1134     handle1 = handle + 1;
   1135 
   1136     // write to invalid file handle
   1137     uint32_t val = 0xDEDBEEF;
   1138     rc = storage_write(handle1,  0, &val, sizeof(val), STORAGE_OP_COMPLETE);
   1139     ASSERT_EQ(-EINVAL, rc);
   1140 
   1141     // read from invalid handle
   1142     rc = storage_read(handle1,  0, &val, sizeof(val));
   1143     ASSERT_EQ(-EINVAL, rc);
   1144 
   1145     // set size
   1146     rc = storage_set_file_size(handle1,  0, STORAGE_OP_COMPLETE);
   1147     ASSERT_EQ(-EINVAL, rc);
   1148 
   1149     // get size
   1150     storage_off_t fsize = (storage_off_t)(-1);
   1151     rc = storage_get_file_size(handle1,  &fsize);
   1152     ASSERT_EQ(-EINVAL, rc);
   1153 
   1154     // close (there is no way to check errors here)
   1155     storage_close_file(handle1);
   1156 
   1157     storage_close_file(handle);
   1158     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1159 }
   1160 
   1161 
   1162 TEST_P(StorageServiceTest, ClosedFileHnadle) {
   1163     int rc;
   1164     file_handle_t handle1;
   1165     file_handle_t handle2;
   1166     const char *fname1 = "test_invalid_file_handle1";
   1167     const char *fname2 = "test_invalid_file_handle2";
   1168 
   1169     rc = storage_open_file(session_, &handle1, fname1,
   1170                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1171                            STORAGE_OP_COMPLETE);
   1172     ASSERT_EQ(0, rc);
   1173 
   1174     rc = storage_open_file(session_, &handle2, fname2,
   1175                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1176                            STORAGE_OP_COMPLETE);
   1177     ASSERT_EQ(0, rc);
   1178 
   1179     // close first file handle
   1180     storage_close_file(handle1);
   1181 
   1182     // write to invalid file handle
   1183     uint32_t val = 0xDEDBEEF;
   1184     rc = storage_write(handle1,  0, &val, sizeof(val), STORAGE_OP_COMPLETE);
   1185     ASSERT_EQ(-EINVAL, rc);
   1186 
   1187     // read from invalid handle
   1188     rc = storage_read(handle1,  0, &val, sizeof(val));
   1189     ASSERT_EQ(-EINVAL, rc);
   1190 
   1191     // set size
   1192     rc = storage_set_file_size(handle1,  0, STORAGE_OP_COMPLETE);
   1193     ASSERT_EQ(-EINVAL, rc);
   1194 
   1195     // get size
   1196     storage_off_t fsize = (storage_off_t)(-1);
   1197     rc = storage_get_file_size(handle1,  &fsize);
   1198     ASSERT_EQ(-EINVAL, rc);
   1199 
   1200     // close (there is no way to check errors here)
   1201     storage_close_file(handle1);
   1202 
   1203     // clean up
   1204     storage_close_file(handle2);
   1205     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   1206     storage_delete_file(session_, fname2, STORAGE_OP_COMPLETE);
   1207 }
   1208 
   1209 // Transactions
   1210 
   1211 TEST_P(StorageServiceTest, TransactDiscardInactive) {
   1212     int rc;
   1213 
   1214     // discard current transaction (there should not be any)
   1215     rc = storage_end_transaction(session_, false);
   1216     ASSERT_EQ(0, rc);
   1217 
   1218     // try it again
   1219     rc = storage_end_transaction(session_, false);
   1220     ASSERT_EQ(0, rc);
   1221 }
   1222 
   1223 TEST_P(StorageServiceTest, TransactCommitInactive) {
   1224     int rc;
   1225 
   1226     // try to commit current transaction
   1227     rc = storage_end_transaction(session_, true);
   1228     ASSERT_EQ(0, rc);
   1229 
   1230     // try it again
   1231     rc = storage_end_transaction(session_, true);
   1232     ASSERT_EQ(0, rc);
   1233 }
   1234 
   1235 TEST_P(StorageServiceTest, TransactDiscardWrite) {
   1236 
   1237     int rc;
   1238     file_handle_t handle;
   1239     size_t blk = 2048;
   1240     size_t exp_len = 32 * 1024;
   1241     storage_off_t fsize = (storage_off_t)(-1);
   1242     const char *fname = "test_transact_discard_write";
   1243 
   1244     // open create truncate file (with commit)
   1245     rc = storage_open_file(session_, &handle, fname,
   1246                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1247                            STORAGE_OP_COMPLETE);
   1248     ASSERT_EQ(0, rc);
   1249 
   1250     // check file size
   1251     rc = storage_get_file_size(handle, &fsize);
   1252     ASSERT_EQ(0, rc);
   1253     ASSERT_EQ((storage_off_t)0, fsize);
   1254 
   1255     // write (without commit)
   1256     WritePattern(handle, 0, exp_len, blk, false);
   1257     ASSERT_FALSE(HasFatalFailure());
   1258 
   1259     // check file size
   1260     rc = storage_get_file_size(handle, &fsize);
   1261     ASSERT_EQ(0, rc);
   1262     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1263 
   1264     // abort current transaction
   1265     rc = storage_end_transaction(session_, false);
   1266     ASSERT_EQ(0, rc);
   1267 
   1268     // check file size
   1269     rc = storage_get_file_size(handle, &fsize);
   1270     ASSERT_EQ(0, rc);
   1271     ASSERT_EQ((storage_off_t)0, fsize);
   1272 
   1273     // cleanup
   1274     storage_close_file( handle);
   1275     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1276 }
   1277 
   1278 
   1279 TEST_P(StorageServiceTest, TransactDiscardWriteAppend) {
   1280 
   1281     int rc;
   1282     file_handle_t handle;
   1283     size_t blk = 2048;
   1284     size_t exp_len = 32 * 1024;
   1285     storage_off_t fsize = (storage_off_t)(-1);
   1286     const char *fname = "test_transact_write_append";
   1287 
   1288     // open create truncate file (with commit)
   1289     rc = storage_open_file(session_, &handle, fname,
   1290                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1291                            STORAGE_OP_COMPLETE);
   1292     ASSERT_EQ(0, rc);
   1293 
   1294     // write data with commit
   1295     WritePattern(handle, 0, exp_len/2, blk, true);
   1296     ASSERT_FALSE(HasFatalFailure());
   1297 
   1298     // write data without commit
   1299     WritePattern(handle, exp_len/2, exp_len/2, blk, false);
   1300     ASSERT_FALSE(HasFatalFailure());
   1301 
   1302     // check file size (should be exp_len)
   1303     rc = storage_get_file_size(handle, &fsize);
   1304     ASSERT_EQ(0, rc);
   1305     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1306 
   1307     // discard transaction
   1308     rc = storage_end_transaction(session_, false);
   1309     ASSERT_EQ(0, rc);
   1310 
   1311     // check file size, it should be exp_len/2
   1312     rc = storage_get_file_size(handle, &fsize);
   1313     ASSERT_EQ(0, rc);
   1314     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   1315 
   1316     // check file data
   1317     ReadPatternEOF(handle, 0, blk, exp_len/2);
   1318     ASSERT_FALSE(HasFatalFailure());
   1319 
   1320     // cleanup
   1321     storage_close_file(handle);
   1322     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1323 }
   1324 
   1325 TEST_P(StorageServiceTest, TransactDiscardWriteRead) {
   1326 
   1327     int rc;
   1328     file_handle_t handle;
   1329     size_t blk = 2048;
   1330     storage_off_t fsize = (storage_off_t)(-1);
   1331     const char *fname = "test_transact_discard_write_read";
   1332 
   1333     // open create truncate file (with commit)
   1334     rc = storage_open_file(session_, &handle, fname,
   1335                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1336                            STORAGE_OP_COMPLETE);
   1337     ASSERT_EQ(0, rc);
   1338 
   1339     // check file size
   1340     rc = storage_get_file_size(handle, &fsize);
   1341     ASSERT_EQ(0, rc);
   1342     ASSERT_EQ((storage_off_t)0, fsize);
   1343 
   1344     // Fill with zeroes (with commit)
   1345     for (uint i = 0; i < 32; i++) {
   1346         WriteZeroChunk(handle, i * blk, blk, true);
   1347         ASSERT_FALSE(HasFatalFailure());
   1348     }
   1349 
   1350     // check that test chunk is filled with zeroes
   1351     ReadChunk(handle, blk, blk, blk, 0, 0);
   1352     ASSERT_FALSE(HasFatalFailure());
   1353 
   1354     // write test pattern (without commit)
   1355     WritePattern(handle, blk, blk, blk, false);
   1356     ASSERT_FALSE(HasFatalFailure());
   1357 
   1358     // read it back an check pattern
   1359     ReadChunk(handle, blk, blk, 0, blk, 0);
   1360     ASSERT_FALSE(HasFatalFailure());
   1361 
   1362     // abort current transaction
   1363     rc = storage_end_transaction(session_, false);
   1364     ASSERT_EQ(0, rc);
   1365 
   1366     // read same chunk back (should be filled with zeros)
   1367     ReadChunk(handle, blk, blk, blk, 0, 0);
   1368     ASSERT_FALSE(HasFatalFailure());
   1369 
   1370     // cleanup
   1371     storage_close_file(handle);
   1372     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1373 }
   1374 
   1375 TEST_P(StorageServiceTest, TransactDiscardWriteMany) {
   1376     int rc;
   1377     file_handle_t handle1;
   1378     file_handle_t handle2;
   1379     size_t blk = 2048;
   1380     size_t exp_len1 = 32 * 1024;
   1381     size_t exp_len2 = 31 * 1024;
   1382     storage_off_t fsize = (storage_off_t)(-1);
   1383     const char *fname1 = "test_transact_discard_write_file1";
   1384     const char *fname2 = "test_transact_discard_write_file2";
   1385 
   1386     // open create truncate (with commit)
   1387     rc = storage_open_file(session_, &handle1, fname1,
   1388                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1389                            STORAGE_OP_COMPLETE);
   1390     ASSERT_EQ(0, rc);
   1391 
   1392     // open create truncate (with commit)
   1393     rc = storage_open_file(session_, &handle2, fname2,
   1394                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1395                            STORAGE_OP_COMPLETE);
   1396     ASSERT_EQ(0, rc);
   1397 
   1398     // file1: fill file with pattern (without commit)
   1399     WritePattern(handle1, 0, exp_len1, blk, false);
   1400     ASSERT_FALSE(HasFatalFailure());
   1401 
   1402     // file2: fill file with pattern (without commit)
   1403     WritePattern(handle2, 0, exp_len2, blk, false);
   1404     ASSERT_FALSE(HasFatalFailure());
   1405 
   1406     // check file size, it should be exp_len1
   1407     rc = storage_get_file_size(handle1, &fsize);
   1408     ASSERT_EQ(0, rc);
   1409     ASSERT_EQ((storage_off_t)exp_len1, fsize);
   1410 
   1411     // check file size, it should be exp_len2
   1412     rc = storage_get_file_size(handle2, &fsize);
   1413     ASSERT_EQ(0, rc);
   1414     ASSERT_EQ((storage_off_t)exp_len2, fsize);
   1415 
   1416     // commit transaction
   1417     rc = storage_end_transaction(session_, false);
   1418     ASSERT_EQ(0, rc);
   1419 
   1420     // check file size, it should be exp_len1
   1421     rc = storage_get_file_size(handle1, &fsize);
   1422     ASSERT_EQ(0, rc);
   1423     ASSERT_EQ((storage_off_t)0, fsize);
   1424 
   1425     // check file size, it should be exp_len2
   1426     rc = storage_get_file_size(handle2, &fsize);
   1427     ASSERT_EQ(0, rc);
   1428     ASSERT_EQ((storage_off_t)0, fsize);
   1429 
   1430     // check data
   1431     ReadPatternEOF(handle1, 0, blk, 0);
   1432     ASSERT_FALSE(HasFatalFailure());
   1433 
   1434     ReadPatternEOF(handle2, 0, blk, 0);
   1435     ASSERT_FALSE(HasFatalFailure());
   1436 
   1437     // cleanup
   1438     storage_close_file(handle1);
   1439     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   1440     storage_close_file(handle2);
   1441     storage_delete_file(session_, fname2, STORAGE_OP_COMPLETE);
   1442 }
   1443 
   1444 TEST_P(StorageServiceTest, TransactDiscardTruncate) {
   1445     int rc;
   1446     file_handle_t handle;
   1447     size_t blk = 2048;
   1448     size_t exp_len = 32 * 1024;
   1449     storage_off_t fsize = (storage_off_t)(-1);
   1450     const char *fname = "test_transact_discard_truncate";
   1451 
   1452     // open create truncate file (with commit)
   1453     rc = storage_open_file(session_, &handle, fname,
   1454                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1455                            STORAGE_OP_COMPLETE);
   1456     ASSERT_EQ(0, rc);
   1457 
   1458     // write data (with commit)
   1459     WritePattern(handle, 0, exp_len, blk, true);
   1460     ASSERT_FALSE(HasFatalFailure());
   1461 
   1462     // check file size
   1463     rc = storage_get_file_size(handle, &fsize);
   1464     ASSERT_EQ(0, rc);
   1465     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1466 
   1467     // close file
   1468     storage_close_file(handle);
   1469 
   1470     // open truncate file (without commit)
   1471     rc = storage_open_file(session_, &handle, fname, STORAGE_FILE_OPEN_TRUNCATE, 0);
   1472     ASSERT_EQ(0, rc);
   1473 
   1474     // check file size
   1475     rc = storage_get_file_size(handle, &fsize);
   1476     ASSERT_EQ(0, rc);
   1477     ASSERT_EQ((storage_off_t)0, fsize);
   1478 
   1479     // abort current transaction
   1480     rc = storage_end_transaction(session_, false);
   1481     ASSERT_EQ(0, rc);
   1482 
   1483     // check file size (should be an oruginal size)
   1484     rc = storage_get_file_size(handle, &fsize);
   1485     ASSERT_EQ(0, rc);
   1486     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1487 
   1488     // cleanup
   1489     storage_close_file(handle);
   1490     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1491 }
   1492 
   1493 TEST_P(StorageServiceTest, TransactDiscardSetSize) {
   1494     int rc;
   1495     file_handle_t handle;
   1496     size_t blk = 2048;
   1497     size_t exp_len = 32 * 1024;
   1498     storage_off_t fsize = (storage_off_t)(-1);
   1499     const char *fname = "test_transact_discard_set_size";
   1500 
   1501     // open create truncate file (with commit)
   1502     rc = storage_open_file(session_, &handle, fname,
   1503                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1504                            STORAGE_OP_COMPLETE);
   1505     ASSERT_EQ(0, rc);
   1506 
   1507     // write data (with commit)
   1508     WritePattern(handle, 0, exp_len, blk, true);
   1509     ASSERT_FALSE(HasFatalFailure());
   1510 
   1511     // check file size
   1512     rc = storage_get_file_size(handle, &fsize);
   1513     ASSERT_EQ(0, rc);
   1514     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1515 
   1516     // set file size to half of original (no commit)
   1517     rc = storage_set_file_size(handle,  (storage_off_t)exp_len/2, 0);
   1518     ASSERT_EQ(0, rc);
   1519 
   1520     // check file size
   1521     rc = storage_get_file_size(handle, &fsize);
   1522     ASSERT_EQ(0, rc);
   1523     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   1524 
   1525     // set file size to 1/3 of original (no commit)
   1526     rc = storage_set_file_size(handle,  (storage_off_t)exp_len/3, 0);
   1527     ASSERT_EQ(0, rc);
   1528 
   1529     // check file size
   1530     rc = storage_get_file_size(handle, &fsize);
   1531     ASSERT_EQ(0, rc);
   1532     ASSERT_EQ((storage_off_t)exp_len/3, fsize);
   1533 
   1534     // abort current transaction
   1535     rc = storage_end_transaction(session_, false);
   1536     ASSERT_EQ(0, rc);
   1537 
   1538     // check file size (should be an original size)
   1539     rc = storage_get_file_size(handle, &fsize);
   1540     ASSERT_EQ(0, rc);
   1541     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1542 
   1543     // cleanup
   1544     storage_close_file(handle);
   1545     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1546 }
   1547 
   1548 TEST_P(StorageServiceTest, TransactDiscardDelete) {
   1549     int rc;
   1550     file_handle_t handle;
   1551     size_t blk = 2048;
   1552     size_t exp_len = 32 * 1024;
   1553     storage_off_t fsize = (storage_off_t)(-1);
   1554     const char *fname = "test_transact_discard_delete";
   1555 
   1556     // open create truncate file (with commit)
   1557     rc = storage_open_file(session_, &handle, fname,
   1558                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1559                            STORAGE_OP_COMPLETE);
   1560     ASSERT_EQ(0, rc);
   1561 
   1562     // write data (with commit)
   1563     WritePattern(handle, 0, exp_len, blk, true);
   1564     ASSERT_FALSE(HasFatalFailure());
   1565 
   1566     // close it
   1567     storage_close_file(handle);
   1568 
   1569     // delete file (without commit)
   1570     rc = storage_delete_file(session_, fname, 0);
   1571     ASSERT_EQ(0, rc);
   1572 
   1573     // try to open it (should fail)
   1574     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1575     ASSERT_EQ(-ENOENT, rc);
   1576 
   1577     // abort current transaction
   1578     rc = storage_end_transaction(session_, false);
   1579     ASSERT_EQ(0, rc);
   1580 
   1581     // try to open it
   1582     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1583     ASSERT_EQ(0, rc);
   1584 
   1585     // check file size (should be an original size)
   1586     rc = storage_get_file_size(handle, &fsize);
   1587     ASSERT_EQ(0, rc);
   1588     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1589 
   1590     // cleanup
   1591     storage_close_file(handle);
   1592     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1593 }
   1594 
   1595 TEST_P(StorageServiceTest, TransactDiscardDelete2) {
   1596     int rc;
   1597     file_handle_t handle;
   1598     size_t blk = 2048;
   1599     size_t exp_len = 32 * 1024;
   1600     storage_off_t fsize = (storage_off_t)(-1);
   1601     const char *fname = "test_transact_discard_delete";
   1602 
   1603     // open create truncate file (with commit)
   1604     rc = storage_open_file(session_, &handle, fname,
   1605                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1606                            STORAGE_OP_COMPLETE);
   1607     ASSERT_EQ(0, rc);
   1608 
   1609     // write data (with commit)
   1610     WritePattern(handle, 0, exp_len, blk, true);
   1611     ASSERT_FALSE(HasFatalFailure());
   1612 
   1613     // delete file (without commit)
   1614     rc = storage_delete_file(session_, fname, 0);
   1615     ASSERT_EQ(0, rc);
   1616     storage_close_file(handle);
   1617 
   1618     // try to open it (should fail)
   1619     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1620     ASSERT_EQ(-ENOENT, rc);
   1621 
   1622     // abort current transaction
   1623     rc = storage_end_transaction(session_, false);
   1624     ASSERT_EQ(0, rc);
   1625 
   1626     // try to open it
   1627     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1628     ASSERT_EQ(0, rc);
   1629 
   1630     // check file size (should be an original size)
   1631     rc = storage_get_file_size(handle, &fsize);
   1632     ASSERT_EQ(0, rc);
   1633     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1634 
   1635     // cleanup
   1636     storage_close_file(handle);
   1637     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1638 }
   1639 
   1640 
   1641 TEST_P(StorageServiceTest, TransactDiscardCreate) {
   1642     int rc;
   1643     file_handle_t handle;
   1644     const char *fname = "test_transact_discard_create_excl";
   1645 
   1646     // delete test file just in case
   1647     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1648 
   1649     // create file (without commit)
   1650     rc = storage_open_file(session_, &handle, fname,
   1651                                STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
   1652                                0);
   1653     ASSERT_EQ(0, rc);
   1654 
   1655     // abort current transaction
   1656     rc = storage_end_transaction(session_, false);
   1657     ASSERT_EQ(0, rc);
   1658 
   1659     // cleanup
   1660     storage_close_file(handle);
   1661     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1662 }
   1663 
   1664 TEST_P(StorageServiceTest, TransactCommitWrites) {
   1665 
   1666     int rc;
   1667     file_handle_t handle;
   1668     file_handle_t handle_aux;
   1669     size_t blk = 2048;
   1670     size_t exp_len = 32 * 1024;
   1671     storage_off_t fsize = (storage_off_t)(-1);
   1672     const char *fname = "test_transact_commit_writes";
   1673 
   1674     // open second session
   1675     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   1676     ASSERT_EQ(0, rc);
   1677 
   1678     // open create truncate file (with commit)
   1679     rc = storage_open_file(session_, &handle, fname,
   1680                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1681                            STORAGE_OP_COMPLETE);
   1682     ASSERT_EQ(0, rc);
   1683 
   1684     // open the same file in aux session
   1685     rc = storage_open_file(aux_session_, &handle_aux, fname,  0, 0);
   1686     ASSERT_EQ(0, rc);
   1687 
   1688     // check file size, it should be 0
   1689     rc = storage_get_file_size(handle_aux, &fsize);
   1690     ASSERT_EQ(0, rc);
   1691     ASSERT_EQ((storage_off_t)0, fsize);
   1692 
   1693     // write data in primary session (without commit)
   1694     WritePattern(handle, 0, exp_len/2, blk, false);
   1695     ASSERT_FALSE(HasFatalFailure());
   1696 
   1697     // write more data in primary session (without commit)
   1698     WritePattern(handle, exp_len/2, exp_len/2, blk, false);
   1699     ASSERT_FALSE(HasFatalFailure());
   1700 
   1701     // check file size in aux session, it should still be 0
   1702     rc = storage_get_file_size(handle_aux, &fsize);
   1703     ASSERT_EQ(0, rc);
   1704     ASSERT_EQ((storage_off_t)0, fsize);
   1705 
   1706     // commit current transaction
   1707     rc = storage_end_transaction(session_, true);
   1708     ASSERT_EQ(0, rc);
   1709 
   1710     // check file size of aux session, should fail
   1711     rc = storage_get_file_size(handle_aux, &fsize);
   1712     ASSERT_EQ(-EBUSY, rc);
   1713 
   1714     // abort transaction in aux session to recover
   1715     rc = storage_end_transaction(aux_session_, false);
   1716     ASSERT_EQ(0, rc);
   1717 
   1718     // check file size in aux session, it should be exp_len
   1719     rc = storage_get_file_size(handle_aux, &fsize);
   1720     ASSERT_EQ(0, rc);
   1721     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1722 
   1723     // check file size in primary session, it should be exp_len
   1724     rc = storage_get_file_size(handle, &fsize);
   1725     ASSERT_EQ(0, rc);
   1726     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1727 
   1728     // check data in primary session
   1729     ReadPatternEOF(handle, 0, blk, exp_len);
   1730     ASSERT_FALSE(HasFatalFailure());
   1731 
   1732     // check data in aux session
   1733     ReadPatternEOF(handle_aux, 0, blk, exp_len);
   1734     ASSERT_FALSE(HasFatalFailure());
   1735 
   1736     // cleanup
   1737     storage_close_file(handle);
   1738     storage_close_file(handle_aux);
   1739     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1740 }
   1741 
   1742 
   1743 TEST_P(StorageServiceTest, TransactCommitWrites2) {
   1744 
   1745     int rc;
   1746     file_handle_t handle;
   1747     file_handle_t handle_aux;
   1748     size_t blk = 2048;
   1749     storage_off_t fsize = (storage_off_t)(-1);
   1750     const char *fname = "test_transact_commit_writes2";
   1751 
   1752     // open second session
   1753     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   1754     ASSERT_EQ(0, rc);
   1755 
   1756     // open create truncate file (with commit)
   1757     rc = storage_open_file(session_, &handle, fname,
   1758                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1759                            STORAGE_OP_COMPLETE);
   1760     ASSERT_EQ(0, rc);
   1761 
   1762     // open the same file in separate session
   1763     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   1764     ASSERT_EQ(0, rc);
   1765 
   1766     // check file size
   1767     rc = storage_get_file_size(handle, &fsize);
   1768     ASSERT_EQ(0, rc);
   1769     ASSERT_EQ((storage_off_t)0, fsize);
   1770 
   1771     rc = storage_get_file_size(handle_aux, &fsize);
   1772     ASSERT_EQ(0, rc);
   1773     ASSERT_EQ((storage_off_t)0, fsize);
   1774 
   1775     // discard transaction in aux_session
   1776     rc = storage_end_transaction(aux_session_,  false);
   1777     ASSERT_EQ(0, rc);
   1778 
   1779     // Fill with zeroes (with commit)
   1780     for (uint i = 0; i < 8; i++) {
   1781         WriteZeroChunk(handle, i * blk, blk, true);
   1782         ASSERT_FALSE(HasFatalFailure());
   1783     }
   1784 
   1785     // check that test chunks are filled with zeroes
   1786     ReadChunk(handle, blk, blk, blk, 0, 0);
   1787     ASSERT_FALSE(HasFatalFailure());
   1788 
   1789     ReadChunk(handle, 2 * blk, blk, blk, 0, 0);
   1790     ASSERT_FALSE(HasFatalFailure());
   1791 
   1792     // write test pattern (without commit)
   1793     WritePattern(handle, blk, blk, blk, false);
   1794     ASSERT_FALSE(HasFatalFailure());
   1795 
   1796     // write test pattern (without commit)
   1797     WritePattern(handle, 2 * blk, blk, blk, false);
   1798     ASSERT_FALSE(HasFatalFailure());
   1799 
   1800     // read it back and check pattern
   1801     ReadChunk(handle, blk, blk, 0, blk, 0);
   1802     ASSERT_FALSE(HasFatalFailure());
   1803 
   1804     ReadChunk(handle, 2 * blk, blk, 0, blk, 0);
   1805     ASSERT_FALSE(HasFatalFailure());
   1806 
   1807     // In aux session it still should be empty
   1808     ReadChunk(handle_aux, blk, blk, blk, 0, 0);
   1809     ASSERT_FALSE(HasFatalFailure());
   1810 
   1811     ReadChunk(handle_aux, 2 * blk, blk, blk, 0, 0);
   1812     ASSERT_FALSE(HasFatalFailure());
   1813 
   1814     // commit current transaction
   1815     rc = storage_end_transaction(session_, true);
   1816     ASSERT_EQ(0, rc);
   1817 
   1818     // read same chunks back in primary session
   1819     ReadChunk(handle, blk, blk, 0, blk, 0);
   1820     ASSERT_FALSE(HasFatalFailure());
   1821 
   1822     ReadChunk(handle, 2 * blk, blk, 0, blk, 0);
   1823     ASSERT_FALSE(HasFatalFailure());
   1824 
   1825     // read same chunks back in aux session (should fail)
   1826     uint32_t val;
   1827     rc = storage_read(handle_aux, blk, &val, sizeof(val));
   1828     ASSERT_EQ(-EBUSY, rc);
   1829 
   1830     rc = storage_read(handle_aux, 2 * blk, &val, sizeof(val));
   1831     ASSERT_EQ(-EBUSY, rc);
   1832 
   1833     // abort transaction in aux session
   1834     rc = storage_end_transaction(aux_session_,  false);
   1835     ASSERT_EQ(0, rc);
   1836 
   1837     // read same chunk again in aux session
   1838     ReadChunk(handle_aux, blk, blk, 0, blk, 0);
   1839     ASSERT_FALSE(HasFatalFailure());
   1840 
   1841     ReadChunk(handle_aux, 2 * blk, blk, 0, blk, 0);
   1842     ASSERT_FALSE(HasFatalFailure());
   1843 
   1844 
   1845     // cleanup
   1846     storage_close_file(handle);
   1847     storage_close_file(handle_aux);
   1848     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1849 }
   1850 
   1851 TEST_P(StorageServiceTest, TransactCommitSetSize) {
   1852     int rc;
   1853     file_handle_t handle;
   1854     file_handle_t handle_aux;
   1855     size_t blk = 2048;
   1856     size_t exp_len = 32 * 1024;
   1857     storage_off_t fsize = (storage_off_t)(-1);
   1858     const char *fname = "test_transact_commit_set_size";
   1859 
   1860     // open second session
   1861     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   1862     ASSERT_EQ(0, rc);
   1863 
   1864     // open create truncate file (with commit)
   1865     rc = storage_open_file(session_, &handle, fname,
   1866                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1867                            STORAGE_OP_COMPLETE);
   1868     ASSERT_EQ(0, rc);
   1869 
   1870     // open the same file in separate session
   1871     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   1872     ASSERT_EQ(0, rc);
   1873 
   1874     // write data (with commit)
   1875     WritePattern(handle, 0, exp_len, blk, true);
   1876     ASSERT_FALSE(HasFatalFailure());
   1877 
   1878     // check file size
   1879     rc = storage_get_file_size(handle, &fsize);
   1880     ASSERT_EQ(0, rc);
   1881     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1882 
   1883     // same in aux session
   1884     rc = storage_get_file_size(handle_aux, &fsize);
   1885     ASSERT_EQ(0, rc);
   1886     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1887 
   1888     // set file size to half of original (no commit)
   1889     rc = storage_set_file_size(handle,  (storage_off_t)exp_len/2, 0);
   1890     ASSERT_EQ(0, rc);
   1891 
   1892     // check file size
   1893     rc = storage_get_file_size(handle, &fsize);
   1894     ASSERT_EQ(0, rc);
   1895     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   1896 
   1897     rc = storage_get_file_size(handle_aux, &fsize);
   1898     ASSERT_EQ(0, rc);
   1899     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1900 
   1901     // set file size to 1/3 of original (no commit)
   1902     rc = storage_set_file_size(handle,  (storage_off_t)exp_len/3, 0);
   1903     ASSERT_EQ(0, rc);
   1904 
   1905     // check file size
   1906     rc = storage_get_file_size(handle, &fsize);
   1907     ASSERT_EQ(0, rc);
   1908     ASSERT_EQ((storage_off_t)exp_len/3, fsize);
   1909 
   1910     rc = storage_get_file_size(handle_aux, &fsize);
   1911     ASSERT_EQ(0, rc);
   1912     ASSERT_EQ((storage_off_t)exp_len, fsize);
   1913 
   1914     // commit current transaction
   1915     rc = storage_end_transaction(session_, true);
   1916     ASSERT_EQ(0, rc);
   1917 
   1918     // check file size (should be 1/3 of an original size)
   1919     rc = storage_get_file_size(handle, &fsize);
   1920     ASSERT_EQ(0, rc);
   1921     ASSERT_EQ((storage_off_t)exp_len/3, fsize);
   1922 
   1923     // check file size from aux session
   1924     rc = storage_get_file_size(handle_aux, &fsize);
   1925     ASSERT_EQ(-EBUSY, rc);
   1926 
   1927     // abort transaction in aux_session
   1928     rc = storage_end_transaction(aux_session_, false);
   1929     ASSERT_EQ(0, rc);
   1930 
   1931     // check again
   1932     rc = storage_get_file_size(handle_aux, &fsize);
   1933     ASSERT_EQ(0, rc);
   1934     ASSERT_EQ((storage_off_t)exp_len/3, fsize);
   1935 
   1936     // cleanup
   1937     storage_close_file(handle);
   1938     storage_close_file(handle_aux);
   1939     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   1940 }
   1941 
   1942 
   1943 TEST_P(StorageServiceTest, TransactCommitDelete) {
   1944     int rc;
   1945     file_handle_t handle;
   1946     file_handle_t handle_aux;
   1947     size_t blk = 2048;
   1948     size_t exp_len = 32 * 1024;
   1949     const char *fname = "test_transact_commit_delete";
   1950 
   1951     // open second session
   1952     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   1953     ASSERT_EQ(0, rc);
   1954 
   1955     // open create truncate file (with commit)
   1956     rc = storage_open_file(session_, &handle, fname,
   1957                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   1958                            STORAGE_OP_COMPLETE);
   1959     ASSERT_EQ(0, rc);
   1960 
   1961     // write data (with commit)
   1962     WritePattern(handle, 0, exp_len, blk, true);
   1963     ASSERT_FALSE(HasFatalFailure());
   1964 
   1965     // close it
   1966     storage_close_file(handle);
   1967 
   1968     // open the same file in separate session
   1969     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   1970     ASSERT_EQ(0, rc);
   1971     storage_close_file(handle_aux);
   1972 
   1973     // delete file (without commit)
   1974     rc = storage_delete_file(session_, fname, 0);
   1975     ASSERT_EQ(0, rc);
   1976 
   1977     // try to open it (should fail)
   1978     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1979     ASSERT_EQ(-ENOENT, rc);
   1980 
   1981     // open the same file in separate session (should be fine)
   1982     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   1983     ASSERT_EQ(0, rc);
   1984     storage_close_file(handle_aux);
   1985 
   1986     // commit current transaction
   1987     rc = storage_end_transaction(session_, true);
   1988     ASSERT_EQ(0, rc);
   1989 
   1990     // try to open it in primary session (still fails)
   1991     rc = storage_open_file(session_, &handle, fname, 0, 0);
   1992     ASSERT_EQ(-ENOENT, rc);
   1993 
   1994     // open the same file in aux session (should also fail)
   1995     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   1996     ASSERT_EQ(-ENOENT, rc);
   1997 }
   1998 
   1999 
   2000 TEST_P(StorageServiceTest, TransactCommitTruncate) {
   2001     int rc;
   2002     file_handle_t handle;
   2003     file_handle_t handle_aux;
   2004     size_t blk = 2048;
   2005     size_t exp_len = 32 * 1024;
   2006     storage_off_t fsize = (storage_off_t)(-1);
   2007     const char *fname = "test_transact_commit_truncate";
   2008 
   2009     // open second session
   2010     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2011     ASSERT_EQ(0, rc);
   2012 
   2013     // open create truncate file (with commit)
   2014     rc = storage_open_file(session_, &handle, fname,
   2015                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2016                            STORAGE_OP_COMPLETE);
   2017     ASSERT_EQ(0, rc);
   2018 
   2019     // write data (with commit)
   2020     WritePattern(handle, 0, exp_len, blk, true);
   2021     ASSERT_FALSE(HasFatalFailure());
   2022 
   2023     // check file size
   2024     rc = storage_get_file_size(handle, &fsize);
   2025     ASSERT_EQ(0, rc);
   2026     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2027 
   2028     // close file
   2029     storage_close_file(handle);
   2030 
   2031     // check from different session
   2032     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2033     ASSERT_EQ(0, rc);
   2034 
   2035     rc = storage_get_file_size(handle_aux, &fsize);
   2036     ASSERT_EQ(0, rc);
   2037     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2038 
   2039     // open truncate file (without commit)
   2040     rc = storage_open_file(session_, &handle, fname, STORAGE_FILE_OPEN_TRUNCATE, 0);
   2041     ASSERT_EQ(0, rc);
   2042 
   2043     // check file size
   2044     rc = storage_get_file_size(handle, &fsize);
   2045     ASSERT_EQ(0, rc);
   2046     ASSERT_EQ((storage_off_t)0, fsize);
   2047 
   2048     rc = storage_get_file_size(handle_aux, &fsize);
   2049     ASSERT_EQ(0, rc);
   2050     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2051 
   2052     // commit current transaction
   2053     rc = storage_end_transaction(session_, true);
   2054     ASSERT_EQ(0, rc);
   2055 
   2056     // check file size (should be 0)
   2057     rc = storage_get_file_size(handle, &fsize);
   2058     ASSERT_EQ(0, rc);
   2059     ASSERT_EQ((storage_off_t)0, fsize);
   2060 
   2061     // check file size in aux session (should be -EBUSY)
   2062     rc = storage_get_file_size(handle_aux, &fsize);
   2063     ASSERT_EQ(-EBUSY, rc);
   2064 
   2065     // abort transaction in aux session
   2066     rc = storage_end_transaction(aux_session_, false);
   2067     ASSERT_EQ(0, rc);
   2068 
   2069     // check again
   2070     rc = storage_get_file_size(handle_aux, &fsize);
   2071     ASSERT_EQ(0, rc);
   2072     ASSERT_EQ((storage_off_t)0, fsize);
   2073 
   2074     // cleanup
   2075     storage_close_file(handle);
   2076     storage_close_file(handle_aux);
   2077     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2078 }
   2079 
   2080 TEST_P(StorageServiceTest, TransactCommitCreate) {
   2081     int rc;
   2082     file_handle_t handle;
   2083     file_handle_t handle_aux;
   2084     storage_off_t fsize = (storage_off_t)(-1);
   2085     const char *fname = "test_transact_commit_create";
   2086 
   2087     // open second session
   2088     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2089     ASSERT_EQ(0, rc);
   2090 
   2091     // delete test file just in case
   2092     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2093 
   2094     // check from aux session
   2095     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2096     ASSERT_EQ(-ENOENT, rc);
   2097 
   2098     // create file (without commit)
   2099     rc = storage_open_file(session_, &handle, fname,
   2100                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
   2101                            0);
   2102     ASSERT_EQ(0, rc);
   2103 
   2104     // check file size
   2105     rc = storage_get_file_size(handle, &fsize);
   2106     ASSERT_EQ(0, rc);
   2107     ASSERT_EQ((storage_off_t)0, fsize);
   2108 
   2109     // close file
   2110     storage_close_file(handle);
   2111 
   2112     // check from aux session (should fail)
   2113     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2114     ASSERT_EQ(-ENOENT, rc);
   2115 
   2116     // commit current transaction
   2117     rc = storage_end_transaction(session_, true);
   2118     ASSERT_EQ(0, rc);
   2119 
   2120     // check open from normal session
   2121     rc = storage_open_file(session_, &handle, fname, 0, 0);
   2122     ASSERT_EQ(0, rc);
   2123 
   2124     // check open from aux session (should succeed)
   2125     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2126     ASSERT_EQ(0, rc);
   2127 
   2128     // cleanup
   2129     storage_close_file(handle);
   2130     storage_close_file(handle_aux);
   2131     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2132 }
   2133 
   2134 TEST_P(StorageServiceTest, TransactCommitCreateMany) {
   2135     int rc;
   2136     file_handle_t handle1;
   2137     file_handle_t handle2;
   2138     file_handle_t handle1_aux;
   2139     file_handle_t handle2_aux;
   2140     storage_off_t fsize = (storage_off_t)(-1);
   2141     const char *fname1 = "test_transact_commit_create1";
   2142     const char *fname2 = "test_transact_commit_create2";
   2143 
   2144     // open second session
   2145     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2146     ASSERT_EQ(0, rc);
   2147 
   2148     // delete test file just in case
   2149     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   2150     storage_delete_file(session_, fname2, STORAGE_OP_COMPLETE);
   2151 
   2152     // create file (without commit)
   2153     rc = storage_open_file(session_, &handle1, fname1,
   2154                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
   2155                            0);
   2156     ASSERT_EQ(0, rc);
   2157 
   2158     // create file (without commit)
   2159     rc = storage_open_file(session_, &handle2, fname2,
   2160                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
   2161                            0);
   2162     ASSERT_EQ(0, rc);
   2163 
   2164     // check file sizes
   2165     rc = storage_get_file_size(handle1, &fsize);
   2166     ASSERT_EQ(0, rc);
   2167     ASSERT_EQ((storage_off_t)0, fsize);
   2168 
   2169     rc = storage_get_file_size(handle1, &fsize);
   2170     ASSERT_EQ(0, rc);
   2171     ASSERT_EQ((storage_off_t)0, fsize);
   2172 
   2173     // close files
   2174     storage_close_file(handle1);
   2175     storage_close_file(handle2);
   2176 
   2177     // open files from aux session
   2178     rc = storage_open_file(aux_session_, &handle1_aux, fname1, 0, 0);
   2179     ASSERT_EQ(-ENOENT, rc);
   2180 
   2181     rc = storage_open_file(aux_session_, &handle2_aux, fname2, 0, 0);
   2182     ASSERT_EQ(-ENOENT, rc);
   2183 
   2184     // commit current transaction
   2185     rc = storage_end_transaction(session_, true);
   2186     ASSERT_EQ(0, rc);
   2187 
   2188     // open from primary session
   2189     rc = storage_open_file(session_, &handle1, fname1, 0, 0);
   2190     ASSERT_EQ(0, rc);
   2191 
   2192     rc = storage_open_file(session_, &handle2, fname2, 0, 0);
   2193     ASSERT_EQ(0, rc);
   2194 
   2195     // open from aux session
   2196     rc = storage_open_file(aux_session_, &handle1_aux, fname1, 0, 0);
   2197     ASSERT_EQ(0, rc);
   2198 
   2199     rc = storage_open_file(aux_session_, &handle2_aux, fname2, 0, 0);
   2200     ASSERT_EQ(0, rc);
   2201 
   2202     // cleanup
   2203     storage_close_file(handle1);
   2204     storage_close_file(handle1_aux);
   2205     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   2206     storage_close_file(handle2);
   2207     storage_close_file(handle2_aux);
   2208     storage_delete_file(session_, fname2, STORAGE_OP_COMPLETE);
   2209 }
   2210 
   2211 
   2212 TEST_P(StorageServiceTest, TransactCommitWriteMany) {
   2213     int rc;
   2214     file_handle_t handle1;
   2215     file_handle_t handle2;
   2216     file_handle_t handle1_aux;
   2217     file_handle_t handle2_aux;
   2218     size_t blk = 2048;
   2219     size_t exp_len1 = 32 * 1024;
   2220     size_t exp_len2 = 31 * 1024;
   2221     storage_off_t fsize = (storage_off_t)(-1);
   2222     const char *fname1 = "test_transact_commit_write_file1";
   2223     const char *fname2 = "test_transact_commit_write_file2";
   2224 
   2225     // open second session
   2226     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2227     ASSERT_EQ(0, rc);
   2228 
   2229     // open create truncate (with commit)
   2230     rc = storage_open_file(session_, &handle1, fname1,
   2231                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2232                            STORAGE_OP_COMPLETE);
   2233     ASSERT_EQ(0, rc);
   2234 
   2235     // open create truncate (with commit)
   2236     rc = storage_open_file(session_, &handle2, fname2,
   2237                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2238                            STORAGE_OP_COMPLETE);
   2239     ASSERT_EQ(0, rc);
   2240 
   2241     // open same files from aux session
   2242     rc = storage_open_file(aux_session_, &handle1_aux, fname1, 0, 0);
   2243     ASSERT_EQ(0, rc);
   2244 
   2245     rc = storage_open_file(aux_session_, &handle2_aux, fname2, 0, 0);
   2246     ASSERT_EQ(0, rc);
   2247 
   2248     // file1: fill file with pattern (without commit)
   2249     WritePattern(handle1, 0, exp_len1, blk, false);
   2250     ASSERT_FALSE(HasFatalFailure());
   2251 
   2252     // file2: fill file with pattern (without commit)
   2253     WritePattern(handle2, 0, exp_len2, blk, false);
   2254     ASSERT_FALSE(HasFatalFailure());
   2255 
   2256     // check file size, it should be exp_len1
   2257     rc = storage_get_file_size(handle1, &fsize);
   2258     ASSERT_EQ(0, rc);
   2259     ASSERT_EQ((storage_off_t)exp_len1, fsize);
   2260 
   2261     // check file size, it should be exp_len2
   2262     rc = storage_get_file_size(handle2, &fsize);
   2263     ASSERT_EQ(0, rc);
   2264     ASSERT_EQ((storage_off_t)exp_len2, fsize);
   2265 
   2266     // check file sizes from aux session (should be 0)
   2267     rc = storage_get_file_size(handle1_aux, &fsize);
   2268     ASSERT_EQ(0, rc);
   2269     ASSERT_EQ((storage_off_t)0, fsize);
   2270 
   2271     rc = storage_get_file_size(handle2_aux, &fsize);
   2272     ASSERT_EQ(0, rc);
   2273     ASSERT_EQ((storage_off_t)0, fsize);
   2274 
   2275     // commit transaction
   2276     rc = storage_end_transaction(session_, true);
   2277     ASSERT_EQ(0, rc);
   2278 
   2279     // check file size, it should be exp_len1
   2280     rc = storage_get_file_size(handle1, &fsize);
   2281     ASSERT_EQ(0, rc);
   2282     ASSERT_EQ((storage_off_t)exp_len1, fsize);
   2283 
   2284     // check file size, it should be exp_len2
   2285     rc = storage_get_file_size(handle2, &fsize);
   2286     ASSERT_EQ(0, rc);
   2287     ASSERT_EQ((storage_off_t)exp_len2, fsize);
   2288 
   2289     // check from aux session (should be -EBUSY)
   2290     rc = storage_get_file_size(handle1_aux, &fsize);
   2291     ASSERT_EQ(-EBUSY, rc);
   2292 
   2293     // abort transaction in aux session
   2294     rc = storage_end_transaction(aux_session_, false);
   2295     ASSERT_EQ(0, rc);
   2296 
   2297     // and check again
   2298     rc = storage_get_file_size(handle1_aux, &fsize);
   2299     ASSERT_EQ(0, rc);
   2300     ASSERT_EQ((storage_off_t)exp_len1, fsize);
   2301 
   2302     rc = storage_get_file_size(handle2_aux, &fsize);
   2303     ASSERT_EQ(0, rc);
   2304     ASSERT_EQ((storage_off_t)exp_len2, fsize);
   2305 
   2306     // check data
   2307     ReadPatternEOF(handle1, 0, blk, exp_len1);
   2308     ASSERT_FALSE(HasFatalFailure());
   2309 
   2310     ReadPatternEOF(handle2, 0, blk, exp_len2);
   2311     ASSERT_FALSE(HasFatalFailure());
   2312 
   2313     ReadPatternEOF(handle1_aux, 0, blk, exp_len1);
   2314     ASSERT_FALSE(HasFatalFailure());
   2315 
   2316     ReadPatternEOF(handle2_aux, 0, blk, exp_len2);
   2317     ASSERT_FALSE(HasFatalFailure());
   2318 
   2319     // cleanup
   2320     storage_close_file(handle1);
   2321     storage_close_file(handle1_aux);
   2322     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   2323     storage_close_file(handle2);
   2324     storage_close_file(handle2_aux);
   2325     storage_delete_file(session_, fname2, STORAGE_OP_COMPLETE);
   2326 }
   2327 
   2328 
   2329 TEST_P(StorageServiceTest, TransactCommitDeleteCreate) {
   2330     int rc;
   2331     file_handle_t handle;
   2332     file_handle_t handle_aux;
   2333     size_t blk = 2048;
   2334     size_t exp_len = 32 * 1024;
   2335     storage_off_t fsize = (storage_off_t)(-1);
   2336     const char *fname = "test_transact_delete_create";
   2337 
   2338     // open second session
   2339     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2340     ASSERT_EQ(0, rc);
   2341 
   2342     // open create truncate file (with commit)
   2343     rc = storage_open_file(session_, &handle, fname,
   2344                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2345                            STORAGE_OP_COMPLETE);
   2346     ASSERT_EQ(0, rc);
   2347 
   2348     // write data (with commit)
   2349     WritePattern(handle, 0, exp_len, blk, true);
   2350     ASSERT_FALSE(HasFatalFailure());
   2351 
   2352     // close it
   2353     storage_close_file(handle);
   2354 
   2355     // delete file (without commit)
   2356     rc = storage_delete_file(session_, fname, 0);
   2357     ASSERT_EQ(0, rc);
   2358 
   2359     // try to open it (should fail)
   2360     rc = storage_open_file(session_, &handle, fname, 0, 0);
   2361     ASSERT_EQ(-ENOENT, rc);
   2362 
   2363     // try to open it in aux session (should succeed)
   2364     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2365     ASSERT_EQ(0, rc);
   2366 
   2367     // create file with the same name (no commit)
   2368     rc = storage_open_file(session_, &handle, fname,
   2369                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_CREATE_EXCLUSIVE,
   2370                            0);
   2371     ASSERT_EQ(0, rc);
   2372 
   2373     // write half of data (with commit)
   2374     WritePattern(handle, 0, exp_len/2, blk, true);
   2375     ASSERT_FALSE(HasFatalFailure());
   2376 
   2377     // check file size (should be half)
   2378     rc = storage_get_file_size(handle, &fsize);
   2379     ASSERT_EQ(0, rc);
   2380     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   2381 
   2382     // commit transaction
   2383     rc = storage_end_transaction(session_, true);
   2384     ASSERT_EQ(0, rc);
   2385 
   2386     // check data from primary session
   2387     ReadPatternEOF(handle, 0, blk, exp_len/2);
   2388     ASSERT_FALSE(HasFatalFailure());
   2389 
   2390     // check from aux session (should fail)
   2391     rc = storage_get_file_size(handle_aux, &fsize);
   2392     ASSERT_EQ(-EINVAL, rc);
   2393 
   2394     // abort trunsaction in aux session
   2395     rc = storage_end_transaction(aux_session_, false);
   2396     ASSERT_EQ(0, rc);
   2397 
   2398     // and try again (should still fail)
   2399     rc = storage_get_file_size(handle_aux, &fsize);
   2400     ASSERT_EQ(-EINVAL, rc);
   2401 
   2402     // close file and reopen it again
   2403     storage_close_file(handle_aux);
   2404     rc = storage_open_file(aux_session_, &handle_aux, fname, 0, 0);
   2405     ASSERT_EQ(0, rc);
   2406 
   2407     // try it again (should succeed)
   2408     rc = storage_get_file_size(handle_aux, &fsize);
   2409     ASSERT_EQ(0, rc);
   2410     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   2411 
   2412     // check data
   2413     ReadPatternEOF(handle_aux, 0, blk, exp_len/2);
   2414     ASSERT_FALSE(HasFatalFailure());
   2415 
   2416     // cleanup
   2417     storage_close_file(handle);
   2418     storage_close_file(handle_aux);
   2419     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2420 }
   2421 
   2422 TEST_P(StorageServiceTest, TransactRewriteExistingTruncate) {
   2423     int rc;
   2424     file_handle_t handle;
   2425     size_t blk = 2048;
   2426     const char *fname = "test_transact_rewrite_existing_truncate";
   2427 
   2428     // open create truncate file (with commit)
   2429     rc = storage_open_file(session_, &handle, fname,
   2430                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2431                            STORAGE_OP_COMPLETE);
   2432     ASSERT_EQ(0, rc);
   2433 
   2434     // close it
   2435     storage_close_file(handle);
   2436 
   2437     // up
   2438     for (uint i = 1; i < 32; i++) {
   2439         // open truncate (no commit)
   2440         rc = storage_open_file(session_, &handle, fname, STORAGE_FILE_OPEN_TRUNCATE, 0);
   2441         ASSERT_EQ(0, rc);
   2442 
   2443         // write data (with commit)
   2444         WritePattern(handle, 0, i * blk, blk, true);
   2445         ASSERT_FALSE(HasFatalFailure());
   2446 
   2447         // close
   2448         storage_close_file(handle);
   2449     }
   2450 
   2451     // down
   2452     for (uint i = 1; i < 32; i++) {
   2453         // open truncate (no commit)
   2454         rc = storage_open_file(session_, &handle, fname, STORAGE_FILE_OPEN_TRUNCATE, 0);
   2455         ASSERT_EQ(0, rc);
   2456 
   2457         // write data (with commit)
   2458         WritePattern(handle, 0, (32 - i) * blk, blk, true);
   2459         ASSERT_FALSE(HasFatalFailure());
   2460 
   2461         // close
   2462         storage_close_file(handle);
   2463     }
   2464 
   2465     // cleanup
   2466     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2467 }
   2468 
   2469 
   2470 TEST_P(StorageServiceTest, TransactRewriteExistingSetSize) {
   2471     int rc;
   2472     file_handle_t handle;
   2473     size_t blk = 2048;
   2474     const char *fname = "test_transact_rewrite_existing_set_size";
   2475 
   2476     // open create truncate file (with commit)
   2477     rc = storage_open_file(session_, &handle, fname,
   2478                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2479                            STORAGE_OP_COMPLETE);
   2480     ASSERT_EQ(0, rc);
   2481 
   2482     // close it
   2483     storage_close_file(handle);
   2484 
   2485     // up
   2486     for (uint i = 1; i < 32; i++) {
   2487         // open truncate (no commit)
   2488         rc = storage_open_file(session_, &handle, fname, 0, 0);
   2489         ASSERT_EQ(0, rc);
   2490 
   2491         // write data (with commit)
   2492         WritePattern(handle, 0, i * blk, blk, false);
   2493         ASSERT_FALSE(HasFatalFailure());
   2494 
   2495         // update size (with commit)
   2496         rc = storage_set_file_size(handle, i * blk, STORAGE_OP_COMPLETE);
   2497         ASSERT_EQ(0, rc);
   2498 
   2499         // close
   2500         storage_close_file(handle);
   2501     }
   2502 
   2503     // down
   2504     for (uint i = 1; i < 32; i++) {
   2505         // open trancate (no commit)
   2506         rc = storage_open_file(session_, &handle, fname, 0, 0);
   2507         ASSERT_EQ(0, rc);
   2508 
   2509         // write data (with commit)
   2510         WritePattern(handle, 0, (32 - i) * blk, blk, false);
   2511         ASSERT_FALSE(HasFatalFailure());
   2512 
   2513         // update size (with commit)
   2514         rc = storage_set_file_size(handle, (32 - i) * blk, STORAGE_OP_COMPLETE);
   2515         ASSERT_EQ(0, rc);
   2516 
   2517         // close
   2518         storage_close_file(handle);
   2519     }
   2520 
   2521     // cleanup
   2522     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2523 }
   2524 
   2525 
   2526 TEST_P(StorageServiceTest, TransactResumeAfterNonFatalError) {
   2527 
   2528     int rc;
   2529     file_handle_t handle;
   2530     file_handle_t handle1;
   2531     size_t blk = 2048;
   2532     size_t exp_len = 32 * 1024;
   2533     storage_off_t fsize = (storage_off_t)(-1);
   2534     const char *fname = "test_transact_resume_writes";
   2535 
   2536     // open create truncate file (with commit)
   2537     rc = storage_open_file(session_, &handle, fname,
   2538                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2539                            STORAGE_OP_COMPLETE);
   2540     ASSERT_EQ(0, rc);
   2541 
   2542     // write (without commit)
   2543     WritePattern(handle, 0, exp_len/2, blk, false);
   2544     ASSERT_FALSE(HasFatalFailure());
   2545 
   2546     // issue some commands that should fail with non-fatal errors
   2547 
   2548     // write past end of file
   2549     uint32_t val = 0xDEDBEEF;
   2550     rc = storage_write(handle,  exp_len/2 + 1, &val, sizeof(val), 0);
   2551     ASSERT_EQ(-EINVAL, rc);
   2552 
   2553     // read past end of file
   2554     rc = storage_read(handle, exp_len/2 + 1, &val, sizeof(val));
   2555     ASSERT_EQ(-EINVAL, rc);
   2556 
   2557     // try to extend file past end of file
   2558     rc = storage_set_file_size(handle, exp_len/2 + 1, 0);
   2559     ASSERT_EQ(-EINVAL, rc);
   2560 
   2561     // open non existing file
   2562     rc = storage_open_file(session_, &handle1, "foo",
   2563                            STORAGE_FILE_OPEN_TRUNCATE, STORAGE_OP_COMPLETE);
   2564     ASSERT_EQ(-ENOENT, rc);
   2565 
   2566     // delete non-existing file
   2567     rc = storage_delete_file(session_, "foo", STORAGE_OP_COMPLETE);
   2568     ASSERT_EQ(-ENOENT, rc);
   2569 
   2570     // then resume writinga (without commit)
   2571     WritePattern(handle, exp_len/2, exp_len/2, blk, false);
   2572     ASSERT_FALSE(HasFatalFailure());
   2573 
   2574     // commit current transaction
   2575     rc = storage_end_transaction(session_, true);
   2576     ASSERT_EQ(0, rc);
   2577 
   2578     // check file size, it should be exp_len
   2579     rc = storage_get_file_size(handle, &fsize);
   2580     ASSERT_EQ(0, rc);
   2581     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2582 
   2583     // check data
   2584     ReadPatternEOF(handle, 0, blk, exp_len);
   2585     ASSERT_FALSE(HasFatalFailure());
   2586 
   2587     // cleanup
   2588     storage_close_file(handle);
   2589     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2590 }
   2591 
   2592 
   2593 // Transaction Collisions
   2594 
   2595 TEST_P(StorageServiceTest, Transact2_WriteNC) {
   2596     int rc;
   2597     file_handle_t handle1;
   2598     file_handle_t handle2;
   2599     size_t blk = 2048;
   2600     const char *fname1 = "test_transact_f1";
   2601     const char *fname2 = "test_transact_f2";
   2602 
   2603     // open second session
   2604     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2605     ASSERT_EQ(0, rc);
   2606 
   2607     rc = storage_open_file(session_, &handle1, fname1,
   2608                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2609                            STORAGE_OP_COMPLETE);
   2610     ASSERT_EQ(0, rc);
   2611 
   2612     rc = storage_open_file(aux_session_, &handle2, fname2,
   2613                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2614                            STORAGE_OP_COMPLETE);
   2615     ASSERT_EQ(0, rc);
   2616 
   2617     // session 1
   2618     WritePattern(handle1, 0, blk, blk, true);
   2619     ASSERT_FALSE(HasFatalFailure());
   2620 
   2621     // read it back
   2622     ReadPatternEOF(handle1, 0, blk, blk);
   2623     ASSERT_FALSE(HasFatalFailure());
   2624 
   2625     // session 2
   2626     WritePattern(handle2, 0, blk, blk, true);
   2627     ASSERT_FALSE(HasFatalFailure());
   2628 
   2629     // read it back
   2630     ReadPatternEOF(handle2, 0, blk, blk);
   2631     ASSERT_FALSE(HasFatalFailure());
   2632 
   2633     // cleanup
   2634     storage_close_file(handle1);
   2635     storage_close_file(handle2);
   2636 
   2637     storage_delete_file(session_, fname1, STORAGE_OP_COMPLETE);
   2638     storage_delete_file(aux_session_, fname2, STORAGE_OP_COMPLETE);
   2639 }
   2640 
   2641 
   2642 TEST_P(StorageServiceTest, Transact2_DeleteNC) {
   2643     int rc;
   2644     file_handle_t handle1;
   2645     file_handle_t handle2;
   2646     size_t blk = 2048;
   2647     const char *fname1 = "test_transact_delete_f1";
   2648     const char *fname2 = "test_transact_delete_f2";
   2649 
   2650     // open second session
   2651     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2652     ASSERT_EQ(0, rc);
   2653 
   2654     rc = storage_open_file(session_, &handle1, fname1,
   2655                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2656                            STORAGE_OP_COMPLETE);
   2657     ASSERT_EQ(0, rc);
   2658 
   2659     rc = storage_open_file(aux_session_, &handle2, fname2,
   2660                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2661                            STORAGE_OP_COMPLETE);
   2662     ASSERT_EQ(0, rc);
   2663 
   2664     // session 1
   2665     WritePattern(handle1, 0, blk, blk, true);
   2666     ASSERT_FALSE(HasFatalFailure());
   2667 
   2668     // read it back
   2669     ReadPatternEOF(handle1, 0, blk, blk);
   2670     ASSERT_FALSE(HasFatalFailure());
   2671 
   2672     // session 2
   2673     WritePattern(handle2, 0, blk, blk, true);
   2674     ASSERT_FALSE(HasFatalFailure());
   2675 
   2676     // read it back
   2677     ReadPatternEOF(handle2, 0, blk, blk);
   2678     ASSERT_FALSE(HasFatalFailure());
   2679 
   2680     // close files and delete them
   2681     storage_close_file(handle1);
   2682     storage_delete_file(session_, fname1, 0);
   2683 
   2684     storage_close_file(handle2);
   2685     storage_delete_file(aux_session_, fname2, 0);
   2686 
   2687     // commit
   2688     rc = storage_end_transaction(session_, true);
   2689     ASSERT_EQ(0, rc);
   2690 
   2691     rc = storage_end_transaction(aux_session_, true);
   2692     ASSERT_EQ(0, rc);
   2693 }
   2694 
   2695 
   2696 TEST_P(StorageServiceTest, Transact2_Write_Read) {
   2697     int rc;
   2698     file_handle_t handle1;
   2699     file_handle_t handle2;
   2700     size_t blk = 2048;
   2701     size_t exp_len = 32 * 1024;
   2702     storage_off_t fsize = (storage_off_t)(-1);
   2703     const char *fname = "test_transact_writeRead";
   2704 
   2705     // open second session
   2706     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2707     ASSERT_EQ(0, rc);
   2708 
   2709     // S1: open create truncate file
   2710     rc = storage_open_file(session_, &handle1, fname,
   2711                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2712                            STORAGE_OP_COMPLETE);
   2713     ASSERT_EQ(0, rc);
   2714 
   2715     // S2: open the same file
   2716     rc = storage_open_file(aux_session_, &handle2, fname,
   2717                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2718                            STORAGE_OP_COMPLETE);
   2719     ASSERT_EQ(0, rc);
   2720 
   2721     // S1: write (no commit)
   2722     WritePattern(handle1, 0, exp_len, blk, false);
   2723     ASSERT_FALSE(HasFatalFailure());
   2724 
   2725     // S1: read it back
   2726     ReadPatternEOF(handle1, 0, blk, exp_len);
   2727     ASSERT_FALSE(HasFatalFailure());
   2728 
   2729     // S2: check file size, it should be 0
   2730     rc = storage_get_file_size(handle2, &fsize);
   2731     ASSERT_EQ(0, rc);
   2732     ASSERT_EQ((storage_off_t)0, fsize);
   2733 
   2734     // S2: read it back (should no data)
   2735     ReadPatternEOF(handle2, 0, blk, 0);
   2736     ASSERT_FALSE(HasFatalFailure());
   2737 
   2738     // S1: commit
   2739     rc = storage_end_transaction(session_, true);
   2740     ASSERT_EQ(0, rc);
   2741 
   2742     // S2: check file size, it should fail
   2743     rc = storage_get_file_size(handle2, &fsize);
   2744     ASSERT_EQ(-EBUSY, rc);
   2745 
   2746     // S2: abort transaction
   2747     rc = storage_end_transaction(aux_session_, false);
   2748     ASSERT_EQ(0, rc);
   2749 
   2750     // S2: check file size again, it should be exp_len
   2751     rc = storage_get_file_size(handle2, &fsize);
   2752     ASSERT_EQ(0, rc);
   2753     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2754 
   2755     // S2: read it again (should be exp_len)
   2756     ReadPatternEOF(handle2, 0, blk, exp_len);
   2757     ASSERT_FALSE(HasFatalFailure());
   2758 
   2759     // cleanup
   2760     storage_close_file(handle1);
   2761     storage_close_file(handle2);
   2762 
   2763     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2764 }
   2765 
   2766 
   2767 TEST_P(StorageServiceTest, Transact2_Write_Write_Commit_Commit) {
   2768     int rc;
   2769     file_handle_t handle1;
   2770     file_handle_t handle2;
   2771     file_handle_t handle3;
   2772     size_t blk = 2048;
   2773     size_t exp_len = 32 * 1024;
   2774     storage_off_t fsize = (storage_off_t)(-1);
   2775     const char *fname = "test_transact_write_write_commit_commit";
   2776 
   2777     // open second session
   2778     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2779     ASSERT_EQ(0, rc);
   2780 
   2781     // S1: open create truncate file
   2782     rc = storage_open_file(session_, &handle1, fname,
   2783                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2784                            STORAGE_OP_COMPLETE);
   2785     ASSERT_EQ(0, rc);
   2786 
   2787     // S2: open the same file
   2788     rc = storage_open_file(aux_session_, &handle2, fname,
   2789                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2790                            STORAGE_OP_COMPLETE);
   2791     ASSERT_EQ(0, rc);
   2792 
   2793     // S1: write (no commit)
   2794     WritePattern(handle1, 0, exp_len, blk, false);
   2795     ASSERT_FALSE(HasFatalFailure());
   2796 
   2797     // S2: write (no commit)
   2798     WritePattern(handle2, 0, exp_len/2, blk, false);
   2799     ASSERT_FALSE(HasFatalFailure());
   2800 
   2801     // S1: commit
   2802     rc = storage_end_transaction(session_, true);
   2803     ASSERT_EQ(0, rc);
   2804 
   2805     // S2: read/write/get/set size/delete (all should fail)
   2806     uint32_t val = 0;
   2807     rc = storage_read(handle2, 0, &val, sizeof(val));
   2808     ASSERT_EQ(-EBUSY, rc);
   2809 
   2810     rc = storage_write(handle2, 0, &val, sizeof(val), 0);
   2811     ASSERT_EQ(-EBUSY, rc);
   2812 
   2813     rc = storage_get_file_size(handle2, &fsize);
   2814     ASSERT_EQ(-EBUSY, rc);
   2815 
   2816     rc = storage_set_file_size(handle2,  fsize, 0);
   2817     ASSERT_EQ(-EBUSY, rc);
   2818 
   2819     rc = storage_delete_file(aux_session_, fname, 0);
   2820     ASSERT_EQ(-EBUSY, rc);
   2821 
   2822     rc = storage_open_file(aux_session_, &handle3, fname,
   2823                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE, 0);
   2824     ASSERT_EQ(-EBUSY, rc);
   2825 
   2826     // S2: commit (should fail, and failed state should be cleared)
   2827     rc = storage_end_transaction(aux_session_, true);
   2828     ASSERT_EQ(-EBUSY, rc);
   2829 
   2830     // S2: check file size, it should be exp_len
   2831     rc = storage_get_file_size(handle2, &fsize);
   2832     ASSERT_EQ(0, rc);
   2833     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2834 
   2835     // S2: read it again (should be exp_len)
   2836     ReadPatternEOF(handle2, 0, blk, exp_len);
   2837     ASSERT_FALSE(HasFatalFailure());
   2838 
   2839     // cleanup
   2840     storage_close_file(handle1);
   2841     storage_close_file(handle2);
   2842 
   2843     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2844 }
   2845 
   2846 
   2847 TEST_P(StorageServiceTest, Transact2_Write_Write_Commit_Discard) {
   2848     int rc;
   2849     file_handle_t handle1;
   2850     file_handle_t handle2;
   2851     file_handle_t handle3;
   2852     size_t blk = 2048;
   2853     size_t exp_len = 32 * 1024;
   2854     storage_off_t fsize = (storage_off_t)(-1);
   2855     const char *fname = "test_transact_write_write_commit_discard";
   2856 
   2857     // open second session
   2858     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2859     ASSERT_EQ(0, rc);
   2860 
   2861     // S1: open create truncate file
   2862     rc = storage_open_file(session_, &handle1, fname,
   2863                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2864                            STORAGE_OP_COMPLETE);
   2865     ASSERT_EQ(0, rc);
   2866 
   2867     // S2: open the same file
   2868     rc = storage_open_file(aux_session_, &handle2, fname,
   2869                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2870                            STORAGE_OP_COMPLETE);
   2871     ASSERT_EQ(0, rc);
   2872 
   2873     // S1: write (no commit)
   2874     WritePattern(handle1, 0, exp_len, blk, false);
   2875     ASSERT_FALSE(HasFatalFailure());
   2876 
   2877     // S2: write (no commit)
   2878     WritePattern(handle2, 0, exp_len/2, blk, false);
   2879     ASSERT_FALSE(HasFatalFailure());
   2880 
   2881     // S1: commit
   2882     rc = storage_end_transaction(session_, true);
   2883     ASSERT_EQ(0, rc);
   2884 
   2885     // S2: read/write/get/set size/delete (all should fail)
   2886     uint32_t val = 0;
   2887     rc = storage_read(handle2, 0, &val, sizeof(val));
   2888     ASSERT_EQ(-EBUSY, rc);
   2889 
   2890     rc = storage_write(handle2, 0, &val, sizeof(val), 0);
   2891     ASSERT_EQ(-EBUSY, rc);
   2892 
   2893     rc = storage_get_file_size(handle2, &fsize);
   2894     ASSERT_EQ(-EBUSY, rc);
   2895 
   2896     rc = storage_set_file_size(handle2,  fsize, 0);
   2897     ASSERT_EQ(-EBUSY, rc);
   2898 
   2899     rc = storage_delete_file(aux_session_, fname, 0);
   2900     ASSERT_EQ(-EBUSY, rc);
   2901 
   2902     rc = storage_open_file(aux_session_, &handle3, fname,
   2903                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE, 0);
   2904     ASSERT_EQ(-EBUSY, rc);
   2905 
   2906     // S2: discard (should fail, and failed state should be cleared)
   2907     rc = storage_end_transaction(aux_session_, false);
   2908     ASSERT_EQ(0, rc);
   2909 
   2910     // S2: check file size, it should be exp_len
   2911     rc = storage_get_file_size(handle2, &fsize);
   2912     ASSERT_EQ(0, rc);
   2913     ASSERT_EQ((storage_off_t)exp_len, fsize);
   2914 
   2915     // S2: read it again (should be exp_len)
   2916     ReadPatternEOF(handle2, 0, blk, exp_len);
   2917     ASSERT_FALSE(HasFatalFailure());
   2918 
   2919     // cleanup
   2920     storage_close_file(handle1);
   2921     storage_close_file(handle2);
   2922 
   2923     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2924 }
   2925 
   2926 TEST_P(StorageServiceTest, Transact2_Write_Write_Discard_Commit) {
   2927     int rc;
   2928     file_handle_t handle1;
   2929     file_handle_t handle2;
   2930     size_t blk = 2048;
   2931     size_t exp_len = 32 * 1024;
   2932     storage_off_t fsize = (storage_off_t)(-1);
   2933     const char *fname = "test_transact_write_write_discard_commit";
   2934 
   2935     // open second session
   2936     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2937     ASSERT_EQ(0, rc);
   2938 
   2939     // S1: open create truncate file
   2940     rc = storage_open_file(session_, &handle1, fname,
   2941                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2942                            STORAGE_OP_COMPLETE);
   2943     ASSERT_EQ(0, rc);
   2944 
   2945     // S2: open the same file
   2946     rc = storage_open_file(aux_session_, &handle2, fname,
   2947                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   2948                            STORAGE_OP_COMPLETE);
   2949     ASSERT_EQ(0, rc);
   2950 
   2951     // S1: write (no commit)
   2952     WritePattern(handle1, 0, exp_len, blk, false);
   2953     ASSERT_FALSE(HasFatalFailure());
   2954 
   2955     // S2: write (no commit)
   2956     WritePattern(handle2, 0, exp_len/2, blk, false);
   2957     ASSERT_FALSE(HasFatalFailure());
   2958 
   2959     // S1: discard
   2960     rc = storage_end_transaction(session_, false);
   2961     ASSERT_EQ(0, rc);
   2962 
   2963     // S2: commit (should succeed)
   2964     rc = storage_end_transaction(aux_session_, true);
   2965     ASSERT_EQ(0, rc);
   2966 
   2967     // S2: check file size, it should be exp_len
   2968     rc = storage_get_file_size(handle2, &fsize);
   2969     ASSERT_EQ(0, rc);
   2970     ASSERT_EQ((storage_off_t)exp_len/2, fsize);
   2971 
   2972     // S2: read it again (should be exp_len)
   2973     ReadPatternEOF(handle2, 0, blk, exp_len/2);
   2974     ASSERT_FALSE(HasFatalFailure());
   2975 
   2976     // cleanup
   2977     storage_close_file(handle1);
   2978     storage_close_file(handle2);
   2979 
   2980     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   2981 }
   2982 
   2983 
   2984 TEST_P(StorageServiceTest, Transact2_Write_Write_Discard_Discard) {
   2985     int rc;
   2986     file_handle_t handle1;
   2987     file_handle_t handle2;
   2988     size_t blk = 2048;
   2989     size_t exp_len = 32 * 1024;
   2990     storage_off_t fsize = (storage_off_t)(-1);
   2991     const char *fname = "test_transact_write_write_discard_Discard";
   2992 
   2993     // open second session
   2994     rc = storage_open_session(TRUSTY_DEVICE_NAME, &aux_session_, port_);
   2995     ASSERT_EQ(0, rc);
   2996 
   2997     // S1: open create truncate file
   2998     rc = storage_open_file(session_, &handle1, fname,
   2999                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   3000                            STORAGE_OP_COMPLETE);
   3001     ASSERT_EQ(0, rc);
   3002 
   3003     // S2: open the same file
   3004     rc = storage_open_file(aux_session_, &handle2, fname,
   3005                            STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE,
   3006                            STORAGE_OP_COMPLETE);
   3007     ASSERT_EQ(0, rc);
   3008 
   3009     // S1: write (no commit)
   3010     WritePattern(handle1, 0, exp_len, blk, false);
   3011     ASSERT_FALSE(HasFatalFailure());
   3012 
   3013     // S2: write (no commit)
   3014     WritePattern(handle2, 0, exp_len/2, blk, false);
   3015     ASSERT_FALSE(HasFatalFailure());
   3016 
   3017     // S1: discard
   3018     rc = storage_end_transaction(session_, false);
   3019     ASSERT_EQ(0, rc);
   3020 
   3021     // S2: discard
   3022     rc = storage_end_transaction(aux_session_, false);
   3023     ASSERT_EQ(0, rc);
   3024 
   3025     // S2: check file size, it should be 0
   3026     rc = storage_get_file_size(handle2, &fsize);
   3027     ASSERT_EQ(0, rc);
   3028     ASSERT_EQ((storage_off_t)0, fsize);
   3029 
   3030     // S2: read it again (should be 0)
   3031     ReadPatternEOF(handle2, 0, blk, 0);
   3032     ASSERT_FALSE(HasFatalFailure());
   3033 
   3034     // cleanup
   3035     storage_close_file(handle1);
   3036     storage_close_file(handle2);
   3037 
   3038     storage_delete_file(session_, fname, STORAGE_OP_COMPLETE);
   3039 }
   3040 
   3041