More tests on dataset state
- changes in the Graph specification:
  - `provides_dataset_config_names` field indicates if the step is providing the list of config names for a dataset
  - `provides_config_split_names` field indicates if the step is providing the list of split names for a config
  - `requires` field has been renamed to `triggered_by`: indeed, the relation between steps is that, when step B is `triggered_by` step A, if A has been updated, a new job will be created for step B.
- ProcessingGraph:
  - the concept of ProcessingStep is simplified: it's a data class, and provides the name, job runner version, input type (as well as the job type and cache kind, which are equal to the processing step name)
  - most of the methods are provided by ProcessingGraph, in particular those related to the edges, or to filtering nodes.
  - the data structure is a [networkx.digraph](https://networkx.org/documentation/stable/reference/classes/digraph.html): the nodes are the step names, and we use the [attributes](https://networkx.org/documentation/stable/tutorial.html#node-attributes) to store some properties
- remove the `/admin/jobs_duration` endpoint, because the finished jobs are now deleted quickly, so: this statistic does not mean much now.
- add tests for state.py. In particular: use small processing graphs with the special cases (children, grand-children, multiple parents, fan-in, fan-out, parallel steps, etc). The "real" processing graph now only has one test. This should reduce code to change when a step is added, modified or deleted.
More tests on dataset state: - changes in the Graph specification:
  - `provides_dataset_config_names` field indicates if the step is providing the list of config names for a dataset
  - `provides_config_split_names` field indicates if the step is providing the list of split names for a config
  - `requires` field has been renamed to `triggered_by`: indeed, the relation between steps is that, when step B is `triggered_by` step A, if A has been updated, a new job will be created for step B.
- ProcessingGraph:
  - the concept of ProcessingStep is simplified: it's a data class, and provides the name, job runner version, input type (as well as the job type and cache kind, which are equal to the processing step name)
  - most of the methods are provided by ProcessingGraph, in particular those related to the edges, or to filtering nodes.
  - the data structure is a [networkx.digraph](https://networkx.org/documentation/stable/reference/classes/digraph.html): the nodes are the step names, and we use the [attributes](https://networkx.org/documentation/stable/tutorial.html#node-attributes) to store some properties
- remove the `/admin/jobs_duration` endpoint, because the finished jobs are now deleted quickly, so: this statistic does not mean much now.
- add tests for state.py. In particular: use small processing graphs with the special cases (children, grand-children, multiple parents, fan-in, fan-out, parallel steps, etc). The "real" processing graph now only has one test. This should reduce code to change when a step is added, modified or deleted.