Example #1
0
def test_serialized_history():
    """Test the serialization of a complete material history."""
    # Create several runs and specs linked together
    buy_spec = LinkByUID("id", "pr723")
    cookie_dough_spec = MaterialSpec("cookie dough spec", process=buy_spec)
    buy_cookie_dough = ProcessRun("Buy cookie dough", uids={'id': '32283'}, spec=buy_spec)
    cookie_dough = MaterialRun("cookie dough", process=buy_cookie_dough, spec=cookie_dough_spec)
    bake = ProcessRun("bake cookie dough", conditions=[
        Condition("oven temp", origin='measured', value=NominalReal(357, 'degF'))])
    IngredientRun(material=cookie_dough,
                  process=bake, number_fraction=NominalReal(1, ''))
    cookie = MaterialRun("cookie", process=bake, tags=["chocolate chip", "drop"])
    MeasurementRun("taste", material=cookie, properties=[
        Property("taste", value=DiscreteCategorical("scrumptious"))])

    cookie_history = complete_material_history(cookie)
    # There are 7 entities in the serialized list: cookie dough (spec & run), buy cookie dough,
    # cookie dough ingredient, bake cookie dough, cookie, taste
    assert len(cookie_history) == 7
    for entity in cookie_history:
        assert len(entity['uids']) > 0, "Serializing material history should assign uids."

    # Check that the measurement points to the material
    taste_dict = next(x for x in cookie_history if x.get('type') == 'measurement_run')
    cookie_dict = next(x for x in cookie_history if x.get('name') == 'cookie')
    scope = taste_dict.get('material').get('scope')
    assert taste_dict.get('material').get('id') == cookie_dict.get('uids').get(scope)

    # Check that both the material spec and the process run point to the same process spec.
    # Because that spec was initially a LinkByUID, this also tests the methods ability to
    # serialize a LinkByUID.
    cookie_dough_spec_dict = next(x for x in cookie_history if x.get('type') == 'material_spec')
    buy_cookie_dough_dict = next(x for x in cookie_history if x.get('name') == 'Buy cookie dough')
    assert cookie_dough_spec_dict.get('process') == buy_spec.as_dict()
    assert buy_cookie_dough_dict.get('spec') == buy_spec.as_dict()
def test_link_by_uid():
    """Test that linking works."""
    root = MaterialRun(name='root', process=ProcessRun(name='root proc'))
    leaf = MaterialRun(name='leaf', process=ProcessRun(name='leaf proc'))
    IngredientRun(process=root.process, material=leaf)
    IngredientRun(process=root.process, material=LinkByUID.from_entity(leaf))

    copy = loads(dumps(root))
    assert copy.process.ingredients[0].material == copy.process.ingredients[
        1].material
Example #3
0
    def crawler(spec):
        from gemd.entity.object.measurement_spec import MeasurementSpec
        from gemd.entity.object.measurement_run import MeasurementRun
        from gemd.entity.object.material_spec import MaterialSpec
        from gemd.entity.object.material_run import MaterialRun
        from gemd.entity.object.ingredient_spec import IngredientSpec
        from gemd.entity.object.ingredient_run import IngredientRun
        from gemd.entity.object.process_spec import ProcessSpec
        from gemd.entity.object.process_run import ProcessRun

        if id(spec) in seen:
            return seen[id(spec)]

        if isinstance(spec, MeasurementSpec):
            seen[id(spec)] = MeasurementRun(name=spec.name, spec=spec)
        elif isinstance(spec, MaterialSpec):
            seen[id(spec)] = MaterialRun(name=spec.name, spec=spec)
            seen[id(spec)].process = crawler(
                spec.process) if spec.process else None
        elif isinstance(spec, IngredientSpec):
            seen[id(spec)] = IngredientRun(spec=spec)
            seen[id(spec)].material = crawler(
                spec.material) if spec.material else None
        elif isinstance(spec, ProcessSpec):
            seen[id(spec)] = ProcessRun(name=spec.name, spec=spec)
            for x in spec.ingredients:
                crawler(x).process = seen[id(spec)]
        else:
            raise TypeError(
                'Passed object is not a spec-like object({})'.format(
                    type(spec)))

        # Should we assume that the same MaterialSpec in different parts of the tree
        # yields the same MaterialRun?
        return seen[id(spec)]
Example #4
0
def test_template_access():
    """A process run's template should be equal to its spec's template."""
    template = ProcessTemplate("process template", uids={'id': str(uuid4())})
    spec = ProcessSpec("A spec", uids={'id': str(uuid4())}, template=template)
    proc = ProcessRun("A run", uids={'id': str(uuid4())}, spec=spec)
    assert proc.template == template

    proc.spec = LinkByUID.from_entity(spec)
    assert proc.template is None
Example #5
0
def test_ingredient_reassignment():
    """Check that an ingredient run can be re-assigned to a new process run."""
    boiling = ProcessRun("Boil potatoes")
    frying = ProcessRun("Fry potatoes")
    oil = IngredientRun(process=boiling)
    potatoes = IngredientRun(process=boiling)
    assert oil.process == boiling
    assert set(boiling.ingredients) == {oil, potatoes}
    assert frying.ingredients == []

    oil.process = frying
    assert oil.process == frying
    assert boiling.ingredients == [potatoes]
    assert frying.ingredients == [oil]

    potatoes.process = frying
    assert potatoes.process == frying
    assert boiling.ingredients == []
    assert set(frying.ingredients) == {oil, potatoes}
Example #6
0
def test_ingredient_run():
    """Tests that a process can house an ingredient, and that pairing survives serialization."""
    # Create a ProcessSpec
    proc_run = ProcessRun(name="a process spec", tags=["tag1", "tag2"])
    ingred_run = IngredientRun(material=MaterialRun(name='Raw'), process=proc_run)

    # Make copies of both specs
    proc_run_copy = loads(dumps(proc_run))

    assert proc_run_copy == proc_run, "Full structure wasn't preserved across serialization"

    assert 'process' in repr(ingred_run)
    assert 'ingredients' in repr(proc_run)
Example #7
0
def test_process_spec():
    """Tests that the Process Spec/Run connection persists when serializing."""
    # Create the ProcessSpec
    condition1 = Condition(name="a condition on the process in general")
    spec = ProcessSpec(conditions=condition1)

    # Create the ProcessRun with a link to the ProcessSpec from above
    condition2 = Condition(name="a condition on this process run in particular")
    process = ProcessRun(conditions=condition2, spec=spec)

    copy_process = loads(dumps(process))
    assert dumps(copy_process.spec) == dumps(spec), \
        "Process spec should be preserved through serialization"
Example #8
0
def test_invalid_assignment():
    """Invalid assignments to `spec` throw a TypeError."""
    with pytest.raises(TypeError):
        ProcessRun("name", spec=[ProcessSpec("spec")])
Example #9
0
def test_serde():
    """Test that an object with a case-insensitive dict can be serialized properly."""
    process = ProcessRun("A process", uids={'Foo': str(17)})
    process_copy = loads(dumps(process))
    assert process == process_copy
    assert process_copy.uids['foo'] == process_copy.uids['Foo']