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