Compare commits

...

20 Commits

Author SHA1 Message Date
brian.mulier
811af5c5a1 WIP 2025-12-22 12:10:41 +01:00
brian.mulier
1b73ddd097 WIP 2025-12-22 12:10:41 +01:00
brian.mulier
9803ecc6d0 fix(core): close FlowListeners properly 2025-12-22 12:10:41 +01:00
brian.mulier
b4871fcb15 fix(tests): remove test UncaughtExceptionHandler 2025-12-22 12:10:41 +01:00
Piyush Bhaskar
f352be5746 fix(core): fix edit btn of custom blueprint (#13789) 2025-12-22 16:22:58 +05:30
Lee KyeongJoon
5fc6d0b5d7 fix(ui): vertically center the search field placeholder (#13677) 2025-12-22 15:01:14 +05:30
Miloš Paunović
de5750f656 docs(core): improve the pull request template (#13787)
Related to https://github.com/kestra-io/kestra/pull/12975.
2025-12-22 09:54:16 +01:00
ben8t
fa870b8df2 chore(core): make the system color theme the default one (#13602)
Closes https://github.com/kestra-io/kestra/issues/13601.
2025-12-22 09:32:31 +01:00
Ritik Verma
fa4bf64a23 refactor(core): remove usage of unnecessary i18n composable (#13738)
Closes https://github.com/kestra-io/kestra/issues/13653.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-22 09:29:38 +01:00
Arshdeep Singh
27f81b5b6d refactor(core): remove usage of unnecessary i18n composable (#13781)
Closes https://github.com/kestra-io/kestra/issues/13257.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-22 09:27:25 +01:00
Nguyen Duc Anh
90d322cd67 refactor(core): remove usage of unnecessary i18n composable (#13784)
Closes https://github.com/kestra-io/kestra/issues/13638.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-12-22 09:25:25 +01:00
brian-mulier-p
04246ace13 fix(core): @Hidden properties were shown in JSON Schema (#13753) 2025-12-19 19:39:37 +01:00
Roman Acevedo
e0e745cb91 Revert "fix(api): add netty-codec-multipart-vintage"
This reverts commit 44d0c10713.
2025-12-19 15:26:15 +01:00
Roman Acevedo
c69ecd7200 Revert "chore(deps): upgrade Micronaut to 4.10.5"
This reverts commit 167734e32a.
2025-12-19 15:26:15 +01:00
Florian Hussonnois
4b3419bc15 fix(executions): query ExecutionDelay to UTC to avoid any offset error
Related-to: kestra-io/kestra-ee#6143
2025-12-19 14:56:07 +01:00
Florian Hussonnois
352d4eb194 chore(test): use MicronautTest when possible 2025-12-19 14:45:27 +01:00
Piyush Bhaskar
e433833e62 fix(core): prevent default namespace from being applied to filters without namespace key (#13767) 2025-12-19 14:25:13 +01:00
Georg Traar
d16a8de90f fix(ui): use lightning bolt for execute button in flow run modal (#13762) 2025-12-19 13:50:22 +01:00
Nicolas K.
4784e459d6 feat(CLI): add a new update from flow source CLI (#13760)
* feat(CLI): add a new update from flow source CLI

* feat(CLI): use the repository instead of the webserver

* feat(CLI): change command name to SyncFromSource

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-12-19 09:55:07 +01:00
Roman Acevedo
2abea0fcde feat(blueprints): use regular Inputs in Blueprint Templates
this handles SELECT input type in template
2025-12-18 19:46:40 +01:00
107 changed files with 476 additions and 399 deletions

View File

@@ -12,7 +12,7 @@ _Example: Replaces legacy scroll directive with the new API._
### 🔗 Related Issue
Which issue does this PR resolve? Use [GitHub Keywords](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests#linking-a-pull-request-to-an-issue) to automatically link the pull request to the issue.
_Example: Closes https://github.com/kestra-io/kestra/issues/12345._
_Example: Closes https://github.com/kestra-io/kestra/issues/ISSUE_NUMBER._
### 🎨 Frontend Checklist

View File

@@ -42,7 +42,7 @@ import picocli.CommandLine.Option;
@Introspected
public abstract class AbstractCommand implements Callable<Integer> {
@Inject
private ApplicationContext applicationContext;
protected ApplicationContext applicationContext;
@Inject
private EndpointDefaultConfiguration endpointConfiguration;

View File

@@ -18,7 +18,8 @@ import picocli.CommandLine;
FlowDotCommand.class,
FlowExportCommand.class,
FlowUpdateCommand.class,
FlowUpdatesCommand.class
FlowUpdatesCommand.class,
FlowsSyncFromSourceCommand.class
}
)
@Slf4j

View File

@@ -0,0 +1,55 @@
package io.kestra.cli.commands.flows;
import io.kestra.cli.AbstractApiCommand;
import io.kestra.cli.services.TenantIdSelectorService;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.flows.GenericFlow;
import io.kestra.core.repositories.FlowRepositoryInterface;
import jakarta.inject.Inject;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
@CommandLine.Command(
name = "syncFromSource",
description = "Update a single flow",
mixinStandardHelpOptions = true
)
@Slf4j
public class FlowsSyncFromSourceCommand extends AbstractApiCommand {
@Inject
private TenantIdSelectorService tenantService;
@SuppressWarnings("deprecation")
@Override
public Integer call() throws Exception {
super.call();
FlowRepositoryInterface repository = applicationContext.getBean(FlowRepositoryInterface.class);
String tenant = tenantService.getTenantId(tenantId);
List<FlowWithSource> persistedFlows = repository.findAllWithSource(tenant);
int count = 0;
for (FlowWithSource persistedFlow : persistedFlows) {
// Ensure exactly one trailing newline. We need this new line
// because when we update a flow from its source,
// we don't update it if no change is detected.
// The goal here is to force an update from the source for every flows
GenericFlow flow = GenericFlow.fromYaml(tenant,persistedFlow.getSource() + System.lineSeparator());
repository.update(flow, persistedFlow);
stdOut("- %s.%s".formatted(flow.getNamespace(), flow.getId()));
count++;
}
stdOut("%s flow(s) successfully updated!".formatted(count));
return 0;
}
protected boolean loadExternalPlugins() {
return true;
}
}

View File

@@ -0,0 +1,73 @@
package io.kestra.cli.commands.flows;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import io.micronaut.runtime.server.EmbeddedServer;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.List;
import org.junit.jupiter.api.Test;
class FlowsSyncFromSourceCommandTest {
@Test
void updateAllFlowsFromSource() {
URL directory = FlowUpdatesCommandTest.class.getClassLoader().getResource("flows");
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
EmbeddedServer embeddedServer = ctx.getBean(EmbeddedServer.class);
embeddedServer.start();
String[] args = {
"--plugins",
"/tmp", // pass this arg because it can cause failure
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word",
"--delete",
directory.getPath(),
};
PicocliRunner.call(FlowUpdatesCommand.class, ctx, args);
assertThat(out.toString()).contains("successfully updated !");
out.reset();
FlowRepositoryInterface repository = ctx.getBean(FlowRepositoryInterface.class);
List<Flow> flows = repository.findAll(MAIN_TENANT);
for (Flow flow : flows) {
assertThat(flow.getRevision()).isEqualTo(1);
}
args = new String[]{
"--plugins",
"/tmp", // pass this arg because it can cause failure
"--server",
embeddedServer.getURL().toString(),
"--user",
"myuser:pass:word"
};
PicocliRunner.call(FlowsSyncFromSourceCommand.class, ctx, args);
assertThat(out.toString()).contains("4 flow(s) successfully updated!");
assertThat(out.toString()).contains("- io.kestra.outsider.quattro");
assertThat(out.toString()).contains("- io.kestra.cli.second");
assertThat(out.toString()).contains("- io.kestra.cli.third");
assertThat(out.toString()).contains("- io.kestra.cli.first");
flows = repository.findAll(MAIN_TENANT);
for (Flow flow : flows) {
assertThat(flow.getRevision()).isEqualTo(2);
}
}
}
}

View File

@@ -24,6 +24,9 @@ dependencies {
// reactor
api "io.projectreactor:reactor-core"
// awaitility
api 'org.awaitility:awaitility'
// micronaut
api "io.micronaut.data:micronaut-data-model"
implementation "io.micronaut:micronaut-http-server-netty"

View File

@@ -42,13 +42,12 @@ import io.kestra.core.plugins.PluginRegistry;
import io.kestra.core.plugins.RegisteredPlugin;
import io.kestra.core.serializers.JacksonMapper;
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.*;
import java.time.*;
@@ -299,7 +298,9 @@ public class JsonSchemaGenerator {
}
// default value
builder.forFields().withDefaultResolver(this::defaults);
builder.forFields()
.withIgnoreCheck(fieldScope -> fieldScope.getAnnotation(Hidden.class) != null)
.withDefaultResolver(this::defaults);
// def name
builder.forTypesInGeneral()
@@ -809,9 +810,9 @@ public class JsonSchemaGenerator {
// we don't return base properties unless specified with @PluginProperty and hidden is false
builder
.forFields()
.withIgnoreCheck(fieldScope -> base != null &&
.withIgnoreCheck(fieldScope -> (base != null &&
(fieldScope.getAnnotation(PluginProperty.class) == null || fieldScope.getAnnotation(PluginProperty.class).hidden()) &&
fieldScope.getDeclaringType().getTypeName().equals(base.getName())
fieldScope.getDeclaringType().getTypeName().equals(base.getName())) || fieldScope.getAnnotation(Hidden.class) != null
);
SchemaGeneratorConfig schemaGeneratorConfig = builder.build();

View File

@@ -5,6 +5,8 @@ import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.models.flows.FlowWithException;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.services.PluginDefaultService;
import io.micronaut.context.annotation.Bean;
import jakarta.annotation.PreDestroy;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import io.kestra.core.queues.QueueFactoryInterface;
@@ -15,7 +17,6 @@ import io.kestra.core.services.FlowListenersInterface;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -26,15 +27,14 @@ import jakarta.inject.Singleton;
@Singleton
@Slf4j
public class FlowListeners implements FlowListenersInterface {
private final AtomicBoolean isStarted = new AtomicBoolean(false);
private final QueueInterface<FlowInterface> flowQueue;
private final List<FlowWithSource> flows;
private final List<Consumer<List<FlowWithSource>>> consumers = new ArrayList<>();
private final List<BiConsumer<FlowWithSource, FlowWithSource>> consumersEach = new ArrayList<>();
private final PluginDefaultService pluginDefaultService;
private Runnable queueListenerCancellation;
@Inject
public FlowListeners(
FlowRepositoryInterface flowRepository,
@@ -49,8 +49,9 @@ public class FlowListeners implements FlowListenersInterface {
@Override
public void run() {
synchronized (this) {
if (this.isStarted.compareAndSet(false, true)) {
this.flowQueue.receive(either -> {
if (queueListenerCancellation == null) {
log.info("STARTING FLOW LISTENER: {}", this);
queueListenerCancellation = this.flowQueue.receive(either -> {
FlowWithSource flow;
if (either.isRight()) {
flow = FlowWithException.from(either.getRight().getRecord(), either.getRight(), log).orElse(null);
@@ -154,4 +155,18 @@ public class FlowListeners implements FlowListenersInterface {
// we forced a deep clone to avoid concurrency where instance are changed during iteration (especially scheduler).
return new ArrayList<>(this.flows);
}
@PreDestroy
@Override
public void close() throws Exception {
synchronized (this) {
boolean b = queueListenerCancellation != null;
log.info("THREAD STACKTRACE: {}", (Object) Thread.currentThread().getStackTrace());
log.info("LISTENER NOT NULL : {}", b);
log.info("LISTENER THIS : {}", this);
if (b) {
queueListenerCancellation.run();
}
}
}
}

View File

@@ -6,7 +6,7 @@ import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public interface FlowListenersInterface {
public interface FlowListenersInterface extends AutoCloseable {
void run();
void listen(Consumer<List<FlowWithSource>> consumer);

View File

@@ -70,4 +70,12 @@ public class ListUtils {
.map(Object::toString)
.toList();
}
public static <T> List<List<T>> partition(List<T> list, int size) {
List<List<T>> parts = new ArrayList<>();
for (int i = 0; i < list.size(); i += size) {
parts.add(list.subList(i, Math.min(i + size, list.size())));
}
return parts;
}
}

View File

@@ -11,21 +11,17 @@ public final class ThreadUncaughtExceptionHandler implements UncaughtExceptionHa
@Override
public void uncaughtException(Thread t, Throwable e) {
boolean isTest = KestraContext.getContext().getEnvironments().contains("test");
try {
// cannot use FormattingLogger due to a dependency loop
log.error("Caught an exception in {}. {}", t, isTest ? "Keeping it running for test." : "Shutting down.", e);
log.error("Caught an exception in {}. Shutting down.", t, e);
} catch (Throwable errorInLogging) {
// If logging fails, e.g. due to missing memory, at least try to log the
// message and the cause for the failed logging.
System.err.println(e.getMessage());
System.err.println(errorInLogging.getMessage());
} finally {
if (!isTest) {
KestraContext.getContext().shutdown();
Runtime.getRuntime().exit(1);
}
KestraContext.getContext().shutdown();
Runtime.getRuntime().exit(1);
}
}
}

View File

@@ -1,16 +1,14 @@
package io.kestra.core.contexts;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import java.util.Map;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class KestraContextTest {
@Inject

View File

@@ -1,8 +1,7 @@
package io.kestra.core.contexts;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -10,7 +9,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest(environments = "maven")
@MicronautTest(environments = "maven")
class MavenPluginRepositoryConfigTest {
@Inject

View File

@@ -10,7 +10,7 @@ import io.kestra.plugin.core.debug.Return;
import io.kestra.plugin.core.flow.Dag;
import io.kestra.plugin.core.flow.Subflow;
import io.kestra.plugin.core.state.Set;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.parallel.ExecutionMode;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
@Execution(ExecutionMode.SAME_THREAD)
class DocumentationGeneratorTest {
@Inject

View File

@@ -2,6 +2,7 @@ package io.kestra.core.models;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.validations.ModelValidator;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
@@ -12,7 +13,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class LabelTest {
@Inject
private ModelValidator modelValidator;

View File

@@ -5,26 +5,21 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.kestra.core.context.TestRunContextFactory;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.serializers.FileSerde;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.NamespaceFile;
import io.kestra.core.storages.StorageInterface;
import io.kestra.plugin.core.namespace.Version;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.junit.jupiter.api.Test;
import org.slf4j.event.Level;
import reactor.core.publisher.Flux;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -37,7 +32,7 @@ import static java.util.Map.entry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class PropertyTest {
@Inject

View File

@@ -1,12 +1,11 @@
package io.kestra.core.models.property;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.*;
import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.NamespaceFactory;
import io.kestra.core.storages.StorageContext;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@@ -28,7 +27,7 @@ import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class URIFetcherTest {
@Inject
private StorageInterface storage;

View File

@@ -1,9 +1,8 @@
package io.kestra.core.models.triggers;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.runners.RunContextFactory;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -17,7 +16,7 @@ import static io.kestra.core.models.triggers.StatefulTriggerService.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@KestraTest
@MicronautTest
class StatefulTriggerInterfaceTest {
@Inject
RunContextFactory runContextFactory;

View File

@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.property.Property;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.Test;
import io.kestra.plugin.core.condition.ExecutionFlow;
@@ -23,7 +24,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest(transactional = false)
public abstract class AbstractMultipleConditionStorageTest {
private static final String NAMESPACE = "io.kestra.unit";

View File

@@ -1,17 +1,15 @@
package io.kestra.core.plugins;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class PluginConfigurationTest {
@Inject

View File

@@ -1,7 +1,7 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.reporter.Reportable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -11,7 +11,7 @@ import java.time.ZoneId;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractFeatureUsageReportTest {
@Inject

View File

@@ -1,6 +1,5 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.collectors.ServiceUsage;
import io.kestra.core.reporter.Reportable;
import io.kestra.core.repositories.ServiceInstanceRepositoryInterface;
@@ -8,6 +7,7 @@ import io.kestra.core.server.Service;
import io.kestra.core.server.ServiceInstance;
import io.kestra.core.server.ServiceType;
import io.kestra.core.utils.IdUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -20,7 +20,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
@KestraTest
@MicronautTest
public abstract class AbstractServiceUsageReportTest {
@Inject

View File

@@ -1,10 +1,10 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.metrics.MetricRegistry;
import io.kestra.plugin.core.http.Trigger;
import io.kestra.plugin.core.log.Log;
import io.kestra.plugin.core.trigger.Schedule;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -13,7 +13,7 @@ import java.time.Instant;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class PluginMetricReportTest {
@Inject

View File

@@ -1,9 +1,9 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.Setting;
import io.kestra.core.repositories.SettingRepositoryInterface;
import io.micronaut.test.annotation.MockBean;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.ConstraintViolationException;
@@ -16,7 +16,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class SystemInformationReportTest {
@Inject

View File

@@ -4,7 +4,6 @@ import com.devskiller.friendly_id.FriendlyId;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.exceptions.InvalidQueryFiltersException;
import io.kestra.core.junit.annotations.FlakyTest;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.Label;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.QueryFilter.Field;
@@ -33,6 +32,7 @@ import io.micronaut.data.model.Pageable;
import io.micronaut.data.model.Sort;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -58,7 +58,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@KestraTest
@MicronautTest
public abstract class AbstractExecutionRepositoryTest {
public static final String NAMESPACE = "io.kestra.unittest";
public static final String FLOW = "full";

View File

@@ -10,7 +10,7 @@ import io.kestra.core.runners.RunContextFactory;
import io.kestra.core.services.ExecutionService;
import io.kestra.plugin.core.debug.Return;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.slf4j.event.Level;
@@ -28,7 +28,7 @@ import java.util.Objects;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractExecutionServiceTest {
@Inject
ExecutionService executionService;

View File

@@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableMap;
import io.kestra.core.events.CrudEvent;
import io.kestra.core.events.CrudEventType;
import io.kestra.core.exceptions.InvalidQueryFiltersException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.Label;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.QueryFilter.Field;
@@ -26,6 +25,7 @@ import io.kestra.core.utils.TestsUtils;
import io.kestra.plugin.core.debug.Return;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.data.model.Pageable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.ConstraintViolationException;
@@ -49,7 +49,7 @@ import static io.kestra.core.utils.NamespaceUtils.SYSTEM_FLOWS_DEFAULT_NAMESPACE
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
@KestraTest
@MicronautTest(transactional = false)
public abstract class AbstractFlowRepositoryTest {
public static final String TEST_NAMESPACE = "io.kestra.unittest";
public static final String TEST_FLOW_ID = "test";

View File

@@ -3,8 +3,8 @@ package io.kestra.core.repositories;
import io.kestra.core.models.topologies.FlowNode;
import io.kestra.core.models.topologies.FlowRelation;
import io.kestra.core.models.topologies.FlowTopology;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -12,7 +12,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractFlowTopologyRepositoryTest {
@Inject
private FlowTopologyRepositoryInterface flowTopologyRepository;

View File

@@ -4,8 +4,8 @@ import io.kestra.core.models.FetchVersion;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.kv.PersistedKvMetadata;
import io.kestra.core.utils.TestsUtils;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.data.model.Pageable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -18,7 +18,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractKvMetadataRepositoryTest {
@Inject
protected KvMetadataRepositoryInterface kvMetadataRepositoryInterface;

View File

@@ -1,7 +1,6 @@
package io.kestra.core.repositories;
import io.kestra.core.exceptions.InvalidQueryFiltersException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.QueryFilter.Field;
import io.kestra.core.models.QueryFilter.Op;
@@ -14,9 +13,9 @@ import io.kestra.core.models.flows.State;
import io.kestra.core.repositories.ExecutionRepositoryInterface.ChildFilter;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.kestra.plugin.core.dashboard.data.Executions;
import io.kestra.plugin.core.dashboard.data.Logs;
import io.micronaut.data.model.Pageable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -37,7 +36,7 @@ import static io.kestra.core.models.flows.FlowScope.USER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest(transactional = false)
public abstract class AbstractLogRepositoryTest {
@Inject
protected LogRepositoryInterface logRepository;

View File

@@ -10,10 +10,9 @@ import io.kestra.core.models.executions.metrics.MetricAggregations;
import io.kestra.core.models.executions.metrics.Timer;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.data.model.Pageable;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.slf4j.event.Level;
import java.time.Duration;
import java.time.ZonedDateTime;
@@ -21,7 +20,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractMetricRepositoryTest {
@Inject
protected MetricRepositoryInterface metricRepository;

View File

@@ -1,11 +1,11 @@
package io.kestra.core.repositories;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.FetchVersion;
import io.kestra.core.models.QueryFilter;
import io.kestra.core.models.namespaces.files.NamespaceFileMetadata;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.data.model.Pageable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -21,7 +21,7 @@ import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest(transactional = false)
public abstract class AbstractNamespaceFileMetadataRepositoryTest {
@Inject
protected NamespaceFileMetadataRepositoryInterface namespaceFileMetadataRepositoryInterface;

View File

@@ -2,8 +2,8 @@ package io.kestra.core.repositories;
import io.kestra.core.models.Setting;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.utils.VersionProvider;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -12,7 +12,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractSettingRepositoryTest {
@Inject
protected SettingRepositoryInterface settingRepository;

View File

@@ -10,7 +10,7 @@ import io.kestra.plugin.core.debug.Return;
import io.kestra.core.utils.IdUtils;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.data.model.Pageable;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import java.time.Duration;
@@ -21,7 +21,6 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -30,7 +29,7 @@ import org.slf4j.LoggerFactory;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public abstract class AbstractTemplateRepositoryTest {
@Inject
protected TemplateRepositoryInterface templateRepository;

View File

@@ -12,6 +12,7 @@ import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.data.model.Pageable;
import io.micronaut.data.model.Sort;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -28,7 +29,7 @@ import static io.kestra.core.models.flows.FlowScope.USER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest(transactional = false)
public abstract class AbstractTriggerRepositoryTest {
private static final String TEST_NAMESPACE = "io.kestra.unittest";

View File

@@ -22,6 +22,7 @@ import io.micronaut.http.MediaType;
import io.micronaut.http.multipart.CompletedFileUpload;
import io.micronaut.http.multipart.CompletedPart;
import io.micronaut.test.annotation.MockBean;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Assertions;
@@ -42,7 +43,7 @@ import java.util.Optional;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class FlowInputOutputTest {
private static final String TEST_SECRET_VALUE = "test-secret-value";

View File

@@ -1,25 +1,25 @@
package io.kestra.core.runners;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.flows.GenericFlow;
import io.kestra.core.models.property.Property;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.utils.Await;
import io.kestra.core.utils.TestsUtils;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeoutException;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.services.FlowListenersInterface;
import io.kestra.plugin.core.debug.Return;
import io.kestra.core.utils.Await;
import io.kestra.core.utils.IdUtils;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import io.kestra.core.utils.TestsUtils;
import io.kestra.plugin.core.debug.Return;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@@ -27,6 +27,9 @@ abstract public class FlowListenersTest {
@Inject
protected FlowRepositoryInterface flowRepository;
@Inject
protected FlowListenersInterface flowListenersService;
protected static FlowWithSource create(String tenantId, String flowId, String taskId) {
FlowWithSource flow = FlowWithSource.builder()
.id(flowId)
@@ -44,60 +47,56 @@ abstract public class FlowListenersTest {
private static final Logger LOG = LoggerFactory.getLogger(FlowListenersTest.class);
public void suite(FlowListenersInterface flowListenersService) throws TimeoutException {
String tenant = TestsUtils.randomTenant(this.getClass().getSimpleName());
flowListenersService.run();
@Test
public void all() throws Exception {
FlowListenersInterface finalFlowListenersService = flowListenersService;
try (finalFlowListenersService) {
finalFlowListenersService.run();
String tenant = TestsUtils.randomTenant(this.getClass().getSimpleName());
AtomicInteger count = new AtomicInteger();
AtomicInteger count = new AtomicInteger();
flowListenersService.listen(flows -> count.set(getFlowsForTenant(flowListenersService, tenant).size()));
flowListenersService.listen(flows -> count.set(getFlowsForTenant(flowListenersService, tenant).size()));
// initial state
LOG.info("-----------> wait for zero");
Await.until(() -> count.get() == 0, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isZero();
// resend on startup done for kafka
LOG.info("-----------> wait for zero kafka");
if (flowListenersService.getClass().getName().equals("io.kestra.ee.runner.kafka.KafkaFlowListeners")) {
// initial state
LOG.info("-----------> wait for zero");
Await.until(() -> count.get() == 0, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isZero();
// create first
LOG.info("-----------> create first flow");
FlowWithSource first = create(tenant, "first_" + IdUtils.create(), "test");
FlowWithSource firstUpdated = create(tenant, first.getId(), "test2");
flowRepository.create(GenericFlow.of(first));
Await.until(() -> "Expected to have 1 flow but got " + count.get(), () -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
// create the same id than first, no additional flows
first = flowRepository.update(GenericFlow.of(firstUpdated), first);
Await.until(() -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
FlowWithSource second = create(tenant, "second_" + IdUtils.create(), "test");
// create a new one
flowRepository.create(GenericFlow.of(second));
Await.until(() -> count.get() == 2, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(2);
// delete first
FlowWithSource deleted = flowRepository.delete(first);
Await.until(() -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
// restore must works
flowRepository.create(GenericFlow.of(first));
Await.until(() -> count.get() == 2, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(2);
}
// create first
LOG.info("-----------> create fist flow");
FlowWithSource first = create(tenant, "first_" + IdUtils.create(), "test");
FlowWithSource firstUpdated = create(tenant, first.getId(), "test2");
flowRepository.create(GenericFlow.of(first));
Await.until(() -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
// create the same id than first, no additional flows
first = flowRepository.update(GenericFlow.of(firstUpdated), first);
Await.until(() -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
FlowWithSource second = create(tenant, "second_" + IdUtils.create(), "test");
// create a new one
flowRepository.create(GenericFlow.of(second));
Await.until(() -> count.get() == 2, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(2);
// delete first
FlowWithSource deleted = flowRepository.delete(first);
Await.until(() -> count.get() == 1, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(1);
// restore must works
flowRepository.create(GenericFlow.of(first));
Await.until(() -> count.get() == 2, Duration.ofMillis(10), Duration.ofSeconds(5));
assertThat(getFlowsForTenant(flowListenersService, tenant).size()).isEqualTo(2);
}
public List<FlowWithSource> getFlowsForTenant(FlowListenersInterface flowListenersService, String tenantId){
public List<FlowWithSource> getFlowsForTenant(FlowListenersInterface flowListenersService, String tenantId) {
return flowListenersService.flows().stream()
.filter(f -> tenantId.equals(f.getTenantId()))
.toList();

View File

@@ -1,6 +1,5 @@
package io.kestra.core.runners;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.flows.DependsOn;
import io.kestra.core.models.flows.Flow;
@@ -24,6 +23,7 @@ import io.kestra.core.utils.IdUtils;
import io.micrometer.core.instrument.MeterRegistry;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.annotation.MockBean;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Assertions;
@@ -36,7 +36,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class RunVariablesTest {
@Inject

View File

@@ -1,8 +1,8 @@
package io.kestra.core.runners;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -14,7 +14,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class VariableRendererTest {
@Inject

View File

@@ -6,7 +6,7 @@ import com.google.common.collect.ImmutableSet;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.utils.Rethrow;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import java.time.ZonedDateTime;
@@ -18,7 +18,7 @@ import jakarta.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class PebbleVariableRendererTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -6,7 +6,7 @@ import com.google.common.collect.ImmutableSet;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.context.annotation.Property;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -15,7 +15,7 @@ import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
@Property(name = "kestra.variables.recursive-rendering", value = "true")
class RecursivePebbleVariableRendererTest {
@Inject

View File

@@ -3,7 +3,7 @@ package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.context.annotation.Value;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -13,7 +13,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class EncryptDecryptFunctionTest {
@Inject
private VariableRenderer variableRenderer;

View File

@@ -1,11 +1,11 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.executions.LogEntry;
import io.kestra.core.repositories.LogRepositoryInterface;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@@ -18,7 +18,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
@Property(name = "kestra.server-type", value = "WORKER")
@Execution(ExecutionMode.SAME_THREAD)
class ErrorLogsFunctionTest {

View File

@@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -13,7 +13,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class FetchContextFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -1,16 +1,15 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.LocalPath;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.NamespaceFactory;
import io.kestra.core.storages.StorageContext;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -30,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
@Execution(ExecutionMode.SAME_THREAD)
@KestraTest(rebuildContext = true)
@MicronautTest(rebuildContext = true)
class FileExistsFunctionTest {
private static final String NAMESPACE = "my.namespace";

View File

@@ -1,16 +1,15 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.LocalPath;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.NamespaceFactory;
import io.kestra.core.storages.StorageContext;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -27,10 +26,9 @@ import org.junit.jupiter.api.parallel.ExecutionMode;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.validator.internal.util.Contracts.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest(rebuildContext = true)
@MicronautTest(rebuildContext = true)
@Execution(ExecutionMode.SAME_THREAD)
public class FileSizeFunctionTest {
private static final String FLOW = "flow";

View File

@@ -5,14 +5,14 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import jakarta.inject.Inject;
@KestraTest
@MicronautTest
class FileURIFunctionTest {
@Inject
private VariableRenderer variableRenderer;

View File

@@ -2,11 +2,11 @@ package io.kestra.core.runners.pebble.functions;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.serializers.FileSerde;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class FromIonFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -2,7 +2,7 @@ package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import java.util.Map;
@@ -11,7 +11,7 @@ import jakarta.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
class FromJsonFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -6,8 +6,8 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.serializers.JacksonMapper;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import io.pebbletemplates.pebble.error.PebbleException;
import jakarta.inject.Inject;
import org.apache.hc.client5.http.utils.Base64;
@@ -25,7 +25,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThrows;
@KestraTest
@MicronautTest
@WireMockTest(httpPort = 28182)
@Execution(ExecutionMode.SAME_THREAD)
class HttpFunctionTest {

View File

@@ -3,13 +3,13 @@ package io.kestra.core.runners.pebble.functions;
import static org.assertj.core.api.Assertions.assertThat;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@KestraTest
@MicronautTest
class IDFunctionTest {
@Inject VariableRenderer variableRenderer;

View File

@@ -1,7 +1,6 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.LocalPath;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.storages.Namespace;
@@ -9,6 +8,7 @@ import io.kestra.core.storages.NamespaceFactory;
import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -27,7 +27,7 @@ import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
@KestraTest(rebuildContext = true)
@MicronautTest(rebuildContext = true)
@Execution(ExecutionMode.SAME_THREAD)
class IsFileEmptyFunctionTest {

View File

@@ -3,14 +3,14 @@ package io.kestra.core.runners.pebble.functions;
import static org.assertj.core.api.Assertions.assertThat;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import java.util.Collections;
import java.util.regex.Pattern;
import org.junit.jupiter.api.Test;
@KestraTest
@MicronautTest
class KSUIDFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -1,7 +1,7 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -10,7 +10,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public class NanoIDFuntionTest {
@Inject

View File

@@ -4,14 +4,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
@KestraTest
@MicronautTest
class RandomIntFunctionTest {
@Inject VariableRenderer variableRenderer;

View File

@@ -1,8 +1,8 @@
package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -10,7 +10,7 @@ import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class RandomPortFunctionTest {
@Inject VariableRenderer variableRenderer;

View File

@@ -10,8 +10,7 @@ import io.kestra.core.storages.StorageInterface;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.micronaut.context.annotation.Property;
import io.kestra.core.junit.annotations.KestraTest;
import io.pebbletemplates.pebble.error.PebbleException;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -34,7 +33,7 @@ import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest(rebuildContext = true)
@MicronautTest(rebuildContext = true)
@Property(name="kestra.server-type", value="WORKER")
@Execution(ExecutionMode.SAME_THREAD)
class ReadFileFunctionTest {

View File

@@ -2,7 +2,7 @@ package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -11,7 +11,7 @@ import java.time.*;
import java.util.HashMap;
import java.util.Map;
@KestraTest
@MicronautTest
class RenderFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -2,14 +2,14 @@ package io.kestra.core.runners.pebble.functions;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Map;
@KestraTest
@MicronautTest
class RenderOncerFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -3,13 +3,13 @@ package io.kestra.core.runners.pebble.functions;
import static org.assertj.core.api.Assertions.assertThat;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.runners.VariableRenderer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@KestraTest
@MicronautTest
class UUIDFunctionTest {
@Inject VariableRenderer variableRenderer;

View File

@@ -3,13 +3,13 @@ package io.kestra.core.runners.pebble.functions;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class YamlFunctionTest {
@Inject
VariableRenderer variableRenderer;

View File

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.jupiter.api.Test;
@@ -14,7 +15,7 @@ import jakarta.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class ObjectMapperFactoryTest {
@Inject
ObjectMapper objectMapper;

View File

@@ -1,7 +1,6 @@
package io.kestra.core.storages;
import io.kestra.core.exceptions.ResourceExpiredException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.repositories.KvMetadataRepositoryInterface;
import io.kestra.core.serializers.JacksonMapper;
import io.kestra.core.storages.kv.InternalKVStore;
@@ -12,6 +11,7 @@ import io.kestra.core.storages.kv.KVValueAndMetadata;
import io.kestra.core.storages.kv.KVValue;
import io.kestra.core.tenant.TenantService;
import io.kestra.core.utils.IdUtils;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;
import static org.junit.jupiter.api.Assertions.assertTrue;
@KestraTest
@MicronautTest
class InternalKVStoreTest {
private static final Instant date = Instant.now().truncatedTo(ChronoUnit.MILLIS);
private static final Map<String, Object> complexValue = Map.of("some", "complex", "object", Map.of("with", "nested", "values", date));

View File

@@ -1,14 +1,11 @@
package io.kestra.core.storages;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.repositories.NamespaceFileMetadataRepositoryInterface;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.PathMatcherPredicate;
import io.kestra.core.utils.TestsUtils;
import io.kestra.storage.local.LocalStorage;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,14 +14,13 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class InternalNamespaceTest {
private static final Logger logger = LoggerFactory.getLogger(InternalNamespaceTest.class);
@@ -34,9 +30,6 @@ class InternalNamespaceTest {
@Inject
private NamespaceFileMetadataRepositoryInterface namespaceFileMetadataRepository;
@Inject
private NamespaceFactory namespaceFactory;
@Test
void shouldGetAllNamespaceFiles() throws IOException, URISyntaxException {

View File

@@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import io.kestra.core.exceptions.KestraRuntimeException;
import io.kestra.storage.local.LocalStorage;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Assertions;
@@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
@KestraTest
@MicronautTest
class StorageInterfaceFactoryTest {
@Inject

View File

@@ -3,8 +3,7 @@ package io.kestra.core.tasks;
import io.kestra.core.context.TestRunContextFactory;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.tasks.runners.PluginUtilsService;
import io.kestra.core.runners.RunContextFactory;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -18,7 +17,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
@MicronautTest
public class PluginUtilsServiceTest {
@Inject
private TestRunContextFactory runContextFactory;

View File

@@ -44,6 +44,6 @@ public class SleepTrigger extends AbstractTrigger implements PollingTriggerInter
@Override
public Duration getInterval() {
return null;
return Duration.ofSeconds(1);
}
}

View File

@@ -1,12 +1,12 @@
package io.kestra.core.tenant;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class TenantServiceTest {
@Inject
private TenantService tenantService;

View File

@@ -1,10 +1,10 @@
package io.kestra.core.test;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContextFactory;
import io.kestra.core.test.flow.Assertion;
import io.kestra.core.test.flow.AssertionResult;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -15,7 +15,7 @@ import static io.kestra.core.test.flow.Assertion.Operator.EQUAL_TO;
import static io.kestra.core.test.flow.Assertion.Operator.IS_NOT_NULL;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class AssertionTest {
@Inject

View File

@@ -14,7 +14,7 @@ import io.kestra.plugin.core.debug.Return;
import io.kestra.plugin.core.flow.Parallel;
import io.kestra.plugin.core.flow.Subflow;
import io.kestra.core.utils.TestsUtils;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@@ -27,7 +27,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class FlowTopologyServiceTest {
@Inject

View File

@@ -1,18 +1,15 @@
package io.kestra.core.topologies;
import io.kestra.core.exceptions.FlowProcessingException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.topologies.FlowNode;
import io.kestra.core.models.topologies.FlowTopology;
import io.kestra.core.models.topologies.FlowTopologyGraph;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.repositories.FlowTopologyRepositoryInterface;
import io.kestra.core.services.FlowService;
import io.kestra.core.utils.IdUtils;
import io.kestra.plugin.core.execution.AssertTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.validation.constraints.AssertTrue;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
@@ -20,7 +17,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
public class FlowTopologyTest {
@Inject
private FlowService flowService;

View File

@@ -12,6 +12,7 @@ import io.kestra.core.storages.Namespace;
import io.kestra.core.storages.NamespaceFactory;
import io.kestra.core.storages.StorageInterface;
import io.kestra.plugin.core.log.Log;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.junit.jupiter.api.Test;
@@ -31,7 +32,7 @@ import java.util.stream.Collectors;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
@Execution(ExecutionMode.SAME_THREAD)
class NamespaceFilesUtilsTest {
@Inject

View File

@@ -1,7 +1,7 @@
package io.kestra.core.utils;
import com.google.common.collect.ImmutableMap;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.flows.Flow;
@@ -10,7 +10,7 @@ import jakarta.inject.Inject;
import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
@MicronautTest
class UriProviderTest {
@Inject
UriProvider uriProvider;

View File

@@ -1,32 +1,6 @@
package io.kestra.runner.h2;
import io.kestra.core.models.flows.FlowInterface;
import io.kestra.core.queues.QueueFactoryInterface;
import io.kestra.core.queues.QueueInterface;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.runners.FlowListeners;
import io.kestra.core.runners.FlowListenersTest;
import io.kestra.core.services.PluginDefaultService;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Test;
class H2FlowListenersTest extends FlowListenersTest {
@Inject
FlowRepositoryInterface flowRepository;
@Inject
@Named(QueueFactoryInterface.FLOW_NAMED)
QueueInterface<FlowInterface> flowQueue;
@Inject
PluginDefaultService pluginDefaultService;
@Test
public void all() throws TimeoutException {
// we don't inject FlowListeners to remove a flaky test
this.suite(new FlowListeners(flowRepository, flowQueue, pluginDefaultService));
}
}
}

View File

@@ -1,9 +1,9 @@
package reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.reporter.reports.AbstractFeatureUsageReportTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class H2FeatureUsageReportTest extends AbstractFeatureUsageReportTest {
}

View File

@@ -1,9 +1,9 @@
package reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.reporter.reports.AbstractServiceUsageReportTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class H2ServiceUsageReportTest extends AbstractServiceUsageReportTest {
}

View File

@@ -1,17 +1,6 @@
package io.kestra.runner.mysql;
import io.kestra.core.runners.FlowListeners;
import io.kestra.core.runners.FlowListenersTest;
import jakarta.inject.Inject;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Test;
class MysqlFlowListenersTest extends FlowListenersTest {
@Inject
FlowListeners flowListenersService;
@Test
public void all() throws TimeoutException {
this.suite(flowListenersService);
}
}
}

View File

@@ -1,17 +1,6 @@
package io.kestra.schedulers.mysql;
import io.kestra.core.runners.FlowListeners;
import io.kestra.jdbc.runner.JdbcScheduler;
import io.kestra.scheduler.AbstractScheduler;
import io.kestra.scheduler.SchedulerExecutionStateInterface;
import io.kestra.scheduler.SchedulerScheduleTest;
class MysqlSchedulerScheduleTest extends SchedulerScheduleTest {
@Override
protected AbstractScheduler scheduler(FlowListeners flowListenersServiceSpy, SchedulerExecutionStateInterface executionStateSpy) {
return new JdbcScheduler(
applicationContext,
flowListenersServiceSpy
);
}
}

View File

@@ -1,9 +1,9 @@
package reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.reporter.reports.AbstractFeatureUsageReportTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class MysqlFeatureUsageReportTest extends AbstractFeatureUsageReportTest {
}

View File

@@ -1,9 +1,9 @@
package reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.reporter.reports.AbstractServiceUsageReportTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class MysqlServiceUsageReportTest extends AbstractServiceUsageReportTest {
}

View File

@@ -1,8 +1,8 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class PostgresFeatureUsageReportTest extends AbstractFeatureUsageReportTest {
}

View File

@@ -1,8 +1,8 @@
package io.kestra.core.reporter.reports;
import io.kestra.core.junit.annotations.KestraTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
@KestraTest
@MicronautTest
class PostgresServiceUsageReportTest extends AbstractServiceUsageReportTest {
}

View File

@@ -1,17 +1,6 @@
package io.kestra.runner.postgres;
import io.kestra.core.runners.FlowListeners;
import io.kestra.core.runners.FlowListenersTest;
import jakarta.inject.Inject;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Test;
class PostgresFlowListenersTest extends FlowListenersTest {
@Inject
FlowListeners flowListenersService;
@Test
public void all() throws TimeoutException {
this.suite(flowListenersService);
}
}
}

View File

@@ -1,17 +1,6 @@
package io.kestra.schedulers.postgres;
import io.kestra.core.runners.FlowListeners;
import io.kestra.jdbc.runner.JdbcScheduler;
import io.kestra.scheduler.AbstractScheduler;
import io.kestra.scheduler.SchedulerExecutionStateInterface;
import io.kestra.scheduler.SchedulerScheduleTest;
class PostgresSchedulerScheduleTest extends SchedulerScheduleTest {
@Override
protected AbstractScheduler scheduler(FlowListeners flowListenersServiceSpy, SchedulerExecutionStateInterface executionStateSpy) {
return new JdbcScheduler(
applicationContext,
flowListenersServiceSpy
);
}
}

View File

@@ -7,6 +7,8 @@ import org.jooq.Record1;
import org.jooq.SelectConditionStep;
import org.jooq.impl.DSL;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.function.Consumer;
@@ -20,6 +22,9 @@ public abstract class AbstractJdbcExecutionDelayStorage extends AbstractJdbcRepo
public void get(Consumer<ExecutionDelay> consumer) {
ZonedDateTime now = ZonedDateTime.now();
// 'date' column in the table is in UTC
// convert 'now' to UTC LocalDateTime to avoid any timezone/offset interpretation by the database.
LocalDateTime localDateTimeNow = now.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
this.jdbcRepository
.getDslContextWrapper()
@@ -28,9 +33,7 @@ public abstract class AbstractJdbcExecutionDelayStorage extends AbstractJdbcRepo
.using(configuration)
.select(AbstractJdbcRepository.field("value"))
.from(this.jdbcRepository.getTable())
.where(
AbstractJdbcRepository.field("date").lessOrEqual(now.toOffsetDateTime())
)
.where(AbstractJdbcRepository.field("date").lessOrEqual(localDateTimeNow))
.forUpdate()
.skipLocked();

View File

@@ -1056,7 +1056,9 @@ public class JdbcExecutor implements ExecutorInterface {
log.error("Unable to kill the execution {}", killedExecution.getExecutionId(), e);
}
log.error("KILLING FROM EXECUTOR");
Executor executor = killingOrAfterKillState(killedExecution.getExecutionId(), Optional.ofNullable(killedExecution.getExecutionState()));
log.error("KILLED FROM EXECUTOR");
// Check whether kill event should be propagated to downstream executions.
// By default, always propagate the ExecutionKill to sub-flows (for backward compatibility).
@@ -1083,20 +1085,24 @@ public class JdbcExecutor implements ExecutorInterface {
}
private Executor killingOrAfterKillState(final String executionId, Optional<State.Type> afterKillState) {
return executionRepository.lock(executionId, pair -> {
Execution currentExecution = pair.getLeft();
FlowInterface flow = flowMetaStore.findByExecution(currentExecution).orElseThrow();
try {
return executionRepository.lock(executionId, pair -> {
Execution currentExecution = pair.getLeft();
FlowInterface flow = flowMetaStore.findByExecution(currentExecution).orElseThrow();
// remove it from the queued store if it was queued so it would not be restarted
if (currentExecution.getState().isQueued()) {
executionQueuedStorage.remove(currentExecution);
}
// remove it from the queued store if it was queued so it would not be restarted
if (currentExecution.getState().isQueued()) {
executionQueuedStorage.remove(currentExecution);
}
Execution killing = executionService.kill(currentExecution, flow, afterKillState);
Executor current = new Executor(currentExecution, null)
.withExecution(killing, "joinKillingExecution");
return Pair.of(current, pair.getRight());
});
Execution killing = executionService.kill(currentExecution, flow, afterKillState);
Executor current = new Executor(currentExecution, null)
.withExecution(killing, "joinKillingExecution");
return Pair.of(current, pair.getRight());
});
} catch (Exception e) {
throw new RuntimeException("ISSUE WHILE KILLING EXECUTION " + executionId, e);
}
}
private void toExecution(Executor executor) {

View File

@@ -23,6 +23,7 @@ import io.micronaut.context.annotation.Value;
import io.micronaut.transaction.exceptions.CannotCreateTransactionException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.awaitility.Awaitility;
import org.jooq.*;
import org.jooq.Record;
import org.jooq.exception.DataException;
@@ -301,20 +302,27 @@ public abstract class JdbcQueue<T> implements QueueInterface<T> {
Timer timer = this.metricRegistry
.timer(MetricRegistry.METRIC_QUEUE_RECEIVE_DURATION, MetricRegistry.METRIC_QUEUE_RECEIVE_DURATION_DESCRIPTION, tags);
StackTraceElement[] parentStackTrace = Thread.currentThread().getStackTrace();
return this.poll(() -> timer.record(() -> {
Result<Record> fetch = dslContextWrapper.transactionResult(configuration -> {
DSLContext ctx = DSL.using(configuration);
Result<Record> fetch;
try {
fetch = dslContextWrapper.transactionResult(configuration -> {
DSLContext ctx = DSL.using(configuration);
Result<Record> result = this.receiveFetch(ctx, consumerGroup, maxOffset.get(), forUpdate);
Result<Record> result = this.receiveFetch(ctx, consumerGroup, maxOffset.get(), forUpdate);
if (!result.isEmpty()) {
List<Integer> offsets = result.map(record -> record.get("offset", Integer.class));
if (!result.isEmpty()) {
List<Integer> offsets = result.map(record -> record.get("offset", Integer.class));
maxOffset.set(offsets.getLast());
}
maxOffset.set(offsets.getLast());
}
return result;
});
return result;
});
} catch (Exception e) {
log.error("Error while receiving messages from JDBC queue. Thread stacktrace: {}", parentStackTrace, e);
throw e;
}
this.send(fetch, consumer);
@@ -426,13 +434,14 @@ public abstract class JdbcQueue<T> implements QueueInterface<T> {
@SuppressWarnings("BusyWait")
protected Runnable poll(Supplier<Integer> runnable) {
AtomicBoolean queriedToStop = new AtomicBoolean(false);
AtomicBoolean running = new AtomicBoolean(true);
poolExecutor.execute(() -> {
List<Configuration.Step> steps = configuration.computeSteps();
Duration sleep = configuration.minPollInterval;
ZonedDateTime lastPoll = ZonedDateTime.now();
while (running.get() && !this.isClosed.get()) {
while (!queriedToStop.get() && !this.isClosed.get()) {
if (!this.isPaused.get()) {
try {
Integer count = runnable.get();
@@ -471,9 +480,21 @@ public abstract class JdbcQueue<T> implements QueueInterface<T> {
throw new RuntimeException(e);
}
}
running.set(false);
});
return () -> running.set(false);
return () -> {
queriedToStop.set(true);
try {
Awaitility.await()
.atMost(Duration.ofSeconds(30))
.pollInterval(Duration.ofMillis(10))
.until(() -> !running.get());
} catch (Exception e) {
log.warn("Error while stopping polling", e);
}
};
}
protected List<Either<T, DeserializationException>> map(Result<Record> fetch) {

View File

@@ -19,6 +19,7 @@ import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
@@ -59,7 +60,7 @@ public class JdbcScheduler extends AbstractScheduler {
});
// No-op consumption of the trigger queue, so the events are purged from the queue
this.triggerQueue.receive(Scheduler.class, trigger -> { });
this.receiveCancellations.add(this.triggerQueue.receive(Scheduler.class, trigger -> { }));
}
@Override

View File

@@ -30,7 +30,7 @@ dependencies {
// as Jackson is in the Micronaut BOM, to force its version we need to use enforcedPlatform but it didn't really work, see later :(
api enforcedPlatform("com.fasterxml.jackson:jackson-bom:$jacksonVersion")
api enforcedPlatform("org.slf4j:slf4j-api:$slf4jVersion")
api platform("io.micronaut.platform:micronaut-platform:4.10.5")
api platform("io.micronaut.platform:micronaut-platform:4.9.4")
api platform("io.qameta.allure:allure-bom:2.32.0")
// we define cloud bom here for GCP, Azure and AWS so they are aligned for all plugins that use them (secret, storage, oss and ee plugins)
api platform('com.google.cloud:libraries-bom:26.73.0')
@@ -38,8 +38,6 @@ dependencies {
api platform('software.amazon.awssdk:bom:2.40.10')
api platform("dev.langchain4j:langchain4j-bom:$langchain4jVersion")
api platform("dev.langchain4j:langchain4j-community-bom:$langchain4jCommunityVersion")
// Micronaut 4.10 brings a Jetty version no compatible with the one from Wiremock so we bump it here
api platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.1.2")
constraints {
// downgrade to proto 1.3.2-alpha as 1.5.0 needs protobuf 4

View File

@@ -25,6 +25,7 @@ import io.kestra.core.runners.FlowListeners;
import io.kestra.core.utils.Await;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.SneakyThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@@ -85,11 +86,18 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
.truncatedTo(ChronoUnit.HOURS);
}
protected AbstractScheduler scheduler(FlowListeners flowListenersServiceSpy, SchedulerExecutionStateInterface executionStateSpy) {
protected AbstractScheduler scheduler(FlowListeners flowListenersServiceSpy) {
return new JdbcScheduler(
applicationContext,
flowListenersServiceSpy
);
) {
@SneakyThrows
@Override
public void close() {
super.close();
flowListenersServiceSpy.close();
}
};
}
@BeforeEach
@@ -139,7 +147,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
triggerState.create(trigger.toBuilder().triggerId("schedule-invalid").flowId(invalid.getId()).build());
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionStateSpy)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receiveExecutions = TestsUtils.receive(executionQueue, throwConsumer(either -> {
Execution execution = either.getLeft();
@@ -200,7 +208,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
triggerState.create(trigger);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
scheduler.run();
Await.until(() -> {
@@ -235,7 +243,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(1);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, either -> {
Execution execution = either.getLeft();
@@ -281,7 +289,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(1);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, either -> {
Execution execution = either.getLeft();
@@ -326,7 +334,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
triggerState.create(lastTrigger);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
scheduler.run();
Await.until(() -> scheduler.isReady(), Duration.ofMillis(100), Duration.ofSeconds(5));
@@ -358,7 +366,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
.build();
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
scheduler.run();
Await.until(() -> {
@@ -422,7 +430,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
triggerState.create(trigger);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
scheduler.run();
// Wait 3s to see if things happen
@@ -462,7 +470,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(2);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, throwConsumer(either -> {
Execution execution = either.getLeft();
@@ -522,7 +530,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(1);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, either -> {
Execution execution = either.getLeft();
@@ -635,7 +643,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(1);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, throwConsumer(either -> {
Execution execution = either.getLeft();
@@ -708,7 +716,7 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
CountDownLatch queueCount = new CountDownLatch(1);
// scheduler
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy, executionState)) {
try (AbstractScheduler scheduler = scheduler(flowListenersServiceSpy)) {
// wait for execution
Flux<Execution> receive = TestsUtils.receive(executionQueue, throwConsumer(either -> {
Execution execution = either.getLeft();
@@ -741,4 +749,4 @@ public class SchedulerScheduleTest extends AbstractSchedulerTest {
Await.until(() -> this.triggerState.findLast(trigger).map(t -> t.getNextExecutionDate().isAfter(lastTrigger.getNextExecutionDate().plusSeconds(10))).orElse(false).booleanValue(), Duration.ofMillis(100), Duration.ofSeconds(20));
}
}
}
}

View File

@@ -128,9 +128,9 @@ $placeholder-font-size: 12px;
font-size: $input-font-size;
background-color: transparent;
width: 100%;
padding-inline: 0.5em;
padding-block: 0.7em;
border: none;
display: flex;
align-items: center;
&:focus {
outline: none;
@@ -139,6 +139,7 @@ $placeholder-font-size: 12px;
&::placeholder {
color: $placeholder-color;
font-size: $placeholder-font-size;
line-height: 1;
}
&:not(:placeholder-shown)~.reset {

View File

@@ -4,7 +4,7 @@ import {useMiscStore} from "override/stores/misc";
import {defaultNamespace} from "../../../composables/useNamespaces";
interface DefaultFilterOptions {
namespace?: string;
namespace?: string | null;
includeTimeRange?: boolean;
includeScope?: boolean;
legacyQuery?: boolean;
@@ -29,7 +29,8 @@ export function applyDefaultFilters(
const query = {...currentQuery};
let change = false;
if (namespace === undefined && defaultNamespace() && !hasFilterKey(query, NAMESPACE_FILTER_PREFIX)) {
if (namespace !== null && defaultNamespace() && !hasFilterKey(query, NAMESPACE_FILTER_PREFIX)) {
query[legacyQuery ? "namespace" : `${NAMESPACE_FILTER_PREFIX}[PREFIX]`] = defaultNamespace();
change = true;
}

View File

@@ -399,6 +399,7 @@ export function useFilters(
const {resetDefaultFilter} = useDefaultFilter({
legacyQuery,
namespace: configuration.keys?.some((k) => k.key === "namespace") ? undefined : null,
includeScope: defaultScope ?? configuration.keys?.some((k) => k.key === "scope"),
includeTimeRange: defaultTimeRange ?? configuration.keys?.some((k) => k.key === "timeRange"),
});

View File

@@ -80,7 +80,7 @@
<script setup>
import ContentCopy from "vue-material-design-icons/ContentCopy.vue";
import Flash from "vue-material-design-icons/Flash.vue";
import LightningBolt from "vue-material-design-icons/LightningBolt.vue";
</script>
<script>
@@ -111,7 +111,7 @@
replaySubmit: {type: Function, default: null},
selectedTrigger: {type: Object, default: undefined},
buttonText: {type: String, default: "launch execution"},
buttonIcon: {type: [Object, Function], default: () => Flash},
buttonIcon: {type: [Object, Function], default: () => LightningBolt},
buttonTestId: {type: String, default: "execute-dialog-button"},
},
data() {

View File

@@ -13,18 +13,16 @@
@on-edit="(event) => emit('on-edit', event, true)"
/>
<el-alert v-else type="warning" :closable="false">
{{ t("unable to generate graph") }}
{{ $t("unable to generate graph") }}
</el-alert>
</div>
</el-card>
</template>
<script setup lang="ts">
import {onBeforeUnmount} from "vue";
import {useI18n} from "vue-i18n";
import {useFlowStore} from "../../stores/flow";
import LowCodeEditor from "../inputs/LowCodeEditor.vue";
const {t} = useI18n();
defineProps<{
isReadOnly?: boolean;
expandedSubflows?: any[];

View File

@@ -7,7 +7,7 @@
<template #label>
<div class="type-div">
<span class="asterisk">*</span>
<code>{{ t("type") }}</code>
<code>{{ $t("type") }}</code>
</div>
</template>
<PluginSelect
@@ -32,7 +32,6 @@
<script setup lang="ts">
import {computed, inject, onActivated, provide, ref, toRaw, watch} from "vue";
import {useI18n} from "vue-i18n";
import * as YAML_UTILS from "@kestra-io/ui-libs/flow-yaml-utils";
import TaskObject from "./tasks/TaskObject.vue";
import PluginSelect from "../../plugins/PluginSelect.vue";
@@ -53,8 +52,6 @@
import isEqual from "lodash/isEqual";
import {useMiscStore} from "../../../override/stores/misc";
const {t} = useI18n();
defineOptions({
name: "TaskEditor",
inheritAttrs: false,

View File

@@ -355,7 +355,7 @@
autoRefreshInterval: 10
},
defaultPreferences: {
theme: "light",
theme: "syncWithSystem",
logsFontSize: 12,
editorFontFamily: "'Source Code Pro', monospace",
editorFontSize: 12,

View File

@@ -66,7 +66,7 @@
<TaskIcon v-for="task in [...new Set(blueprint.includedTasks)]" :key="task" :cls="task" :icons="pluginsStore.icons" />
</div>
<div class="action-button">
<div class="d-flex align-items-center gap-2">
<el-tooltip v-if="embed && !system" trigger="click" content="Copied" placement="left" :autoClose="2000" effect="light">
<el-button
type="primary"

View File

@@ -6,20 +6,20 @@
<Action
v-if="tab === 'flows'"
:label="t('create_flow')"
:label="$t('create_flow')"
:to="{name: 'flows/create', query: {namespace}}"
/>
<Action
v-if="tab === 'kv'"
:label="t('kv.inherited')"
:label="$t('kv.inherited')"
:icon="FamilyTree"
@click="namespacesStore.inheritedKVModalVisible = true"
/>
<Action
v-if="tab === 'kv'"
:label="t('kv.add')"
:label="$t('kv.add')"
@click="namespacesStore.addKvModalVisible = true"
/>
</template>
@@ -27,7 +27,6 @@
<script setup lang="ts">
import {computed, Ref} from "vue";
import {useRoute, useRouter} from "vue-router";
import {useI18n} from "vue-i18n";
import {useNamespacesStore} from "override/stores/namespaces";
import Action from "../../../components/namespaces/components/buttons/Action.vue";
import Dashboards from "../../../components/dashboard/components/selector/Selector.vue";
@@ -36,7 +35,6 @@
const route = useRoute();
const router = useRouter();
const {t} = useI18n({useScope: "global"});
const namespacesStore = useNamespacesStore();
const onSelectDashboard = (value: any) => {

View File

@@ -7,6 +7,7 @@ import {apiUrl} from "override/utils/route";
import {useMiscStore} from "override/stores/misc";
import {trackBlueprintSelection} from "../utils/tabTracking";
import {Input} from "./flow.ts";
export type BlueprintType = "community" | "custom";
type BlueprintKind = "flow" | "dashboard" | "app";
@@ -24,18 +25,9 @@ interface Blueprint {
[key: string]: any;
}
export interface TemplateArgument {
id: string,
displayName: string,
type: string,
itemType?: string,
required: boolean,
defaults?: any
}
export interface BlueprintTemplate {
source: string;
templateArguments: Record<string, TemplateArgument>;
templateArguments: Record<string, Input>;
}
export interface FlowBlueprint {

Some files were not shown because too many files have changed in this diff Show More