int test_unique(cl_cluster *clc) { cl_object key; cl_object key2; cl_bin bin; cl_rv rv; cl_write_parameters cl_wp; citrusleaf_object_init_str(&key, myKey); citrusleaf_object_init_str(&key2, myKey2); strcpy(&bin.bin_name[0],bin1); citrusleaf_object_init_str(&bin.object, strData2); cl_write_parameters_set_default(&cl_wp); cl_wp.unique = 1; rv = citrusleaf_put(clc, ns, myset, &key, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_FAIL_KEY_EXISTS ){ printf(" TEST FAILED - test unique: should return key exists, returns %d\n", rv); return -1; } rv = citrusleaf_put(clc, ns, myset, &key2, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - test unique: value should have been able to be written, actual value %d\n",rv); return -1; } return 0; }
int test_batch(cl_cluster *clc) { cl_rv rv; cl_bin bins[3]; cl_object keys[2]; cf_digest digests[2]; char *userData = "foobar"; citrusleaf_object_init_str(&keys[0],myKey); citrusleaf_object_init_str(&keys[1],myKey2); citrusleaf_object_init(&bins[0].object); citrusleaf_object_init(&bins[1].object); citrusleaf_object_init(&bins[2].object); strcpy(&bins[0].bin_name[0], bin1); strcpy(&bins[1].bin_name[0], bin2); strcpy(&bins[2].bin_name[0], bin3); citrusleaf_calculate_digest(myset, &keys[0], &digests[0]); citrusleaf_calculate_digest(myset, &keys[1], &digests[1]); rv = citrusleaf_get_many_digest(clc, (char *)ns, digests, 2, bins, 3, false, batch_cb, userData); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILS - get many (batch) fails with %d\n", rv); return -1; } return 0; }
int lset_create_test (char * keystr, char * ldt_bin ){ static char * meth = "lset_create_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; char * create_package = "StandardList"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); citrusleaf_object_init_str( &o_key, keystr ); cl_rv rv = 0; rv = aerospike_lset_create( c, ns, set, &o_key, bname, create_spec, lset_g_config->timeout_ms); citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rv; }
int lset_config_test(char * keystr, char * ldt_bin) { static char * meth = "lset_config_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = 1; char * valstr; as_result * resultp; time_t cur_t; cur_t = time(NULL); cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; citrusleaf_object_init_str( &o_key, keystr ); //print config of lset rc = aerospike_lset_config( &resultp, c, ns, set, &o_key, bname, lset_g_config->timeout_ms); if ( rc == CITRUSLEAF_OK ) { valstr = as_val_tostring( resultp->value ); printf(" Config parameters:\n %s \n", valstr); } citrusleaf_object_free( &o_key ); return rc; }
int write_new_value(uint32_t key, cl_object *key_o, cf_digest *d) { uint64_t new_value_int; do { new_value_int = rand_64(); } while (new_value_int == VALUE_UNINIT || new_value_int == VALUE_DELETED); g_config.values[key] = new_value_int; char new_value_str[g_config.value_len+1]; my_itoa(new_value_str, new_value_int, g_config.value_len); cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init_str(&values[0].object, new_value_str); cl_write_parameters cl_w_p; cl_write_parameters_set_default(&cl_w_p); cl_w_p.timeout_ms = g_config.timeout_ms; int rv; rv = citrusleaf_put(g_config.asc, g_config.ns, g_config.set, key_o, values, 1, &cl_w_p); if (rv != 0) { fprintf(stderr, "aerospike put returned error %d, fail digest %"PRIx64"\n",rv, *(uint64_t *)d); if (g_config.strict) return(-1); } citrusleaf_object_init(&values[0].object); rv = citrusleaf_verify(g_config.asc, g_config.ns, g_config.set, key_o, values, 1, g_config.timeout_ms, NULL); if (rv != 0) { fprintf(stderr, "aerospike get returned error %d digest %"PRIx64"\n",rv, *(uint64_t *)d); if (g_config.strict) return(-1); } // test! if (values[0].object.type != CL_STR) { fprintf(stderr, "read value has wrong type: expect string (3) got %d, fail digest %"PRIx64"\n",(int)values[0].object.type, *(uint64_t *)d); if (g_config.strict) return(-1); } if (strcmp(values[0].object.u.str, new_value_str) != 0) { fprintf(stderr, "read value does not match set value. digest %"PRIx64"\n", *(uint64_t *)d); fprintf(stderr, " expecting: %s\n",new_value_str); fprintf(stderr, " got: %s\n",values[0].object.u.str); if (g_config.strict) return( -1); } citrusleaf_object_free(&values[0].object); atomic_int_add(g_config.read_counter, 1); atomic_int_add(g_config.write_counter, 1); return(0); }
void asval_to_clobject(as_val * val, cl_object * obj) { switch(val->type) { case AS_NIL: { citrusleaf_object_init_null(obj); break; } case AS_INTEGER: { as_integer * v = as_integer_fromval(val); citrusleaf_object_init_int(obj, as_integer_toint(v)); break; } case AS_STRING: { as_string * v = as_string_fromval(val); citrusleaf_object_init_str(obj, as_string_get(v)); break; } case AS_BYTES: { as_bytes * v = as_bytes_fromval(val); citrusleaf_object_init_blob2(obj, v->value, v->size, (cl_type)v->type); break; } case AS_LIST:{ as_buffer buffer; as_buffer_init(&buffer); as_serializer ser; as_msgpack_init(&ser); as_serializer_serialize(&ser, val, &buffer); as_serializer_destroy(&ser); citrusleaf_object_init_blob_handoff(obj, buffer.data, buffer.size, CL_LIST); break; } case AS_MAP: { as_buffer buffer; as_buffer_init(&buffer); as_serializer ser; as_msgpack_init(&ser); as_serializer_serialize(&ser, val, &buffer); as_serializer_destroy(&ser); citrusleaf_object_init_blob_handoff(obj, buffer.data, buffer.size, CL_MAP); break; } default: { // raise an error break; } } }
/** * LSET Search WITH TRANSFORM TEST * For a single record, perform a series of SET Search. * and do a server side transform of the byte-packed data * Using the previously created record, repeatedly call stack search with * varying numbers of search counts. */ int lset_search_with_transform_test(char * keystr, char * ldt_bin, char * filter_function, as_list * fargs, int iterations ) { static char * meth = "lset_search_with_transform_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } cl_rv rc = 0; INFO("[ENTER]:<%s:%s>: Iterations(%d) Key(%s) LSOBin(%s)", MOD, meth, iterations, keystr, ldt_bin ); cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; int vals_read; int misses; int errs; int i; as_result * resultp; INFO("[DEBUG]:<%s:%s>: Run search() iterations(%d)", MOD, meth, iterations ); // NOTE: Must FREE the result (resultp) for EACH ITERATION. int search_count = 2; // Soon -- set by Random Number citrusleaf_object_init_str( &o_key, keystr ); for ( i = 0; i < iterations ; i ++ ){ search_count++; rc = aerospike_lset_search_then_filter( &resultp, c, ns, set, &o_key, bname, search_count, filter_function, fargs, lset_g_config->timeout_ms); //lset_process_read_results( meth, rc, resultp, i, &vals_read, &misses, // &errs, search_count ); // Count up the reads (total) lset_g_config->read_vals_counter += search_count; lset_g_config->read_ops_counter += 1; } // end for each search iteration citrusleaf_object_free( &o_key ); INFO("[EXIT]:<%s:%s>: RC(%d)", MOD, meth, rc ); return rc; } // end lset_search_with_transform_test()
int lset_size_test(char * keystr, char * ldt_bin, uint32_t * size) { static char * meth = "lset_size_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = 0; cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; citrusleaf_object_init_str( &o_key, keystr ); //check size of lset rc = aerospike_lset_size( size, c, ns, set, &o_key, bname, lset_g_config->timeout_ms); citrusleaf_object_free( &o_key ); return rc; }
/** * LSET READ TEST * For a single record, perform a series of SET READS. * Using the previously created record, repeatedly call set read with * varying keys (value type is passed in via "format"). * NOTE: We must EXPLICITLY FREE the result, as it is a malloc'd * object that is handed to us. * + keystr: String Key to find the record * + ldt_bin: Bin Name of the LDT * + iterations: Number of iterations to run this test * + seed: Seed value for the random number pattern * + data_format: Type of value (number, string, list) */ int lset_search_test(char * keystr, char * ldt_bin, int iterations, int seed, int data_format ) { static char * meth = "lset_search_test()"; cl_rv rc = CITRUSLEAF_OK; as_result * resultp; char * valstr; // INFO("[ENTER]:<%s:%s>: Iterations(%d) Key(%s) LSOBin(%s) Sd(%d) DF(%d)", // MOD, meth, iterations, keystr, ldt_bin, seed, data_format); cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; int vals_read = 0; int misses = 0; int errs = 0; // INFO("[DEBUG]:<%s:%s>: Run search() iterations(%d)", MOD, meth, iterations ); as_val * valp ; srand( seed ); // NOTE: Must FREE the result for EACH ITERATION. citrusleaf_object_init_str( &o_key, keystr ); int iseed; if(iterations == 0) { rc = aerospike_lset_search( &resultp, c, ns, set, &o_key, bname, NULL, lset_g_config->timeout_ms); //printf("search result is %s\n", as_val_tostring(resultp->value)); if( resultp != NULL ) as_result_destroy( resultp ); } else { for ( int i = 0; i < iterations ; i ++ ){ iseed = i * 10; lset_generate_value( &valp, iseed, data_format ); // INFO("[DEBUG]:<%s:%s>: Peek(%d)", MOD, meth, iterations ); rc = aerospike_lset_search( &resultp, c, ns, set, &o_key, bname, valp, lset_g_config->timeout_ms); if(rc == CITRUSLEAF_OK) { rc = lset_process_read_results( meth, rc, resultp, i, &vals_read, &misses, &errs, valp); } //printf("compared result: exp-%s act-%s ",as_val_tostring(valp),as_val_tostring(resultp->value)); // Clean up -- release the result object if( resultp != NULL ) as_result_destroy( resultp ); // Count up the reads (total) if(rc == 0) { lset_g_config->read_vals_counter += 1; } lset_g_config->read_ops_counter += 1; } // end for each search iteration } citrusleaf_object_free( &o_key ); // INFO("[EXIT]:<%s:%s>: RC(%d)", MOD, meth, rc ); return rc; } // end lset_search_test()
int test_operate(cl_cluster *clc) { cl_object key; cl_operation ops[3]; cl_rv rv; citrusleaf_object_init_str(&key, myKey); strcpy(&ops[0].bin.bin_name[0],bin1); strcpy(&ops[1].bin.bin_name[0],bin2); strcpy(&ops[2].bin.bin_name[0],bin3); citrusleaf_object_init(&ops[0].bin.object); citrusleaf_object_init_int(&ops[1].bin.object, 2); citrusleaf_object_init_blob(&ops[2].bin.object, blobData2, strlen(blobData2)+1); ops[0].op = CL_OP_READ; ops[1].op = CL_OP_INCR; ops[2].op = CL_OP_WRITE; rv = citrusleaf_operate(clc, ns, myset, &key, &ops[0], 3, NULL, false, NULL); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - go-right case of Operate is failing with %d\n", rv); return -1; } // and look at the value we read... if( strcmp(ops[0].bin.object.u.str, strData) ){ printf( "TEST FAILED - Operate did not read back correct data! %s, %s\n", ops[0].bin.object.u.str, strData); return -1; } // and release that value... citrusleaf_object_free(&ops[0].bin.object); // now read the values back. ops[0].op = CL_OP_READ; ops[1].op = CL_OP_READ; ops[2].op = CL_OP_READ; citrusleaf_object_init(&ops[0].bin.object); citrusleaf_object_init(&ops[1].bin.object); citrusleaf_object_init(&ops[2].bin.object); rv = citrusleaf_operate(clc, ns, myset, &key, &ops[0], 3, NULL ,false, NULL); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - go-right case of Operate is failing with %d\n", rv); return -1; } // check the values... if( strcmp(ops[0].bin.object.u.str, strData) ){ printf(" TEST FAILED - did not read back the same string\n"); return -1; } if( ops[1].bin.object.u.i64 != intData+2 ){ printf(" TEST FAILED - did not read back correct int %lu %lu\n", ops[1].bin.object.u.i64, intData+2); return -1; } if( strcmp(ops[2].bin.object.u.blob, blobData2 ) ){ printf(" TEST FAILED - did not read back blob correctly %s, %s\n", (char *)ops[2].bin.object.u.blob, blobData2); return -1; } // and free them all... citrusleaf_object_free(&ops[0].bin.object); citrusleaf_object_free(&ops[1].bin.object); citrusleaf_object_free(&ops[2].bin.object); // what happens if I request something that doesn't exist? // XXX - should do this elsewhere... /* strcpy(&ops[0].bin.bin_name[0], "doesnt exist"); rv = citrusleaf_operate(clc, mySet, myKey, &ops[3], 3, NULL ); */ return 0; }
void * work_fn(void *gcc_is_ass) { // Forever, do { // Pick a key to use. Look it up to see if anyone else is using it. uint32_t key = rand_64() % g_config.n_keys; uint32_t die = rand_64() & 0x03; if (SHASH_OK == shash_put_unique(g_config.in_progress_hash, &key, 0) ) { cl_rv rv; // Make the key into a string char key_s[g_config.key_len+1]; my_itoa(key_s, key, g_config.key_len); // Make an cl_object that represents the key cl_object key_o; citrusleaf_object_init_str(&key_o, key_s); cf_digest d; citrusleaf_calculate_digest(g_config.set, &key_o, &d); if (VALUE_UNINIT == g_config.values[key]) { // simply set the value to something - can't really check anything because we don't know the state if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) goto Fail; } atomic_int_add(g_config.key_counter, 1); } else if (VALUE_DELETED == g_config.values[key]) { // Shouldn't exist cl_bin *cl_v = 0; int cl_v_len; rv = citrusleaf_get_all(g_config.asc, g_config.ns, g_config.set, &key_o, &cl_v, &cl_v_len, g_config.timeout_ms, NULL); if (rv != CITRUSLEAF_FAIL_NOTFOUND) { fprintf(stderr, "Get after delete returned improper value when should be deleted %d key %s digest %"PRIx64"\n",rv,key_s, *(uint64_t *)&d); if (g_config.strict) goto Fail; } if (cl_v) free(cl_v); atomic_int_add(g_config.read_counter, 1); // did two ops here // write a new value if (die < 2) { if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) goto Fail; } atomic_int_add(g_config.key_counter, 1); } } // Value is well known. Check to see that it's still right. else { cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init(&values[0].object); // Make string version of old value for checking char new_value_str[g_config.value_len+1]; my_itoa(new_value_str, g_config.values[key], g_config.value_len); citrusleaf_object_init_str(&values[0].object, new_value_str); rv = citrusleaf_verify(g_config.asc, g_config.ns, g_config.set, &key_o, values, 1, g_config.timeout_ms, NULL); if (rv != 0) { fprintf(stderr, "Get returned improper value %d when should be set : key %d digest %"PRIx64"\n",rv,key, *(uint64_t *)&d); if (g_config.strict) goto Fail; goto V1; } // test! if (values[0].object.type != CL_STR) { fprintf(stderr, "read value has wrong type: expect string (3) got %d\n",(int)values[0].object.type); if (g_config.strict) return((void *)-1); } else if (strcmp(values[0].object.u.str, new_value_str) != 0) { fprintf(stderr, "read value does not match set value.\n"); fprintf(stderr, " expecting: %s\n",new_value_str); fprintf(stderr, " got: %s\n",values[0].object.u.str); if (g_config.strict) goto Fail; } citrusleaf_object_free(&values[0].object); atomic_int_add(g_config.read_counter, 1); // Delete, write new value, what's your pleasure? V1: if (die < 2) { if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) return((void *)-1); } } // Delete! else if (die == 2) { rv = citrusleaf_delete_verify(g_config.asc, g_config.ns, g_config.set, &key_o, 0); if (rv != 0) { fprintf(stderr, "Delete returned improper value %d, fail: key %d digest %"PRIx64"\n",rv, key, *(uint64_t *)&d); if (g_config.strict) goto Fail; } cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init(&values[0].object); rv = citrusleaf_get(g_config.asc, g_config.ns, g_config.set, &key_o, values, 1, g_config.timeout_ms, NULL); if (rv != CITRUSLEAF_FAIL_NOTFOUND) { fprintf(stderr, "Get after delete returned improper value %d digest %"PRIx64"\n",rv, *(uint64_t *)&d); if (g_config.strict) goto Fail; } citrusleaf_object_free(&values[0].object); g_config.values[key] = VALUE_DELETED; atomic_int_add(g_config.read_counter, 1); // did two ops here atomic_int_add(g_config.delete_counter, 1); atomic_int_add(g_config.key_counter, -1); } } // remove my lock on this key shash_delete(g_config.in_progress_hash, &key); } } while (1); Fail: abort(); return((void *)-1); }
int main(int argc, char **argv){ cl_cluster *clc; cl_rv return_value; cl_object key1; cl_object key2; printf(" STARTING TESTS\n"); // initialize internal citrusleaf structures just once citrusleaf_init(); // Create a cluster with a particular starting host printf(" STARTING CLUSTER CREATION TEST .... \n"); clc = citrusleaf_cluster_create(); if (!clc){ printf("TEST FAILED: Could not create cluster object"); return(-1); } return_value = citrusleaf_cluster_add_host(clc, host, 3000, 1000); if( return_value != CITRUSLEAF_OK ){ printf("TEST FAILED - cannot connect to host\n"); return -1; } // XXX - need to do some info calls with a bigger cluster! printf(" DONE\n"); // set up the key. Create a stack object, set its value to a string cl_object key_obj; citrusleaf_object_init_str(&key_obj, myKey); // set up a specific bins to fetch // the response will be in this value cl_bin values[3]; strcpy( &values[0].bin_name[0], bin1 ); citrusleaf_object_init_str( &values[0].object, strData); strcpy( &values[1].bin_name[0], bin2); citrusleaf_object_init_int( &values[1].object, intData ); strcpy( &values[2].bin_name[0], bin3); citrusleaf_object_init_blob( &values[2].object, blobData, strlen(blobData)+1); printf("params to put are clc %p, ns %s, set %s, key %p, values %p\n", clc, ns, myset, &key_obj, values); return_value = citrusleaf_put(clc, ns, myset, &key_obj, values, 3, NULL); if( return_value != CITRUSLEAF_OK ){ printf(" TEST FAILS - INITIAL PUT FAILS, value is %d\n", return_value); return(-1); } citrusleaf_object_init(&values[0].object); citrusleaf_object_init(&values[1].object); citrusleaf_object_init(&values[2].object); return_value = citrusleaf_get(clc, ns, myset, &key_obj, values, 3, 0, NULL); switch (return_value) { case CITRUSLEAF_OK: if (values[0].object.type != CL_STR) { printf(" TEST FAILS - value has unexpected type %d\n",values[0].object.type); goto cleanup; } else if( strcmp(values[0].object.u.str, strData) ){ printf("TEST FAILS - WRITE DOES NOT RETURN WHAT WAS WRITTEN: %s, %s\n", values[0].object.u.str, strData); goto cleanup; } if (values[1].object.type != CL_INT) { printf(" TEST FAILS - value has unexpected type %d\n",values[1].object.type); goto cleanup; } else if( values[1].object.u.i64 != intData){ printf("TEST FAILS - WRITE DOES NOT RETURN WHAT WAS WRITTEN, %lu, %lu\n", values[1].object.u.i64, intData); goto cleanup; } if( values[2].object.type != CL_BLOB) { printf(" TEST FAILS - value has unexpected type %d\n",values[1].object.type); goto cleanup; }else if( strcmp(values[2].object.u.blob, blobData) ){ printf(" TEST FAILS - WRITE DOES NOT RETURN CORRECT BLOB DATA\n"); goto cleanup; } break; case CITRUSLEAF_FAIL_NOTFOUND: printf(" TEST FAILS - citrusleaf says that key does not exist\n"); goto cleanup; break; case CITRUSLEAF_FAIL_CLIENT: printf(" TEST FAILS - citrusleaf client error: local error\n"); goto cleanup; break; case CITRUSLEAF_FAIL_PARAMETER: printf(" TEST FAILS - citrusleaf - bad parameter passed in \n"); goto cleanup; break; case CITRUSLEAF_FAIL_TIMEOUT: printf(" TEST FAILS - citrusleaf - timeout on get\n"); goto cleanup; break; case CITRUSLEAF_FAIL_UNKNOWN: printf(" TEST _FAILS - citrusleaf - unknown server error\n"); goto cleanup; break; default : printf(" TEST_FAILS - error %d\n", return_value); goto cleanup; } // clean up the retrieved objects citrusleaf_object_free(&values[0].object); citrusleaf_object_free(&values[1].object); if( test_getall(clc) ) goto cleanup; if( read_mod_write(clc) ) goto cleanup; if( test_unique(clc) ) goto cleanup; if( test_operate(clc) ) goto cleanup; if( test_batch(clc) ) goto cleanup; printf("TEST SUCCESSFUL!\n"); cleanup: citrusleaf_object_init_str(&key1,myKey); citrusleaf_object_init_str(&key2,myKey2); citrusleaf_delete(clc, ns, myset, &key1, NULL); citrusleaf_delete(clc, ns, myset, &key2, NULL); // Clean up the cluster object citrusleaf_cluster_destroy(clc); // Clean up the unit citrusleaf_shutdown(); }
// This is a read-modify-write test. We read the data and the generation count, and // then write the data using varous wp parameters int read_mod_write(cl_cluster *clc) { cl_object key; cl_bin bin; cl_rv rv; uint32_t gen_count; citrusleaf_object_init_str(&key, myKey); strcpy(&bin.bin_name[0],bin1); citrusleaf_object_init(&bin.object); rv = citrusleaf_get(clc, ns, myset, &key, &bin, 1, 0, &gen_count); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - Get returns value %d\n", rv); return -1; } // reuse old bin - must free memory allocated by system first citrusleaf_object_free(&bin.object); // check - does free reset the free pointer? XXX if( bin.object.free ){ printf(" TEST FAILED - free pointer not reset on object_free \n"); return -1; } citrusleaf_object_init_str(&bin.object,strData2); cl_write_parameters cl_wp; cl_write_parameters_set_default(&cl_wp); cl_write_parameters_set_generation(&cl_wp, gen_count); // now attempt to write with the same gen count - should work just fine citrusleaf_object_init_str(&bin.object, strData2); rv = citrusleaf_put(clc, ns, myset, &key, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - put with gen count fails!\n"); return -1; } // now attempt to write again - gen count on server should have changed! citrusleaf_object_init_str(&bin.object, "badData"); rv = citrusleaf_put(clc, ns, myset, &key, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_FAIL_GENERATION ){ printf(" TEST FAILED - generation count should fail, actual return value is %d\n", rv); return -1; } // check that value has not changed citrusleaf_object_init(&bin.object); uint32_t new_gen; rv = citrusleaf_get(clc, ns, myset, &key, &bin, 1,0, &new_gen); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - get in rmw is failing\n"); return -1; } if( strcmp(bin.object.u.str, strData2) ){ printf(" TEST FAILED - data on server changes despite generation count!!\n"); return -1; } citrusleaf_object_free(&bin.object); // one more time - use the generation gt thing... cl_write_parameters_set_default(&cl_wp); cl_write_parameters_set_generation_gt(&cl_wp, gen_count+2); citrusleaf_object_init_str(&bin.object, strData); rv = citrusleaf_put(clc, ns, myset, &key, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - put with gen count gt fails! err %d gen count %d\n", rv, gen_count); return -1; } // check that value is correct - and get the new gen_count citrusleaf_object_init(&bin.object); rv = citrusleaf_get(clc, ns, myset, &key, &bin, 1, 0, &gen_count); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - get in rmw is failing\n"); return -1; } if( strcmp(bin.object.u.str, strData) ){ printf(" TEST FAILED - data on server changes despite generation count!!\n"); return -1; } citrusleaf_object_free(&bin.object); // now attempt to write again - gen count on server should have changed! citrusleaf_object_init_str(&bin.object, "badData"); cl_write_parameters_set_default(&cl_wp); cl_write_parameters_set_generation_gt(&cl_wp, gen_count); rv = citrusleaf_put(clc, ns, myset, &key, &bin, 1, &cl_wp); if( rv != CITRUSLEAF_FAIL_GENERATION ){ printf(" TEST FAILED - generation count should fail, actual return value is %d\n", rv); return -1; } // check that value has not changed citrusleaf_object_init(&bin.object); rv = citrusleaf_get(clc, ns, myset, &key, &bin, 1, 0, NULL); if( rv != CITRUSLEAF_OK ){ printf(" TEST FAILED - get in rmw is failing\n"); return -1; } if( strcmp(bin.object.u.str, strData) ){ printf(" TEST FAILED - data on server changes despite generation count!!\n"); return -1; } // at the end of this function, bin1 is strdata return 0; }
int test_getall(cl_cluster *clc){ // set up the key. cl_object key_obj; citrusleaf_object_init_str(&key_obj, myKey); // create variables to return all values cl_bin *bins; int n_bins; // do the get citrusleaf_get_all(clc, ns, myset, &key_obj, &bins, &n_bins, 0, NULL); // check the contained values int haveStr = 0; int haveInt = 0; int haveBlob = 0; if( n_bins != 3 ){ printf(" TEST FAILED - get_all returns wrong number of bins, %d\n", n_bins); return -1; } for (int i=0;i<n_bins;i++) { printf (" bin %d name %s\n",i,bins[i].bin_name); if (bins[i].object.type == CL_STR){ if( strcmp(bins[i].object.u.str, strData) ){ printf(" TEST FAILED - str output of get_all does not match input\n"); return -1; } if( !bins[i].object.free ){ printf(" TEST FAILED - string allocated, but free pointer not set\n"); return -1; } haveStr = 1; }else if (bins[i].object.type == CL_INT ){ if( bins[i].object.u.i64 != intData ){ printf(" TEST FAILED - int output of get_all does not match input\n"); return -1; } if( bins[i].object.free ){ printf(" TEST FAILED - int output indicated as allocated but is not\n"); return -1; } haveInt = 1; }else if( bins[i].object.type == CL_BLOB ){ haveBlob = 1; if( strcmp(bins[i].object.u.blob, blobData) ){ printf(" TEST FAILED - blob output does not match input\n"); return -1; } // check - free pointer set? if( !bins[i].object.free ){ printf(" TEST FAILED - blob allocated, but free pointer not set\n"); return -1; } }else{ printf("TEST FAILED - unexpected bin type %d\n",(int) bins[i].object.type); return(-1); } } if( !(haveInt && haveStr && haveBlob ) ){ printf("TEST FAILED - not all values have correct types\n"); return -1; } // free the allocated memory for( int i=0; i<n_bins;i++) { citrusleaf_object_free(&bins[i].object); } free(bins); return 0; }
/** * LSET Insert WITH_TRANSFORM TEST * For a single record, perform a series of SET Insert of BYTE-PACKED data. * Create a new record, then repeatedly call stack insert. */ int lset_insert_with_transform_test(char * keystr, char * ldt_bin, int iterations) { static char * meth = "lset_insert_with_transform_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = 0; int i; INFO("[ENTER]:<%s:%s>: It(%d) Key(%s) LSOBin(%s)", MOD, meth, iterations, keystr, ldt_bin ); // Abbreviate for simplicity. cl_cluster * c = lset_g_config->asc; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; cl_object o_key; // Set up the Creation Spec parameter -- mostly setting the Package // (which is the name for a canned set of settings). char * create_package = "ProdListValBinStore"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); INFO("[DEBUG]:<%s:%s>: Run insert_with_transform() iterations(%d)", MOD, meth, iterations ); citrusleaf_object_init_str( &o_key, keystr ); for ( i = 0; i < iterations; i++ ) { int val = i * 10; as_list * listp = as_arraylist_new( 5, 5 ); int64_t urlid = val + 1; as_list_add_integer( listp, urlid ); int64_t created = val + 2; as_list_add_integer( listp, created ); int64_t meth_a = val + 3; as_list_add_integer( listp, meth_a ); int64_t meth_b = val + 4; as_list_add_integer( listp, meth_b ); int64_t status = val + 5; as_list_add_integer( listp, status ); rc = aerospike_lset_create_and_insert( c, ns, set, &o_key, bname, (as_val *)listp, create_spec, lset_g_config->timeout_ms); if ( rc != CITRUSLEAF_OK ) { INFO("[ERROR]:<%s:%s>:LSO PUSH WITH TRANSFROM Error: i(%d) rc(%d)", MOD, meth, i, rc ); as_val_destroy ( listp ); goto cleanup; } // Count the write operation for stats gathering lset_g_config->write_ops_counter += 1; lset_g_config->write_vals_counter += 1; as_val_destroy( listp ); // must destroy every iteration. listp = NULL; } // end for cleanup: citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rc; } // end lset_insert_with_transform_test()
int do_example(config *c) { int rv; // Put some test values cl_object o_key; citrusleaf_object_init_str(&o_key, "example_key"); cl_bin values[2]; strcpy(values[0].bin_name, "test_bin_one"); citrusleaf_object_init_str(&values[0].object, "example_value_one"); strcpy(values[1].bin_name, "test_bin_two"); citrusleaf_object_init_int(&values[1].object, 0xDEADBEEF); // set a non-default write parameter cl_write_parameters cl_wp; cl_write_parameters_set_default(&cl_wp); cl_wp.timeout_ms = 1000; if (0 != (rv = citrusleaf_put(c->asc, c->ns, c->set, &o_key, values, 2, &cl_wp))) { fprintf(stderr, "citrusleaf put failed: error %d\n",rv); return(-1); } fprintf(stderr, "citrusleaf put succeeded\n"); // Get all the values in this key (enjoy the fine c99 standard) cl_bin *cl_v = 0; uint32_t generation; int cl_v_len; if (0 != (rv = citrusleaf_get_all(c->asc, c->ns, c->set, &o_key, &cl_v, &cl_v_len, c->timeout_ms, &generation))) { fprintf(stderr, "get after put failed, but there should be a key here - %d\n",rv); if (cl_v) free(cl_v); return(-1); } fprintf(stderr, "get all returned %d bins\n",cl_v_len); for (int i=0;i<cl_v_len;i++) { fprintf(stderr, "%d: bin %s ",i,cl_v[i].bin_name); switch (cl_v[i].object.type) { case CL_STR: fprintf(stderr, "type string: value %s\n", cl_v[i].object.u.str); break; case CL_INT: fprintf(stderr, "type int: value %"PRId64"\n",cl_v[i].object.u.i64); break; default: fprintf(stderr, "type unknown! (%d)\n",(int)cl_v[i].object.type); break; } // could have done this -- but let's free the objects in the bins later // citrusleaf_object_free(&cl_v[i].object); } if (cl_v) { citrusleaf_bins_free(cl_v, cl_v_len); free(cl_v); // only one free for all bins } fprintf(stderr,"citrusleaf getall succeeded\n"); // Delete the key you just set if (0 != (rv = citrusleaf_delete(c->asc, c->ns, c->set, &o_key, 0/*default write params*/))) { fprintf(stderr, "citrusleaf delete failed: error %d\n",rv); return(-1); } fprintf(stderr, "citrusleaf delete succeeded\n"); return(0); }
/** * LSET INSERT TEST * For a single record, perform a series of SET insert. * Create a new record, then repeatedly call lset insert. * This should work for data that is a NUMBER, a STRING or a LIST. * Parms: * + keystr: String Key to find the record * + ldt_bin: Bin Name of the LDT * + iterations: Number of iterations to run this test * + seed: Seed value for the random number pattern * + data_format: Type of value (number, string, list) */ int lset_insert_test(char * keystr, char * ldt_bin, int iterations, int seed, int data_format ) { static char * meth = "lset_insert_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = CITRUSLEAF_OK; int i; as_val *valp; time_t cur_t; cur_t = time(NULL); // INFO("[ENTER]:<%s:%s>: It(%d) Key(%s) LSOBin(%s) Seed(%d)", // MOD, meth, iterations, keystr, ldt_bin, seed); // We have two choices: We can create the LSO bin here, and then // do a bunch of inserts into it -- or we can just do the combined // "create_and_insert" insert, which upon reflection, is really the // most likely mode we'll be in. We'll choose the later. // Set up the Creation Spec parameter -- mostly setting the Package // (which is the name for a canned set of settings). char * create_package = "StandardList"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; int iseed; //INFO("[DEBUG]:<%s:%s>: Run insert() iterations(%d)", MOD, meth, iterations ); citrusleaf_object_init_str( &o_key, keystr ); for ( i = 0; i < iterations; i++ ) { iseed = i * 10; lset_generate_value( &valp, iseed, data_format ); rc = aerospike_lset_create_and_insert( c, ns, set, &o_key, bname, valp, create_spec, lset_g_config->timeout_ms); if ( rc != CITRUSLEAF_OK ) { //INFO("[ERROR]:<%s:%s>:H Error: i(%d) rc(%d)", MOD, meth,i,rc ); as_val_destroy ( valp ); goto cleanup; } // Count the write operation for stats gathering lset_g_config->write_ops_counter += 1; lset_g_config->write_vals_counter += 1; as_val_destroy( valp ); // must destroy every iteration. valp = NULL; // unnecessary insurance } // end for cleanup: citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rc; } // end lset_insert_test()