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