<commit_before># -*- coding: utf-8 -*-
import pytest
from plexapi.exceptions import BadRequest, NotFound

from . import conftest as utils
from . import test_mixins

def test_Collection_attrs(collection):
    assert utils.is_datetime(collection.addedAt)
    assert collection.art is None
    assert collection.artBlurHash is None
    assert collection.childCount == 1
    assert collection.collectionMode == -1
    assert collection.collectionPublished is False
    assert collection.collectionSort == 0
    assert collection.content is None
    assert collection.contentRating is None
    assert not collection.fields
    assert collection.guid.startswith("collection://")
    assert utils.is_int(collection.index)
    assert collection.key.startswith("/library/collections/")
    assert not collection.labels
    assert utils.is_int(collection.librarySectionID)
    assert collection.librarySectionKey == "/library/sections/%s" % collection.librarySectionID
    assert collection.librarySectionTitle == "Movies"
    assert utils.is_int(collection.maxYear)
    assert utils.is_int(collection.minYear)
    assert utils.is_int(collection.ratingCount)
    assert utils.is_int(collection.ratingKey)
    assert collection.smart is False
    assert collection.subtype == "movie"
    assert collection.summary == ""
    assert collection.thumb.startswith("/library/collections/%s/composite" % collection.ratingKey)
    assert collection.thumbBlurHash is None
    assert collection.title == "Test Collection"
    assert collection.titleSort == collection.title
    assert collection.type == "collection"
    assert utils.is_datetime(collection.updatedAt)
    assert collection.listType == "video"
    assert collection.metadataType == collection.subtype
    assert collection.isVideo is True
    assert collection.isAudio is False
    assert collection.isPhoto is False

def test_Collection_section(collection, movies):
    assert collection.section() == movies

def test_Collection_item(collection):
    item1 = collection.item("Elephants Dream")
    assert item1.title == "Elephants Dream"
    item2 = collection.get("Elephants Dream")
    assert item2.title == "Elephants Dream"
    assert item1 == item2
    with pytest.raises(NotFound):
        collection.item("Does not exist")

def test_Collection_items(collection):
    items = collection.items()
    assert len(items) == 1

def test_Collection_modeUpdate(collection):
    mode_dict = {"default": -1, "hide": 0, "hideItems": 1, "showItems": 2}
    for key, value in mode_dict.items():
        collection.modeUpdate(mode=key)
        collection.reload()
        assert collection.collectionMode == value
    with pytest.raises(BadRequest):
        collection.modeUpdate(mode="bad-mode")
    collection.modeUpdate("default")

def test_Collection_sortUpdate(collection):
    sort_dict = {"release": 0, "alpha": 1}
    for key, value in sort_dict.items():
        collection.sortUpdate(sort=key)
        collection.reload()
        assert collection.collectionSort == value
    with pytest.raises(BadRequest):
        collection.sortUpdate(sort="bad-sort")
    collection.sortUpdate("release")

def test_Collection_add_remove(collection, movies, show):
    movie = movies.get("Big Buck Bunny")
    assert movie not in collection
    collection.addItems(movie)
    collection.reload()
    assert movie in collection
    collection.removeItems(movie)
    collection.reload()
    assert movie not in collection
    with pytest.raises(BadRequest):
        collection.addItems(show)

def test_Collection_edit(collection, movies):
    fields = {"title", "titleSort", "contentRating", "summary"}
    title = collection.title
    titleSort = collection.titleSort
    contentRating = collection.contentRating
    summary = collection.summary

    newTitle = "New Title"
    newTitleSort = "New Title Sort"
    newContentRating = "New Content Rating"
    newSummary = "New Summary"
    collection.edit(
        title=newTitle,
        titleSort=newTitleSort,
        contentRating=newContentRating,
        summary=newSummary
    )
    collection.reload()
    assert collection.title == newTitle
    assert collection.titleSort == newTitleSort
    assert collection.contentRating == newContentRating
    assert collection.summary == newSummary
    lockedFields = [f.locked for f in collection.fields if f.name in fields]
    assert all(lockedFields)

    collection.edit(
        title=title,
        titleSort=titleSort,
        contentRating=contentRating or "",
        summary=summary,
        **{
            "title.locked": 0,
            "titleSort.locked": 0,
            "contentRating.locked": 0,
            "summary.locked": 0
        }
    )
    collection.reload()
    assert collection.title == title
    assert collection.titleSort == titleSort
    assert collection.contentRating is None
    assert collection.summary == summary
    lockedFields = [f.locked for f in collection.fields if f.name in fields]
    assert not any(lockedFields)

def test_Collection_create(plex, tvshows):
    title = "test_Collection_create"
    try:
        collection = plex.createCollection(
            title=title,
            section=tvshows,
            items=tvshows.all()
        )
        assert collection in tvshows.collections()
        assert collection.smart is False
    finally:
        collection.delete()

def test_Collection_createSmart(plex, tvshows):
    title = "test_Collection_createSmart"
    try:
        collection = plex.createCollection(
            title=title,
            section=tvshows,
            smart=True,
            limit=3,
            libtype="episode",
            sort="episode.index:desc",
            filters={"show.title": "Game of Thrones"}
        )
        assert collection in tvshows.collections()
        assert collection.smart is True
        assert len(collection.items()) == 3
        assert all([e.type == "episode" for e in collection.items()])
        assert all([e.grandparentTitle == "Game of Thrones" for e in collection.items()])
        assert collection.items() == sorted(collection.items(), key=lambda e: e.index, reverse=True)
        collection.updateFilters(limit=5, libtype="episode", filters={"show.title": "The 100"})
        collection.reload()
        assert len(collection.items()) == 5
        assert all([e.grandparentTitle == "The 100" for e in collection.items()])
    finally:
        collection.delete()

def test_Collection_exceptions(plex, movies, movie, artist):
    title = 'test_Collection_exceptions'
    try:
        collection = plex.createCollection(title, section=movies.title, items=movie)
        with pytest.raises(BadRequest):
            collection.updateFilters()
        with pytest.raises(BadRequest):
            collection.addItems(artist)
    finally:
        collection.delete()

    with pytest.raises(BadRequest):
        plex.createCollection(title, section=movies, items=[])
    with pytest.raises(BadRequest):
        plex.createCollection(title, section=movies, items=[movie, artist])

    try:
        collection = plex.createCollection(title, smart=True, section=movies.title, **{'year>>': 2000})
        with pytest.raises(BadRequest):
            collection.addItems(movie)
        with pytest.raises(BadRequest):
            collection.removeItems(movie)
    finally:
        collection.delete()

def test_Collection_posters(collection):
    posters = collection.posters()
    assert posters

def test_Collection_art(collection):
    arts = collection.arts()
    assert not arts  # Collection has no default art

def test_Collection_mixins_images(collection):
    test_mixins.edit_art(collection)
    test_mixins.edit_poster(collection)
    test_mixins.attr_artUrl(collection)
    test_mixins.attr_posterUrl(collection)

def test_Collection_mixins_rating(collection):
    test_mixins.edit_rating(collection)

def test_Collection_mixins_tags(collection):
    test_mixins.edit_label(collection)
<commit_msg>Update collection tests for moving items<commit_after># -*- coding: utf-8 -*-
import pytest
from plexapi.exceptions import BadRequest, NotFound

from . import conftest as utils
from . import test_mixins

def test_Collection_attrs(collection):
    assert utils.is_datetime(collection.addedAt)
    assert collection.art is None
    assert collection.artBlurHash is None
    assert collection.childCount == 1
    assert collection.collectionMode == -1
    assert collection.collectionPublished is False
    assert collection.collectionSort == 0
    assert collection.content is None
    assert collection.contentRating is None
    assert not collection.fields
    assert collection.guid.startswith("collection://")
    assert utils.is_int(collection.index)
    assert collection.key.startswith("/library/collections/")
    assert not collection.labels
    assert utils.is_int(collection.librarySectionID)
    assert collection.librarySectionKey == "/library/sections/%s" % collection.librarySectionID
    assert collection.librarySectionTitle == "Movies"
    assert utils.is_int(collection.maxYear)
    assert utils.is_int(collection.minYear)
    assert utils.is_int(collection.ratingCount)
    assert utils.is_int(collection.ratingKey)
    assert collection.smart is False
    assert collection.subtype == "movie"
    assert collection.summary == ""
    assert collection.thumb.startswith("/library/collections/%s/composite" % collection.ratingKey)
    assert collection.thumbBlurHash is None
    assert collection.title == "Test Collection"
    assert collection.titleSort == collection.title
    assert collection.type == "collection"
    assert utils.is_datetime(collection.updatedAt)
    assert collection.listType == "video"
    assert collection.metadataType == collection.subtype
    assert collection.isVideo is True
    assert collection.isAudio is False
    assert collection.isPhoto is False

def test_Collection_section(collection, movies):
    assert collection.section() == movies

def test_Collection_item(collection):
    item1 = collection.item("Elephants Dream")
    assert item1.title == "Elephants Dream"
    item2 = collection.get("Elephants Dream")
    assert item2.title == "Elephants Dream"
    assert item1 == item2
    with pytest.raises(NotFound):
        collection.item("Does not exist")

def test_Collection_items(collection):
    items = collection.items()
    assert len(items) == 1

def test_Collection_modeUpdate(collection):
    mode_dict = {"default": -1, "hide": 0, "hideItems": 1, "showItems": 2}
    for key, value in mode_dict.items():
        collection.modeUpdate(mode=key)
        collection.reload()
        assert collection.collectionMode == value
    with pytest.raises(BadRequest):
        collection.modeUpdate(mode="bad-mode")
    collection.modeUpdate("default")

def test_Collection_sortUpdate(collection):
    sort_dict = {"release": 0, "alpha": 1}
    for key, value in sort_dict.items():
        collection.sortUpdate(sort=key)
        collection.reload()
        assert collection.collectionSort == value
    with pytest.raises(BadRequest):
        collection.sortUpdate(sort="bad-sort")
    collection.sortUpdate("release")

def test_Collection_add_move_remove(collection, movies, show):
    movie = movies.get("Big Buck Bunny")
    assert movie not in collection
    collection.addItems(movie)
    collection.reload()
    assert movie in collection
    items = collection.items()
    collection.moveItem(items[1])
    items_moved = collection.reload().items()
    assert items_moved[0] == items[1]
    assert items_moved[1] == items[0]
    collection.moveItem(items[1], after=items[0])
    items_moved = collection.reload().items()
    assert items_moved[0] == items[0]
    assert items_moved[1] == items[1]
    collection.removeItems(movie)
    collection.reload()
    assert movie not in collection

def test_Collection_edit(collection, movies):
    fields = {"title", "titleSort", "contentRating", "summary"}
    title = collection.title
    titleSort = collection.titleSort
    contentRating = collection.contentRating
    summary = collection.summary

    newTitle = "New Title"
    newTitleSort = "New Title Sort"
    newContentRating = "New Content Rating"
    newSummary = "New Summary"
    collection.edit(
        title=newTitle,
        titleSort=newTitleSort,
        contentRating=newContentRating,
        summary=newSummary
    )
    collection.reload()
    assert collection.title == newTitle
    assert collection.titleSort == newTitleSort
    assert collection.contentRating == newContentRating
    assert collection.summary == newSummary
    lockedFields = [f.locked for f in collection.fields if f.name in fields]
    assert all(lockedFields)

    collection.edit(
        title=title,
        titleSort=titleSort,
        contentRating=contentRating or "",
        summary=summary,
        **{
            "title.locked": 0,
            "titleSort.locked": 0,
            "contentRating.locked": 0,
            "summary.locked": 0
        }
    )
    collection.reload()
    assert collection.title == title
    assert collection.titleSort == titleSort
    assert collection.contentRating is None
    assert collection.summary == summary
    lockedFields = [f.locked for f in collection.fields if f.name in fields]
    assert not any(lockedFields)

def test_Collection_create(plex, tvshows):
    title = "test_Collection_create"
    try:
        collection = plex.createCollection(
            title=title,
            section=tvshows,
            items=tvshows.all()
        )
        assert collection in tvshows.collections()
        assert collection.smart is False
    finally:
        collection.delete()

def test_Collection_createSmart(plex, tvshows):
    title = "test_Collection_createSmart"
    try:
        collection = plex.createCollection(
            title=title,
            section=tvshows,
            smart=True,
            limit=3,
            libtype="episode",
            sort="episode.index:desc",
            filters={"show.title": "Game of Thrones"}
        )
        assert collection in tvshows.collections()
        assert collection.smart is True
        assert len(collection.items()) == 3
        assert all([e.type == "episode" for e in collection.items()])
        assert all([e.grandparentTitle == "Game of Thrones" for e in collection.items()])
        assert collection.items() == sorted(collection.items(), key=lambda e: e.index, reverse=True)
        collection.updateFilters(limit=5, libtype="episode", filters={"show.title": "The 100"})
        collection.reload()
        assert len(collection.items()) == 5
        assert all([e.grandparentTitle == "The 100" for e in collection.items()])
    finally:
        collection.delete()

def test_Collection_exceptions(plex, movies, movie, artist):
    title = 'test_Collection_exceptions'
    try:
        collection = plex.createCollection(title, section=movies.title, items=movie)
        with pytest.raises(BadRequest):
            collection.updateFilters()
        with pytest.raises(BadRequest):
            collection.addItems(artist)
    finally:
        collection.delete()

    with pytest.raises(BadRequest):
        plex.createCollection(title, section=movies, items=[])
    with pytest.raises(BadRequest):
        plex.createCollection(title, section=movies, items=[movie, artist])

    try:
        collection = plex.createCollection(title, smart=True, section=movies.title, **{'year>>': 2000})
        with pytest.raises(BadRequest):
            collection.addItems(movie)
        with pytest.raises(BadRequest):
            collection.removeItems(movie)
        with pytest.raises(BadRequest):
            collection.moveItem(movie)
    finally:
        collection.delete()

def test_Collection_posters(collection):
    posters = collection.posters()
    assert posters

def test_Collection_art(collection):
    arts = collection.arts()
    assert not arts  # Collection has no default art

def test_Collection_mixins_images(collection):
    test_mixins.edit_art(collection)
    test_mixins.edit_poster(collection)
    test_mixins.attr_artUrl(collection)
    test_mixins.attr_posterUrl(collection)

def test_Collection_mixins_rating(collection):
    test_mixins.edit_rating(collection)

def test_Collection_mixins_tags(collection):
    test_mixins.edit_label(collection)
<|endoftext|>


<commit_before>import sys

from card import *

class Count(dict):
    def __init__(self, seq=[]):

        for x in seq:
            self.count(x)

    def count(self, x, f=1):
        self[x] = self.get(x, 0) + f
        if self[x] == 0:
            del self[x]

class PokerHand(Hand):

    labelss = ['pair', 'twopair', 'threeofakind', 'straight', 'flush', 'fullhouse', 'fourofakind', 'straightflush', 'highcard']

    def make_histograms(self):
        self.suits = Count()
        self.ranks = Count()
        for c in self.cards:
            self.suits.count(c.suit)
            self.ranks.count(c.rank)

        self.sets = self.ranks.values()
        self.sets.sort(reverse=True)
    def has_highcard(self):
        """Returns True if this hand has a high card."""
        return len(self.cards)

    def check_sets(self, *t):
        for need, have in zip(t, self.sets):
            if need > have: return False
        return True

    def has_pair(self):
        """Checks whether this hand has a pair."""
        return self.check_sets(2)

    def has_twopair(self):
        """Checks whether this hand has two pair."""
        return self.check_sets(2, 2)

    def has_threeofakind(self):
        """Checks whether this hand has three of a kind."""
        return self.check_sets(3)

    def has_fourofakind(self):
        """Checks whether this hand has four of a kind."""
        return self.check_sets(4)

    def has_fullhouse(self):
        """Checks whether this hand has a full house."""
        return self.check_sets(3, 2)

    def has_flush(self):
        """Checks whether this hand has a flush."""
        for val in self.suits.values():
            if val >= 5:
                return True
        return False

    def has_straight(self):
        """Checks whether this hand has a straight."""
        # make a copy of the rank histogram before we mess with it
        ranks = self.ranks.copy()
        ranks[14] = ranks.get(1, 0)

        # see if we have 5 in a row
        return self.in_a_row(ranks, 5)

    def in_a_row(self, ranks, n):
        """Checks whether the histogram has n ranks in a row.

        hist: map from rank to frequency
        n: number we need to get to
        """
        count = 0
        for i in range(1, 15):
            if ranks.get(i, 0):
                count += 1
                if count == 5: return True
            else:
                count = 0
        return False

    def has_straightflush(self):
        """Checks whether this hand has a straight flush.

        Clumsy algorithm.
        """
        # make a set of the (rank, suit) pairs we have
        s = set()
        for c in self.cards:
            s.add((c.rank, c.suit))
            if c.rank == 1:
                s.add((14, c.suit))

        # iterate through the suits and ranks and see if we
        # get to 5 in a row
        for suit in range(4):
            count = 0
            for rank in range(1, 15):
                if (rank, suit) in s:
                    count += 1
                    if count == 5: return True
                else:
                    count = 0
        return False

    def has_straightflush(self):
        """Checks whether this hand has a straight flush.

        Better algorithm (in the sense of being more demonstrably
        correct).
        """
        # partition the hand by suit and check each
        # sub-hand for a straight
        d = {}
        for c in self.cards:
            d.setdefault(c.suit, PokerHand()).add_card(c)

        # see if any of the partitioned hands has a straight
        for hand in d.values():
            if len(hand.cards) < 5:
                continue
            hand.make_histograms()
            if hand.has_straight():
                return True
        return False

    def classify(self):
        """Classifies this hand.
        Creates attributes:
          labels:
        """
        self.make_histograms()

        self.labels = []
        for label in PokerHand.labelss:
            f = getattr(self, 'has_' + label)
            if f():
                self.labels.append(label)

class PokerDeck(Deck):
    """Represents a deck of cards that can deal poker hands."""

    def deal_hands(deck, num_cards=5, num_hands=10):
        hands = []
        for i in range(num_hands):
            hand = PokerHand()
            deck.move_cards(hand, num_cards)
            hand.classify()
            hands.append(hand)
        return hands

def main(*args):
    counterlabel = Count()
    n = 10000
    for i in range(n):
        if i % 1000 == 0:
            print i
        deck = PokerDeck()
        deck.shuffle()

        hands = deck.deal_hands(7,7)
        for hand in hands:
            for label in hand.labels:
                counterlabel.count(label)
    total = 7.0 * n
    print 'Number of hands', total
    for label in PokerHand.labelss:
        probab = counterlabel.get(label, 0)
        if probab == 0:
            continue
        p = total / probab
        print '%s probability is %.2f' % (label, p)

if __name__ == '__main__':
    main(*sys.argv)<commit_msg>Update mypoker.py<commit_after>import sys

from card import *

class Count(dict):
    def __init__(self, seq=[]):

        for x in seq:
            self.count(x)

    def count(self, x, f=1):
        self[x] = self.get(x, 0) + f
        if self[x] == 0:
            del self[x]

class PokerHand(Hand):

    labelss = ['pair', 'twopair', 'threeofakind', 'straight', 'flush', 'fullhouse', 'fourofakind', 'straightflush', 'highcard']

    def make_histograms(self):
        self.suits = Count()
        self.ranks = Count()
        for c in self.cards:
            self.suits.count(c.suit)
            self.ranks.count(c.rank)

        self.sets = self.ranks.values()
        self.sets.sort(reverse=True)
    def has_highcard(self):
        """Returns True if this hand has a high card."""
        return len(self.cards)

    def check_sets(self, *t):
        for need, have in zip(t, self.sets):
            if need > have: return False
        return True

    def has_pair(self):
        """Checks whether this hand has a pair."""
        return self.check_sets(2)

    def has_twopair(self):
        """Checks whether this hand has two pair."""
        return self.check_sets(2, 2)

    def has_threeofakind(self):
        """Checks whether this hand has three of a kind."""
        return self.check_sets(3)

    def has_fourofakind(self):
        """Checks whether this hand has four of a kind."""
        return self.check_sets(4)

    def has_fullhouse(self):
        """Checks whether this hand has a full house."""
        return self.check_sets(3, 2)

    def has_flush(self):
        """Checks whether this hand has a flush."""
        for val in self.suits.values():
            if val >= 5:
                return True
        return False

    def has_straight(self):
        """Checks whether this hand has a straight."""
        # make a copy of the rank histogram before we mess with it
        ranks = self.ranks.copy()
        ranks[14] = ranks.get(1, 0)

        # see if we have 5 in a row
        return self.in_a_row(ranks, 5)

    def in_a_row(self, ranks, n):
        """Checks whether the histogram has n ranks in a row.

        hist: map from rank to frequency
        n: number we need to get to
        """
        count = 0
        for i in range(1, 15):
            if ranks.get(i, 0):
                count += 1
                if count == 5: return True
            else:
                count = 0
        return False

    def has_straightflush(self):
        """Checks whether this hand has a straight flush.

        Clumsy algorithm.
        """
        # make a set of the (rank, suit) pairs we have
        s = set()
        for c in self.cards:
            s.add((c.rank, c.suit))
            if c.rank == 1:
                s.add((14, c.suit))

        # iterate through the suits and ranks and see if we
        # get to 5 in a row
        for suit in range(4):
            count = 0
            for rank in range(1, 15):
                if (rank, suit) in s:
                    count += 1
                    if count == 5: return True
                else:
                    count = 0
        return False

    def has_straightflush(self):
        """Checks whether this hand has a straight flush.

        Better algorithm (in the sense of being more demonstrably
        correct).
        """
        # partition the hand by suit and check each
        # sub-hand for a straight
        d = {}
        for c in self.cards:
            d.setdefault(c.suit, PokerHand()).add_card(c)

        # see if any of the partitioned hands has a straight
        for hand in d.values():
            if len(hand.cards) < 5:
                continue
            hand.make_histograms()
            if hand.has_straight():
                return True
        return False

    def classify(self):
        """Classifies this hand.
        Creates attributes:
          labels:
        """
        self.make_histograms()

        self.labels = []
        for label in PokerHand.labelss:
            f = getattr(self, 'has_' + label)
            if f():
                self.labels.append(label)

class PokerDeck(Deck):
    """Represents a deck of cards that can deal poker hands."""

    def deal_hands(deck, num_cards=5, num_hands=10):
        hands = []
        for i in range(num_hands):
            hand = PokerHand()
            deck.move_cards(hand, num_cards)
            hand.classify()
            hands.append(hand)
        return hands

def main(*args):
    counterlabel = Count()
    n = 10000
    for i in range(n):
        if i % 1000 == 0:
            print i
        deck = PokerDeck()
        deck.shuffle()

        hands = deck.deal_hands(7,7)
        for hand in hands:
            for label in hand.labels:
                counterlabel.count(label)
    total = 7.0 * n
    print 'Number of hands', total
    for label in PokerHand.labelss:
        probab = counterlabel.get(label, 0)
        if probab == 0:
            continue
        p = total / probab
        print '%s happens one time in %.2f' % (label, p)

if __name__ == '__main__':
    main(*sys.argv)
<|endoftext|>


<commit_before>import pytest
import abc
import os
from glob import glob
import xarray as xr
import numpy as np
from climt import (
    DataArray, HeldSuarez, GrayLongwaveRadiation,
    Frierson06LongwaveOpticalDepth)

cache_folder = os.path.join(
    os.path.dirname(os.path.realpath(__file__)), 'cached_component_output')

def cache_dictionary(dictionary, filename):
    dataset = xr.Dataset(dictionary)
    dataset.to_netcdf(filename, engine='scipy')

def load_dictionary(filename):
    dataset = xr.open_dataset(filename, engine='scipy')
    return dict(dataset.data_vars)

class ComponentBase(object):

    @abc.abstractmethod
    def get_input_state(self):
        pass

    @abc.abstractmethod
    def get_component_instance(self):
        pass

    def get_cached_output(self):
        cache_filename_list = sorted(glob(
            os.path.join(
                cache_folder,
                '{}-*.cache'.format(
                    self.__class__.__name__))))
        if len(cache_filename_list) > 0:
            return_list = []
            for filename in cache_filename_list:
                return_list.append(load_dictionary(filename))
            if len(return_list) > 1:
                return tuple(return_list)
            elif len(return_list) == 1:
                return return_list[0]
        else:
            return None

    def cache_output(self, output):
        if not isinstance(output, tuple):
            output = (output,)
        for i in range(len(output)):
            cache_filename = os.path.join(
                cache_folder, '{}-{}.cache'.format(self.__class__.__name__, i))
            cache_dictionary(output[i], cache_filename)

    def test_output_matches_cached_output(self):
        state = self.get_input_state()
        component = self.get_component_instance()
        output = component(state)
        cached_output = self.get_cached_output()
        if cached_output is None:
            self.cache_output(output)
            raise AssertionError(
                'Failed due to no cached output, cached current output')
        else:
            compare_outputs(output, cached_output)

    def test_component_listed_inputs_are_accurate(self):
        state = self.get_input_state()
        component = self.get_component_instance()
        input_state = {}
        for key in component.inputs:
            input_state[key] = state[key]
        output = component(state)
        cached_output = self.get_cached_output()
        if cached_output is not None:
            compare_outputs(output, cached_output)

    def test_consistent_dim_length(self):
        input_state = self.get_input_state()
        assert_dimension_lengths_are_consistent(input_state)
        component = self.get_component_instance()
        output = component(input_state)
        if isinstance(output, tuple):
            # Check diagnostics/tendencies/outputs are consistent with one
            # another
            test_state = {}
            for state in output:
                test_state.update(state)
            assert_dimension_lengths_are_consistent(test_state)
        else:
            test_state = output  # if not a tuple assume it's a dict
            assert_dimension_lengths_are_consistent(test_state)

def assert_dimension_lengths_are_consistent(state):
    dimension_lengths = {}
    for name, value in state.items():
        for i, dim_name in enumerate(value.dims):
            if dim_name in dimension_lengths:
                assert dimension_lengths[dim_name] == value.shape[i]
            else:
                dimension_lengths[dim_name] = value.shape[i]

def compare_outputs(current, cached):
    if isinstance(current, tuple) and isinstance(cached, tuple):
        for i in range(len(current)):
            compare_one_state_pair(current[i], cached[i])
    elif (not isinstance(current, tuple)) and (not isinstance(cached, tuple)):
        compare_one_state_pair(current, cached)
    else:
        raise AssertionError('Different number of dicts returned than cached.')

def compare_one_state_pair(current, cached):
    for key in current.keys():
        assert np.all(current[key].values == cached[key].values)
        for attr in current[key].attrs:
            assert current[key].attrs[attr] == cached[key].attrs[attr]
        for attr in cached[key].attrs:
            assert attr in current[key].attrs
        assert current[key].dims == cached[key].dims
    for key in cached.keys():
        assert key in current.keys()

class TestHeldSuarez(ComponentBase):

    def get_input_state(self):
        random = np.random.RandomState(0)
        return {
            'latitude': DataArray(
                random.randn(3), dims=['lat'], attrs={'units': 'degrees_N'}),
            'air_pressure': DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            'sigma': DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}),
            'air_temperature': DataArray(
                270. + random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'degK'}),
            'eastward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
            'northward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
        }

    def get_component_instance(self):
        return HeldSuarez()

class TestHeldSuarezCachedCoordinates(ComponentBase):

    def get_input_state(self):
        random = np.random.RandomState(0)
        return {
            'latitude': DataArray(
                np.linspace(-90, 90, num=3),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            'air_pressure': DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            'sigma': DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}),
            'air_temperature': DataArray(
                270. + random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'degK'}),
            'eastward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
            'northward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
        }

    def get_component_instance(self):
        random = np.random.RandomState(0)
        return HeldSuarez(
            latitude=DataArray(
                np.linspace(-90, 90, num=3),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            air_pressure=DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            sigma=DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}))

class TestFrierson06LongwaveOpticalDepth(ComponentBase):

    def get_input_state(self):
        state = {
            'latitude': DataArray(
                np.linspace(-90, 90, num=10),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            'sigma_on_interface_levels': DataArray(
                np.linspace(0., 1., num=6),
                dims=['interface_levels'], attrs={'units': ''}),
        }
        return state

    def get_component_instance(self):
        return Frierson06LongwaveOpticalDepth()

class TestGrayLongwaveRadiation(ComponentBase):

    def get_component_instance(self):
        return GrayLongwaveRadiation()

    def get_input_state(self):
        random = np.random.RandomState(1)
        nx, ny, nz = 4, 4, 10
        state = {
            'longwave_optical_depth_on_interface_levels': DataArray(
                (np.linspace(0, 6, nz+1)[None, None, :] *
                 (1 + 0.1*random.randn(nx, ny))[:, :, None]),
                dims=['x', 'y', 'interface_levels'], attrs={'units': ''},
            ),
            'air_temperature': DataArray(
                5*random.randn(nx, ny, nz) + 270.,
                dims=['x', 'y', 'mid_levels'], attrs={'units': 'degK'},
            ),
            'air_pressure_on_interface_levels': DataArray(
                np.linspace(1e5, 0, nz+1),
                dims=['interface_levels'], attrs={'units': 'Pa'},
            ),
            'surface_temperature': DataArray(
                5 * random.randn(nx, ny) + 270.,
                dims=['x', 'y'], attrs={'units': 'degK'},
            )}
        return state

class TestGrayLongwaveRadiation1D(ComponentBase):

    def get_component_instance(self):
        return GrayLongwaveRadiation()

    def get_input_state(self):
        random = np.random.RandomState(1)
        nz = 10
        state = {
            'longwave_optical_depth_on_interface_levels': DataArray(
                np.linspace(0, 6, nz+1)[None, None, :],
                dims=['interface_levels'], attrs={'units': ''},
            ),
            'air_temperature': DataArray(
                5*random.randn(nz) + 270.,
                dims=['mid_levels'], attrs={'units': 'degK'},
            ),
            'air_pressure_on_interface_levels': DataArray(
                np.linspace(1e5, 0, nz+1),
                dims=['interface_levels'], attrs={'units': 'Pa'},
            ),
            'surface_temperature': DataArray(
                270.,
                dims=[], attrs={'units': 'degK'},
            )}
        return state

if __name__ == '__main__':
    pytest.main([__file__])
<commit_msg>Corrected error in 1D test, but still failing.<commit_after>import pytest
import abc
import os
from glob import glob
import xarray as xr
import numpy as np
from climt import (
    DataArray, HeldSuarez, GrayLongwaveRadiation,
    Frierson06LongwaveOpticalDepth)

cache_folder = os.path.join(
    os.path.dirname(os.path.realpath(__file__)), 'cached_component_output')

def cache_dictionary(dictionary, filename):
    dataset = xr.Dataset(dictionary)
    dataset.to_netcdf(filename, engine='scipy')

def load_dictionary(filename):
    dataset = xr.open_dataset(filename, engine='scipy')
    return dict(dataset.data_vars)

class ComponentBase(object):

    @abc.abstractmethod
    def get_input_state(self):
        pass

    @abc.abstractmethod
    def get_component_instance(self):
        pass

    def get_cached_output(self):
        cache_filename_list = sorted(glob(
            os.path.join(
                cache_folder,
                '{}-*.cache'.format(
                    self.__class__.__name__))))
        if len(cache_filename_list) > 0:
            return_list = []
            for filename in cache_filename_list:
                return_list.append(load_dictionary(filename))
            if len(return_list) > 1:
                return tuple(return_list)
            elif len(return_list) == 1:
                return return_list[0]
        else:
            return None

    def cache_output(self, output):
        if not isinstance(output, tuple):
            output = (output,)
        for i in range(len(output)):
            cache_filename = os.path.join(
                cache_folder, '{}-{}.cache'.format(self.__class__.__name__, i))
            cache_dictionary(output[i], cache_filename)

    def test_output_matches_cached_output(self):
        state = self.get_input_state()
        component = self.get_component_instance()
        output = component(state)
        cached_output = self.get_cached_output()
        if cached_output is None:
            self.cache_output(output)
            raise AssertionError(
                'Failed due to no cached output, cached current output')
        else:
            compare_outputs(output, cached_output)

    def test_component_listed_inputs_are_accurate(self):
        state = self.get_input_state()
        component = self.get_component_instance()
        input_state = {}
        for key in component.inputs:
            input_state[key] = state[key]
        output = component(state)
        cached_output = self.get_cached_output()
        if cached_output is not None:
            compare_outputs(output, cached_output)

    def test_consistent_dim_length(self):
        input_state = self.get_input_state()
        assert_dimension_lengths_are_consistent(input_state)
        component = self.get_component_instance()
        output = component(input_state)
        if isinstance(output, tuple):
            # Check diagnostics/tendencies/outputs are consistent with one
            # another
            test_state = {}
            for state in output:
                test_state.update(state)
            assert_dimension_lengths_are_consistent(test_state)
        else:
            test_state = output  # if not a tuple assume it's a dict
            assert_dimension_lengths_are_consistent(test_state)

def assert_dimension_lengths_are_consistent(state):
    dimension_lengths = {}
    for name, value in state.items():
        for i, dim_name in enumerate(value.dims):
            if dim_name in dimension_lengths:
                assert dimension_lengths[dim_name] == value.shape[i]
            else:
                dimension_lengths[dim_name] = value.shape[i]

def compare_outputs(current, cached):
    if isinstance(current, tuple) and isinstance(cached, tuple):
        for i in range(len(current)):
            compare_one_state_pair(current[i], cached[i])
    elif (not isinstance(current, tuple)) and (not isinstance(cached, tuple)):
        compare_one_state_pair(current, cached)
    else:
        raise AssertionError('Different number of dicts returned than cached.')

def compare_one_state_pair(current, cached):
    for key in current.keys():
        assert np.all(current[key].values == cached[key].values)
        for attr in current[key].attrs:
            assert current[key].attrs[attr] == cached[key].attrs[attr]
        for attr in cached[key].attrs:
            assert attr in current[key].attrs
        assert current[key].dims == cached[key].dims
    for key in cached.keys():
        assert key in current.keys()

class TestHeldSuarez(ComponentBase):

    def get_input_state(self):
        random = np.random.RandomState(0)
        return {
            'latitude': DataArray(
                random.randn(3), dims=['lat'], attrs={'units': 'degrees_N'}),
            'air_pressure': DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            'sigma': DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}),
            'air_temperature': DataArray(
                270. + random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'degK'}),
            'eastward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
            'northward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
        }

    def get_component_instance(self):
        return HeldSuarez()

class TestHeldSuarezCachedCoordinates(ComponentBase):

    def get_input_state(self):
        random = np.random.RandomState(0)
        return {
            'latitude': DataArray(
                np.linspace(-90, 90, num=3),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            'air_pressure': DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            'sigma': DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}),
            'air_temperature': DataArray(
                270. + random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'degK'}),
            'eastward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
            'northward_wind': DataArray(
                random.randn(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'm/s'}),
        }

    def get_component_instance(self):
        random = np.random.RandomState(0)
        return HeldSuarez(
            latitude=DataArray(
                np.linspace(-90, 90, num=3),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            air_pressure=DataArray(
                random.rand(2, 3, 6), dims=['lon', 'lat', 'lev'],
                attrs={'units': 'hPa'},),
            sigma=DataArray(
                np.linspace(0., 1., num=6), dims=['lev'], attrs={'units': ''}))

class TestFrierson06LongwaveOpticalDepth(ComponentBase):

    def get_input_state(self):
        state = {
            'latitude': DataArray(
                np.linspace(-90, 90, num=10),
                dims=['lat'], attrs={'units': 'degrees_N'}),
            'sigma_on_interface_levels': DataArray(
                np.linspace(0., 1., num=6),
                dims=['interface_levels'], attrs={'units': ''}),
        }
        return state

    def get_component_instance(self):
        return Frierson06LongwaveOpticalDepth()

class TestGrayLongwaveRadiation(ComponentBase):

    def get_component_instance(self):
        return GrayLongwaveRadiation()

    def get_input_state(self):
        random = np.random.RandomState(1)
        nx, ny, nz = 4, 4, 10
        state = {
            'longwave_optical_depth_on_interface_levels': DataArray(
                (np.linspace(0, 6, nz+1)[None, None, :] *
                 (1 + 0.1*random.randn(nx, ny))[:, :, None]),
                dims=['x', 'y', 'interface_levels'], attrs={'units': ''},
            ),
            'air_temperature': DataArray(
                5*random.randn(nx, ny, nz) + 270.,
                dims=['x', 'y', 'mid_levels'], attrs={'units': 'degK'},
            ),
            'air_pressure_on_interface_levels': DataArray(
                np.linspace(1e5, 0, nz+1),
                dims=['interface_levels'], attrs={'units': 'Pa'},
            ),
            'surface_temperature': DataArray(
                5 * random.randn(nx, ny) + 270.,
                dims=['x', 'y'], attrs={'units': 'degK'},
            )}
        return state

class TestGrayLongwaveRadiation1D(ComponentBase):

    def get_component_instance(self):
        return GrayLongwaveRadiation()

    def get_input_state(self):
        random = np.random.RandomState(1)
        nz = 10
        state = {
            'longwave_optical_depth_on_interface_levels': DataArray(
                np.linspace(0, 6, nz+1),
                dims=['interface_levels'], attrs={'units': ''},
            ),
            'air_temperature': DataArray(
                5*random.randn(nz) + 270.,
                dims=['mid_levels'], attrs={'units': 'degK'},
            ),
            'air_pressure_on_interface_levels': DataArray(
                np.linspace(1e5, 0, nz+1),
                dims=['interface_levels'], attrs={'units': 'Pa'},
            ),
            'surface_temperature': DataArray(
                270.,
                dims=[], attrs={'units': 'degK'},
            )}
        return state

if __name__ == '__main__':
    pytest.main([__file__])
<|endoftext|>


<commit_before>import pytest
import numpy as np

from cycleindex.cyclecount import (
    clean_matrix,
    is_symmetric,
    cycle_count
)

@pytest.mark.parametrize("A,out", [
    (
        np.array([[1,0,0],[0,0,0],[0,1,0]]),
        np.array([[1,0],[0,1]])
    ),
    (
        np.array([[1,0,0],[0,1,0],[0,0,1]]),
        np.array([[1,0,0],[0,1,0],[0,0,1]])
    )
])
def test_clean_matrix(A,out):
    assert not np.any(clean_matrix(A) != out)

@pytest.mark.parametrize("A,expected", [
    (
        np.array([[0,0.5,0],[0,0,0.5],[0.4,0,0]]),
        False
    ),
    (
        np.array([[0,0.5,0],[0.5,0,0.5],[0,0.5,0]]),
        True
    )
])
def test_is_symmetric(A,expected):
    assert is_symmetric(A) == expected

@pytest.mark.parametrize("A,expected", [
    (
        np.array([[0,0.5,0],[0,0,-0.5],[0.5,0,0]]),
        [0,0,-0.12500,0,0]
    ),
    (
        np.array([[0,0.5,0.5,0],[0.5,0,0.5,0],[0.5,0.5,0,0.4],[0,0,0.4,0]]),
        [0,0.91,0.25,0,0]
    )
])
def test_cycle_count(A,expected):
    print(cycle_count(A,5))
    assert np.allclose(cycle_count(A,5),expected)
<commit_msg>Improve tests a little bit<commit_after>import pytest
import numpy as np

from cycleindex.cyclecount import (
    clean_matrix,
    is_symmetric,
    cycle_count
)

@pytest.mark.parametrize("A,out", [
    (
        np.array([[1,0,0],[0,0,0],[0,1,0]]),
        np.array([[1,0],[0,1]])
    ),
    (
        np.array([[1,0,0],[0,1,0],[0,0,1]]),
        np.array([[1,0,0],[0,1,0],[0,0,1]])
    )
])
def test_clean_matrix(A,out):
    assert not np.any(clean_matrix(A) != out)

@pytest.mark.parametrize("A,expected", [
    (
        np.array([[0,0.5,0],[0,0,0.5],[0.4,0,0]]),
        False
    ),
    (
        np.array([[0,0.5,0],[0.5,0,0.5],[0,0.5,0]]),
        True
    )
])
def test_is_symmetric(A,expected):
    assert is_symmetric(A) == expected

@pytest.mark.parametrize("A,expected", [
    (
        np.array([[0,0.5,0],[0,0,-0.5],[0.5,0,0]]),
        [0,0,-0.12500,0,0,0,0]
    ),
    (
        np.array([[0,0.5,0.5,0],[0.5,0,0.5,0],[0.5,0.5,0,0.4],[0,0,0.4,0]]),
        [0,0.91,0.25,0,0,0,0]
    ),
    (
        np.array([[0, 0.5, 0, 0, 0, 0, 0],
                  [0.5, 0, 0.4, 0.4, 0, 0, 0],
                  [0, 0.4, 0, -0.5, 0.1, 0, 0],
                  [0, 0.4, -0.5, 0, 0, 0.6, 0],
                  [0, 0, 0.1, 0, 0, 0, 0.8],
                  [0, 0, 0, 0.6, 0, 0, 0.7],
                  [0, 0, 0, 0, 0.8, 0.7, 0]]),
        [0,2.3200,-0.1600,0,-0.0336,0.010752,0]
    )
])
def test_cycle_count(A,expected):
    assert np.allclose(cycle_count(A,7),expected)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#-------------------------------------------------------------------------------
import socket
import random
import string
import time
import shutil
from contextlib import contextmanager

from commands.command       import *
from commands.vsbuild       import *

from config.system          import *

from utilities.files        import *
from utilities.hashing      import *
from utilities.paths        import *
from utilities.perforce     import *
from utilities.processes    import *

VERSION_FILE_PATH = "Development\\Src\\Engine\\DNE\\DNEOnlineSuiteBuildId.h"

#-------------------------------------------------------------------------------
class Ue3BuildCommand(Command):

    def __init__(self):
        Command.__init__(self, 'ue3-build', 'Build UE3 executable')

    #---------------------------------------------------------------------------
    def configure_arguments(self, context, parser):
        settings = context.settings

        parser.add_argument('-c',
                            '--configuration',
                            help    = 'configurations to build',
                            metavar = '<configuration>',
                            nargs   = '+',
                            default = settings.default_ue3_configurations)

        parser.add_argument('-p',
                            '--platform',
                            help    = 'platforms to build',
                            metavar = '<platform>',
                            nargs   = '+',
                            default = settings.default_ue3_platforms)

        parser.add_argument('--generate-version-file',
                            help    = 'Generates a code file containing build specific informations',
                            action  = "store_true",
                            default = False)
        return True

    #---------------------------------------------------------------------------
    def run(self, context):
        settings = context.settings
        arguments = context.arguments

        platforms               = arguments.platform
        configurations          = arguments.configuration
        result                  = True
        version_file_cl         = None

        log_verbose("Building UBT")
        if not self._build_project(context, "UnrealBuildTool/UnrealBuildTool.csproj",'Release'):
            log_error("Error building UBT")
            return False

        with generate_version_file():
            for platform in platforms:
                if platform.lower() == 'win64':
                    if not self._build_editor_csharp(context):
                        return False
                for configuration in configurations:
                    if not self._build(context, platform, configuration):
                        return False

        return True

    #-------------------------------------------------------------------------------
    def _build(self, context, platform, configuration):

        dict_vcxproj = {
            'win32' :   'Windows/ExampleGame Win32.vcxproj',
            'win64' :   'Windows/ExampleGame Win64.vcxproj',
            'ps3' :     'PS3/ExampleGame PS3.vcxproj',
            'ps4' :     'ExampleGame PS4/ExampleGame PS4.vcxproj',
            'xbox360' : 'Xenon/ExampleGame Xbox360.vcxproj',
            'xboxone' : 'Dingo/ExampleGame Dingo/ExampleGame Dingo.vcxproj',
        }

        platform_project = dict_vcxproj[platform.lower()]
        return self._build_project(context, platform_project, configuration, 'build')

    def _build_editor_csharp(self, context):
        log_notification("Building Editor C# libraries")

        if not self._build_project(context, 'DNEEdCSharp/DNEEdCSharp.csproj', 'Release'):
            return False

        if not self._build_project(context, 'UnrealEdCSharp/UnrealEdCSharp.csproj', 'Release'):
            return False

        dll_target = os.path.join('Binaries/Win64/Editor/Release')
        dll_source = os.path.join('Binaries/Editor/Release')

        try:
            shutil.copy(os.path.join(dll_source, 'DNEEdCSharp.dll'), dll_target)
            shutil.copy(os.path.join(dll_source, 'DNEEdCSharp.pdb'), dll_target)
            shutil.copy(os.path.join(dll_source, 'UnrealEdCSharp.dll'), dll_target)
            shutil.copy(os.path.join(dll_source, 'UnrealEdCSharp.pdb'), dll_target)
        except Exception as ex:
            log_error("Error while copying editor dlls {0}".format(ex))
            return False
        return True

    def _build_project(self, context,  project, configuration, target = 'rebuild'):
        base_dir = 'Development/Src'
        project  = os.path.join(base_dir, project)
        lis_sln  = os.path.join(base_dir,'whatif_vs2012.sln')

        vs_build_args = [ lis_sln,
                          project,
                          '-V11',
                          '-t', target,
                          '-c', configuration,
                          '-p', 'Mixed platforms' ]

        return self._run_sub_command(context, VsBuildCommand(), vs_build_args)

#---------------------------------------------------------------------------
@contextmanager
def generate_version_file():
     version_file_format    = "#define SEE_ONLINE_SUITE_BUILD_ID \"{0}@%Y-%m-%dT%H:%M:%S.000Z@{1}-v4\"\n#define DNE_FORCE_USE_ONLINE_SUITE 1";
     machine_name           = socket.gethostname()
     random_character       = random.choice(string.ascii_lowercase)
     version_file_content   = version_file_format.format(random_character, machine_name)
     version_file_content   = time.strftime(version_file_content, time.gmtime())

     with PerforceTransaction("Version File Checkout", VERSION_FILE_PATH) as transaction:
        transaction.abort()
        write_file_content(VERSION_FILE_PATH, version_file_content)
        yield
<commit_msg>Modified build order for UnrealEdCsharp and DneEdCsharp<commit_after># -*- coding: utf-8 -*-

#-------------------------------------------------------------------------------
import socket
import random
import string
import time
import shutil
from contextlib import contextmanager

from commands.command       import *
from commands.vsbuild       import *

from config.system          import *

from utilities.files        import *
from utilities.hashing      import *
from utilities.paths        import *
from utilities.perforce     import *
from utilities.processes    import *

VERSION_FILE_PATH = "Development\\Src\\Engine\\DNE\\DNEOnlineSuiteBuildId.h"

#-------------------------------------------------------------------------------
class Ue3BuildCommand(Command):

    def __init__(self):
        Command.__init__(self, 'ue3-build', 'Build UE3 executable')

    #---------------------------------------------------------------------------
    def configure_arguments(self, context, parser):
        settings = context.settings

        parser.add_argument('-c',
                            '--configuration',
                            help    = 'configurations to build',
                            metavar = '<configuration>',
                            nargs   = '+',
                            default = settings.default_ue3_configurations)

        parser.add_argument('-p',
                            '--platform',
                            help    = 'platforms to build',
                            metavar = '<platform>',
                            nargs   = '+',
                            default = settings.default_ue3_platforms)

        parser.add_argument('--generate-version-file',
                            help    = 'Generates a code file containing build specific informations',
                            action  = "store_true",
                            default = False)
        return True

    #---------------------------------------------------------------------------
    def run(self, context):
        settings = context.settings
        arguments = context.arguments

        platforms               = arguments.platform
        configurations          = arguments.configuration
        result                  = True
        version_file_cl         = None

        log_verbose("Building UBT")
        if not self._build_project(context, "UnrealBuildTool/UnrealBuildTool.csproj",'Release'):
            log_error("Error building UBT")
            return False

        with generate_version_file():
            for platform in platforms:
                if platform.lower() == 'win64':
                    if not self._build_editor_csharp(context):
                        return False
                for configuration in configurations:
                    if not self._build(context, platform, configuration):
                        return False

        return True

    #-------------------------------------------------------------------------------
    def _build(self, context, platform, configuration):

        dict_vcxproj = {
            'win32' :   'Windows/ExampleGame Win32.vcxproj',
            'win64' :   'Windows/ExampleGame Win64.vcxproj',
            'ps3' :     'PS3/ExampleGame PS3.vcxproj',
            'ps4' :     'ExampleGame PS4/ExampleGame PS4.vcxproj',
            'xbox360' : 'Xenon/ExampleGame Xbox360.vcxproj',
            'xboxone' : 'Dingo/ExampleGame Dingo/ExampleGame Dingo.vcxproj',
        }

        platform_project = dict_vcxproj[platform.lower()]
        return self._build_project(context, platform_project, configuration, 'build')

    def _build_editor_csharp(self, context):
        log_notification("Building Editor C# libraries")

        if not self._build_project(context, 'UnrealEdCSharp/UnrealEdCSharp.csproj', 'Release'):
            return False

        if not self._build_project(context, 'DNEEdCSharp/DNEEdCSharp.csproj', 'Release'):
            return False

        dll_target = os.path.join('Binaries/Win64/Editor/Release')
        dll_source = os.path.join('Binaries/Editor/Release')

        try:
            shutil.copy(os.path.join(dll_source, 'DNEEdCSharp.dll'), dll_target)
            shutil.copy(os.path.join(dll_source, 'DNEEdCSharp.pdb'), dll_target)
            shutil.copy(os.path.join(dll_source, 'UnrealEdCSharp.dll'), dll_target)
            shutil.copy(os.path.join(dll_source, 'UnrealEdCSharp.pdb'), dll_target)
        except Exception as ex:
            log_error("Error while copying editor dlls {0}".format(ex))
            return False
        return True

    def _build_project(self, context,  project, configuration, target = 'rebuild'):
        base_dir = 'Development/Src'
        project  = os.path.join(base_dir, project)
        lis_sln  = os.path.join(base_dir,'whatif_vs2012.sln')

        vs_build_args = [ lis_sln,
                          project,
                          '-V11',
                          '-t', target,
                          '-c', configuration,
                          '-p', 'Mixed platforms' ]

        return self._run_sub_command(context, VsBuildCommand(), vs_build_args)

#---------------------------------------------------------------------------
@contextmanager
def generate_version_file():
     version_file_format    = "#define SEE_ONLINE_SUITE_BUILD_ID \"{0}@%Y-%m-%dT%H:%M:%S.000Z@{1}-v4\"\n#define DNE_FORCE_USE_ONLINE_SUITE 1";
     machine_name           = socket.gethostname()
     random_character       = random.choice(string.ascii_lowercase)
     version_file_content   = version_file_format.format(random_character, machine_name)
     version_file_content   = time.strftime(version_file_content, time.gmtime())

     with PerforceTransaction("Version File Checkout", VERSION_FILE_PATH) as transaction:
        transaction.abort()
        write_file_content(VERSION_FILE_PATH, version_file_content)
        yield
<|endoftext|>


<commit_before>import common

import json
import base64
import hashlib
import unittest2
from mock import patch, Mock

from google.appengine.api import memcache, urlfetch

class TestDTMMUtils(common.DMSTestCase):
    @patch('google.appengine.api.urlfetch.fetch', autospec=True)
    def test_authed_fetch_with_remaining(self, fetch):
        fetch.return_value.headers = {'x-ratelimit-remaining': 'lots'}
        fetch.return_value.content = (
            'Lorem ipsum dolor sit amet, consectetur adipisicing elit.')

        import dtmm_utils
        end_data = dtmm_utils.authed_fetch('http://mock.com')
        self.assertEqual(fetch.return_value.content, end_data.content)

    @patch('google.appengine.api.urlfetch.fetch', autospec=True)
    def test_authed_fetch_without_remaining(self, fetch):
        fetch.return_value.headers = {'x-ratelimit-remaining': None}
        fetch.return_value.content = (
            'Lorem ipsum dolor sit amet, consectetur adipisicing elit.')

        import dtmm_utils
        dtmm_utils.authed_fetch('http://mock.com')

        # a little unsure how to ensure correct behaviour here

    @patch('dtmm_utils.authed_fetch')
    def test_get_url_content_fetch_from_remote(self, mock_authed_fetch):
        url = 'http://mock.com'
        content = {
            u'tree': [{
                u'sha': u'ac178f6489f2d3f601df6a9a5e641b62a0388eae',
                u'mode': u'100644',
                u'path': u'README.md',
                u'type': u'blob',
                u'size': 314
            }]
        }
        mock_authed_fetch.return_value.content = json.dumps(content)

        import dtmm_utils
        end_data = dtmm_utils.get_url_content(None, 'http://mock.com')
        self.assertEqual(
            memcache.get(hashlib.md5(url).hexdigest()),
            content
        )

    def test_get_url_content_retrieve_from_memcache(self):
        import dtmm_utils

        url_digest = hashlib.md5('http://mock.com').hexdigest()

        memcache.set(url_digest, {'content': 'word'})
        end_data = dtmm_utils.get_url_content(None, 'http://mock.com')
        self.assertEqual(end_data, {'content': 'word'})

    @patch('dtmm_utils.authed_fetch', autospec=True)
    @patch('logging.error', autospec=True)
    def test_get_url_content_download_error_handling(self, _, authed_fetch):
        authed_fetch.side_effect = urlfetch.DownloadError

        import dtmm_utils

        mock_handler = Mock()
        dtmm_utils.get_url_content(mock_handler, 'http://mock.com')

        mock_handler.error.assert_called_with(408)

    @patch('dtmm_utils.authed_fetch')
    def test_get_tree(self, mock_authed_fetch):
        content = {
            'tree': [{
                u'sha': u'ac178f6489f2d3f601df6a9a5e641b62a0388eae',
                u'mode': u'100644',
                u'path': u'README.md',
                u'type': u'blob',
                u'size': 314
            }]
        }
        mock_authed_fetch.return_value.content = json.dumps(content)

    @patch('dtmm_utils.get_url_content', autospec=True)
    def test_get_live_module_data(self, get_url_content):
        get_url_content.return_value = {
            'content': base64.b64encode('''
                MODULE = {
                    Type = "Hardware",
                    Name = "HMD2043",
                    Version = "1.1",
                    SDescription = "Deprecated HMD2043 hardware device",
                    URL = "False URL"
                };''')
        }

        import dtmm_utils
        end_data = dtmm_utils.get_live_module_data(
            None, {"url": "http://mock.url/hardware_file"})
        self.assertEqual(
            end_data,
            {
                'URL': 'False URL',
                'SDescription': 'Deprecated HMD2043 hardware device',
                'Version': '1.1',
                'Type': 'Hardware',
                'Name': 'HMD2043'
            }
        )

    @patch('dtmm_utils.get_url_content', autospec=True)
    def test_get_live_hardware_data(self, get_url_content):
        get_url_content.return_value = {
            'content': base64.b64encode('''
                HARDWARE = {
                    ID = 0x74fa4cae,
                    Version = 0x07c2,
                    Manufacturer = 0x21544948 -- HAROLD_IT
                };''')
        }

        import dtmm_utils
        end_data = dtmm_utils.get_live_hardware_data(
            None, {"url": "http://mock.url/hardware_file"})
        self.assertEqual(
            end_data,
            {
                'Version': 1986,
                'ID': 1962560686,
                'Manufacturer': 559171912
            }
        )

def main():
    unittest2.main()

if __name__ == '__main__':
    main()
<commit_msg>Test more stuff :P<commit_after>import common

import json
import base64
import hashlib
import unittest2
from mock import patch, Mock

from google.appengine.api import memcache, urlfetch

class TestDTMMUtils(common.DMSTestCase):
    @patch('google.appengine.api.urlfetch.fetch', autospec=True)
    def test_authed_fetch_with_remaining(self, fetch):
        fetch.return_value.headers = {'x-ratelimit-remaining': 'lots'}
        fetch.return_value.content = (
            'Lorem ipsum dolor sit amet, consectetur adipisicing elit.')

        import dtmm_utils
        end_data = dtmm_utils.authed_fetch('http://mock.com')
        self.assertEqual(fetch.return_value.content, end_data.content)

        fetch.assert_called_with(
            url='http://mock.com?client_auth_data=%7Bu%27client_secret%27%3A+u%27false_data%27%2C+u%27client_id%27%3A+u%27false_data%27%7D',
            headers={'X-Admin-Contact': 'admin@lysdev.com'}
        )

    @patch('google.appengine.api.urlfetch.fetch', autospec=True)
    def test_authed_fetch_without_remaining(self, fetch):
        fetch.return_value.headers = {'x-ratelimit-remaining': None}
        fetch.return_value.content = (
            'Lorem ipsum dolor sit amet, consectetur adipisicing elit.')

        import dtmm_utils
        dtmm_utils.authed_fetch('http://mock.com')

        fetch.assert_called_with(
            url='http://mock.com?client_auth_data=%7Bu%27client_secret%27%3A+u%27false_data%27%2C+u%27client_id%27%3A+u%27false_data%27%7D',
            headers={'X-Admin-Contact': 'admin@lysdev.com'}
        )
        # a little unsure how to ensure correct behaviour here

    @patch('dtmm_utils.authed_fetch')
    def test_get_url_content_fetch_from_remote(self, mock_authed_fetch):
        url = 'http://mock.com'
        content = {
            u'tree': [{
                u'sha': u'ac178f6489f2d3f601df6a9a5e641b62a0388eae',
                u'mode': u'100644',
                u'path': u'README.md',
                u'type': u'blob',
                u'size': 314
            }]
        }
        mock_authed_fetch.return_value.content = json.dumps(content)

        import dtmm_utils
        end_data = dtmm_utils.get_url_content(None, url)
        self.assertEqual(end_data, content)

        mock_authed_fetch.assert_called_with(url)
        self.assertEqual(
            memcache.get(hashlib.md5(url).hexdigest()),
            content
        )

    def test_get_url_content_retrieve_from_memcache(self):
        import dtmm_utils

        url_digest = hashlib.md5('http://mock.com').hexdigest()

        memcache.set(url_digest, {'content': 'word'})
        end_data = dtmm_utils.get_url_content(None, 'http://mock.com')
        self.assertEqual(end_data, {'content': 'word'})

    @patch('dtmm_utils.authed_fetch', autospec=True)
    @patch('logging.error', autospec=True)
    def test_get_url_content_download_error_handling(self, _, authed_fetch):
        authed_fetch.side_effect = urlfetch.DownloadError

        import dtmm_utils

        mock_handler = Mock()
        dtmm_utils.get_url_content(mock_handler, 'http://mock.com')

        mock_handler.error.assert_called_with(408)

    @patch('dtmm_utils.authed_fetch')
    def test_get_tree(self, mock_authed_fetch):
        content = {
            'tree': [{
                u'sha': u'ac178f6489f2d3f601df6a9a5e641b62a0388eae',
                u'mode': u'100644',
                u'path': u'README.md',
                u'type': u'blob',
                u'size': 314
            }]
        }
        mock_authed_fetch.return_value.content = json.dumps(content)

        import dtmm_utils
        end_data = dtmm_utils.get_tree()
        self.assertEqual(end_data, content['tree'])

    @patch('dtmm_utils.get_url_content', autospec=True)
    def test_get_live_module_data(self, get_url_content):
        get_url_content.return_value = {
            'content': base64.b64encode('''
                MODULE = {
                    Type = "Hardware",
                    Name = "HMD2043",
                    Version = "1.1",
                    SDescription = "Deprecated HMD2043 hardware device",
                    URL = "False URL"
                };''')
        }

        import dtmm_utils
        end_data = dtmm_utils.get_live_module_data(
            None, {"url": "http://mock.url/hardware_file"})
        self.assertEqual(
            end_data,
            {
                'URL': 'False URL',
                'SDescription': 'Deprecated HMD2043 hardware device',
                'Version': '1.1',
                'Type': 'Hardware',
                'Name': 'HMD2043'
            }
        )

    @patch('dtmm_utils.get_url_content', autospec=True)
    def test_get_live_hardware_data(self, get_url_content):
        get_url_content.return_value = {
            'content': base64.b64encode('''
                HARDWARE = {
                    ID = 0x74fa4cae,
                    Version = 0x07c2,
                    Manufacturer = 0x21544948 -- HAROLD_IT
                };''')
        }

        import dtmm_utils
        end_data = dtmm_utils.get_live_hardware_data(
            None, {"url": "http://mock.url/hardware_file"})
        self.assertEqual(
            end_data,
            {
                'Version': 1986,
                'ID': 1962560686,
                'Manufacturer': 559171912
            }
        )

def main():
    unittest2.main()

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>from common.converters import BytesToInt
from common.padders import MDPadder

class MDHashBasedMACMessageForger(object):

    MAX_KEY_LENGTH = 512

    def __init__(self, mac_validator):
        self.mac_validator = mac_validator
        self.resumable_hash = self._resumable_hash()
        self.endianness = self.resumable_hash.endianness()

    def _pad_message(self, message, size=None):
        return MDPadder(message, self.endianness).value(size)

    def _get_registers_from(self, hash_bytes):
        return [BytesToInt(hash_bytes[i:i+4],
                           endianness=self.endianness).value()
                for i in range(0, len(hash_bytes), 4)]

    def _build_message_to_forge(self, message, new_message, key_length):
        total_prefix_length = key_length + len(message)
        padded_message = self._pad_message(message, total_prefix_length)
        return padded_message + new_message

    def _build_message_to_hash(self, message_to_forge, new_message,
                               key_length):
        total_bit_length = 8*(key_length + len(message_to_forge))
        new_message_padded = self._pad_message(new_message)
        return new_message_padded[:-8] +\
               self.endianness.from_int(total_bit_length, size=8).value()

    def forge(self, message, message_mac, new_message):
        registers = self._get_registers_from(message_mac)
        resumable_hash = self.resumable_hash(registers)
        # Since key length is unknown, iterate until we find it.
        for key_length in range(self.MAX_KEY_LENGTH):
            # First step: assemble the message that will be forged:
            # <original message> + <SHA1 padding for this key length>
            # + <appendix>
            message_to_forge = self._build_message_to_forge(message,
                                                            new_message,
                                                            key_length)
            # Second step: assemble the message to resume SHA1 computations:
            # <appendix> + <SHA1 padding for the appendix>
            # + <total bit length, including the guessed key length>
            # Since message_to_forge has already k*512 bits before the
            # appendix, the SHA1 padding for the appendix alone will work fine.
            message_to_hash = self._build_message_to_hash(message_to_forge,
                                                          new_message,
                                                          key_length)
            hash_value = resumable_hash.hash(message_to_hash)
            if self.mac_validator.validate(message_to_forge, hash_value):
                return message_to_forge, hash_value

    def _resumable_hash(self):
        raise NotImplementedError

class ResumableMDHash(object):

    def __init__(self, hash_function_class):
        self.hash_function_class = hash_function_class

    def value(self):
        class ResumableHash(self.hash_function_class):
            def __init__(_self, registers):
                self.hash_function_class.__init__(_self)
                _self.custom_registers = registers

            def _initialize_registers(_self):
                _self.registers = list(_self.custom_registers)

            def _pad_message(_self, message):
                # Treat incoming messages as if they were already padded.
                return message

        return ResumableHash<commit_msg>Refactoring.<commit_after>from common.padders import MDPadder

class MDHashBasedMACMessageForger(object):

    MAX_KEY_LENGTH = 512

    def __init__(self, mac_validator):
        self.mac_validator = mac_validator
        self.resumable_hash = self._resumable_hash()
        self.endianness = self.resumable_hash.endianness()

    def _pad_message(self, message, size=None):
        return MDPadder(message, self.endianness).value(size)

    def _get_registers_from(self, hash_bytes):
        return [self.endianness.to_int(hash_bytes[i:i+4]).value()
                for i in range(0, len(hash_bytes), 4)]

    def _build_message_to_forge(self, message, new_message, key_length):
        total_prefix_length = key_length + len(message)
        padded_message = self._pad_message(message, total_prefix_length)
        return padded_message + new_message

    def _build_message_to_hash(self, message_to_forge, new_message,
                               key_length):
        total_bit_length = 8*(key_length + len(message_to_forge))
        new_message_padded = self._pad_message(new_message)
        return new_message_padded[:-8] +\
               self.endianness.from_int(total_bit_length, size=8).value()

    def forge(self, message, message_mac, new_message):
        registers = self._get_registers_from(message_mac)
        resumable_hash = self.resumable_hash(registers)
        # Since key length is unknown, iterate until we find it.
        for key_length in range(self.MAX_KEY_LENGTH):
            # First step: assemble the message that will be forged:
            # <original message> + <SHA1 padding for this key length>
            # + <appendix>
            message_to_forge = self._build_message_to_forge(message,
                                                            new_message,
                                                            key_length)
            # Second step: assemble the message to resume SHA1 computations:
            # <appendix> + <SHA1 padding for the appendix>
            # + <total bit length, including the guessed key length>
            # Since message_to_forge has already k*512 bits before the
            # appendix, the SHA1 padding for the appendix alone will work fine.
            message_to_hash = self._build_message_to_hash(message_to_forge,
                                                          new_message,
                                                          key_length)
            hash_value = resumable_hash.hash(message_to_hash)
            if self.mac_validator.validate(message_to_forge, hash_value):
                return message_to_forge, hash_value

    def _resumable_hash(self):
        raise NotImplementedError

class ResumableMDHash(object):

    def __init__(self, hash_function_class):
        self.hash_function_class = hash_function_class

    def value(self):
        class ResumableHash(self.hash_function_class):
            def __init__(_self, registers):
                self.hash_function_class.__init__(_self)
                _self.custom_registers = registers

            def _initialize_registers(_self):
                _self.registers = list(_self.custom_registers)

            def _pad_message(_self, message):
                # Treat incoming messages as if they were already padded.
                return message

        return ResumableHash<|endoftext|>


<commit_before>from datetime import timedelta
import time

from conftest import app as app_, client as client_
import pytest

TEST_TTL = 300

@pytest.fixture
def redis_app(redis_store):
    return app_(redis_store)

@pytest.fixture
def redis_client(redis_app):
    return client_(redis_app)

def test_redis_expiration_permanent_session(
    redis, redis_store, redis_app, redis_client
):
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=TEST_TTL
    )

    redis_client.get('/store-in-session/k1/v1/')
    redis_client.get('/make-session-permanent/')

    sid = redis_store.keys()[0]
    ttl = redis.ttl(sid)

    # 5 seconds tolerance should be plenty
    assert TEST_TTL-ttl <= 5

def test_redis_expiration_ephemeral_session(
    redis, redis_store, redis_app, redis_client
):
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=TEST_TTL
    )

    redis_client.get('/store-in-session/k1/v1/')

    sid = redis_store.keys()[0]
    ttl = redis.ttl(sid)

    assert TEST_TTL-ttl <= 5

def test_redis_expiration_lifetime(
    redis, redis_store, redis_app, redis_client
):
    '''
    check if the session expires according to
    PERMANENT_SESSION_LIFETIME
    '''

    MY_TTL = 2
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=MY_TTL
    )

    # t_0 = 0 seconds starts now
    t_0 = time.time()
    klist_0 = redis.keys()
    res_0 = redis_client.get('/store-in-session/k1/v1/')

    # t_1 = 0 + epsilon
    assert res_0.headers.get('Set-Cookie') is not None
    klist_1 = redis.keys()
    assert len(klist_1) - len(klist_0) == 1
    sid_1 = klist_1[0]
    cookie_1 = res_0.headers.get('Set-Cookie')
    ttl_1 = redis.ttl(sid_1)
    assert ttl_1 <= MY_TTL

    res_1 = redis_client.get('/store-in-session/k1/v1/')
    assert cookie_1 == res_1.headers.get('Set-Cookie')

    # initial session expired, key should evaporate
    time.sleep(MY_TTL)
    # t = MY_TTL + epsilon
    klist_2 = redis.keys()
    assert len(klist_2) == len(klist_0)

    # t = MY_TTL + epsilon
    # get a new session, cookie gets renewed
    res_2 = redis_client.get('/store-in-session/k1/v1/')
    cookie_2 = res_2.headers.get('Set-Cookie')
    assert cookie_2 != cookie_1

    # t = MY_TTL + epsilon
    klist_3 = redis.keys()
    sid_3 = klist_3[0]

    # cookie does not get renewed, but session lifetime is extended
    time.sleep(MY_TTL-1)
    # t = 2xMY_TTL - 1 + epsilon
    res_3 = redis_client.get('/store-in-session/k1/v1/')
    assert res_3.headers.get('Set-Cookie') == cookie_2

    # ttl should now be very close to original value, i.e. MY_TTL
    ttl_3 = redis.ttl(sid_3)
    assert MY_TTL-1 <= ttl_3 <= MY_TTL

    # wait once more, beyond t_0
    time.sleep(MY_TTL-1)
    # t = 2xMY_TTL + epsilon
    res_4 = redis_client.get('/store-in-session/k1/v1/')
    # expect the cookie to still be alive
    assert res_4.headers.get('Set-Cookie') == cookie_2

<commit_msg>fix comment for clarity<commit_after>from datetime import timedelta
import time

from conftest import app as app_, client as client_
import pytest

TEST_TTL = 300

@pytest.fixture
def redis_app(redis_store):
    return app_(redis_store)

@pytest.fixture
def redis_client(redis_app):
    return client_(redis_app)

def test_redis_expiration_permanent_session(
    redis, redis_store, redis_app, redis_client
):
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=TEST_TTL
    )

    redis_client.get('/store-in-session/k1/v1/')
    redis_client.get('/make-session-permanent/')

    sid = redis_store.keys()[0]
    ttl = redis.ttl(sid)

    # 5 seconds tolerance should be plenty
    assert TEST_TTL-ttl <= 5

def test_redis_expiration_ephemeral_session(
    redis, redis_store, redis_app, redis_client
):
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=TEST_TTL
    )

    redis_client.get('/store-in-session/k1/v1/')

    sid = redis_store.keys()[0]
    ttl = redis.ttl(sid)

    assert TEST_TTL-ttl <= 5

def test_redis_expiration_lifetime(
    redis, redis_store, redis_app, redis_client
):
    '''
    check if the session expires according to
    PERMANENT_SESSION_LIFETIME
    '''

    MY_TTL = 2
    redis_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(
        seconds=MY_TTL
    )

    # t_0 = 0 seconds starts now
    t_0 = time.time()
    klist_0 = redis.keys()
    res_0 = redis_client.get('/store-in-session/k1/v1/')

    # t_1 = 0 + epsilon
    assert res_0.headers.get('Set-Cookie') is not None
    klist_1 = redis.keys()
    assert len(klist_1) - len(klist_0) == 1
    sid_1 = klist_1[0]
    cookie_1 = res_0.headers.get('Set-Cookie')
    ttl_1 = redis.ttl(sid_1)
    assert ttl_1 <= MY_TTL

    res_1 = redis_client.get('/store-in-session/k1/v1/')
    assert cookie_1 == res_1.headers.get('Set-Cookie')

    # initial session expired, key should evaporate
    time.sleep(MY_TTL)
    # t = MY_TTL + epsilon
    klist_2 = redis.keys()
    assert len(klist_2) == len(klist_0)

    # t = MY_TTL + epsilon
    # get a new session, cookie gets renewed
    res_2 = redis_client.get('/store-in-session/k1/v1/')
    cookie_2 = res_2.headers.get('Set-Cookie')
    assert cookie_2 != cookie_1

    # t = MY_TTL + epsilon
    klist_3 = redis.keys()
    sid_3 = klist_3[0]

    # cookie does not get renewed, but session lifetime is extended
    time.sleep(MY_TTL-1)
    # t = 2xMY_TTL - 1 + epsilon
    res_3 = redis_client.get('/store-in-session/k1/v1/')
    assert res_3.headers.get('Set-Cookie') == cookie_2

    # ttl should now be very close to original value, i.e. MY_TTL
    ttl_3 = redis.ttl(sid_3)
    assert MY_TTL-1 <= ttl_3 <= MY_TTL

    # wait once more, beyond t_0 + MY_TTL
    time.sleep(MY_TTL-1)
    # t = 2xMY_TTL + epsilon
    res_4 = redis_client.get('/store-in-session/k1/v1/')
    # expect the cookie to still be alive
    assert res_4.headers.get('Set-Cookie') == cookie_2

<|endoftext|>