Can Gradle task dependencies be set up to exclude a task? - gradle

We have in our build a lifecycle task which is supposed to run everything to do a quick check of the code. It looks like this:
task minimalBuild(dependsOn: [jar, testJar, javadoc])
Someone said it should also run checks, which seems reasonable, except that if I depend on check itself, check depends on test, so all the tests will be run and it's no longer a quick build.
I could manually list the individual checks of course, and that is my best idea right now, but every time someone installs a new checking tool, they will have to update this list, and they might not know they have to.
Is there a way to do this programmatically at least? Can I make minimalBuild depend on "everything check depends on except for test"?

You can onfigure it via taskGraph, like so:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(minimalBuild)) {
tasks.withType(Test){
enabled = false
}
}
}
This configuration should be added to root of the script. It waits untill the execution graph is ready (it contains all the task, which should be really executed), after that it checks, whether minimalBuild task will be executed and if yes, then it disables all the tasks wit Test type.

Related

Testing behavior not consistent when watching actor for termination

When I write tests that involve subscribing to events on the Eventstream or watching actors and listning for "Terminated", the tests work fine running them 1 by 1 but when I run the whole testsuite those tests fail.
Tests also works if each of those tests are in a separate test class with Xunit.
How come?
A repo with those kind of tests: https://github.com/Lejdholt/AkkaTestError
Took a look at your repository. I can reproduce the problems you are describing.
It feels like a bug in the TestKit, some timing issue somewhere. But its hard to pin down.
Also, not all unit test frameworks are created equally. The testkit uses its own TaskDispatcher to enable the testing of what are normally inherently asynchronous processed operations.
This sometimes causes some conflicts with the testframework being used. Is also coincidentally why akka.net also moved to XUnit for their own CI process.
I have managed to fix your problem, by not using the TestProbe. Although im not sure if the problem lies with the TestProbe per say, or the fact that your where using an global reference (your 'process' variable).
I suspect that the testframework, while running tests in parrallel, might be causing some wierd things to happen with your testprobe reference.
Example of how i changed one of your tests:
[Test]
public void GivenAnyTime_WhenProcessTerminates_ShouldLogStartRemovingProcess()
{
IProcessFactory factory = Substitute.For<IProcessFactory>();
var testactor = Sys.ActorOf<FakeActor>("test2");
processId = Guid.NewGuid();
factory.Create(Arg.Any<IActorRefFactory>(), Arg.Any<SupervisorStrategy>()).Returns(testactor);
manager = Sys.ActorOf(Props.Create(() => new Manager(factory)));
manager.Tell(new StartProcessCommand(processId));
EventFilter.Info("Removing process.")
.ExpectOne(() => Sys.Stop(testactor));
}
It should be fairly self explanatory on how you should change your other test.
The FakeActor is nothing more then an empty ReceiveActor implementation.

Gradle - Capturing output written to out / err on a per task basis

I'm trying to capture output written from each task as it is executed. The code below works as expected when running Gradle with --max-workers 1, but when multiple tasks are running in parallel this code below picks up output written from other tasks running simultaneously.
The API documentation states the following about the "getLogging" method on Task. From what it says I judge that it should support capturing output from single tasks regardless of any other tasks running at the same time.
getLogging()
Returns the LoggingManager which can be used to control the logging level and standard output/error capture for this task. https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html
graph.allTasks.forEach { Task task ->
task.ext.capturedOutput = [ ]
def listener = { task.capturedOutput << it } as StandardOutputListener
task.logging.addStandardErrorListener(listener)
task.logging.addStandardOutputListener(listener)
task.doLast {
task.logging.removeStandardOutputListener(listener)
task.logging.removeStandardErrorListener(listener)
}
}
Have I messed up something in the code above or should I report this as a bug?
It looks like every LoggingManager instance shares an OutputLevelRenderer, which is what your listeners eventually get added to. This did make me wonder why you weren't getting duplicate messages because you're attaching the same listeners to the same renderer over and over again. But it seems the magic is in BroadcastDispatch, which keeps the listeners in a map, keyed by the listener object itself. So you can't have duplicate listeners.
Mind you, for that to hold, the hash code of each listener must be the same, which seems surprising. Anyway, perhaps this is working as intended, perhaps it isn't. It's certainly worth an issue to get some clarity on whether Gradle should support listeners per task. Alternatively raise it on the dev mailing list.

Gradle Tasks Difference

What's the difference between the following two code snippets?
First:
task copyFiles(type: Copy) << {
from "folder/from"
into "dest/folder"
}
Second:
task copyFiles(type: Copy) {
from "folder/from"
into "dest/folder"
}
In short, the first snippet is getting it wrong, and the second one is getting it right.
A Gradle build proceeds in three phases: initialization, configuration, and execution. Methods like from and into configure a task, hence they need to be invoked in the configuration phase. However, << (which is a shortcut for doLast) adds a task action - it instructs the task what to do if and when it gets executed. In other words, the first snippet configures the task in the execution phase, and even worse, after its main (copy) action has been executed. Hence the configuration won't have any effect.
Typically, a task has either a type (which already brings along a task action) or a << (for an ad-hoc task). There are legitimate uses cases for having both (doing a bit of custom work after the task's "main" work), but more often that not, it's a mistake where the task gets configured too late.
I generally recommend to use doLast instead of <<, because it's less cryptic and makes it easier to spot such mistakes. (Once you understand the concepts, it's kind of obvious that task copyFiles(type: Copy) { doLast { from ... } } is wrong.)
The first block of code create a task and append an Action to it. A task is composed of actions which are instructions blocks run sequentially when the task is called
The second block create a task and configure it. These instructions are run in the gradle "configuration" lifecycle phase.
here you find a clear explanation of the differences
here you can find an in depth explanation of gradle tasks
here is the gradle guide about lifecycle

Troubles trying to start two asynchronous tasks.

I want to start two Async Tasks but the second will not start until the first has completed.
From what I've googled, people usually suggest this approach:
new MyAsyncTask().execute(params);
new MyAsyncTask().execute(params);
However, I need to instantiate them separately and also keep the handles of the task's (to pass messages for example). Therefore, I SORT OF do this:
onStart()
{
taskA = new MyAsyncTask(paramsA);
taskB = new MyAsyncTask(paramsB);
}
onButtonPress()
{
taskA.execute();
taskB.execute();
}
Edit:
I've noticed that taskB does not actually start executing until taskA completes (which runs a tcp/ip server so it takes a long time). I cannot figure out why. Any thoughts or comments ?
The short answer is that, depending on your version of Android, all AsyncTask subclasses may be using the same thread, so you can only do one at a time. There are two ways around this:
Use Runnable instead of AsyncTask
Replace one call to execute with executeOnExecutor(Executor.THREAD_POOL_EXECUTOR, params)
Clearly, try #2 first - it's less of a code change. But if that doesn't work pretty quickly, I'd switch to #1. In that case, you don't have to worry about how Android might change in the future.
If you want more details about the threading model for AsyncTask, have a look at the Android doc entry.

Program structure regarding NSTask

I want to run an unknown amount (unknown at compile time) of NSTasks and I want to run an unknown amount (again, at compile time, max. 8) of them simultaneously. So basically I loop through a list of files, generate an NSTask, run it until the maximum of simultaneous tasks are ran and whenever one finishes another NSTask starts until all of them are done.
My approach would be creating a class that generates an NSTask and subclass it to change parameters here and there when there's a different input (changes that are made from the interface). Then the superclass will run the NSTask and will have an #synthesize method returning its progress. Those objects will be generated in the above repeat loop and the progress will be displayed.
Is this a good way to go? If so, can someone give me a quick example of how the repeat loop would look like? I don't know how I would reference to all objects once they're run.
for (; !done ;) {
if (maxValue ≥ currentValue) {
//Run Object with next file.
//Set currentValue.
}
//display progress and set done to YES if needed and set currentValue to it -1 if needed
}
Thanks in advance.
There's no loop exactly.
Create an array for tasks not yet started, another with tasks that are running, and another with tasks that have finished. Have a method that pulls one task from the pending-tasks array, starts (launches) it, and adds it to the running-tasks array. After creating the arrays and filling out the pending-tasks array, call that method eight times.
When a task finishes, remove the task from the running-tasks array and add it to the finished-tasks array, then check whether there are any tasks yet to run. If there's at least one, call the run-another-one method again. Otherwise, check whether there are any still running: If not, all tasks have finished, and you can assemble the results now (if you haven't been displaying them live).

Resources