// -------------------------------------------------------------------------- // // void Test_Specswap::testAddCurve() { // Setup a specswap object. int sample = 250; Mlrnd rand; std::string path("./testfiles/testlibLarge"); Specswap ss(sample, rand, path); // Check that there are no curve data added. CPPUNIT_ASSERT_EQUAL( static_cast<int>(ss.curve_data_.size()), 0 ); // Setup input for adding a curve. std::string curve_name("bas"); std::string filename("./testfiles/exafs_ref.data"); double sigma = 0.0002; bool area_renorm = true; ss.add_curve(sigma, area_renorm, curve_name, filename); // Check that a scalar distribution has been added. CPPUNIT_ASSERT_EQUAL( static_cast<int>(ss.curve_data_.size()), 1 ); // Add another one. ss.add_curve(sigma, area_renorm, curve_name, filename); // Check. CPPUNIT_ASSERT_EQUAL( static_cast<int>(ss.curve_data_.size()), 2 ); // Make sure we fail with an unrecognized curve. curve_name = "NOT_A_CURVENAME"; //ss.add_curve(sigma, area_renorm, curve_name, filename); CPPUNIT_ASSERT_THROW( ss.add_curve(sigma, area_renorm, curve_name, filename), IOException ); // Make sure we fail with a non existing reference file. curve_name = "bas"; filename = "./testfiles/NO_SUCH_FILE"; //ss.add_curve(sigma, area_renorm, curve_name, filename); CPPUNIT_ASSERT_THROW( ss.add_curve(sigma, area_renorm, curve_name, filename), IOException ); }
// -------------------------------------------------------------------------- // // void Test_Specswap::testAccept() { // Setup a specswap object with many different data sets. std::string path("./testfiles/testlibLarge"); int sample = 12; Mlrnd rand; rand.set_seed(39); Specswap ss1(sample, rand, path); // Mean scalar. std::string scalarname("VP-Volume"); double target = 0.5; double sigma = 1.0; ss1.add_scalar_mean(scalarname, target, sigma); sigma = 0.0012; ss1.add_scalar_mean(scalarname, target, sigma); // Value scalar. scalarname = "VP-Area"; double value_low = 0.5; double value_high = 1.0; double fraction = 0.6; sigma = 0.0001; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); fraction = 0.1; sigma = 0.0001; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); value_low = 0.0; value_high = 1.3; fraction = 0.99; sigma = 0.01; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); // Scalar distribution. scalarname = "VP-Volume"; std::string filename("./testfiles/vvol_ref.data"); sigma = 0.0002; ss1.add_scalar_distribution(scalarname, filename, sigma); sigma = 0.0099; ss1.add_scalar_distribution(scalarname, filename, sigma); // Curve. std::string curve_name("bas"); filename = "./testfiles/exafs_ref.data"; sigma = 0.0002; bool area_renorm = true; ss1.add_curve(sigma, area_renorm, curve_name, filename); area_renorm = false; ss1.add_curve(sigma, area_renorm, curve_name, filename); // Setup input for adding a pcf. double rmin = 0.0; double rmax = 5.0; double dr = 0.02; double numberdensity = 0.4; std::pair<double,double> fit_interval(1.3, 3.0); int nbins = 250; std::pair<int,int> partial(0,1); std::string ref_path("./testfiles/gr_ref.data"); sigma = 0.01; ss1.add_pcf(rmin, rmax, dr, sigma, numberdensity, fit_interval, nbins, partial, ref_path); sigma = 0.0123; ss1.add_pcf(rmin, rmax, dr, sigma, numberdensity, fit_interval, nbins, partial, ref_path); // Setup. ss1.setup(); // Move. ss1.move(); // Check what slot and indices will be swapped. CPPUNIT_ASSERT_EQUAL( ss1.from_sample_, 583); CPPUNIT_ASSERT_EQUAL( ss1.from_basis_, 2354); CPPUNIT_ASSERT_EQUAL( ss1.slot_, 11); // Check that the sample set is correct. CPPUNIT_ASSERT_EQUAL( ss1.sampleset_.index_at(ss1.slot_), ss1.from_sample_); // Notify. ss1.notify(); // Check the chi2 value. double diff = 7.2603029936e+08 - 6.5624713898e-04 - ss1.chi2_; CPPUNIT_ASSERT_DOUBLES_EQUAL( diff, 0.0, 1.0e-10 ); // Check that the chi2_new value has been updated. diff = 7.4256423439e+08 + 1.9059181213e-03 - ss1.chi2_new_; CPPUNIT_ASSERT_DOUBLES_EQUAL( diff, 0.0, 1.0e-10 ); // Call the accept and make sure Chi2 has been accepted. ss1.accept(); CPPUNIT_ASSERT_DOUBLES_EQUAL( ss1.chi2_, ss1.chi2_new_, 1.0e-10 ); // Check that the sample set is correct. CPPUNIT_ASSERT_EQUAL( ss1.sampleset_.index_at(ss1.slot_), ss1.from_basis_); }
// -------------------------------------------------------------------------- // // void Test_Specswap::testNotify() { // Setup a specswap object with many different data sets. std::string path("./testfiles/testlibLarge"); int sample = 12; Mlrnd rand; rand.set_seed(39); Specswap ss1(sample, rand, path); // Mean scalar. std::string scalarname("VP-Volume"); double target = 0.5; double sigma = 1.0; ss1.add_scalar_mean(scalarname, target, sigma); sigma = 0.0012; ss1.add_scalar_mean(scalarname, target, sigma); // Value scalar. scalarname = "VP-Area"; double value_low = 0.5; double value_high = 1.0; double fraction = 0.6; sigma = 0.0001; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); fraction = 0.1; sigma = 0.0001; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); value_low = 0.0; value_high = 1.3; fraction = 0.99; sigma = 0.01; ss1.add_scalar_value(scalarname, value_low, value_high, fraction, sigma); // Scalar distribution. scalarname = "VP-Volume"; std::string filename("./testfiles/vvol_ref.data"); sigma = 0.0002; ss1.add_scalar_distribution(scalarname, filename, sigma); sigma = 0.0099; ss1.add_scalar_distribution(scalarname, filename, sigma); // Curve. std::string curve_name("bas"); filename = "./testfiles/exafs_ref.data"; sigma = 0.0002; bool area_renorm = true; ss1.add_curve(sigma, area_renorm, curve_name, filename); area_renorm = false; ss1.add_curve(sigma, area_renorm, curve_name, filename); // Setup input for adding a pcf. double rmin = 0.0; double rmax = 5.0; double dr = 0.02; double numberdensity = 0.4; std::pair<double,double> fit_interval(1.3, 3.0); int nbins = 250; std::pair<int,int> partial(0,1); std::string ref_path("./testfiles/gr_ref.data"); sigma = 0.01; ss1.add_pcf(rmin, rmax, dr, sigma, numberdensity, fit_interval, nbins, partial, ref_path); sigma = 0.0123; ss1.add_pcf(rmin, rmax, dr, sigma, numberdensity, fit_interval, nbins, partial, ref_path); // Set the initial chi2_ value to some thing unreasonable. ss1.chi2_new_ = -1.123; // Call the setup function. ss1.from_sample_ = 0; ss1.from_basis_ = 12; ss1.setup(); // Call notify. ss1.notify(); // Check that the chi2 value has been updated. CPPUNIT_ASSERT_DOUBLES_EQUAL(735129583.538380026817, ss1.chi2_new_, 1.0e-8); }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop(void) { struct uftp_h *header; struct group_list_t *group; unsigned char *buf, *decrypted, *message; char rxname[INET6_ADDRSTRLEN]; unsigned int decryptlen, meslen; int packetlen, rval, i, ecn; uint8_t version, *func, tos; uint16_t txseq; union sockaddr_u src; struct timeval *tv, rxtime; double new_grtt; log2(0, 0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { if (privkey_type[i] == KEYBLOB_RSA) { log2(0, 0, 0, "Loaded %d bit RSA key with fingerprint %s", RSA_keylen(privkey[i].rsa) * 8, print_key_fingerprint(privkey[i], KEYBLOB_RSA)); } else { log2(0, 0, 0, "Loaded ECDSA key with curve %s and fingerprint %s", curve_name(get_EC_curve(privkey[i].ec)), print_key_fingerprint(privkey[i], KEYBLOB_EC)); } } buf = safe_calloc(MAXMTU, 1); decrypted = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (tv) { log5(0, 0, 0, "read timeout: %d.%06d", tv->tv_sec, tv->tv_usec); } if (read_packet(listener, &src, buf, &packetlen, MAXMTU, tv, &tos) <= 0) { continue; } gettimeofday(&rxtime, NULL); if ((rval = getnameinfo((struct sockaddr *)&src, family_len(src), rxname, sizeof(rxname), NULL, 0, NI_NUMERICHOST)) != 0) { log1(0, 0, 0, "getnameinfo failed: %s", gai_strerror(rval)); } if (header->version == UFTP_VER_NUM) { version = header->version; group = find_group(ntohl(header->group_id), header->group_inst); } else { log1(0, 0, 0, "Invalid message from %s: not uftp packet " "or invalid version", rxname); continue; } if (packetlen < sizeof(struct uftp_h) + 4) { log1(0, 0, 0, "Invalid packet size from %s: %d", rxname, packetlen); continue; } txseq = htons(header->seq); // A KEY_INFO or ABORT could come from a proxy, so don't check the seq // TODO: need to account for these in the loss history if ((group != NULL) && (header->func != KEYINFO) && (header->func != ABORT)) { if ((int16_t)(group->max_txseq - txseq) > MAXMISORDER) { glog3(group, "seq out of range, dropping"); continue; } if (group->cc_type != CC_NONE) { ecn = ((tos & 0x3) == 3); update_loss_history(group, txseq, packetlen, ecn); } else if ((int16_t)(txseq - group->max_txseq) > 0) { group->max_txseq = txseq; } } if ((header->func == ENCRYPTED) && (group != NULL) && (group->keytype != KEY_NONE)) { if (group->phase == PHASE_REGISTERED) { glog1(group, "Got encrypted packet from %s " "but keys not established", rxname); } if (!validate_and_decrypt(buf, packetlen, &decrypted, &decryptlen, group->keytype, group->groupkey, group->groupsalt, group->ivlen, group->hashtype, group->grouphmackey, group->hmaclen, group->sigtype, group->keyextype, group->server_pubkey, group->server_pubkeylen)) { glog1(group, "Rejecting message from %s: " "decrypt/validate failed", rxname); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((group != NULL) && (group->keytype != KEY_NONE) && ((header->func == FILEINFO) || (header->func == FILESEG) || (header->func == DONE) || (header->func == DONE_CONF) || ((header->func == ABORT) && (group->phase != PHASE_REGISTERED)))) { glog1(group, "Rejecting %s message from %s: not encrypted", func_name(header->func), rxname); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = packetlen - sizeof(struct uftp_h); } if (group != NULL) { new_grtt = unquantize_grtt(header->grtt); if (fabs(new_grtt - group->grtt) > 0.001) { group->grtt = new_grtt; set_timeout(group, 1); } group->gsize = unquantize_gsize(header->gsize); glog5(group, "grtt: %.3f", group->grtt); } if (header->func == PROXY_KEY) { handle_proxy_key(&src, message, meslen); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, message, meslen, hb_hosts, hbhost_count, privkey[0], privkey_type[0], uid); continue; } if (header->func == ANNOUNCE) { // Ignore any ANNOUNCE for a group we're already handling if (group == NULL) { handle_announce(&src, buf, packetlen, rxtime); } else if (group->phase == PHASE_MIDGROUP) { // Make sure we don't time out while waiting for other // clients to register with the server. set_timeout(group, 0); } } else { if (group == NULL) { // group / file ID not in list continue; } if (group->version != version) { glog1(group, "Version mismatch"); continue; } if (group->src_id != header->src_id) { glog1(group, "Source ID mismatch"); continue; } if (*func == ABORT) { handle_abort(group, message, meslen); continue; } switch (group->phase) { case PHASE_REGISTERED: if (group->keytype != KEY_NONE) { if (*func == KEYINFO) { handle_keyinfo(group, message, meslen, header->src_id); } else { glog1(group, "Expected KEYINFO, got %s", func_name(*func)); } } else if (group->keytype == KEY_NONE) { if (*func == REG_CONF) { handle_regconf(group, message, meslen); } else if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else { glog1(group, "Expected REG_CONF, got %s", func_name(*func)); } } break; case PHASE_MIDGROUP: if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else if (*func == KEYINFO) { handle_keyinfo(group, message, meslen, header->src_id); } else if (*func == DONE) { handle_done(group, message, meslen); } else { // Other clients may be still getting earlier files or // setting up, so silently ignore anything unexpected // and reset the timeout. set_timeout(group, 0); } break; case PHASE_RECEIVING: if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else if (*func == FILESEG) { handle_fileseg(group, message, meslen, txseq); } else if (*func == DONE) { handle_done(group, message, meslen); } else if (*func == CONG_CTRL) { handle_cong_ctrl(group, message, meslen, rxtime); } break; case PHASE_COMPLETE: if (*func == DONE_CONF) { handle_done_conf(group, message, meslen); } break; } } } }