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