Ejemplo n.º 1
0
def test_object_key_substitution():
    """Test that client can copy a dictionary in which keys are BaseEntity objects."""
    spec = ProcessSpec("A process spec",
                       uids={
                           'id': str(uuid4()),
                           'auto': str(uuid4())
                       })
    run1 = ProcessRun("A process run",
                      spec=spec,
                      uids={
                          'id': str(uuid4()),
                          'auto': str(uuid4())
                      })
    run2 = ProcessRun("Another process run",
                      spec=spec,
                      uids={'id': str(uuid4())})
    process_dict = {spec: [run1, run2]}

    subbed = substitute_links(process_dict, native_uid='auto')
    for key, value in subbed.items():
        assert key == LinkByUID.from_entity(spec, name='auto')
        assert LinkByUID.from_entity(run1, name='auto') in value
        assert LinkByUID.from_entity(run2) in value

    reverse_process_dict = {run2: spec}
    subbed = substitute_links(reverse_process_dict, native_uid='auto')
    for key, value in subbed.items():
        assert key == LinkByUID.from_entity(run2)
        assert value == LinkByUID.from_entity(spec, name='auto')
Ejemplo n.º 2
0
def test_flatten_empty_history():
    """Test that flatten works when the objects are empty and go through a whole history."""
    procured = ProcessSpec(name="procured")
    input = MaterialSpec(name="foo", process=procured)
    transform = ProcessSpec(name="transformed")
    ingredient = IngredientSpec(name="input",
                                material=input,
                                process=transform)

    procured_run = ProcessRun(name="procured", spec=procured)
    input_run = MaterialRun(name="foo", process=procured_run, spec=input)
    transform_run = ProcessRun(name="transformed", spec=transform)
    ingredient_run = IngredientRun(material=input_run,
                                   process=transform_run,
                                   spec=ingredient)

    assert len(flatten(procured)) == 1
    assert len(flatten(input)) == 1
    assert len(flatten(ingredient)) == 3
    assert len(flatten(transform)) == 3

    assert len(flatten(procured_run)) == 3
    assert len(flatten(input_run)) == 3
    assert len(flatten(ingredient_run)) == 7
    assert len(flatten(transform_run)) == 7
Ejemplo n.º 3
0
def test_process_reassignment():
    """Test that a material can be assigned to a new process."""
    drying = ProcessRun("drying")
    welding = ProcessRun("welding")
    powder = MaterialRun("Powder", process=welding)

    assert powder.process == welding
    assert welding.output_material == powder

    powder.process = drying
    assert powder.process == drying
    assert drying.output_material == powder
    assert welding.output_material is None
Ejemplo n.º 4
0
def test_order_objects():
    """Test that sorting works when given objects."""
    unsorted = [MaterialRun("bar"), ProcessRun("foo")]
    sorted_list = sorted(unsorted, key=lambda x: writable_sort_order(x))

    assert isinstance(sorted_list[0], ProcessRun)
    assert isinstance(sorted_list[1], MaterialRun)
Ejemplo n.º 5
0
def test_dict_serialization():
    """Test that a dictionary can be serialized and then deserialized as a taurus object."""
    process = ProcessRun("A process")
    mat = MaterialRun("A material", process=process)
    meas = MeasurementRun("A measurement", material=mat)
    copy = loads(dumps(meas.as_dict()))
    assert copy == meas
Ejemplo n.º 6
0
def test_unexpected_serialization():
    """Trying to serialize an unexpected class should throw a TypeError."""
    class DummyClass:
        def __init__(self, foo):
            self.foo = foo

    with pytest.raises(TypeError):
        dumps(ProcessRun("A process", notes=DummyClass("something")))
Ejemplo n.º 7
0
def test_tuple_sub():
    """substitute_objects() should correctly substitute tuple values."""
    proc = ProcessRun('foo', uids={'id': '123'})
    proc_link = LinkByUID.from_entity(proc)
    index = {(proc_link.scope, proc_link.id): proc}
    tup = (proc_link,)
    subbed = substitute_objects(tup, index)
    assert subbed[0] == proc
Ejemplo n.º 8
0
def test_invalid_assignment():
    """Invalid assignments to `process` or `spec` throw a TypeError."""
    with pytest.raises(TypeError):
        MaterialRun(name=12)
    with pytest.raises(TypeError):
        MaterialRun("name", spec=ProcessRun("a process"))
    with pytest.raises(TypeError):
        MaterialRun("name", process=MaterialSpec("a spec"))
Ejemplo n.º 9
0
def test_flatmap_unidirectional_ordering():
    """Test that the unidirecitonal setting is obeyed."""
    # The writeable link is ingredient -> process, not process -> ingredients
    proc = ProcessRun(name="foo")
    IngredientRun(notes="bar", process=proc)

    assert len(recursive_flatmap(proc, lambda x: [x],
                                 unidirectional=False)) == 2
    assert len(recursive_flatmap(proc, lambda x: [x],
                                 unidirectional=True)) == 0
Ejemplo n.º 10
0
def test_unexpected_deserialization():
    """Trying to deserialize an unexpected class should throw a TypeError."""
    class DummyClass(DictSerializable):
        typ = 'dummy_class'

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

    # DummyClass cannot be serialized since dumps will round-robin serialize
    # in the substitute_links method
    with pytest.raises(TypeError):
        dumps(ProcessRun("A process", notes=DummyClass("something")))
Ejemplo n.º 11
0
def test_unexpected_deserialization():
    """Trying to deserialize an unexpected class should throw a TypeError."""
    class DummyClass(DictSerializable):
        typ = 'dummy_class'

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

    # DummyClass can be serialized because it is a DictSerializable, but cannot be
    # deserialized because it is not in the _clazzes list.
    serialized = dumps(ProcessRun("A process", notes=DummyClass("something")))
    with pytest.raises(TypeError):
        loads(serialized)
Ejemplo n.º 12
0
def test_dictionary_substitution():
    """substitute_objects() should substitute LinkByUIDs that occur in dict keys and values."""
    proc = ProcessRun("A process", uids={'id': '123'})
    mat = MaterialRun("A material", uids={'generic id': '38f8jf'})

    proc_link = LinkByUID.from_entity(proc)
    mat_link = LinkByUID.from_entity(mat)
    index = {(mat_link.scope.lower(), mat_link.id): mat,
             (proc_link.scope.lower(), proc_link.id): proc}

    test_dict = {LinkByUID.from_entity(proc): LinkByUID.from_entity(mat)}
    substitute_objects(test_dict, index)
    assert test_dict[proc] == mat
Ejemplo n.º 13
0
def test_many_ingredients():
    """Test that ingredients remain connected to processes when round-robined through json."""
    proc = ProcessRun("foo", spec=ProcessSpec("sfoo"))
    expected = []
    for i in range(10):
        mat = MaterialRun(name=str(i), spec=MaterialSpec("s{}".format(i)))
        i_spec = IngredientSpec(name="i{}".format(i), material=mat.spec, process=proc.spec)
        IngredientRun(process=proc, material=mat, spec=i_spec)
        expected.append("i{}".format(i))

    reloaded = loads(dumps(proc))
    assert len(list(reloaded.ingredients)) == 10
    names = [x.name for x in reloaded.ingredients]
    assert sorted(names) == sorted(expected)
Ejemplo n.º 14
0
def test_process_run():
    """Test that a process run can house a material, and that it survives serde."""
    process_run = ProcessRun("Bake a cake", uids={'My_ID': 17})
    material_run = MaterialRun("A cake", process=process_run)

    # Check that a bi-directional link is established
    assert material_run.process == process_run
    assert process_run.output_material == material_run

    copy_material = loads(dumps(material_run))
    assert dumps(copy_material) == dumps(material_run)

    assert 'output_material' in repr(process_run)
    assert 'process' in repr(material_run)
Ejemplo n.º 15
0
def test_recursive_foreach():
    """Test that recursive foreach will actually walk through a material history."""
    mat_run = MaterialRun("foo")
    process_run = ProcessRun("bar")
    IngredientRun(process=process_run, material=mat_run)
    output = MaterialRun(process=process_run)

    # property templates are trickier than templates because they are referenced in attributes
    template = PropertyTemplate("prop", bounds=RealBounds(0, 1, ""))
    prop = Property("prop", value=NominalReal(1.0, ""), template=template)
    MeasurementRun("check", material=output, properties=prop)

    types = []
    recursive_foreach(output, lambda x: types.append(x.typ))

    expected = [
        "ingredient_run", "material_run", "material_run", "process_run",
        "measurement_run", "property_template"
    ]
    assert sorted(types) == sorted(expected)
Ejemplo n.º 16
0
def test_serialize():
    """Serializing a nested object should be identical to individually serializing each piece."""
    condition = Condition(name="A condition", value=NominalReal(7, ''))
    parameter = Parameter(name="A parameter", value=NormalReal(mean=17, std=1, units=''))
    input_material = MaterialRun(tags="input")
    process = ProcessRun(tags="A tag on a process run")
    ingredient = IngredientRun(material=input_material, process=process)
    material = MaterialRun(tags=["A tag on a material"], process=process)
    measurement = MeasurementRun(tags="A tag on a measurement", conditions=condition,
                                 parameters=parameter, material=material)

    # serialize the root of the tree
    native_object = json.loads(dumps(measurement))
    # ingredients don't get serialized on the process
    assert(len(native_object[0]) == 3)
    assert(native_object[1]["type"] == LinkByUID.typ)

    # serialize all of the nodes
    native_batch = json.loads(dumps([material, process, measurement, ingredient]))
    assert(len(native_batch[0]) == 5)
    assert(len(native_batch[1]) == 4)
    assert(all(x["type"] == LinkByUID.typ for x in native_batch[1]))
Ejemplo n.º 17
0
def make_data_island(density, bulk_modulus, firing_temperature, binders, powders, tag=None):
    """Helper function to create a relatively involved data island."""
    binder_specs = keymap(lambda x: MaterialSpec(name=x), binders)
    powder_specs = keymap(lambda x: MaterialSpec(name=x), powders)

    binder_runs = keymap(lambda x: MaterialRun(spec=x), binder_specs)
    powder_runs = keymap(lambda x: MaterialRun(spec=x), powder_specs)

    all_input_materials = keymap(lambda x: x.spec.name, merge(binder_runs, powder_runs))
    mixing_composition = Condition(
        name="composition",
        value=NominalComposition(all_input_materials)
    )
    mixing_process = ProcessRun(
        tags=["mixing"],
        conditions=[mixing_composition]
    )
    binder_ingredients = []
    for run in binder_runs:
        binder_ingredients.append(
            IngredientRun(
                material=run,
                process=mixing_process,
                mass_fraction=NominalReal(binders[run.spec.name], ''),
            )
        )

    powder_ingredients = []
    for run in powder_runs:
        powder_ingredients.append(
            IngredientRun(
                material=run,
                process=mixing_process,
                mass_fraction=NominalReal(powders[run.spec.name], ''),
            )
        )

    green_sample = MaterialRun(process=mixing_process)

    measured_firing_temperature = Condition(
        name="Firing Temperature",
        value=UniformReal(firing_temperature - 0.5, firing_temperature + 0.5, 'degC'),
        template=firing_temperature_template
    )

    specified_firing_setting = Parameter(
        name="Firing setting",
        value=DiscreteCategorical("hot")
    )
    firing_spec = ProcessSpec(template=firing_template)
    firing_process = ProcessRun(
        conditions=[measured_firing_temperature],
        parameters=[specified_firing_setting],
        spec=firing_spec
    )
    IngredientRun(
        green_sample,
        process=firing_process,
        mass_fraction=NormalReal(1.0, 0.0, ''),
        volume_fraction=NormalReal(1.0, 0.0, ''),
        number_fraction=NormalReal(1.0, 0.0, '')
    )

    measured_density = Property(
        name="Density",
        value=NominalReal(density, ''),
        template=density_template
    )
    measured_modulus = Property(
        name="Bulk modulus",
        value=NormalReal(bulk_modulus, bulk_modulus / 100.0, '')
    )
    measurement_spec = MeasurementSpec(template=measurement_template)
    measurement = MeasurementRun(
        properties=[measured_density, measured_modulus],
        spec=measurement_spec
    )

    tags = [tag] if tag else []

    material_spec = MaterialSpec(template=material_template)
    material_run = MaterialRun(process=firing_process, tags=tags, spec=material_spec)
    measurement.material = material_run
    return material_run