void test_KineticClient_GetKeyRange_should_return_a_list_of_keys_within_the_specified_range(void)
{
    ByteBuffer_AppendCString(&StartKey, "key_range_00_00");
    ByteBuffer_AppendCString(&EndKey, "key_range_00_03");

    KineticKeyRange keyRange = {
        .startKey = StartKey,
        .endKey = EndKey,
        .startKeyInclusive = true,
        .endKeyInclusive = true,
        .maxReturned = MAX_KEYS_RETRIEVED,
        .reverse = false,
    };
    ByteBufferArray keyArray = {
        .buffers = &Keys[0],
        .count = MAX_KEYS_RETRIEVED
    };
    KineticOperation operation;

    KineticAllocator_NewOperation_ExpectAndReturn(&Session, &operation);
    KineticBuilder_BuildGetKeyRange_ExpectAndReturn(&operation, &keyRange, &keyArray, KINETIC_STATUS_SUCCESS);
    KineticController_ExecuteOperation_ExpectAndReturn(&operation, NULL, KINETIC_STATUS_BUFFER_OVERRUN);

    KineticStatus status = KineticClient_GetKeyRange(&Session, &keyRange, &keyArray, NULL);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_BUFFER_OVERRUN, status);
}
Пример #2
0
void test_KineticPDU_Send_should_send_the_PDU_and_return_true_upon_successful_transmission_of_full_PDU_with_value_payload(void)
{
    LOG_LOCATION;
    ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader));

    KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection);
    uint8_t valueData[128];
    ByteBuffer valueBuffer = ByteBuffer_Create(valueData, sizeof(valueData));
    ByteBuffer_AppendCString(&valueBuffer, "Some arbitrary value");
    KineticEntry entry = {.value = valueBuffer};
    KineticPDU_AttachEntry(&PDU, &entry);

    KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1);
    KineticHMAC_Populate_Expect(&PDU.hmac,
                                &PDU.protoData.message.proto, PDU.connection->session.hmacKey);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SUCCESS);
    KineticSocket_WriteProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &PDU.entry.value, KINETIC_STATUS_SUCCESS);

    TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header");

    KineticStatus status = KineticPDU_Send(&PDU);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
}
void* store_data(void* args)
{
    write_args* thread_args = (write_args*)args;
    KineticEntry* entry = &(thread_args->entry);
    int32_t objIndex;
    for (objIndex = 0; ByteBuffer_BytesRemaining(thread_args->data) > 0; objIndex++) {

        // Configure meta-data
        char keySuffix[8];
        snprintf(keySuffix, sizeof(keySuffix), "%02d", objIndex);
        entry->key.bytesUsed = strlen(thread_args->keyPrefix);
        ByteBuffer_AppendCString(&entry->key, keySuffix);
        entry->synchronization = KINETIC_SYNCHRONIZATION_WRITEBACK;

        // Prepare the next chunk of data to store
        ByteBuffer_AppendArray(&entry->value, ByteBuffer_Consume(&thread_args->data, KINETIC_OBJ_SIZE));

        // Store the data slice
        KineticStatus status = KineticClient_Put(thread_args->session, entry, NULL);
        if (status != KINETIC_STATUS_SUCCESS) {
            fprintf(stderr, "Failed writing entry %d to disk w/status: %s",
                objIndex+1, Kinetic_GetStatusDescription(status));
            return (void*)NULL;
        }
    }
    printf("File stored successfully to Kinetic device across %d entries!\n", objIndex);
    return (void*)NULL;
}
Пример #4
0
void store_data(write_args* args)
{
    KineticEntry* entry = &(args->entry);
    int32_t objIndex = 0;

    while (ByteBuffer_BytesRemaining(args->data) > 0) {

        // Configure entry meta-data
        ByteBuffer_Reset(&entry->key);
        ByteBuffer_AppendCString(&entry->key, args->keyPrefix);
        char keySuffix[8];
        snprintf(keySuffix, sizeof(keySuffix), "%02d", objIndex);
        ByteBuffer_AppendCString(&entry->key, keySuffix);

        // Prepare entry with the next object to store
        ByteBuffer_Reset(&entry->value);
        ByteBuffer_AppendArray(
            &entry->value,
            ByteBuffer_Consume(
                &args->data,
                MIN(ByteBuffer_BytesRemaining(args->data), KINETIC_OBJ_SIZE))
        );

        // Store the object
        KineticStatus status = KineticClient_Put(args->session, entry, NULL);
        if (status != KINETIC_STATUS_SUCCESS) {
            fprintf(stderr, "Kinetic PUT of object %d to host %s failed w/ status: %s\n",
                objIndex, args->ip, Kinetic_GetStatusDescription(status));
            exit(-1);
        }

        objIndex++;
    }

    printf("File stored on Kinetic Device across %d entries\n", objIndex);
}
void setUp(void)
{
    KineticLogger_Init("stdout", 3);

    // Configure start and end key buffers
    StartKey = ByteBuffer_Create(StartKeyData, sizeof(StartKeyData), sizeof(StartKeyData));
    EndKey = ByteBuffer_Create(EndKeyData, sizeof(EndKeyData), sizeof(EndKeyData));

    // Initialize buffers to hold returned keys in requested range
    for (int i = 0; i < MAX_KEYS_RETRIEVED; i++) {
        Keys[i] = ByteBuffer_Create(&KeyRangeData[i], sizeof(KeyRangeData[i]), sizeof(KeyRangeData[i]));
        char keyBuf[64];
        snprintf(keyBuf, sizeof(keyBuf), "key_range_00_%02d", i);
        ByteBuffer_AppendCString(&Keys[i], keyBuf);
    }
}
Пример #6
0
void* kinetic_put(void* kinetic_arg)
{
    struct kinetic_thread_arg* arg = kinetic_arg;
    KineticEntry* entry = &(arg->entry);
    int32_t objIndex = 0;

    while (ByteBuffer_BytesRemaining(arg->data) > 0) {

        // Configure meta-data
        char keySuffix[8];
        snprintf(keySuffix, sizeof(keySuffix), "_%02d", objIndex);
        entry->key.bytesUsed = arg->keyPrefixLength;
        ByteBuffer_AppendCString(&entry->key, keySuffix);

        // Move dbVersion back to newVersion, since successful PUTs do this
        // in order to sync with the actual entry on disk
        if (entry->newVersion.array.data == NULL) {
            entry->newVersion = entry->dbVersion;
            entry->dbVersion = BYTE_BUFFER_NONE;
        }

        // Prepare the next chunk of data to store
        ByteBuffer_AppendArray(
            &entry->value,
            ByteBuffer_Consume(
                &arg->data,
                MIN(ByteBuffer_BytesRemaining(arg->data), KINETIC_OBJ_SIZE)
            )
        );

        // Store the data slice
        LOGF("Storing a data slice (%u bytes)", entry->value.bytesUsed);
        KineticStatus status = KineticClient_Put(arg->sessionHandle, entry);
        TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
        LOGF("KineticClient put to disk success, ip:%s", arg->ip);

        objIndex++;
    }

    return (void*)0;
}
Пример #7
0
void test_KineticBuilder_BuildPut_should_build_and_execute_a_PUT_operation_to_create_a_new_object_with_calculated_tag(void)
{
    ByteArray value = ByteArray_CreateWithCString("Luke, I am your father");
    ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray newVersion = ByteArray_CreateWithCString("v1.0");
    ByteArray tag = ByteArray_CreateWithCString("some_tag");

    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .newVersion = ByteBuffer_CreateWithArray(newVersion),
        .tag = ByteBuffer_CreateWithArray(tag),
        .algorithm = KINETIC_ALGORITHM_SHA1,
        .value = ByteBuffer_CreateWithArray(value),
        .computeTag = true,
    };

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Operation.request->message, &entry);

    // Build the operation
    KineticBuilder_BuildPut(&Operation, &entry);

    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL_PTR(entry.value.array.data, Operation.value.data);
    TEST_ASSERT_EQUAL(entry.value.bytesUsed, Operation.value.len);
    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__PUT,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_ByteArray(value, Operation.entry->value.array);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
}

uint8_t ValueData[KINETIC_OBJ_SIZE];

void test_KineticBuilder_BuildGet_should_build_a_GET_operation(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = {.data = ValueData, .len = sizeof(ValueData)};
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGet(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GET, Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_FALSE(Operation.entry->metadataOnly);
}

void test_KineticBuilder_BuildGet_should_build_a_GET_operation_requesting_metadata_only(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData));
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .metadataOnly = true,
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGet(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GET, Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_TRUE(Operation.entry->metadataOnly);
}

void test_KineticBuilder_BuildGetNext_should_build_a_GETNEXT_operation(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = {.data = ValueData, .len = sizeof(ValueData)};
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGetNext(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETNEXT,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_FALSE(Operation.entry->metadataOnly);
}

void test_KineticBuilder_BuildGetNext_should_build_a_GETNEXT_operation_with_metadata_only(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData));
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .metadataOnly = true,
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGetNext(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETNEXT,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_TRUE(Operation.entry->metadataOnly);
}

void test_KineticBuilder_BuildGetPrevious_should_build_a_GETPREVIOUS_operation(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = {.data = ValueData, .len = sizeof(ValueData)};
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGetPrevious(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETPREVIOUS,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_FALSE(Operation.entry->metadataOnly);
}

void test_KineticBuilder_BuildGetPrevious_should_build_a_GETPREVIOUS_operation_with_metadata_only(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData));
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .metadataOnly = true,
        .value = ByteBuffer_CreateWithArray(value),
    };
    entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildGetPrevious(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETPREVIOUS,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_TRUE(Operation.entry->metadataOnly);
}



void test_KineticBuilder_BuildFlush_should_build_a_FLUSHALLDATA_operation(void)
{
    KineticOperation_ValidateOperation_Expect(&Operation);

    KineticBuilder_BuildFlush(&Operation);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__FLUSHALLDATA,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Basic, Operation.opCallback);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);

    TEST_ASSERT_NULL(Operation.response);
}



void test_KineticBuilder_BuildDelete_should_build_a_DELETE_operation(void)
{
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData));
    KineticEntry entry = {.key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value)};

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry);

    KineticBuilder_BuildDelete(&Operation, &entry);

    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__DELETE,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Delete, Operation.opCallback);
    TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data);
    TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len);
    TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
}


void test_KineticBuilder_BuildGetKeyRange_should_build_a_GetKeyRange_request(void)
{
    const int maxKeyLen = 32; // arbitrary key length for test
    uint8_t startKeyData[maxKeyLen];
    uint8_t endKeyData[maxKeyLen];
    ByteBuffer startKey, endKey;
    startKey = ByteBuffer_Create(startKeyData, sizeof(startKeyData), 0);
    ByteBuffer_AppendCString(&startKey, "key_range_00_00");
    endKey = ByteBuffer_Create(endKeyData, sizeof(endKeyData), 0);
    ByteBuffer_AppendCString(&endKey, "key_range_00_03");
    const int numKeysInRange = 4;
    KineticKeyRange range = {
        .startKey = startKey,
        .endKey = endKey,
        .startKeyInclusive = true,
        .endKeyInclusive = true,
        .maxReturned = numKeysInRange,
        .reverse = false,
    };

    uint8_t keysData[numKeysInRange][maxKeyLen];
    ByteBuffer keyBuffers[numKeysInRange];
    for (int i = 0; i < numKeysInRange; i++) {
        keyBuffers[i] = ByteBuffer_Create(keysData[i], maxKeyLen, 0);
    }
    ByteBufferArray keys = {.buffers = keyBuffers, .count = numKeysInRange};

    KineticOperation_ValidateOperation_Expect(&Operation);
    KineticMessage_ConfigureKeyRange_Expect(&Request.message, &range);

    KineticBuilder_BuildGetKeyRange(&Operation, &range, &keys);

    TEST_ASSERT_TRUE(Request.command->header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETKEYRANGE,
        Request.command->header->messagetype);
    TEST_ASSERT_EQUAL_PTR(KineticCallbacks_GetKeyRange, Operation.opCallback);
    TEST_ASSERT_NULL(Operation.entry);
    TEST_ASSERT_EQUAL_PTR(&Request, Operation.request);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
    TEST_ASSERT_EQUAL_PTR(&Request.message.command, Request.command);
}


void test_KineticBuilder_BuildP2POperation_should_build_a_P2POperation_request(void)
{
    ByteBuffer oldKey1 = ByteBuffer_Create((void*)0x1234, 10, 10);
    ByteBuffer newKey1 = ByteBuffer_Create((void*)0x4321, 33, 33);
    ByteBuffer version1 = ByteBuffer_Create((void*)0xABC, 6, 6);

    ByteBuffer oldKey2 = ByteBuffer_Create((void*)0x5678, 12, 12);
    ByteBuffer newKey2 = ByteBuffer_Create((void*)0x8765, 200, 200);

    KineticP2P_OperationData ops2[] ={
        {
            .key = oldKey2,
            .newKey = newKey2,
        }
    };

    KineticP2P_Operation chained_p2pOp = {
        .peer = {
            .hostname = "hostname1",
            .port = 4321,
        },
        .numOperations = 1,
        .operations = ops2
    };

    KineticP2P_OperationData ops[] ={
        {
            .key = oldKey1,
            .version = version1,
            .newKey = newKey1,
            .chainedOperation = &chained_p2pOp,
        },
        {
            .key = oldKey2,
            .newKey = newKey2,
        }
    };

    KineticP2P_Operation p2pOp = {
        .peer = {
            .hostname = "hostname",
            .port = 1234,
            .tls = true,
        },
        .numOperations = 2,
        .operations = ops
    };

    KineticOperation_ValidateOperation_Expect(&Operation);

    KineticBuilder_BuildP2POperation(&Operation, &p2pOp);

    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__PEER2PEERPUSH,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body);
    
    TEST_ASSERT_NOT_NULL(Request.command->body->p2poperation);

    TEST_ASSERT_EQUAL("hostname",
        Request.command->body->p2poperation->peer->hostname);

    TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->has_port);

    TEST_ASSERT_EQUAL(1234,
        Request.command->body->p2poperation->peer->port);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->has_tls);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->tls);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->allchildoperationssucceeded);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->has_allchildoperationssucceeded);

    TEST_ASSERT_EQUAL(2,
        Request.command->body->p2poperation->n_operation);

    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_key);
    TEST_ASSERT_EQUAL(oldKey1.array.data,
        Request.command->body->p2poperation->operation[0]->key.data);
    TEST_ASSERT_EQUAL(oldKey1.bytesUsed,
        Request.command->body->p2poperation->operation[0]->key.len);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_newkey);
    TEST_ASSERT_EQUAL(newKey1.array.data,
        Request.command->body->p2poperation->operation[0]->newkey.data);
    TEST_ASSERT_EQUAL(newKey1.bytesUsed,
        Request.command->body->p2poperation->operation[0]->newkey.len);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_version);
    TEST_ASSERT_EQUAL(version1.array.data,
        Request.command->body->p2poperation->operation[0]->version.data);
    TEST_ASSERT_EQUAL(version1.bytesUsed,
        Request.command->body->p2poperation->operation[0]->version.len);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->has_force);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->force);

    TEST_ASSERT_NOT_NULL(Request.command->body->p2poperation->operation[0]->p2pop);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->peer->has_port);
    TEST_ASSERT_EQUAL(4321,
        Request.command->body->p2poperation->operation[0]->p2pop->peer->port);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->peer->has_tls);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->p2pop->peer->tls);
    TEST_ASSERT_EQUAL(1,
        Request.command->body->p2poperation->operation[0]->p2pop->n_operation);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_key);
    TEST_ASSERT_EQUAL(oldKey2.array.data,
        Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->key.data);
    TEST_ASSERT_EQUAL(oldKey2.bytesUsed,
        Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->key.len);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_newkey);
    TEST_ASSERT_EQUAL(newKey2.array.data,
        Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->newkey.data);
    TEST_ASSERT_EQUAL(newKey2.bytesUsed,
        Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->newkey.len);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_version);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_force);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->force);
    TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[0]->status);

    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_key);
    TEST_ASSERT_EQUAL(oldKey2.array.data,
        Request.command->body->p2poperation->operation[1]->key.data);
    TEST_ASSERT_EQUAL(oldKey2.bytesUsed,
        Request.command->body->p2poperation->operation[1]->key.len);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_newkey);
    TEST_ASSERT_EQUAL(newKey2.array.data,
        Request.command->body->p2poperation->operation[1]->newkey.data);
    TEST_ASSERT_EQUAL(newKey2.bytesUsed,
        Request.command->body->p2poperation->operation[1]->newkey.len);
    TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[1]->has_version);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_force);
    TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->force);
    TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[1]->p2pop);
    TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[1]->status);

    TEST_ASSERT_EQUAL_PTR(&p2pOp, Operation.p2pOp);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);

    TEST_ASSERT_NULL(Operation.response);

    // This just free's the malloc'd memory and sets statuses to "invalid" (since no operation was actually performed)
    KineticAllocator_FreeP2PProtobuf(Request.command->body->p2poperation);
}



/*******************************************************************************
 * Admin Client Operations
*******************************************************************************/

void test_KineticBuilder_BuildGetLog_should_build_a_GetLog_request(void)
{
    KineticLogInfo* pInfo;

    KineticOperation_ValidateOperation_Expect(&Operation);

    KineticStatus status = KineticBuilder_BuildGetLog(&Operation,
        KINETIC_DEVICE_INFO_TYPE_STATISTICS, BYTE_ARRAY_NONE, &pInfo);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETLOG,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body);
    TEST_ASSERT_EQUAL_PTR(&Request.message.getLog, Request.command->body->getlog);
    TEST_ASSERT_NOT_NULL(Request.command->body->getlog->types);
    TEST_ASSERT_EQUAL(1, Request.command->body->getlog->n_types);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__STATISTICS,
        Request.command->body->getlog->types[0]);
    TEST_ASSERT_EQUAL_PTR(&pInfo, Operation.deviceInfo);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
}

void test_KineticBuilder_BuildGetLog_should_build_a_GetLog_request_to_retrieve_device_specific_log_info(void)
{
    KineticLogInfo* pInfo;
    const char nameData[] = "com.WD";
    ByteArray name = ByteArray_CreateWithCString(nameData);

    KineticOperation_ValidateOperation_Expect(&Operation);

    KineticStatus status = KineticBuilder_BuildGetLog(&Operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
    TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETLOG,
        Request.message.command.header->messagetype);
    TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body);
    TEST_ASSERT_EQUAL_PTR(&Request.message.getLog, Request.command->body->getlog);
    TEST_ASSERT_NOT_NULL(Request.command->body->getlog->types);
    TEST_ASSERT_EQUAL(1, Request.command->body->getlog->n_types);
    TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE,
        Request.command->body->getlog->types[0]);
    TEST_ASSERT_EQUAL_PTR(&Request.message.getLogDevice, Request.command->body->getlog->device);
    TEST_ASSERT_TRUE(Request.command->body->getlog->device->has_name);
    TEST_ASSERT_EQUAL_PTR(nameData, Request.command->body->getlog->device->name.data);
    TEST_ASSERT_EQUAL(strlen(nameData), Request.command->body->getlog->device->name.len);
    TEST_ASSERT_EQUAL_PTR(&pInfo, Operation.deviceInfo);
    TEST_ASSERT_FALSE(Request.pinAuth);
    TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds);
    TEST_ASSERT_NULL(Operation.response);
}

void test_KineticBuilder_BuildGetLog_should_return_KINETIC_STATUS_DEVICE_NAME_REQUIRED_if_name_not_specified_correctly(void)
{
    KineticLogInfo* pInfo;
    char nameData[] = "com.WD";
    ByteArray name;
    KineticStatus status;

    // Length is zero
    name.data = (uint8_t*)nameData;
    name.len = 0;
    KineticOperation_ValidateOperation_Expect(&Operation);
    status = KineticBuilder_BuildGetLog(&Operation,
        COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo);
    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status);

    // Data is NULL
    name.data = NULL;
    name.len = strlen(nameData);
    KineticOperation_ValidateOperation_Expect(&Operation);
    status = KineticBuilder_BuildGetLog(&Operation,
        COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo);
    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status);

    // Length is zero and data is NULL
    name.data = NULL;
    name.len = 0;
    KineticOperation_ValidateOperation_Expect(&Operation);
    status = KineticBuilder_BuildGetLog(&Operation,
        COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo);
    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status);
}
Пример #8
0
void test_kinetic_client_should_be_able_to_store_an_arbitrarily_large_binary_object_and_split_across_entries_via_ovelapped_IO_operations(void)
{
    const int maxIterations = 4;
    const int numCopiesToStore = 4;
    const KineticSession sessionConfig = {
        .host = "localhost",
        .port = KINETIC_PORT,
        .nonBlocking = false,
        .clusterVersion = 0,
        .identity = 1,
        .hmacKey = ByteArray_CreateWithCString("asdfasdf"),
    };

    for (int iteration = 0; iteration < maxIterations; iteration++) {

        printf("Overlapped PUT operation (iteration %d of %d)\n",
               iteration + 1, maxIterations);

        char* buf = malloc(sizeof(char) * BUFSIZE);
        int fd = open("test/support/data/test.data", O_RDONLY);
        int dataLen = read(fd, buf, BUFSIZE);
        close(fd);
        TEST_ASSERT_MESSAGE(dataLen > 0, "read error");

        /* thread structure */
        struct kinetic_thread_arg* kt_arg;
        pthread_t thread_id[KINETIC_MAX_THREADS];

        kinetic_client = malloc(sizeof(KineticSessionHandle) * numCopiesToStore);
        TEST_ASSERT_NOT_NULL_MESSAGE(kinetic_client, "kinetic_client malloc failed");

        kt_arg = malloc(sizeof(struct kinetic_thread_arg) * numCopiesToStore);
        TEST_ASSERT_NOT_NULL_MESSAGE(kt_arg, "kinetic_thread_arg malloc failed");

        for (int i = 0; i < numCopiesToStore; i++) {

            printf("    Overlapped PUT operations (writing copy %d of %d) on IP (iteration %d of %d):%s\n",
                   i + 1, numCopiesToStore, iteration + 1, maxIterations, sessionConfig.host);

            // Establish connection
            TEST_ASSERT_EQUAL_KineticStatus(
                KINETIC_STATUS_SUCCESS,
                KineticClient_Connect(&sessionConfig, &kinetic_client[i]));
            strcpy(kt_arg[i].ip, sessionConfig.host);

            // Configure the KineticEntry
            char keyPrefix[128];
            snprintf(keyPrefix, sizeof(keyPrefix), "pre_%02d%02d", iteration, i);
            LOGF("NEW HUNK PREFIX: %s", keyPrefix);
            ByteBuffer keyBuf = ByteBuffer_Create(kt_arg[i].key, sizeof(kt_arg[i].key));
            ByteBuffer_AppendCString(&keyBuf, keyPrefix);
            kt_arg[i].keyPrefixLength = keyBuf.bytesUsed;

            ByteBuffer verBuf = ByteBuffer_Create(kt_arg[i].version, sizeof(kt_arg[i].version));
            ByteBuffer_AppendCString(&verBuf, "v1.0");

            ByteBuffer tagBuf = ByteBuffer_Create(kt_arg[i].tag, sizeof(kt_arg[i].tag));
            ByteBuffer_AppendCString(&tagBuf, "some_value_tag...");

            ByteBuffer valBuf = ByteBuffer_Create(kt_arg[i].value, sizeof(kt_arg[i].value));
            
            kt_arg[i].entry = (KineticEntry) {
                .key = keyBuf,
                .newVersion = verBuf,
                .tag = tagBuf,
                .metadataOnly = false,
                .algorithm = KINETIC_ALGORITHM_SHA1,
                .value = valBuf,
            };

            // Create a ByteBuffer for consuming chunks of data out of for overlapped PUTs
            kt_arg[i].data = ByteBuffer_Create(buf, dataLen);

            // Spawn the worker thread
            kt_arg[i].sessionHandle = kinetic_client[i];
            int create_status = pthread_create(&thread_id[i], NULL, kinetic_put, &kt_arg[i]);
            TEST_ASSERT_EQUAL_MESSAGE(0, create_status, "pthread create failed");
        }

        // Wait for each overlapped PUT operations to complete and cleanup
        printf("  Waiting for PUT threads to exit...\n");
        for (int i = 0; i < numCopiesToStore; i++) {
            int join_status = pthread_join(thread_id[i], NULL);
            TEST_ASSERT_EQUAL_MESSAGE(0, join_status, "pthread join failed");
            KineticClient_Disconnect(&kinetic_client[i]);
        }

        // Cleanup the rest of the reources
        free(kinetic_client);
        free(kt_arg);
        free(buf);

        printf("  Iteration complete!\n");
    }

    printf("Overlapped PUT operation test complete!\n");
}
Пример #9
0
void test_KineticPDU_Send_should_send_the_specified_message_and_return_false_upon_failure_to_send_header(void)
{
    LOG_LOCATION;
    ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader));

    KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection);
    char valueData[] = "Some arbitrary value";
    KineticEntry entry = {.value = ByteBuffer_Create(valueData, strlen(valueData))};
    KineticPDU_AttachEntry(&PDU, &entry);

    KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1);
    KineticHMAC_Populate_Expect(&PDU.hmac, &PDU.protoData.message.proto, PDU.connection->session.hmacKey);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SOCKET_ERROR);

    TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header");

    KineticStatus status = KineticPDU_Send(&PDU);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_ERROR, status);
}

void test_KineticPDU_Send_should_send_the_specified_message_and_return_false_upon_failure_to_send_protobuf(void)
{
    LOG_LOCATION;
    ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader));

    KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection);
    char valueData[] = "Some arbitrary value";
    KineticEntry entry = {.value = ByteBuffer_Create(valueData, strlen(valueData))};
    KineticPDU_AttachEntry(&PDU, &entry);

    KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1);
    KineticHMAC_Populate_Expect(&PDU.hmac,
                                &PDU.protoData.message.proto, PDU.connection->session.hmacKey);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SUCCESS);
    KineticSocket_WriteProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SOCKET_TIMEOUT);

    TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header");

    KineticStatus status = KineticPDU_Send(&PDU);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_TIMEOUT, status);
}

void test_KineticPDU_Send_should_send_the_specified_message_and_return_KineticStatus_if_value_write_fails(void)
{
    LOG_LOCATION;
    ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader));

    KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection);
    uint8_t valueData[128];
    KineticEntry entry = {.value = ByteBuffer_Create(valueData, sizeof(valueData))};
    ByteBuffer_AppendCString(&entry.value, "Some arbitrary value");
    KineticPDU_AttachEntry(&PDU, &entry);

    KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1);
    KineticHMAC_Populate_Expect(&PDU.hmac, &PDU.protoData.message.proto, PDU.connection->session.hmacKey);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SUCCESS);
    KineticSocket_WriteProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS);
    KineticSocket_Write_ExpectAndReturn(Connection.socket, &entry.value, KINETIC_STATUS_SOCKET_TIMEOUT);

    TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header");

    KineticStatus status = KineticPDU_Send(&PDU);

    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_TIMEOUT, status);
}


void test_KineticPDU_Receive_should_receive_a_message_with_value_payload_and_return_true_upon_receipt_of_valid_PDU(void)
{
    LOG_LOCATION;
    Connection.connectionID = 98765;
    KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection);
    ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader));

    // Fake value/payload length
    uint8_t data[1024];
    ByteArray expectedValue = ByteArray_Create(data, sizeof(data));
    ByteArray_FillWithDummyData(expectedValue);
    KineticEntry entry = {.value = ByteBuffer_CreateWithArray(expectedValue)};
    KineticPDU_AttachEntry(&PDU, &entry);

    KineticSocket_Read_ExpectAndReturn(Connection.socket, &headerNBO, sizeof(KineticPDUHeader), KINETIC_STATUS_SUCCESS);
    KineticSocket_ReadProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS);
    KineticHMAC_Validate_ExpectAndReturn(PDU.proto, PDU.connection->session.hmacKey, true);
    KineticSocket_Read_ExpectAndReturn(Connection.socket, &entry.value, expectedValue.len, KINETIC_STATUS_SUCCESS);

    PDU.headerNBO.valueLength = KineticNBO_FromHostU32(expectedValue.len);
    EnableAndSetPDUConnectionID(&PDU, 12345);
    EnableAndSetPDUStatus(&PDU, KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS);

    KineticStatus status = KineticPDU_Receive(&PDU);

    TEST_ASSERT_EQUAL(KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS,
                      PDU.protoData.message.status.code);
    TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
}
Пример #10
0
int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    // Initialize kinetic-c and configure sessions
    KineticSession* session;
    KineticClientConfig clientConfig = {
        .logFile = "stdout",
        .logLevel = 1,
    };
    KineticClient * client = KineticClient_Init(&clientConfig);
    if (client == NULL) { return 1; }
    const char HmacKeyString[] = "asdfasdf";
    KineticSessionConfig sessionConfig = {
        .host = "localhost",
        .port = KINETIC_PORT,
        .clusterVersion = 0,
        .identity = 1,
        .hmacKey = ByteArray_CreateWithCString(HmacKeyString),
    };
    KineticStatus status = KineticClient_CreateSession(&sessionConfig, client, &session);
    if (status != KINETIC_STATUS_SUCCESS) {
        fprintf(stderr, "Failed connecting to the Kinetic device w/status: %s\n",
            Kinetic_GetStatusDescription(status));
        exit(1);
    }

    // Read in file contents to store
    const char* dataFile = "test/support/data/test.data";
    struct stat st;
    stat(dataFile, &st);
    char* buf = malloc(st.st_size);
    int fd = open(dataFile, O_RDONLY);
    long dataLen = read(fd, buf, st.st_size);
    close(fd);
    if (dataLen <= 0) {
        fprintf(stderr, "Failed reading data file to store: %s\n", dataFile);
        exit(-1);
    }


    write_args* writeArgs = calloc(1, sizeof(write_args));
    writeArgs->session = session;
    
    // Create a ByteBuffer for consuming chunks of data out of for overlapped PUTs
    writeArgs->data = ByteBuffer_Create(buf, dataLen, 0);

    // Configure common meta-data for the entries
    struct timeval now;
    gettimeofday(&now, NULL);
    snprintf(writeArgs->keyPrefix, sizeof(writeArgs->keyPrefix), "%010ld_", now.tv_sec);
    ByteBuffer verBuf = ByteBuffer_Create(writeArgs->version, sizeof(writeArgs->version), 0);
    ByteBuffer_AppendCString(&verBuf, "v1.0");
    ByteBuffer tagBuf = ByteBuffer_Create(writeArgs->tag, sizeof(writeArgs->tag), 0);
    ByteBuffer_AppendCString(&tagBuf, "some_value_tag...");
    writeArgs->entry = (KineticEntry) {
        .key = ByteBuffer_Create(writeArgs->key, sizeof(writeArgs->key), 0),
        // .newVersion = verBuf,
        .tag = tagBuf,
        .algorithm = KINETIC_ALGORITHM_SHA1,
        .value = ByteBuffer_Create(writeArgs->value, sizeof(writeArgs->value), 0),
        .synchronization = KINETIC_SYNCHRONIZATION_WRITEBACK,
    };
    strcpy(writeArgs->ip, sessionConfig.host);

    // Store the data
    printf("\nWriting data file to the Kinetic device...\n");
    store_data(writeArgs);

    // Shutdown client connection and cleanup
    KineticClient_DestroySession(writeArgs->session);
    KineticClient_Shutdown(client);
    free(writeArgs);
    free(buf);

    return 0;
}