def test_changes_in_the_graph_without_removing_resource(self): """ If the graph changes without removing resource tuttle should display a message event if the removed resource is used elsewhere (from bug) """ first = """ <- file://A echo Action after A is created. file://B <- file://A echo B > B file://C <- file://B echo C > C """ rcode, output = run_tuttle_file(first) print output assert rcode == 0, output second = """ <- file://A echo Action after A is created. file://C <- file://B echo C > C """ rcode, output = tuttle_invalidate(project=second) assert rcode == 0, output assert output.find("Report has been updated to reflect") >= 0, output
def test_duration(self): """ Should display a message if there is no tuttlefile in the current directory""" project = """file://B <- file://A echo A creates B python -c "import time; time.sleep(1)" echo A creates B > B file://C <- file://B echo A creates C python -c "import time; time.sleep(1.2)" echo A creates C > C """ rcode, output = run_tuttle_file(project) assert rcode == 0, output assert isfile('B') assert isfile('C') rcode, output = tuttle_invalidate(urls=['file://B']) assert rcode == 0, output assert output.find('* file://B') >= 0, output assert output.find('* file://C') >= 0, output assert output.find('s of processing will be lost') >= 0, output assert output.find('\n0s') == -1, output assert not isfile('B'), output assert not isfile('C'), output
def test_not_modified_new_primary_resources_should_not_invalidate_dependencies( self): """ If a resource has become a primary resource, but signature has not changed that was produced with previous workflow shouldn't invalidate dependencies if it hasn't changed""" project = """file://B <- file://A echo A produces B echo A produces B > B file://C <- file://B echo B produces C echo B produces C > C """ rcode, output = run_tuttle_file(project) print output assert rcode == 0, output project = """ file://C <- file://B echo B produces C echo B produces C > C """ rcode, output = tuttle_invalidate(project=project) assert rcode == 0, output assert output.find("Report has been updated to reflect") >= 0, output
def test_a_failing_process_without_output_should_be_invalidated(self): """ When a process fail, Tuttle should exit with status code 2, even if the process has no outputs""" project = """file://B <- file://A echo A produces B echo B > B <- file://B error echo This should not be written echo C > C """ rcode, output = run_tuttle_file(project) assert rcode == 2 assert isfile('B') assert not isfile('C') report_path = join('.tuttle', 'report.html') assert isfile(report_path) report = open(report_path).read() title_match_failure = search(r'<h1>.*Failure.*</h1>', report, DOTALL) assert title_match_failure, report rcode, output = tuttle_invalidate() assert rcode == 0 report = open(report_path).read() title_match_failure = search(r'<h1>.*Failure.*</h1>', report, DOTALL) assert not title_match_failure, title_match_failure.group()
def test_invalidate_nothing_have_run(self): """ Should display a message when launching invalidate and tuttle hasn't been run before : nothing to invalidate """ project = """file://B <- file://A echo A creates B echo A creates B > B """ rcode, output = tuttle_invalidate(project=project) assert rcode == 2, output assert output.find("Tuttle has not run yet ! It has produced nothing, " "so there is nothing to invalidate.") >= 0, output
def test_unknown_resource_should_be_ignored(self): """ Should display a message if there is no tuttlefile in the current directory""" project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0 rcode, output = tuttle_invalidate(urls=['file://C']) assert rcode == 0, output assert output.find("Ignoring file://C") >= 0, output
def test_invalid_url_should_fail(self): """ Should display an error if the url passed in parameter is not valid or unknown scheme """ project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0 rcode, output = tuttle_invalidate(urls=['error://B']) assert rcode == 2, output assert output.find("'error://B'") >= 0, output
def test_workflow_must_be_run_after_resource_invalidation_in_cascade(self): """ After invalidation of a resource, tuttle run should re-produce this resource and the dependencies""" project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0, output rcode, output = tuttle_invalidate(urls=["file://A"]) assert rcode == 0, output assert output.find("Ignoring file://A") >= 0, output
def test_no_error_with_download_process(self): """ Download process does not create code in reserved_path for the process... Thus it cant be moved when """ """ retreiving logs and reserved path from previous execution(from bug) """ project = """file://g <- http://localhost:8043/a_resource ! download file://h <- file://g ERROR """ rcode, output = run_tuttle_file(project) assert rcode == 2, output rcode, output = tuttle_invalidate() assert rcode == 0, output rcode, output = run_tuttle_file() assert rcode == 2, output
def test_command_invalidate(self): """ Should display a message if there is no tuttlefile in the current directory""" project = """file://B <- file://A echo A creates B echo A creates B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0 assert isfile('B') rcode, output = tuttle_invalidate(urls=['file://B']) assert rcode == 0, output assert output.find('* file://B') >= 0, output assert not isfile('B'), output
def test_invalidate_an_output_should_invalidate_all_outputs(self): """ Should invalidate all outputs if one is invalidated """ project = """file://B file://C <- file://A echo A produces B echo A produces B > B echo A produces C echo A produces C > C """ rcode, output = run_tuttle_file(project) assert rcode == 0 rcode, output = tuttle_invalidate(urls=['file://C']) assert rcode == 0, output assert output.find("* file://B") >= 0, output assert output.find("* file://C") >= 0, output assert output.find(BROTHER_INVALID.format("file://C")) >= 0, output
def test_workflow_must_run_after_invalidation_because_of_an_error(self): """ If a process fails, it can be invalidated then run again (from bug) """ project = """file://B <- file://A echo A produces B echo A produces B > B file://C <- file://B ERROR """ rcode, output = run_tuttle_file(project) assert rcode == 2, output rcode, output = tuttle_invalidate() assert rcode == 0, output rcode, output = run_tuttle_file(project) # If if we get here, it means no exception was raised assert rcode == 2, output
def test_process_in_error_should_be_invalidated(self): """ If a process failed, its dependencies should be invalidated """ project = """file://B <- file://A echo A produces B echo A produces B > B an error """ rcode, output = run_tuttle_file(project) print output assert rcode == 2, output assert isfile('B') rcode, output = tuttle_invalidate(project=project) assert rcode == 0, output assert output.find("file://B") >= 0, output assert not isfile('B'), output
def test_dont_invalidate_outputless_process(self): """ Don't invalidate a successful process without outputs(from bug) """ first = """file://C <- file://A echo A produces C > C <- file://B echo Action after B is created """ rcode, output = run_tuttle_file(first) assert rcode == 0, output rcode, output = tuttle_invalidate() assert rcode == 0, output rcode, output = run_tuttle_file(first) assert rcode == 0 assert output.find("Nothing to do") >= 0, output assert output.find("Action") == -1, output
def test_try_invalidate_bad_project(self): """ Should display a message if the tuttlefile is incorrect""" project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0 bad_project = """file://B <- file://A bad echo A produces B echo A produces B > B """ rcode, output = tuttle_invalidate(project=bad_project, urls=['file://B']) assert rcode == 2, output assert output.find( 'Invalidation has failed because tuttlefile is has errors' ) >= 0, output
def test_workflow_must_be_run_after_resource_invalidation(self): """ After invalidation of a resource, tuttle run should re-produce this resource """ project = """file://B <- file://A echo A produces B echo A produces B > B file://C <- file://B echo B produces C echo B produces C > C """ rcode, output = run_tuttle_file(project) assert rcode == 0, output rcode, output = tuttle_invalidate(urls=["file://C"]) assert rcode == 0, output assert output.find("file://C") >= 0, output rcode, output = run_tuttle_file(project) assert output.find("Nothing to do") == -1, output assert output.find("B produces C") >= 0, output
def test_invalidate_no_urls(self): """ Should remove everything that is not in the last version of the tuttlefile """ project = """file://B <- file://A echo A produces B echo A produces B > B file://C <- file://B echo B produces C echo B produces C > C """ rcode, output = run_tuttle_file(project) assert rcode == 0 new_project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = tuttle_invalidate(project=new_project) assert rcode == 0, output assert output.find('* file://C') >= 0, output assert output.find('no longer created') >= 0, output
def test_not_produced_resource_should_be_ignored(self): """ Should display a message if there is no tuttlefile in the current directory""" project = """file://B <- file://A echo A produces B echo A produces B > B """ rcode, output = run_tuttle_file(project) assert rcode == 0 project = """file://B <- file://A echo A produces B echo A produces B > B file://C <- file://B echo B produces C echo B produces C > C """ rcode, output = tuttle_invalidate(project=project, urls=['file://C']) assert rcode == 0, output assert output.find( "Ignoring file://C : this resource has not been produced yet" ) >= 0, output