void test_intermittent() {
    sc::blocking_queue<MyMovableStr> queue{};
    std::thread producer([&] {
        TestStringGenerator gen{};
        for (size_t i = 0; i < 10; i++) {
            std::string str = gen.generate(42);
            queue.emplace(std::move(str));
        }
        std::this_thread::sleep_for(std::chrono::milliseconds{200});
        for (size_t i = 10; i < 20; i++) {
            std::string str = gen.generate(42);
            queue.emplace(std::move(str));
        }
        std::this_thread::sleep_for(std::chrono::milliseconds{300});
        for (size_t i = 20; i < ELEMENTS_COUNT; i++) {
            std::string str = gen.generate(42);
            queue.emplace(std::move(str));
        }
    });
    std::thread consumer([&] {
        for (size_t i = 0; i < ELEMENTS_COUNT; i++) {
            MyMovableStr el{""};
            bool success = queue.take(el);
            slassert(success);
            slassert(42 == el.get_val().size());
        }
    });
    producer.join();
    consumer.join();
}
void test_write() {
    std::ostringstream stream{};
    io::streambuf_sink sink{stream.rdbuf()};
    auto written = sink.write("foo", 3);
    slassert(3 == written);
    slassert("foo" == stream.str());
}
void test_put() {
    // server
    hs::http_server server(2, TCP_PORT, asio::ip::address_v4::any(), SERVER_CERT_PATH, pwdcb, CA_PATH, verifier);
    server.add_handler("PUT", "/", put_handler);
    server.add_payload_handler("PUT", "/", [](hs::http_request_ptr&) {
        return PayloadReceiver{}; });
    server.start();
    // client
    try {
        hc::HttpSession session{};
        hc::HttpRequestOptions opts{};
        opts.headers = {{"User-Agent", "test"}, {"X-Method", "PUT"}};
        opts.method = "PUT";
        enrich_opts_ssl(opts);
        io::string_source post_data{POSTPUT_DATA};
        hc::HttpResource src = session.open_url(URL, std::move(post_data), opts);
        // check
        std::string out{};
        out.resize(PUT_RESPONSE.size());
        std::streamsize res = io::read_all(src, std::addressof(out.front()), out.size());
        slassert(out.size() == static_cast<size_t> (res));
        slassert(PUT_RESPONSE == out);
    } catch (const std::exception&) {
        server.stop(true);
        throw;
    }
    // stop server
    server.stop(true);
}
void test_delete() {
    // server
    hs::http_server server(2, TCP_PORT, asio::ip::address_v4::any(), SERVER_CERT_PATH, pwdcb, CA_PATH, verifier);
    server.add_handler("DELETE", "/", delete_handler);
    server.start();
    // client
    try {
        hc::HttpSession session{};
        hc::HttpRequestOptions opts{};
        opts.headers = {{"User-Agent", "test"}, {"X-Method", "DELETE"}};
        enrich_opts_ssl(opts);
        opts.method = "DELETE";

        hc::HttpResource src = session.open_url(URL, opts);
        // check
        std::string out{};
        out.resize(DELETE_RESPONSE.size());
        std::streamsize res = io::read_all(src, std::addressof(out.front()), out.size());
        slassert(out.size() == static_cast<size_t> (res));
        slassert(DELETE_RESPONSE == out);
    } catch (const std::exception&) {
        server.stop(true);
        throw;
    }
    // stop server
    server.stop(true);
}
void get_handler(hs::http_request_ptr& req, hs::tcp_connection_ptr& conn) {
    slassert("test" == req->get_header("User-Agent"));
    slassert("GET" == req->get_header("X-Method"));
    auto writer = hs::http_response_writer::create(conn, req);
    writer->write(GET_RESPONSE);
    writer->send();
}
示例#6
0
/* Get a file from another point of filesystem =D and copy
 * it into slackyd's dir.
 */
int get_file_over_fs (net_t *netpolicy)
{
    const char *destpath = netpolicy->destpath;
	const char *hostname = netpolicy->hostname;
	const char *message  = netpolicy->msg;
	char srcpath[BUFFSIZE0];
	char buffer[HUGE0];
		
    FILE *fdsrc = NULL;
    int rval;
    
    slassert (netpolicy != NULL);

	/* Fix local path:
	 * If we are using a local mirror, hostname will be base path.
	 * Ex: using mirror "/mnt/data/slackware/" `hostname' will be "mnt".
	 */ 
	snprintf (srcpath, BUFFSIZE, "/%s/%s", hostname, netpolicy->srcpath);

	fprintf (stdout, message);
    fflush (stdout);

    if (!netpolicy->savepart)
     slassert (!netpolicy->checkstamp);

    /* check for overwrite */
    if (!netpolicy->overwrite &&
        file_exist (destpath, NULL, true)) /* regular file exist */
    {
        return shutdown_net_t (netpolicy, FILE_DOWNLOADED, "Already downloaded");
    }

	/* Check for timestamp */
    if (netpolicy->checkstamp
     && (fdsrc = fopen (srcpath, "rb"))
     && (netpolicy->fddest = fopen (destpath, "rb"))
     && fread (netpolicy->stampdata, 1, STAMPSZ, fdsrc) == STAMPSZ
     && fread (netpolicy->stamprecv, 1, STAMPSZ, netpolicy->fddest) == STAMPSZ
     && memcmp (netpolicy->stampdata, netpolicy->stamprecv, STAMPSZ) == 0)
    {
        fclose (fdsrc);
        return shutdown_net_t (netpolicy, FILE_ALREADY_UPDATE, "Already update");
    }
    if (fdsrc) fclose (fdsrc); 
    if (netpolicy->fddest) fclose (netpolicy->fddest);
    
    netpolicy->fddest = fopen (destpath, "wb");
    __act (netpolicy->fddest, -1, destpath);

    __act (fdsrc = fopen (srcpath, "rb"), -1, srcpath);

    
    while ((rval = fread (buffer, 1, HUGE, fdsrc)) > 0)
    {
        fwrite (buffer, 1, rval, netpolicy->fddest);
    }
    
    fclose (fdsrc);
    return shutdown_net_t (netpolicy, FILE_DOWNLOADED, "done");
}
void test_small_dest() {
    std::string hello = "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82";
    iu::ustring_sink sink{5};
    std::streamsize written = sink.write(hello.c_str(), hello.length());
    slassert(12 == written);
    std::string res = iu::to_utf8(sink.get_string());
    slassert(hello == res);
}
void test_movable() {
    io::unique_sink<NonCopyableSink> sink{new NonCopyableSink{}};
    io::counting_sink<io::unique_sink<NonCopyableSink>> wrapped{std::move(sink)};    
    auto written = wrapped.write("foo", 3);
    slassert(3 == written);
    slassert(3 == wrapped.get_count());
    slassert(3 == wrapped.get_sink().get_sink().get_count());
}
void test_overread() {
    io::buffered_source<TwoBytesAtOnceSource, 3> src{TwoBytesAtOnceSource{"foo42"}};
    std::string dest{};
    dest.resize(5);
    auto read = src.read(std::addressof(dest.front()), 5);
    slassert(5 == read);
    slassert(5 == dest.size());
    slassert("foo42" == dest);
}
void test_read() {
    std::array<char, 3> arr = {{'b', 'a', 'r'}};
    io::array_source src(arr.data(), arr.size());
    std::array<char, 4> out;
    auto res = src.read(out.data(), out.size());
    slassert(3 == res);
    slassert('b' == out[0]);
    slassert('a' == out[1]);
    slassert('r' == out[2]);
}
void test_connectfail() {
    hc::HttpSession session{};
    hc::HttpRequestOptions opts{};
    opts.abort_on_connect_error = false;
    opts.connecttimeout_millis = 100;
    hc::HttpResource src = session.open_url(URL, opts);
    auto res = src.read(nullptr, 0);
    slassert(std::char_traits<char>::eof() == res);
    slassert(!src.get_info().connection_success());
}
void put_handler(hs::http_request_ptr& req, hs::tcp_connection_ptr& conn) {
    slassert("test" == req->get_header("User-Agent"));
    slassert("PUT" == req->get_header("X-Method"));
    auto ph = req->get_payload_handler<PayloadReceiver>();
    slassert(nullptr != ph);
    slassert(ph->is_received());
    auto writer = hs::http_response_writer::create(conn, req);
    writer->write(PUT_RESPONSE);
    writer->send();
}
void test_movable() {
    MyMovableRange range{3};
    auto transformed = sl::ranges::transform(std::move(range), [](my_movable el) {
        return el.get_val();
    });
    auto vec = transformed.to_vector();
    slassert(3 == vec.size());
    slassert(1 == vec[0]);
    slassert(2 == vec[1]);
    slassert(3 == vec[2]);
}
void test_small_src() {
    std::string hello = "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82";
    iu::ustring_sink sink{};
    std::streamsize written1 = sink.write(hello.c_str(), 2);
    slassert(2 == written1);
    std::streamsize written2 = sink.write(hello.c_str() + 2, 1);
    slassert(1 == written2);
    std::streamsize written3 = sink.write(hello.c_str() + 3, 9);
    slassert(9 == written3);
    std::string res = iu::to_utf8(sink.get_string());
    slassert(hello == res);
}
void test_unblock() {
    sc::blocking_queue<MyMovableStr> queue{};
    std::thread consumer([&] {
        MyMovableStr el{""};
        bool success = queue.poll(el);
        slassert(!success);
        slassert(el.get_val() == "");
    });
    // ensure lock
    std::this_thread::sleep_for(std::chrono::milliseconds{100});
    queue.unblock();
    consumer.join();
}
void test_hash() {
    io::string_source src{"foo42\n"};
    auto sink = sc::make_sha256_sink(io::string_sink{});
    std::array<char, 2> buf;
    io::copy_all(src, sink, buf.data(), buf.size());
    
    slassert("ee41b4f1a590fae151736f09890dbd98d0707421ad84fa25afe89e1e30006009" == sink.get_hash());
}
void test() {
    auto line = __LINE__;
    auto msg = TRACEMSG("foo");
    auto expected = std::string("foo\n") 
            .append("    at myfancynamespace::test(tracemsg_test.cpp:")
            .append(ss::to_string(line + 1))
            .append(")");
    slassert(expected == msg);
}
void test_take() {
    TestStringGenerator gen{};
    std::vector<std::string> data{};
    sc::blocking_queue<MyMovableStr> queue{};
    for (size_t i = 0; i < ELEMENTS_COUNT; i++) {
        std::string str = gen.generate(42);
        data.push_back(str);
        queue.emplace(std::move(str));
    }
    std::thread consumer([&]{
        for (size_t i = 0; i < ELEMENTS_COUNT; i++) {
            MyMovableStr el{""};
            bool success = queue.take(el);
            slassert(success);
            slassert(el.get_val() == data[i]);
        }
    });
    consumer.join();
}
示例#19
0
/* require `package' from N_REPO repository already load from config file */
int
get_pkg (pkg_t *package)
{
    const char *cache = opt.dest;
    int r = package->N_REPO;
    net_t netpolicy;
    char *loc, *name, *host, *path;
    
    slassert (package != NULL);

    loc  = package->location;
    name = package->name;
    host = REPOS[r].hostname;
    path = REPOS[r].path;

    init_net_t (&netpolicy, REPOS[r].proto_t, REPOS[r].port);
    netpolicy.savepart   = true;
    netpolicy.overwrite  = false;
    netpolicy.checkstamp = false;
    strncpy (netpolicy.hostname, host, BUFFSIZE);
    snprintf (netpolicy.msg, BUFFSIZE, "%s %s/%s.",
        (REPOS[r].proto_t == proto_file) ? "Copying to" : "Downloading to", cache, name);
    snprintf (netpolicy.srcpath,  BUFFSIZE, "%s/%s/%s", path, loc, name);
    snprintf (netpolicy.destpath, BUFFSIZE, "%s/%s", cache, name);

    if(opt.wget){ 
	    switch (REPOS[r].proto_t) {
		case proto_http: return get_file_over_wget (&netpolicy,true);  break;
		case proto_ftp:  return get_file_over_wget (&netpolicy,false);  break;
		case proto_file: return get_file_over_fs   (&netpolicy);  break;
		default:   slassert (NULL);                               break;
	    }
    }else{
	    switch (REPOS[r].proto_t) {
		case proto_http: return get_file_over_http (&netpolicy);  break;
		case proto_ftp:  return get_file_over_ftp  (&netpolicy);  break;
		case proto_file: return get_file_over_fs   (&netpolicy);  break;
		default:   slassert (NULL);                               break;
		}
    }

    return -1;
}
示例#20
0
/* Verify if MD5 hash of file `filename' is equal to hash `checksum'. */
void md5file(char *filename, char *checksum, const char *md5list)
{
    FILE *fd;
    MD5_CTX ctx;
    int i, p = 0x00;
    unsigned len;
    unsigned char buffer[BUFFSIZE0], digest[MD5LEN] = { 0 };
    char hash[STRMD5LEN + 1] = { 0 };

    fprintf (stdout, "\r* Verify md5 checksum: ");
    fflush (stdout);

    if (checksum == NULL) {
        if (errno == 0x00)
         fprintf (stdout, "not found !\n");
        else
         fprintf (stdout, "%s: %s.\n", md5list, strerror (errno));
        return;
    }

    slassert (filename);
    
    if ((fd = fopen (filename, "rb")) == NULL)
    {
		fprintf (stdout, "error, %s: %s\n", filename, strerror (errno));
		return;
    }

    MD5_Init(&ctx);
    while ((len = fread (buffer, 1, BUFFSIZE, fd)))
    {
		MD5_Update (&ctx, buffer, len);
    }

    MD5_Final (digest, &ctx);
    fclose (fd);

    for (i = 0; i < MD5LEN; i++, p += 2)
    {
		sprintf((char *) hash + p, "%02x", digest[i]);
    }

    if (strcmp (hash, checksum))
    {
		fprintf (stdout, "\n\n"
		">>> WARNING : %s hash mismatch.\n"
		">>> Original: %s\n"
		">>> Checked : %s\n\n", filename, checksum, hash);
	}
    else
    {
        fprintf (stdout, "ok.\n");
    }
    return;
}
示例#21
0
void test_fail_create() {
    icu::UnicodeString st{"((fail"};
    icu::ErrorCode ec{};
    icu::RegexMatcher ma{st, 0, ec};
    bool caught = false;
    try {
        su::make_uobj(ma, ec);
    } catch (const su::IcuErrorException&) {
        caught = true;
    }
    slassert(caught);
}
示例#22
0
void test_fail_call() {
    icu::UnicodeString st{"((fail"};
    icu::RegexPattern pattern{};
    auto pt = su::make_uobj(pattern, icu::ErrorCode{});
    bool caught = false;
    try {
        pt->compile(st, 0, pt.code());
    } catch (const su::IcuErrorException&) {
        caught = true;
    }
    slassert(caught);
}
void test_take_wait() {
    sc::blocking_queue<MyMovableStr> queue{};
    std::thread producer([&queue] {
        std::this_thread::sleep_for(std::chrono::milliseconds{200});
        queue.emplace("aaa");
        std::this_thread::sleep_for(std::chrono::milliseconds{200});
        queue.emplace("bbb");
    });
    std::thread consumer([&queue] {
        // not yet available
        MyMovableStr el1{""};
        bool success1 = queue.take(el1, 100);
        slassert(!success1);
        slassert("" == el1.get_val());
        // first received
        MyMovableStr el2{""};
        bool success2 = queue.take(el2, 150);
        slassert(success2);
        slassert("aaa" == el2.get_val());
        // wait for next
        std::this_thread::sleep_for(std::chrono::milliseconds{200});
        // should be already there
        MyMovableStr el3{""};
        bool success3 = queue.take(el3, 10);
        slassert(success3);
        slassert("bbb" == el3.get_val());
    });

    producer.join();
    consumer.join();
}
示例#24
0
/* If timeout is minor or equal to 0 use traditional connect()
 * over blocking socket, else set `sockfd' in non-blocking mode 
 * and try to connect socket.
*/
static int
t_connect (int sockfd, void *serv_addr, socklen_t addrlen, u_short timeout)
{
    int rval = 0;
	unsigned long  u_sec = 0;
    const unsigned short pause = 2;
    const unsigned long  USEC  = 100000;

    if (timeout <= 0) return connect (sockfd, serv_addr, addrlen);

    slassert (fcntl(sockfd, F_SETFL, O_NONBLOCK) >= 0);
    
    while (1)
    {
    	rval = connect (sockfd, serv_addr, addrlen);
    	
    	if (!rval)
    	{
    		break;		/* success */
		}
		else
		if (rval < 0 && errno != EINPROGRESS && errno != EALREADY)
		{
			return -1;
		}
		else
		if ((u_sec / (10 * USEC)) >= timeout) /* timeout is in second */
		{
			errno = ETIMEDOUT;
			return -1;
		}
		
		usleep (pause * USEC);
		u_sec += (pause * USEC);
    }

    slassert (fcntl (sockfd, F_SETFL, 0) >= 0);
    return 0;
}
void test_copyable() {
    std::shared_ptr<NonCopyableSource> source{new NonCopyableSource{}};
    io::shared_source<NonCopyableSource> shared1{source};
    io::shared_source<NonCopyableSource> shared2{source};
    std::array<char, 3> buf;
    auto read1 = shared1.read(buf.data(), 3);
    slassert(3 == read1);
    slassert(3 == source->get_count());
    slassert(3 == shared1.get_source().get_count());
    slassert(3 == shared2.get_source().get_count());
    auto read2 = shared2.read(buf.data(), 2);
    slassert(2 == read2);
    slassert(5 == source->get_count());
    slassert(5 == shared1.get_source().get_count());
    slassert(5 == shared2.get_source().get_count());
}
void test_multi() {
    sc::blocking_queue<MyMovableStr> queue{};
    auto take = [&](size_t count) {
        for (size_t i = 0; i < count; i++) {
            MyMovableStr el{""};
            bool success = queue.take(el);
            slassert(success);
            slassert(42 == el.get_val().size());
        }
    };
    auto put = [&](size_t count) {
        TestStringGenerator gen{};
        for (size_t i = 0; i < count; i++) {
            std::string str = gen.generate(42);
            queue.emplace(std::move(str));
        }
    };
    std::thread producer1(put, 100);
    std::thread producer2(put, 100);
    std::thread producer3(put, 100);
    std::thread consumer1(take, 50);
    std::thread consumer2(take, 50);
    std::thread consumer3(take, 50);
    std::thread consumer4(take, 50);
    std::thread consumer5(take, 50);
    std::thread consumer6(take, 50);
    producer1.join();
    producer2.join();
    producer3.join();
    consumer1.join();
    consumer2.join();
    consumer3.join();
    consumer4.join();
    consumer5.join();
    consumer6.join();
}
void test_integral() {
    sc::blocking_queue<int> queue{};
    int a = 42;
    int b = 43;
    int& b_ref = b;
    queue.emplace(41);
    queue.emplace(a);
    queue.emplace(b_ref);
    slassert(3 == queue.size());
    int taken;
    slassert(queue.poll(taken));
    slassert(41 == taken);
    slassert(queue.poll(taken));
    slassert(42 == taken);
    slassert(queue.poll(taken));
    slassert(43 == taken);
    slassert(!queue.poll(taken));
}
示例#28
0
/* search hash of `file' in `checksum_path' file path and return md5 string.
 * If nothing found or an error occured, return NULL.
 */
char *
getmd5 (const char *file, const char *checksum_path)
{
    const char endlim[] = " \n\t";
    char buffer[BUFFSIZE0];
    FILE *fd;
    int len;

    slassert (file != NULL);
    
    errno = 0x00;

    if (!(fd = fopen (checksum_path, "r")))
    {
     	return NULL;
	}

    while (fgets (buffer, BUFFSIZE, fd))
    {
        if (strstr (buffer, file) == NULL)
        {
            continue;
        }

        len = strlen (buffer) - 1;
        while (len > 1 && strchr (endlim, buffer[len]))
        {
            buffer[len--] = 0x00;
        }
        len++;

        len -= strlen (file);

        if (len > 0 && buffer[len - 1] == '/' && !strcmp (buffer + len, file))
        {
            if (ismd5 (buffer))
            {
                fclose (fd);
                return xstrndup (buffer, STRMD5LEN); /* return hash */
            }
        }
    }

    fclose (fd);
    return NULL; /* hash not found */
}
void test_read() {
    std::string hello{"\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82"};
    auto st = iu::from_utf8(hello);
    iu::ustring_source src{std::move(st)};
    std::array<char, 32> buf;
    std::memset(buf.data(), '\0', buf.size());
    std::streamsize read1 = src.read(buf.data(), 1);
    slassert(1 == read1);
    slassert('\xd0' == buf[0]);
    std::streamsize read2 = src.read(buf.data(), 2);
    slassert(2 == read2);
    slassert('\xbf' == buf[0]);
    slassert('\xd1' == buf[1]);
    std::streamsize read3 = src.read(buf.data(), 16);
    slassert(9 == read3);
    slassert((hello.substr(3) == std::string{buf.data(), 9}));
    std::streamsize read4 = src.read(buf.data(), 16);
    slassert(std::char_traits<char>::eof() == read4);
}
示例#30
0
/* Receive data from socket `sd' saving it in `data' big `datasz' bytes.
 */
static int
t_recv (int sd, char *data, size_t datasz)
{
    fd_set read_set;
    struct timeval timeout;
    int rval;
    const int maxtimeout = opt.TIMEOUT;

    memset (data, 0, datasz);

    if (maxtimeout <= 0) /* no timeout, return default recv() */
     return recv (sd, data, datasz, 0);
     
    while (1)
    {
        FD_ZERO(&read_set);
	    FD_SET(sd, &read_set);
	    timeout.tv_sec  = maxtimeout;
        timeout.tv_usec = 0x00;
        
	    rval = select (sd + 1, &read_set, NULL, NULL, &timeout);
    
        if (rval < 0)
        {
            fprintf (stderr, "\n\nselect() error: %s.\n\n", strerror (errno));
            abort();
        }
        else
        if (rval == 0)
	    {
            errno = ETIMEDOUT;
            return -1;
        }
        else
        if (rval > 0)
        {
            return recv (sd, data, datasz, 0);
	    }
    }

    slassert (NULL); /* never here */
    return -1;
}