def test_predator_only():
    """Tests simulations with Predators only.

    The population is expected to die off after a timestep.
    """
    clean_outs()

    # A reference simulation input for Lotka-Volterra simulation
    sim_input = os.path.join(DIR, "input", "predator.xml")

    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()

    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]

    print("Confirming valid Cyclus execution.")
    assert_equal(rtn, 0)

    series = agent_time_series([prey, pred])
    print("Prey:", series[prey], "Predators:", series[pred])

    prey_exp = [0 for n in range(10)]
    pred_exp = [1, 1] + [0 for n in range(8)]

    assert_equal(series[prey], prey_exp)
    assert_equal(series[pred], pred_exp)

    clean_outs()
Beispiel #2
0
def test_prey_only():
    """Tests simulations with Preys only.

    The population is expected to grow exponentially.
    """
    clean_outs()
    sim_input = "./input/prey.xml"
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()

    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]

    print("Confirming valid Cyclus execution.")
    assert_equal(rtn, 0)

    series = agent_time_series([prey, pred])
    print("Prey:", series[prey], "Predators:", series[pred])

    prey_exp = [2**n for n in range(10)]
    pred_exp = [0 for n in range(10)]

    assert_equal(series[prey], prey_exp)
    assert_equal(series[pred], pred_exp)

    clean_outs()
Beispiel #3
0
def check_null_sink(fname, given_spec):
    """Testing for null sink case without a source facility.

    No transactions are expected in this test; therefore, a table with
    transaction records must not exist in order to pass this test.
    """
    clean_outs()
    if not cyclus_has_coin():
        raise SkipTest("Cyclus does not have COIN")

    # Cyclus simulation input for null sink testing
    sim_input = os.path.join(INPUT, fname)
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()
    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]
    if rtn != 0:
        return  # don't execute further commands

    legal_paths = ["/AgentEntry", "/Info"]
    illegal_paths = ["/Transactions"]  # this must contain tables to test
    # Check if these tables exist
    yield assert_true, tables_exist(outfile, legal_paths)
    if not tables_exist(outfile, legal_paths):
        outfile.close()
        clean_outs()
        return  # don't execute further commands

    # Get specific data
    if outfile == h5out:
        output = tables.open_file(h5out, mode="r")
        agent_entry = output.get_node("/AgentEntry")[:]
        info = output.get_node("/Info")[:]
        output.close()

    else:
        conn = sqlite3.connect(outfile)
        conn.row_factory = sqlite3.Row
        cur = conn.cursor()
        exc = cur.execute
        agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
        info = exc('SELECT * FROM Info').fetchall()
        conn.close()

    # Sink's deployment
    agent_ids = to_ary(agent_entry, "AgentId")
    spec = to_ary(agent_entry, "Spec")

    sink_id = find_ids(given_spec, spec, agent_ids)
    # Test if one SimpleSink is deployed
    yield assert_equal, len(sink_id), 1

    # No resource exchange is expected
    yield assert_false, tables_exist(outfile, illegal_paths)

    clean_outs()
Beispiel #4
0
def check_null_sink(fname, given_spec):
    """Testing for null sink case without a source facility.

    No transactions are expected in this test; therefore, a table with
    transaction records must not exist in order to pass this test.
    """
    clean_outs()
    if not cyclus_has_coin():
        raise SkipTest("Cyclus does not have COIN")

    # Cyclus simulation input for null sink testing
    sim_input = os.path.join(INPUT, fname)
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()
    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]
    if rtn != 0:
        return  # don't execute further commands

    legal_paths = ["/AgentEntry", "/Info"]
    illegal_paths = ["/Transactions"]  # this must contain tables to test
    # Check if these tables exist
    yield assert_true, tables_exist(outfile, legal_paths)
    if not tables_exist(outfile, legal_paths):
        outfile.close()
        clean_outs()
        return  # don't execute further commands

    # Get specific data
    if outfile == h5out:
        output = tables.open_file(h5out, mode = "r")
        agent_entry = output.get_node("/AgentEntry")[:]
        info = output.get_node("/Info")[:]
        output.close()

    else:
        conn = sqlite3.connect(outfile)
        conn.row_factory = sqlite3.Row
        cur = conn.cursor()
        exc = cur.execute
        agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
        info = exc('SELECT * FROM Info').fetchall()
        conn.close()

    # Sink's deployment
    agent_ids = to_ary(agent_entry, "AgentId")
    spec = to_ary(agent_entry, "Spec")

    sink_id = find_ids(given_spec, spec, agent_ids)
    # Test if one SimpleSink is deployed
    yield assert_equal, len(sink_id), 1

    # No resource exchange is expected
    yield assert_false, tables_exist(outfile, illegal_paths)

    clean_outs()
Beispiel #5
0
def test_include_recipe():
    """Testing for including of other XML files.
    """
    clean_outs()
    # Cyclus simulation input for recipe including
    sim_input = "./input/include_recipe.xml"
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()
    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]
    if rtn != 0:
        return  # don't execute further commands
    clean_outs()
Beispiel #6
0
def test_stub_example():
    """Testing for the stubs example."""
    clean_outs()

    # Cyclus simulation input for null sink testing
    sim_input = "./input/stub_example.xml"
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()
    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, os.getcwd(), holdsrtn
    rtn = holdsrtn[0]
    if rtn != 0:
        return  # don't execute further commands

    legal_paths = ["/AgentEntry", "/Info"]
    illegal_paths = ["/Transactions"]  # this must contain tables to test
    # Check if these tables exist
    yield assert_true, tables_exist(outfile, legal_paths)
    if not tables_exist(outfile, legal_paths):
        outfile.close()
        clean_outs()
        return  # don't execute further commands

    # Get specific data
    if outfile == h5out:
        output = tables.open_file(h5out, mode="r")
        agent_entry = output.get_node("/AgentEntry")[:]
        info = output.get_node("/Info")[:]
        output.close()
    else:
        conn = sqlite3.connect(sqliteout)
        conn.row_factory = sqlite3.Row
        cur = conn.cursor()
        exc = cur.execute
        agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
        info = exc('SELECT * FROM Info').fetchall()
        conn.close()

    # Sink's deployment
    agent_ids = to_ary(agent_entry, "AgentId")
    spec = to_ary(agent_entry, "Spec")

    sink_id = find_ids("stubs:StubFacility:StubFacility", spec, agent_ids)
    # Test if one SimpleSink is deployed
    yield assert_equal, len(sink_id), 1

    # No resource exchange is expected
    yield assert_false, tables_exist(outfile, illegal_paths)

    clean_outs()
Beispiel #7
0
def test_stub_example():
    """Testing for the stubs example."""
    clean_outs()

    # Cyclus simulation input for null sink testing
    sim_input = "./input/stub_example.xml"
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()
    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, os.getcwd(), holdsrtn
    rtn = holdsrtn[0]
    if rtn != 0:
        return  # don't execute further commands

    legal_paths = ["/AgentEntry", "/Info"]
    illegal_paths = ["/Transactions"]  # this must contain tables to test
    # Check if these tables exist
    yield assert_true, tables_exist(outfile, legal_paths)
    if not tables_exist(outfile, legal_paths):
        outfile.close()
        clean_outs()
        return  # don't execute further commands

    # Get specific data
    if outfile == h5out:
        output = tables.open_file(h5out, mode = "r")
        agent_entry = output.get_node("/AgentEntry")[:]
        info = output.get_node("/Info")[:]
        output.close()
    else:
        conn = sqlite3.connect(sqliteout)
        conn.row_factory = sqlite3.Row
        cur = conn.cursor()
        exc = cur.execute
        agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
        info = exc('SELECT * FROM Info').fetchall()
        conn.close()
        
    # Sink's deployment
    agent_ids = to_ary(agent_entry, "AgentId")
    spec = to_ary(agent_entry, "Spec")

    sink_id = find_ids("stubs:StubFacility:StubFacility", spec, agent_ids)
    # Test if one SimpleSink is deployed
    yield assert_equal, len(sink_id), 1

    # No resource exchange is expected
    yield assert_false, tables_exist(outfile, illegal_paths)

    clean_outs()
Beispiel #8
0
def test_lotka_volterra():
    """Tests simulations with Preys and Predators

    Preys offer a resource representing itself. Predators acquire the resources
    of the preys. When the prey's resource gets accepted, it decommissions
    itself. Preys and predators have a fixed life expectancy. However, if
    a predator does not get any resource for several time steps,
    it must decommission itself as well.
    After certain time steps, predators and preys reproduce and deploy new
    predators and preys respectively.

    A single oscillation is expected and the peak of the predator population is
    expected to occur after the peak of the prey population.
    """
    clean_outs()
    sim_input = "./input/lotka_volterra_determ.xml"
    holdsrtn = [1]  # needed because nose does not send() to test generator
    outfile = which_outfile()

    cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
    yield check_cmd, cmd, '.', holdsrtn
    rtn = holdsrtn[0]

    print("Confirming valid Cyclus execution.")
    assert_equal(rtn, 0)

    series = agent_time_series([prey, pred])
    print("Prey:", series[prey], "Predators:", series[pred])

    prey_max = series[prey].index(max(series[prey]))
    pred_max = series[pred].index(max(series[pred]))
    print("t_prey_max:", prey_max, "t_pred_max:", pred_max)

    assert_true(prey_max < pred_max)

    clean_outs()
Beispiel #9
0
def test_source_to_sink():
    """Tests simulations with one facility that has a conversion factor.

    The trivial cycle simulation involves only one KFacility which provides
    what it requests itself. The conversion factors for requests and bids
    are kept the same so that the facility provides exactly what it requests.
    The amount of the transactions follow a power law.

    Amount = InitialAmount * ConversionFactor ^ Time

    This equation is used to test each transaction amount.
    """
    # A reference simulation input for the trivial cycle simulation.
    ref_input = "./input/trivial_cycle.xml"
    # Conversion factors for the three simulations
    k_factors = [0.95, 1, 2]

    for k_factor in k_factors:
        clean_outs()

        sim_input = create_sim_input(ref_input, k_factor, k_factor)

        holdsrtn = [1]  # needed because nose does not send() to test generator
        outfile = which_outfile()
        cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
        yield check_cmd, cmd, '.', holdsrtn
        rtn = holdsrtn[0]
        if rtn != 0:
            return  # don't execute further commands

        # tables of interest
        paths = ["/AgentEntry", "/Resources", "/Transactions", "/Info"]
        # Check if these tables exist
        yield assert_true, tables_exist(outfile, paths)
        if not tables_exist(outfile, paths):
            outfile.close()
            clean_outs()
            return  # don't execute further commands

        # Get specific tables and columns
        if outfile == h5out:
            output = tables.open_file(h5out, mode="r")
            agent_entry = output.get_node("/AgentEntry")[:]
            info = output.get_node("/Info")[:]
            resources = output.get_node("/Resources")[:]
            transactions = output.get_node("/Transactions")[:]
            output.close()
        else:
            conn = sqlite3.connect(sqliteout)
            conn.row_factory = sqlite3.Row
            cur = conn.cursor()
            exc = cur.execute
            agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
            info = exc('SELECT * FROM Info').fetchall()
            resources = exc('SELECT * FROM Resources').fetchall()
            transactions = exc('SELECT * FROM Transactions').fetchall()
            conn.close()

        # Find agent ids
        agent_ids = to_ary(agent_entry, "AgentId")
        spec = to_ary(agent_entry, "Spec")

        facility_id = find_ids(":agents:KFacility", spec, agent_ids)
        # Test for only one KFacility
        yield assert_equal, len(facility_id), 1

        sender_ids = to_ary(transactions, "SenderId")
        receiver_ids = to_ary(transactions, "ReceiverId")
        expected_sender_array = np.empty(sender_ids.size)
        expected_sender_array.fill(facility_id[0])
        expected_receiver_array = np.empty(receiver_ids.size)
        expected_receiver_array.fill(facility_id[0])
        yield assert_array_equal, sender_ids, expected_sender_array
        yield assert_array_equal, receiver_ids, expected_receiver_array

        # Transaction ids must be equal range from 1 to the number of rows
        expected_trans_ids = np.arange(0, sender_ids.size, 1)
        yield assert_array_equal, \
            to_ary(transactions, "TransactionId"), \
                   expected_trans_ids

        # Track transacted resources
        resource_ids = to_ary(resources, "ResourceId")
        quantities = to_ary(resources, "Quantity")

        # Almost equal cases due to floating point k_factors
        i = 0
        initial_capacity = quantities[0]
        for q in quantities:
            yield assert_almost_equal, q, initial_capacity * k_factor**i
            i += 1

        clean_outs()
        os.remove(sim_input)
Beispiel #10
0
def test_minimal_cycle():
    """Tests simulations with two facilities with several conversion factors.

    The commodities of the facilities are different. Facility A offers a
    commodity A and requests commodity B; whereas, Facility B offers a
    commodity B and requests commodity A. In addition, it is also assumed that
    the first requests and offers are the same quantities for respective
    receivers and senders.
    The amount of the transactions follow a power law.

    Amount = InitialAmount * ConversionFactor ^ Time

    This equation is used to test each transaction amount.
    """
    # A reference simulation input for minimal cycle with different commodities
    ref_input = "./input/minimal_cycle.xml"
    # Conversion factors for the simulations
    k_factors = [0.95, 1, 2]

    for k_factor_a in k_factors:
        for k_factor_b in k_factors:
            clean_outs()
            sim_input = change_minimal_input(ref_input, k_factor_a, k_factor_b)

            holdsrtn = [1]  # needed b/c nose does not send() to test generator
            outfile = which_outfile()
            cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
            yield check_cmd, cmd, '.', holdsrtn
            rtn = holdsrtn[0]
            if rtn != 0:
                return  # don't execute further commands

             # tables of interest
            paths = ["/AgentEntry", "/Resources", "/Transactions",
                    "/Info"]
            # Check if these tables exist
            yield assert_true, tables_exist(outfile, paths)
            if not tables_exist(outfile, paths):
                outfile.close()
                clean_outs()
                return  # don't execute further commands

            # Get specific tables and columns
            if outfile == h5out:
                output = tables.open_file(h5out, mode = "r")
                agent_entry = output.root.AgentEntry[:]
                info = output.get_node("/Info")[:]
                resources = output.get_node("/Resources")[:]
                transactions = output.get_node("/Transactions")[:]
                output.close()
 
            else:
                conn = sqlite3.connect(sqliteout)
                conn.row_factory = sqlite3.Row
                cur = conn.cursor()
                exc = cur.execute

                agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
                info = exc('SELECT * FROM Info').fetchall()
                resources = exc('SELECT * FROM Resources').fetchall()
                transactions = exc('SELECT * FROM Transactions').fetchall()
                conn.close()
                
            # Find agent ids
            agent_ids = to_ary(agent_entry, "AgentId")
            spec = to_ary(agent_entry, "Spec")
            agent_protos = to_ary(agent_entry, "Prototype")
            duration = to_ary(info, "Duration")[0]

            facility_id = find_ids(":agents:KFacility", spec, agent_ids)
            # Test for two KFacility
            yield assert_equal, len(facility_id), 2

            # Test for one Facility A and Facility B
            facility_a = find_ids("FacilityA", agent_protos, agent_ids)
            facility_b = find_ids("FacilityB", agent_protos, agent_ids)
            yield assert_equal, len(facility_a), 1
            yield assert_equal, len(facility_b), 1

            # Test if both facilities are KFracilities
            # Assume FacilityA is deployed first according to the schema
            yield assert_equal, facility_a[0], facility_id[0]
            yield assert_equal, facility_b[0], facility_id[1]

            # Test if the transactions are strictly between Facility A and
            # Facility B. There are no Facility A to Facility A or vice versa.
            sender_ids = to_ary(transactions, "SenderId")
            receiver_ids = to_ary(transactions, "ReceiverId")
            pattern_one = np.arange(0, sender_ids.size, 2)
            pattern_two = np.arange(1, sender_ids.size, 2)
            pattern_a = pattern_one  # expected pattern for Facility A as sender
            pattern_b = pattern_two  # expected pattern for Facility B as sender

            # Re-assign in case the expected patterns are incorrect
            if sender_ids[0] == facility_b[0]:
                pattern_a = pattern_two
                pattern_b = pattern_one

            yield assert_array_equal, \
                np.where(sender_ids == facility_a[0])[0], \
                pattern_a, "Fac A Pattern A"
            yield assert_array_equal, \
                np.where(receiver_ids == facility_a[0])[0], \
                pattern_b, "Fac A Pattern B"  # reverse pattern when acted as a receiver

            yield assert_array_equal, \
                np.where(sender_ids == facility_b[0])[0], \
                pattern_b, "Fac B Pattern A"
            yield assert_array_equal, \
                np.where(receiver_ids == facility_b[0])[0], \
                pattern_a, "Fac B Pattern B"  # reverse pattern when acted as a receiver

            # Transaction ids must be equal range from 1 to the number of rows
            expected_trans_ids = np.arange(sender_ids.size)
            yield assert_array_equal, \
                to_ary(transactions, "TransactionId"), \
                expected_trans_ids

            # When k_factors are very low and the simulation time is big
            # the number of transactions maybe shortened due to the lower
            # limit cyclus::eps() for transaction amounts.
            # Expect not to have shortened transactions, so for two facilities,
            # there must be (2 * duration) number of transactions.
            exp = 2 * duration
            obs = sender_ids.size
            yield assert_equal, exp, obs, "number of transactions, {} != {}".format(exp, obs)

            # Track transacted resources
            quantities = to_ary(resources, "Quantity")

            # Almost equal cases due to floating point k_factors
            init_capacity_a = quantities[0]
            init_capacity_b = quantities[1]
            j = 0
            for p in pattern_a:
                yield assert_almost_equal, quantities[p], \
                    init_capacity_a * k_factor_a ** j
                j += 1

            j = 0
            for p in pattern_b:
                yield assert_almost_equal, quantities[p], \
                    init_capacity_b * k_factor_b ** j
                j += 1

            clean_outs()
            os.remove(sim_input)
Beispiel #11
0
def test_source_to_sink():
    """Tests linear growth of sink inventory by checking if the transactions
    were of equal quantities and only between sink and source facilities.
    """
    clean_outs()

    # Cyclus simulation input for Source and Sink
    sim_inputs = ["./input/source_to_sink.xml"]

    for sim_input in sim_inputs:
        holdsrtn = [1]  # needed because nose does not send() to test generator
        outfile = which_outfile()
        cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
        yield check_cmd, cmd, '.', holdsrtn
        rtn = holdsrtn[0]
        if rtn != 0:
            return  # don't execute further commands

        # Tables of interest
        paths = ["/AgentEntry", "/Resources", "/Transactions", "/Info"]
        # Check if these tables exist
        yield assert_true, tables_exist(outfile, paths)
        if not tables_exist(outfile, paths):
            outfile.close()
            clean_outs()
            return  # don't execute further commands

    # Get specific tables and columns
        if outfile == h5out:
            output = tables.open_file(h5out, mode="r")

            agent_entry = output.get_node("/AgentEntry")[:]
            info = output.get_node("/Info")[:]
            resources = output.get_node("/Resources")[:]
            transactions = output.get_node("/Transactions")[:]
            output.close()
        else:
            conn = sqlite3.connect(outfile)
            conn.row_factory = sqlite3.Row
            cur = conn.cursor()
            exc = cur.execute

            agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
            info = exc('SELECT * FROM Info').fetchall()
            resources = exc('SELECT * FROM Resources').fetchall()
            transactions = exc('SELECT * FROM Transactions').fetchall()
            conn.close()

        # Find agent ids of source and sink facilities
        agent_ids = to_ary(agent_entry, "AgentId")
        spec = to_ary(agent_entry, "Spec")

        source_id = find_ids(":agents:Source", spec, agent_ids)
        sink_id = find_ids(":agents:Sink", spec, agent_ids)

        # Test for only one source and one sink are deployed in the simulation
        yield assert_equal, len(source_id), 1
        yield assert_equal, len(sink_id), 1

        # Check if transactions are only between source and sink
        sender_ids = to_ary(transactions, "SenderId")
        receiver_ids = to_ary(transactions, "ReceiverId")
        expected_sender_array = np.empty(sender_ids.size)
        expected_sender_array.fill(source_id[0])
        expected_receiver_array = np.empty(receiver_ids.size)
        expected_receiver_array.fill(sink_id[0])
        yield assert_array_equal, sender_ids, expected_sender_array
        yield assert_array_equal, receiver_ids, expected_receiver_array

        # Transaction ids must be equal range from 1 to the number of rows
        expected_trans_ids = np.arange(0, sender_ids.size, 1)
        yield assert_array_equal, \
            to_ary(transactions, "TransactionId"),\
            expected_trans_ids

        # Track transacted resources
        resource_ids = to_ary(resources, "ResourceId")
        quantities = to_ary(resources, "Quantity")
        expected_quantities = np.empty(resource_ids.size)
        # Expect that every transaction quantity is the same amount
        expected_quantities.fill(quantities[0])

        yield assert_array_equal, quantities, expected_quantities

        clean_outs()
Beispiel #12
0
def test_minimal_cycle():
    """Tests simulations with two facilities with several conversion factors.

    The commodities of the facilities are different. Facility A offers a
    commodity A and requests commodity B; whereas, Facility B offers a
    commodity B and requests commodity A. In addition, it is also assumed that
    the first requests and offers are the same quantities for respective
    receivers and senders.
    The amount of the transactions follow a power law.

    Amount = InitialAmount * ConversionFactor ^ Time

    This equation is used to test each transaction amount.
    """
    # A reference simulation input for minimal cycle with different commodities
    ref_input = "./input/minimal_cycle.xml"
    # Conversion factors for the simulations
    k_factors = [0.95, 1, 2]

    for k_factor_a in k_factors:
        for k_factor_b in k_factors:
            clean_outs()
            sim_input = change_minimal_input(ref_input, k_factor_a, k_factor_b)

            holdsrtn = [1]  # needed b/c nose does not send() to test generator
            outfile = which_outfile()
            cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
            yield check_cmd, cmd, '.', holdsrtn
            rtn = holdsrtn[0]
            if rtn != 0:
                return  # don't execute further commands

            # tables of interest
            paths = ["/AgentEntry", "/Resources", "/Transactions", "/Info"]
            # Check if these tables exist
            yield assert_true, tables_exist(outfile, paths)
            if not tables_exist(outfile, paths):
                outfile.close()
                clean_outs()
                return  # don't execute further commands

            # Get specific tables and columns
            if outfile == h5out:
                output = tables.open_file(h5out, mode="r")
                agent_entry = output.root.AgentEntry[:]
                info = output.get_node("/Info")[:]
                resources = output.get_node("/Resources")[:]
                transactions = output.get_node("/Transactions")[:]
                output.close()

            else:
                conn = sqlite3.connect(sqliteout)
                conn.row_factory = sqlite3.Row
                cur = conn.cursor()
                exc = cur.execute

                agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
                info = exc('SELECT * FROM Info').fetchall()
                resources = exc('SELECT * FROM Resources').fetchall()
                transactions = exc('SELECT * FROM Transactions').fetchall()
                conn.close()

            # Find agent ids
            agent_ids = to_ary(agent_entry, "AgentId")
            spec = to_ary(agent_entry, "Spec")
            agent_protos = to_ary(agent_entry, "Prototype")
            duration = to_ary(info, "Duration")[0]

            facility_id = find_ids(":agents:KFacility", spec, agent_ids)
            # Test for two KFacility
            yield assert_equal, len(facility_id), 2

            # Test for one Facility A and Facility B
            facility_a = find_ids("FacilityA", agent_protos, agent_ids)
            facility_b = find_ids("FacilityB", agent_protos, agent_ids)
            yield assert_equal, len(facility_a), 1
            yield assert_equal, len(facility_b), 1

            # Test if both facilities are KFracilities
            # Assume FacilityA is deployed first according to the schema
            yield assert_equal, facility_a[0], facility_id[0]
            yield assert_equal, facility_b[0], facility_id[1]

            # Test if the transactions are strictly between Facility A and
            # Facility B. There are no Facility A to Facility A or vice versa.
            sender_ids = to_ary(transactions, "SenderId")
            receiver_ids = to_ary(transactions, "ReceiverId")
            pattern_one = np.arange(0, sender_ids.size, 2)
            pattern_two = np.arange(1, sender_ids.size, 2)
            pattern_a = pattern_one  # expected pattern for Facility A as sender
            pattern_b = pattern_two  # expected pattern for Facility B as sender

            # Re-assign in case the expected patterns are incorrect
            if sender_ids[0] == facility_b[0]:
                pattern_a = pattern_two
                pattern_b = pattern_one

            yield assert_array_equal, \
                np.where(sender_ids == facility_a[0])[0], \
                pattern_a
            yield assert_array_equal, \
                np.where(receiver_ids == facility_a[0])[0], \
                pattern_b  # reverse pattern when acted as a receiver

            yield assert_array_equal, \
                np.where(sender_ids == facility_b[0])[0], \
                pattern_b
            yield assert_array_equal, \
                np.where(receiver_ids == facility_b[0])[0], \
                pattern_a  # reverse pattern when acted as a receiver

            # Transaction ids must be equal range from 1 to the number of rows
            expected_trans_ids = np.arange(sender_ids.size)
            yield assert_array_equal, \
                to_ary(transactions, "TransactionId"), \
                expected_trans_ids

            # When k_factors are very low and the simulation time is big
            # the number of transactions maybe shortened due to the lower
            # limit cyclus::eps() for transaction amounts.
            # Expect not to have shortened transactions, so for two facilities,
            # there must be (2 * duration) number of transactions.
            yield assert_equal, sender_ids.size, 2 * duration

            # Track transacted resources
            quantities = to_ary(resources, "Quantity")

            # Almost equal cases due to floating point k_factors
            init_capacity_a = quantities[0]
            init_capacity_b = quantities[1]
            j = 0
            for p in pattern_a:
                yield assert_almost_equal, quantities[p], \
                    init_capacity_a * k_factor_a ** j
                j += 1

            j = 0
            for p in pattern_b:
                yield assert_almost_equal, quantities[p], \
                    init_capacity_b * k_factor_b ** j
                j += 1

            clean_outs()
            os.remove(sim_input)
def test_source_to_sink():
    """Tests simulations with one facility that has a conversion factor.

    The trivial cycle simulation involves only one KFacility which provides
    what it requests itself. The conversion factors for requests and bids
    are kept the same so that the facility provides exactly what it requests.
    The amount of the transactions follow a power law.

    Amount = InitialAmount * ConversionFactor ^ Time

    This equation is used to test each transaction amount.
    """
    if not cyclus_has_coin():
        raise SkipTest("Cyclus does not have COIN")

    # A reference simulation input for the trivial cycle simulation.
    ref_input = os.path.join(INPUT, "trivial_cycle.xml")
    # Conversion factors for the three simulations
    k_factors = [0.95, 1, 2]

    for k_factor in k_factors:
        clean_outs()

        sim_input = create_sim_input(ref_input, k_factor, k_factor)

        holdsrtn = [1]  # needed because nose does not send() to test generator
        outfile = which_outfile()
        cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
        yield check_cmd, cmd, '.', holdsrtn
        rtn = holdsrtn[0]
        if rtn != 0:
            return  # don't execute further commands

        # tables of interest
        paths = ["/AgentEntry", "/Resources", "/Transactions",
                "/Info"]
        # Check if these tables exist
        yield assert_true, tables_exist(outfile, paths)
        if not tables_exist(outfile, paths):
            outfile.close()
            clean_outs()
            return  # don't execute further commands

        # Get specific tables and columns
        if outfile == h5out:
            output = tables.open_file(h5out, mode = "r")
            agent_entry = output.get_node("/AgentEntry")[:]
            info = output.get_node("/Info")[:]
            resources = output.get_node("/Resources")[:]
            transactions = output.get_node("/Transactions")[:]
            output.close()
        else:
            conn = sqlite3.connect(sqliteout)
            conn.row_factory = sqlite3.Row
            cur = conn.cursor()
            exc = cur.execute
            agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
            info = exc('SELECT * FROM Info').fetchall()
            resources = exc('SELECT * FROM Resources').fetchall()
            transactions = exc('SELECT * FROM Transactions').fetchall()
            conn.close()

        # Find agent ids
        agent_ids = to_ary(agent_entry, "AgentId")
        spec = to_ary(agent_entry, "Spec")

        facility_id = find_ids(":agents:KFacility", spec, agent_ids)
        # Test for only one KFacility
        yield assert_equal, len(facility_id), 1

        sender_ids = to_ary(transactions, "SenderId")
        receiver_ids = to_ary(transactions, "ReceiverId")
        expected_sender_array = np.empty(sender_ids.size)
        expected_sender_array.fill(facility_id[0])
        expected_receiver_array = np.empty(receiver_ids.size)
        expected_receiver_array.fill(facility_id[0])
        yield assert_array_equal, sender_ids, expected_sender_array
        yield assert_array_equal, receiver_ids, expected_receiver_array

        # Transaction ids must be equal range from 1 to the number of rows
        expected_trans_ids = np.arange(0, sender_ids.size, 1)
        yield assert_array_equal, \
            to_ary(transactions, "TransactionId"), \
                   expected_trans_ids

        # Track transacted resources
        resource_ids = to_ary(resources, "ResourceId")
        quantities = to_ary(resources, "Quantity")

        # Almost equal cases due to floating point k_factors
        i = 0
        initial_capacity = quantities[0]
        for q in quantities:
            yield assert_almost_equal, q, initial_capacity * k_factor ** i
            i += 1

        clean_outs()
        os.remove(sim_input)
def check_source_to_sink(fname, source_spec, sink_spec):
    """Tests linear growth of sink inventory by checking if the transactions
    were of equal quantities and only between sink and source facilities.
    """
    clean_outs()
    if not cyclus_has_coin():
        raise SkipTest("Cyclus does not have COIN")

    # Cyclus simulation input for Source and Sink
    sim_inputs = [os.path.join(INPUT, fname)]

    for sim_input in sim_inputs:
        holdsrtn = [1]  # needed because nose does not send() to test generator
        outfile = which_outfile()
        cmd = ["cyclus", "-o", outfile, "--input-file", sim_input]
        yield check_cmd, cmd, '.', holdsrtn
        rtn = holdsrtn[0]
        if rtn != 0:
            return  # don't execute further commands

        # Tables of interest
        paths = ["/AgentEntry", "/Resources", "/Transactions", "/Info"]
        # Check if these tables exist
        yield assert_true, tables_exist(outfile, paths)
        if not tables_exist(outfile, paths):
            clean_outs()
            return  # don't execute further commands

       # Get specific tables and columns
        if outfile == h5out:
            output = tables.open_file(h5out, mode = "r")

            agent_entry = output.get_node("/AgentEntry")[:]
            info = output.get_node("/Info")[:]
            resources = output.get_node("/Resources")[:]
            transactions = output.get_node("/Transactions")[:]
            output.close()
        else:
            conn = sqlite3.connect(outfile)
            conn.row_factory = sqlite3.Row
            cur = conn.cursor()
            exc = cur.execute

            agent_entry = exc('SELECT * FROM AgentEntry').fetchall()
            info = exc('SELECT * FROM Info').fetchall()
            resources = exc('SELECT * FROM Resources').fetchall()
            transactions = exc('SELECT * FROM Transactions').fetchall()
            conn.close()

        # Find agent ids of source and sink facilities
        agent_ids = to_ary(agent_entry, "AgentId")
        spec = to_ary(agent_entry, "Spec")

        source_id = find_ids(source_spec, spec, agent_ids)
        sink_id = find_ids(sink_spec, spec, agent_ids)

        # Test for only one source and one sink are deployed in the simulation
        yield assert_equal, len(source_id), 1
        yield assert_equal, len(sink_id), 1

        # Check if transactions are only between source and sink
        sender_ids = to_ary(transactions, "SenderId")
        receiver_ids = to_ary(transactions, "ReceiverId")
        expected_sender_array = np.empty(sender_ids.size)
        expected_sender_array.fill(source_id[0])
        expected_receiver_array = np.empty(receiver_ids.size)
        expected_receiver_array.fill(sink_id[0])
        yield assert_array_equal, sender_ids, expected_sender_array
        yield assert_array_equal, receiver_ids, expected_receiver_array

        # Transaction ids must be equal range from 1 to the number of rows
        expected_trans_ids = np.arange(0, sender_ids.size, 1)
        yield assert_array_equal, \
            to_ary(transactions, "TransactionId"),\
            expected_trans_ids

        # Track transacted resources
        resource_ids = to_ary(resources, "ResourceId")
        quantities = to_ary(resources, "Quantity")
        expected_quantities = np.empty(resource_ids.size)
        # Expect that every transaction quantity is the same amount
        expected_quantities.fill(quantities[0])

        yield assert_array_equal, quantities, expected_quantities

        clean_outs()