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