void test_KineticBuilder_BuildPut_should_build_and_execute_a_PUT_operation_to_create_a_new_object(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), }; 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); }
void test_KineticSession_Connect_should_connect_to_specified_host(void) { const uint8_t hmacKey[] = {1, 6, 3, 5, 4, 8, 19}; KineticSession expected = { .config = (KineticSessionConfig) { .host = "valid-host.com", .port = 1234, .clusterVersion = 17, .identity = 12, .hmacKey = { .data = expected.config.keyData, .len = sizeof(hmacKey)}, }, .connected = true, .socket = 24, }; memcpy(expected.config.hmacKey.data, hmacKey, expected.config.hmacKey.len); KineticSession session = { .config = (KineticSessionConfig) { .host = "valid-host.com", .port = expected.config.port, .clusterVersion = expected.config.clusterVersion, .identity = expected.config.identity, .hmacKey = { .data = Session.config.keyData, .len = sizeof(hmacKey)}, }, .connected = true, .socket = 24, }; memcpy(session.config.hmacKey.data, hmacKey, expected.config.hmacKey.len); KineticSocket_Connect_ExpectAndReturn(expected.config.host, expected.config.port, expected.socket); Bus_RegisterSocket_ExpectAndReturn(NULL, BUS_SOCKET_PLAIN, expected.socket, &session, true); KineticResourceWaiter_WaitTilAvailable_ExpectAndReturn(&session.connectionReady, KINETIC_CONNECTION_TIMEOUT_SECS, true); // Establish connection KineticStatus status = KineticSession_Connect(&session); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_TRUE(session.connected); TEST_ASSERT_EQUAL(expected.socket, session.socket); TEST_ASSERT_EQUAL_STRING(expected.config.host, session.config.host); TEST_ASSERT_EQUAL(expected.config.port, session.config.port); TEST_ASSERT_EQUAL_INT64(expected.config.clusterVersion, session.config.clusterVersion); TEST_ASSERT_EQUAL_INT64(expected.config.identity, session.config.identity); TEST_ASSERT_EQUAL_ByteArray(expected.config.hmacKey, session.config.hmacKey); }
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); }
void setUp(void) { SystemTestSetup(0, true); KeyBuffer = ByteBuffer_CreateAndAppendCString(KeyData, sizeof(KeyData), strKey); ExpectedKeyBuffer = ByteBuffer_CreateAndAppendCString(ExpectedKeyData, sizeof(ExpectedKeyData), strKey); TagBuffer = ByteBuffer_CreateAndAppendCString(TagData, sizeof(TagData), "SomeTagValue"); ExpectedTagBuffer = ByteBuffer_CreateAndAppendCString(ExpectedTagData, sizeof(ExpectedTagData), "SomeTagValue"); TestValue = ByteArray_CreateWithCString("lorem ipsum... blah blah blah... etc."); ValueBuffer = ByteBuffer_CreateAndAppendArray(ValueData, sizeof(ValueData), TestValue); // Setup to write some test data KineticEntry putEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_FLUSH, }; KineticStatus status = KineticClient_Put(Fixture.session, &putEntry, NULL); if (status != KINETIC_STATUS_SUCCESS) { failing = true; TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } // Validate the object exists initially KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_WRITETHROUGH, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL_ByteArray(putEntry.key.array, getEntry.key.array); TEST_ASSERT_EQUAL_ByteArray(putEntry.tag.array, getEntry.tag.array); TEST_ASSERT_EQUAL(putEntry.algorithm, getEntry.algorithm); TEST_ASSERT_EQUAL_ByteBuffer(putEntry.value, getEntry.value); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); // Set the erase PIN to something non-empty strcpy(NewPinData, SESSION_PIN); OldPin = ByteArray_Create(OldPinData, 0); NewPin = ByteArray_Create(NewPinData, strlen(NewPinData)); status = KineticAdminClient_SetErasePin(Fixture.adminSession, OldPin, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } void tearDown(void) { KineticStatus status = KINETIC_STATUS_INVALID; if (failing) { return; } // Validate the object no longer exists KineticEntry regetEntryMetadata = { .key = KeyBuffer, .tag = TagBuffer, .metadataOnly = true, }; status = KineticClient_Get(Fixture.session, ®etEntryMetadata, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_NOT_FOUND, status); TEST_ASSERT_ByteArray_EMPTY(regetEntryMetadata.value.array); SystemTestShutDown(); } void test_SecureErase_should_erase_device_contents(void) { KineticStatus status = KineticAdminClient_SecureErase(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } void test_InstantErase_should_erase_device_contents(void) { KineticStatus status = KineticAdminClient_InstantErase(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); }
void setUp(void) { NewPinSet = false; Locked = false; SystemTestSetup(1, true); KeyBuffer = ByteBuffer_CreateAndAppendCString(KeyData, sizeof(KeyData), strKey); ExpectedKeyBuffer = ByteBuffer_CreateAndAppendCString(ExpectedKeyData, sizeof(ExpectedKeyData), strKey); TagBuffer = ByteBuffer_CreateAndAppendCString(TagData, sizeof(TagData), "SomeTagValue"); ExpectedTagBuffer = ByteBuffer_CreateAndAppendCString(ExpectedTagData, sizeof(ExpectedTagData), "SomeTagValue"); TestValue = ByteArray_CreateWithCString("lorem ipsum... blah blah blah... etc."); ValueBuffer = ByteBuffer_CreateAndAppendArray(ValueData, sizeof(ValueData), TestValue); // Setup to write some test data KineticEntry putEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_FLUSH, }; KineticStatus status = KineticClient_Put(Fixture.session, &putEntry, NULL); // Validate the object exists initially KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_WRITETHROUGH, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL_ByteArray(putEntry.key.array, getEntry.key.array); TEST_ASSERT_EQUAL_ByteArray(putEntry.tag.array, getEntry.tag.array); TEST_ASSERT_EQUAL(putEntry.algorithm, getEntry.algorithm); TEST_ASSERT_EQUAL_ByteBuffer(putEntry.value, getEntry.value); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); // Set the erase PIN to something non-empty strcpy(NewPinData, SESSION_PIN); OldPin = ByteArray_Create(OldPinData, 0); NewPin = ByteArray_Create(NewPinData, strlen(NewPinData)); status = KineticAdminClient_SetLockPin(Fixture.adminSession, OldPin, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); NewPinSet = true; } void tearDown(void) { KineticStatus status; // Unlock if for some reason we are still locked in order to // prevent the device from staying in a locked/unusable state if (Locked) { status = KineticAdminClient_UnlockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = false; } // Set the lock PIN back to empty if (NewPinSet) { status = KineticAdminClient_SetLockPin(Fixture.adminSession, NewPin, OldPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); NewPinSet = false; } SystemTestShutDown(); } void test_KineticAdmin_should_lock_and_unlock_a_device(void) { KineticStatus status; status = KineticAdminClient_LockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = true; /* Currently, the device appears to just hang up on us rather than * returning DEVICE_LOCKED (unlike the simulator). Some sort of * command here to confirm that the device lock succeeded would * be a better test. We need to check if the drive has another * interface that exposes this. */ if (SystemTestIsUnderSimulator()) { // Validate the object cannot being accessed while locked KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .value = ValueBuffer, .force = true, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_LOCKED, status); } status = KineticAdminClient_UnlockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = false; }
void test_KineticOperation_BuildGet_should_build_a_GET_operation(void) { LOG_LOCATION; const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = {.data = ValueData, .len = sizeof(ValueData)}; KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value), }; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildGet(&Operation, &entry); // GET // The GET operation is used to retrieve the value and metadata for a given key. // // Request Message: // command { // header { // // See above for descriptions of these fields // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // // The mesageType should be GET // messageType: GET TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType); // } // body { // keyValue { // // See above // key: "..." // } // } // } // // See above // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_EQUAL_ByteArray(value, Operation.response->entry.value.array); TEST_ASSERT_EQUAL(0, Operation.response->entry.value.bytesUsed); } void test_KineticOperation_BuildGet_should_build_a_GET_operation_requesting_metadata_only(void) { LOG_LOCATION; 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), }; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildGet(&Operation, &entry); // GET // The GET operation is used to retrieve the value and metadata for a given key. // // Request Message: // command { // header { // // See above for descriptions of these fields // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // // The mesageType should be GET // messageType: GET TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType); // } // body { // keyValue { // // See above // key: "..." // } // } // } // // See above // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_ByteBuffer_NULL(Response.entry.value); } void test_KineticOperation_BuildDelete_should_build_a_DELETE_operation(void) { LOG_LOCATION; const ByteArray key = ByteArray_CreateWithCString("foobar"); KineticEntry entry = {.key = ByteBuffer_CreateWithArray(key)}; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildDelete(&Operation, &entry); // The `DELETE` operation removes the entry for a given key. It respects the // same locking behavior around `dbVersion` and `force` as described in the previous sections. // The following request will remove a key value pair to the store. // // ``` // command { // // See top level cross cutting concerns for header details // header { // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // messageType should be DELETE // messageType: DELETE TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_DELETE, Request.proto->command->header->messageType); // } // body { // keyValue { // key: "..." // // See write operation cross cutting concerns // synchronization: ... // } // } // } // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_ByteBuffer_NULL(Response.entry.value); }
void test_KineticOperation_BuildPut_should_build_and_execute_a_PUT_operation_to_create_a_new_object(void) { LOG_LOCATION; 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"); KineticConnection_IncrementSequence_Expect(&Connection); // PUT // The PUT operation sets the value and metadata for a given key. If a value // already exists in the store for the given key, the client must pass a // value for dbVersion which matches the stored version for this key to // overwrite the value metadata. This behavior can be overridden (so that // the version is ignored and the value and metadata are always written) by // setting forced to true in the KeyValue option. // // Request Message: // // command { // // See top level cross cutting concerns for header details // header { // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // messageType: PUT // } // body: { // keyValue { // // Required bytes // // The key for the value being set // key: "..." // // // Required bytes // // Versions are set on objects to support optimistic locking. // // For operations that modify data, if the dbVersion sent in the // // request message does not match the version stored in the db, the // // request will fail. // dbVersion: "..." // // // Required bytes // // Specifies what the next version of the data will be if this // // operation is successful. // newVersion: "..." // // // Optional bool, default false // // Setting force to true ignores potential version mismatches // // and carries out the operation. // force: true // // // Optional bytes // // The integrity value for the data. This value should be computed // // by the client application by applying the hash algorithm // // specified below to the value (and only to the value). // // The algorithm used should be specified in the algorithm field. // // The Kinetic Device will not do any processing on this value. // tag: "..." // // // Optional enum // // The algorithm used by the client to compute the tag. // // The allowed values are: SHA1, SHA2, SHA3, CRC32, CRC64 // algorithm: ... // // // Optional Synchronization enum value, defaults to WRITETHROUGH // // Allows client to specify if the data must be written to disk // // immediately, or can be written in the future. // // // // WRITETHROUGH: This request is made persistent before returning. // // This does not effect any other pending operations. // // WRITEBACK: They can be made persistent when the drive chooses, // // or when a subsequent FLUSH is give to the drive. // // FLUSH: All pending information that has not been written is // // pushed to the disk and the command that specifies // // FLUSH is written last and then returned. All WRITEBACK writes // // that have received ending status will be guaranteed to be // // written before the FLUSH operation is returned completed. // synchronization: ... // } KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .newVersion = ByteBuffer_CreateWithArray(newVersion), // .dbVersion = ByteBuffer_CreateWithArray(BYTE_ARRAY_NONE), .tag = ByteBuffer_CreateWithArray(tag), .algorithm = KINETIC_ALGORITHM_SHA1, .value = ByteBuffer_CreateWithArray(value), }; KineticMessage_ConfigureKeyValue_Expect(&Operation.request->protoData.message, &entry); // } // } // hmac: "..." // // Build the operation KineticOperation_BuildPut(&Operation, &entry); // Ensure proper message type TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_PUT, Request.proto->command->header->messageType); TEST_ASSERT_EQUAL_ByteArray(value, Operation.request->entry.value.array); TEST_ASSERT_EQUAL(0, Operation.request->entry.value.bytesUsed); TEST_ASSERT_ByteBuffer_NULL(Response.entry.value); }