Example #1
0
def test_disabled_unsubscribes(ctx):
    """
    tests that if pubsub is disabled for a 
    feed, it becomes unsubscribed from it's 
    hub.
    """
    from eventlet import sleep, spawn
    from melkman.db import RemoteFeed
    from melkman.fetch.pubsubhubbub import WSGISubClient, callback_url_for 
    from melkman.fetch.pubsubhubbub import hubbub_sub, update_pubsub_state
    
    w = WSGISubClient(ctx)
    client = spawn(w.run)

    hub = FakeHub()
    hub_proc = spawn(hub.run)    
    hub_url = 'http://localhost:%d/' % hub.port

    feed_url = 'http://example.org/feeds/99'
    rf = RemoteFeed.create_from_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url},
                              {'rel': 'hub', 'href': hub_url}]}
    rf.save()
    
    # subscribe to the feed on the hub
    cb = callback_url_for(feed_url, ctx)
    assert not hub.is_verified(cb, feed_url)
    r, c = hubbub_sub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    assert hub.is_verified(cb, feed_url)
    
    # disable pubsub for the feed
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert rf.hub_info.enabled == True and rf.hub_info.subscribed == True
    rf.hub_info.enabled = False
    rf.save()
    
    # trigger an update
    update_pubsub_state(rf, ctx)
    
    # check that it is now unsubscribed.
    sleep(.5)
    assert not hub.is_verified(cb, feed_url)
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert rf.hub_info.enabled == False and rf.hub_info.subscribed == False
    
    client.kill()
    client.wait()
    hub_proc.kill()
    hub_proc.wait()
Example #2
0
def test_hub_lease_renew(ctx):
    """
    tests that we resubscribe with a hub 
    within the hub specified lease window.
    """
    from eventlet import sleep, spawn
    from melkman.db import RemoteFeed
    from melkman.fetch.pubsubhubbub import WSGISubClient, callback_url_for 
    from melkman.fetch.pubsubhubbub import hubbub_sub, update_pubsub_state

    w = WSGISubClient(ctx)
    client = spawn(w.run)

    # create a hub with a very short lease time.
    hub = FakeHub(lease_seconds=2)
    hub_proc = spawn(hub.run)    
    hub_url = 'http://localhost:%d/' % hub.port

    feed_url = 'http://example.org/feeds/99'
    rf = RemoteFeed.create_from_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url},
                              {'rel': 'hub', 'href': hub_url}]}
    rf.save()
    
    # subscribe to the feed on the hub
    cb = callback_url_for(feed_url, ctx)
    assert not hub.is_verified(cb, feed_url)
    r, c = hubbub_sub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    assert hub.is_verified(cb, feed_url)
    rf = RemoteFeed.get_by_url(feed_url, ctx)

    assert hub.renewals(cb, feed_url) == 0
    
    sleep(2)
    
    update_pubsub_state(rf, ctx)
    
    # make sure we triggered a lease renewal
    assert hub.renewals(cb, feed_url) == 1

    client.kill()
    client.wait()
    hub_proc.kill()
    hub_proc.wait()
Example #3
0
def test_hub_lease_renew_failover(ctx):
    """
    tests that if we fail to renew a lease with a hub 
    we will failover to a different hub if one is available.
    """
    from eventlet import sleep, spawn
    from melkman.db import RemoteFeed
    from melkman.fetch.pubsubhubbub import WSGISubClient, callback_url_for 
    from melkman.fetch.pubsubhubbub import hubbub_sub, update_pubsub_state


    w = WSGISubClient(ctx)
    client = spawn(w.run)

    # create a hub with a very short lease time.
    hub = FakeHub(lease_seconds=2)
    hub_proc = spawn(hub.run)    
    hub_url = 'http://localhost:%d/' % hub.port

    hub2 = FakeHub(port=9298)
    hub2_proc = spawn(hub2.run)
    hub2_url = 'http://localhost:%d/' % hub2.port

    feed_url = 'http://example.org/feeds/99'
    rf = RemoteFeed.create_from_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url},
                              {'rel': 'hub', 'href': hub_url}, 
                              {'rel': 'hub', 'href': hub2_url}]}
    rf.save()

    # subscribe to the feed on the hub
    cb = callback_url_for(feed_url, ctx)
    assert not hub.is_verified(cb, feed_url)
    r, c = hubbub_sub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert rf.hub_info.subscribed == True
    assert rf.hub_info.hub_url == hub_url
    assert hub.is_verified(cb, feed_url)
    assert not hub2.is_verified(cb, feed_url)

    assert hub.renewals(cb, feed_url) == 0
    sleep(2)
    
    # kill the first hub so that when we update, 
    # the renewal will fail...
    hub_proc.kill()

    # when this update is triggered, renewal should fail and 
    # we should instead subscribe to the alternate hub.
    update_pubsub_state(rf, ctx)
    
    assert hub.renewals(cb, feed_url) == 0
    rf = RemoteFeed.get_by_url(feed_url, ctx)    
    assert rf.hub_info.subscribed == True
    assert rf.hub_info.hub_url == hub2_url
    assert hub2.is_verified(cb, feed_url)

    client.kill()
    client.wait()
    hub2_proc.kill()
    hub2_proc.wait()
Example #4
0
def test_hub_invalidation_resub(ctx):
    """
    tests that if a currently subscribed hub is 
    no longer listed, we subscribe to a different
    hub if any are listed.
    """
    from eventlet import sleep, spawn
    from melkman.db import RemoteFeed
    from melkman.fetch.pubsubhubbub import WSGISubClient, callback_url_for 
    from melkman.fetch.pubsubhubbub import hubbub_sub, update_pubsub_state

    w = WSGISubClient(ctx)
    client = spawn(w.run)

    # create two hubs
    hub = FakeHub()
    hub_proc = spawn(hub.run)    
    hub_url = 'http://localhost:%d/' % hub.port

    hub2 = FakeHub(port=9298)
    hub2_proc = spawn(hub2.run)    
    hub2_url = 'http://localhost:%d/' % hub2.port


    feed_url = 'http://example.org/feeds/99'
    rf = RemoteFeed.create_from_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url},
                              {'rel': 'hub', 'href': hub_url}]}
    rf.save()
    
    # subscribe to the feed on the hub
    cb = callback_url_for(feed_url, ctx)
    assert not hub.is_verified(cb, feed_url)
    r, c = hubbub_sub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    assert hub.is_verified(cb, feed_url)

    # remove the hub from the list of hubs, but replace it with another
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url}, 
                              {'rel': 'hub', 'href': hub2_url}]}
    rf.save()

    # trigger an update
    update_pubsub_state(rf, ctx)
    
    # check that it is now unsubscribed from the original hub, and 
    # is now subscribed to the new hub.
    sleep(2)
    assert not hub.is_verified(cb, feed_url)
    assert hub2.is_verified(cb, feed_url)
    
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert rf.hub_info.enabled == True and rf.hub_info.subscribed == True
    
    client.kill()
    client.wait()
    hub_proc.kill()
    hub_proc.wait()
    hub2_proc.kill()
    hub2_proc.wait()
Example #5
0
def test_sub_to_hub(ctx):
    """
    test make_sub_request and make_unsub_request
    """
    
    from httplib2 import Http
    from eventlet import sleep, spawn
    from melk.util.nonce import nonce_str
    import traceback

    from melkman.db import RemoteFeed
    from melkman.fetch.worker import run_feed_indexer
    from melkman.fetch.pubsubhubbub import WSGISubClient
    from melkman.fetch.pubsubhubbub import callback_url_for
    from melkman.fetch.pubsubhubbub import hubbub_sub
    from melkman.fetch.pubsubhubbub import hubbub_unsub
    from melkman.fetch.pubsubhubbub import psh_digest
    
    import logging
    logging.basicConfig(level=logging.WARN)
    


    w = WSGISubClient(ctx)
    client = spawn(w.run)
    indexer = spawn(run_feed_indexer, ctx)

    hub = FakeHub()
    hub_proc = spawn(hub.run)
    
    hub_url = 'http://localhost:%d/' % hub.port
    
    feed_url = 'http://example.org/feeds/99'
    rf = RemoteFeed.create_from_url(feed_url, ctx)
    rf.feed_info = {'links': [{'rel': 'self', 'href': feed_url},
                              {'rel': 'hub', 'href': hub_url}]}
    rf.save()
    
    cb = callback_url_for(feed_url, ctx)
    
    # subscribe to the hub
    assert not hub.is_verified(cb, feed_url)
    r, c = hubbub_sub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    assert hub.is_verified(cb, feed_url)
    secret = hub.secret_for(cb, feed_url)
    
    http = Http()

    # simulate hub posting to callback URL
    content = random_atom_feed(feed_url, 10, link=feed_url, hub_urls=[hub_url])
    digest = 'sha1=%s' % psh_digest(content, secret)
    r, c = http.request(cb, 'POST', body=content, headers={'X-Hub-Signature': digest})
    assert r.status == 200, 'Expected 200, got %d' % r.status
    sleep(0.5)
    
    # since we are subscribed, new items should be in the feed now
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert len(rf.entries) == 10
    for iid in melk_ids_in(content, feed_url):
        assert iid in rf.entries
    
    # unsubscribe from hub
    r, c = hubbub_unsub(rf, ctx)
    assert r.status == 202, 'Expected 202, got %d' % r.status
    sleep(.5)
    assert not hub.is_verified(cb, feed_url)
    
    # simulate another POST to the callback URL 
    # this time it should fail (we are not subscribed)
    content = random_atom_feed(feed_url, 10, link=feed_url, hub_urls=[hub_url])
    digest = "sha1=%s" % psh_digest(content, secret)
    r, c = http.request(cb, 'POST', body=content, headers={'X-Hub-Signature': digest})
    assert r.status == 200, 'Expected 200, got %d' % r.status
    sleep(0.5)
    # items should be the same as before (not subscribed)
    rf = RemoteFeed.get_by_url(feed_url, ctx)
    assert len(rf.entries) == 10
    for iid in melk_ids_in(content, feed_url):
        assert not iid in rf.entries
        
    client.kill()
    client.wait()
    indexer.kill()
    indexer.wait()
    hub_proc.kill()
    hub_proc.wait()