Repository: apache/camel-k
Pull request #2992 (2022-02-07 12:53:00)

Enhance Http proxy test about the OLM
<!-- Description -->




<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
NONE
```


bouskaJ: @astefanutti can you take a look at this? WDYT?
astefanutti: @bouskaJ I think that's a very good idea 👍🏼.
bouskaJ: @astefanutti do you know what's wrong with the `upgrade` test? Can you rerun/merge this?

```
Run ./.github/actions/kamel-build-bundle/build-index-image.sh \
time="2022-02-07T14:26:10Z" level=warning msg="--skip-tls flag is set: this mode is insecure and meant for development purposes only."
time="2022-02-07T14:26:10Z" level=info msg="building the index" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
time="2022-02-07T14:26:10Z" level=info msg="Pulling previous image quay.io/operatorhubio/catalog:latest to get metadata" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
time="2022-02-07T14:26:10Z" level=info msg="running /usr/bin/docker pull quay.io/operatorhubio/catalog:latest" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
time="2022-02-07T14:26:14Z" level=info msg="running /usr/bin/docker pull quay.io/operatorhubio/catalog:latest" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
time="2022-02-07T14:26:14Z" level=info msg="Getting label data from previous image" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
time="2022-02-07T14:26:14Z" level=info msg="running docker inspect" bundles="[kind-registry:5000/apache/camel-k-bundle:1.9.0-SNAPSHOT]"
Error: index image quay.io/operatorhubio/catalog:latest missing label operators.operatorframework.io.index.database.v1
Usage:
  opm index add [flags]

Examples:

```
astefanutti: @bouskaJ please see #2972 for more details about the current OLM upgrade tests failure.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28cf398f8..39f4bf1ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,12 @@
 
 **Closed issues:**
 
+- IntegrationKit creation based on YAML file fails [\#3033](https://github.com/apache/camel-k/issues/3033)
+- Expose Camel-related metrics \(Prometheus\) [\#3027](https://github.com/apache/camel-k/issues/3027)
 - Helm multiple namespace install Camel-K [\#2985](https://github.com/apache/camel-k/issues/2985)
+- \[E2E\] Test error handler appears to be flaky [\#2744](https://github.com/apache/camel-k/issues/2744)
 - Documentation for `kamel local run` [\#2490](https://github.com/apache/camel-k/issues/2490)
+- Support for POJO, bring it back!  [\#1821](https://github.com/apache/camel-k/issues/1821)
 
 **Merged pull requests:**
 
diff --git a/docs/modules/ROOT/pages/running/local.adoc b/docs/modules/ROOT/pages/running/local.adoc
index ad702220a..0cc1ea34a 100644
--- a/docs/modules/ROOT/pages/running/local.adoc
+++ b/docs/modules/ROOT/pages/running/local.adoc
@@ -169,4 +169,4 @@ $ kamel local run --integration-directory <dir-name> --containerize --network=ho
 [[running-locally-limitations]]
 == Limitations
 
-* Since there is no platform to leverage, traits are not usable for `kamel local` commands. Right now, if you specify any traits in the xref:cli/modeline.adoc[modeline] an integration will not run locally throwing an error.
+* Since there is no platform to leverage, traits are not usable for `kamel local` commands. If you specify any traits in the xref:cli/modeline.adoc[modeline], they are simply ignored; The commands show a warning and run an integration locally without traits.
diff --git a/pkg/cmd/local.go b/pkg/cmd/local.go
index 2cc0cbbab..cac6e51d5 100644
--- a/pkg/cmd/local.go
+++ b/pkg/cmd/local.go
@@ -18,6 +18,8 @@ limitations under the License.
 package cmd
 
 import (
+	"fmt"
+
 	"github.com/spf13/cobra"
 )
 
@@ -38,3 +40,9 @@ func newCmdLocal(rootCmdOptions *RootCmdOptions) *cobra.Command {
 
 	return &cmd
 }
+
+func warnTraitUsages(cmd *cobra.Command, traits []string) {
+	if len(traits) > 0 {
+		fmt.Fprintf(cmd.OutOrStdout(), "Warning: traits are specified but don't take effect for local run: %v\n", traits)
+	}
+}
diff --git a/pkg/cmd/local_build.go b/pkg/cmd/local_build.go
index a7593d10a..e2b0322ec 100644
--- a/pkg/cmd/local_build.go
+++ b/pkg/cmd/local_build.go
@@ -37,7 +37,7 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localBui
 		Long:    `Build integration images locally for containerized integrations.`,
 		PreRunE: decode(&options),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := options.validate(args); err != nil {
+			if err := options.validate(cmd, args); err != nil {
 				return err
 			}
 			if err := options.init(args); err != nil {
@@ -67,6 +67,12 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localBui
 	cmd.Flags().StringArrayP("dependency", "d", nil, "Add an additional dependency")
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
+	// hidden flags for compatibility with kamel run
+	cmd.Flags().StringArrayP("trait", "t", nil, "")
+	if err := cmd.Flags().MarkHidden("trait"); err != nil {
+		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
+	}
+
 	return &cmd, &options
 }
 
@@ -81,9 +87,10 @@ type localBuildCmdOptions struct {
 	Properties             []string `mapstructure:"properties"`
 	PropertyFiles          []string `mapstructure:"property-files"`
 	MavenRepositories      []string `mapstructure:"maven-repositories"`
+	Traits                 []string `mapstructure:"traits"`
 }
 
-func (command *localBuildCmdOptions) validate(args []string) error {
+func (command *localBuildCmdOptions) validate(cmd *cobra.Command, args []string) error {
 	// Validate integration files.
 	if len(args) > 0 {
 		err := validateIntegrationFiles(args)
@@ -129,6 +136,8 @@ func (command *localBuildCmdOptions) validate(args []string) error {
 		return errors.New("to output dependencies the integration directory flag must be set")
 	}
 
+	warnTraitUsages(cmd, command.Traits)
+
 	return nil
 }
 
diff --git a/pkg/cmd/local_inspect.go b/pkg/cmd/local_inspect.go
index 525e592ac..a5e1919be 100644
--- a/pkg/cmd/local_inspect.go
+++ b/pkg/cmd/local_inspect.go
@@ -35,8 +35,8 @@ func newCmdLocalInspect(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localI
 top level dependencies only. When --all-dependencies is enabled, the transitive dependencies
 will be generated by calling Maven and then printed in the selected output format.`,
 		PreRunE: decode(&options),
-		RunE: func(_ *cobra.Command, args []string) error {
-			if err := options.validate(args); err != nil {
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if err := options.validate(cmd, args); err != nil {
 				return err
 			}
 			if err := options.init(); err != nil {
@@ -61,6 +61,12 @@ will be generated by calling Maven and then printed in the selected output forma
 	cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
+	// hidden flags for compatibility with kamel run
+	cmd.Flags().StringArrayP("trait", "t", nil, "")
+	if err := cmd.Flags().MarkHidden("trait"); err != nil {
+		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
+	}
+
 	return &cmd, &options
 }
 
@@ -70,9 +76,10 @@ type localInspectCmdOptions struct {
 	OutputFormat           string   `mapstructure:"output"`
 	AdditionalDependencies []string `mapstructure:"dependencies"`
 	MavenRepositories      []string `mapstructure:"maven-repositories"`
+	Traits                 []string `mapstructure:"traits"`
 }
 
-func (command *localInspectCmdOptions) validate(args []string) error {
+func (command *localInspectCmdOptions) validate(cmd *cobra.Command, args []string) error {
 	err := validateIntegrationFiles(args)
 	if err != nil {
 		return err
@@ -83,6 +90,8 @@ func (command *localInspectCmdOptions) validate(args []string) error {
 		return err
 	}
 
+	warnTraitUsages(cmd, command.Traits)
+
 	return nil
 }
 
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index cf1095649..fd6c8db9b 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -37,7 +37,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 		Long:    `Run integration locally using the input integration files.`,
 		PreRunE: decode(&options),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := options.validate(args); err != nil {
+			if err := options.validate(cmd, args); err != nil {
 				return err
 			}
 			if err := options.init(); err != nil {
@@ -67,6 +67,12 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 	cmd.Flags().StringArrayP("dependency", "d", nil, additionalDependencyUsageMessage)
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
+	// hidden flags for compatibility with kamel run
+	cmd.Flags().StringArrayP("trait", "t", nil, "")
+	if err := cmd.Flags().MarkHidden("trait"); err != nil {
+		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
+	}
+
 	return &cmd, &options
 }
 
@@ -81,9 +87,10 @@ type localRunCmdOptions struct {
 	Properties             []string `mapstructure:"properties"`
 	AdditionalDependencies []string `mapstructure:"dependencies"`
 	MavenRepositories      []string `mapstructure:"maven-repositories"`
+	Traits                 []string `mapstructure:"traits"`
 }
 
-func (command *localRunCmdOptions) validate(args []string) error {
+func (command *localRunCmdOptions) validate(cmd *cobra.Command, args []string) error {
 	// Validate integration files when no image is provided and we are
 	// not running an already locally-built integration.
 	if command.Image == "" && command.IntegrationDirectory == "" {
@@ -110,6 +117,8 @@ func (command *localRunCmdOptions) validate(args []string) error {
 		return errors.New("containerization is active but no image name has been provided")
 	}
 
+	warnTraitUsages(cmd, command.Traits)
+
 	return nil
 }
 


Test patch:
diff --git a/e2e/common/build/maven_http_proxy_test.go b/e2e/common/build/maven_http_proxy_test.go
index 4197672e2..81b8099ed 100644
--- a/e2e/common/build/maven_http_proxy_test.go
+++ b/e2e/common/build/maven_http_proxy_test.go
@@ -29,8 +29,11 @@ import (
 	"crypto/x509/pkix"
 	"encoding/pem"
 	"fmt"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/olm"
 	"math/big"
 	rand2 "math/rand"
+	"reflect"
 	"strings"
 	"testing"
 	"time"
@@ -38,6 +41,7 @@ import (
 	. "github.com/onsi/gomega"
 	. "github.com/onsi/gomega/gstruct"
 
+	configv1 "github.com/openshift/api/config/v1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -141,13 +145,37 @@ func TestMavenProxy(t *testing.T) {
 		noProxy = append(noProxy, svc.Spec.ClusterIPs...)
 
 		// Install Camel K with the HTTP proxy
-		Expect(Kamel("install", "-n", ns,
-			"--operator-env-vars", fmt.Sprintf("HTTP_PROXY=http://%s", hostname),
-			// TODO: enable TLS for the HTTPS proxy when Maven supports it
-			// "--operator-env-vars", fmt.Sprintf("HTTPS_PROXY=https://%s", hostname),
-			// "--maven-ca-secret", secret.Name+"/"+corev1.TLSCertKey,
-			"--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","),
-		).Execute()).To(Succeed())
+		olm, olmErr := olm.IsAPIAvailable(TestContext, TestClient(), ns)
+		installed, inErr := kubernetes.IsAPIResourceInstalled(TestClient(), configv1.GroupVersion.String(), reflect.TypeOf(configv1.Proxy{}).Name())
+		permission, pErr := kubernetes.CheckPermission(TestContext, TestClient(), configv1.GroupName, reflect.TypeOf(configv1.Proxy{}).Name(), "", "cluster", "edit")
+		olmInstall := pErr == nil && olmErr == nil && inErr == nil && olm && installed && permission
+		var defaultProxy configv1.Proxy
+		if olmInstall  {
+			// use OLM autoconfiguration
+			defaultProxy = configv1.Proxy{}
+			key := ctrl.ObjectKey{
+				Name:      "cluster",
+			}
+			Expect(TestClient().Get(TestContext, key, &defaultProxy)).To(Succeed())
+
+			newProxy := defaultProxy.DeepCopy()
+			newProxy.Spec.HTTPProxy = fmt.Sprintf("http://%s", hostname)
+			newProxy.Spec.NoProxy = strings.Join(noProxy, ",")
+			Expect(TestClient().Update(TestContext, newProxy))
+
+			// ENV values should be injected by the OLM
+			Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+
+
+		} else {
+			Expect(Kamel("install", "-n", ns,
+				"--operator-env-vars", fmt.Sprintf("HTTP_PROXY=http://%s", hostname),
+				// TODO: enable TLS for the HTTPS proxy when Maven supports it
+				// "--operator-env-vars", fmt.Sprintf("HTTPS_PROXY=https://%s", hostname),
+				// "--maven-ca-secret", secret.Name+"/"+corev1.TLSCertKey,
+				"--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","),
+			).Execute()).To(Succeed())
+		}
 
 		Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
 
@@ -182,6 +210,10 @@ func TestMavenProxy(t *testing.T) {
 		Expect(TestClient().Delete(TestContext, service)).To(Succeed())
 		Expect(TestClient().Delete(TestContext, secret)).To(Succeed())
 		Expect(TestClient().Delete(TestContext, config)).To(Succeed())
+
+		if olmInstall {
+			TestClient().Update(TestContext, &defaultProxy)
+		}
 	})
 }
 
diff --git a/e2e/common/cli/install_test.go b/e2e/common/cli/install_test.go
index 8d99b789f..bfe1bae53 100644
--- a/e2e/common/cli/install_test.go
+++ b/e2e/common/cli/install_test.go
@@ -23,7 +23,17 @@ limitations under the License.
 package common
 
 import (
+	"bytes"
+	"github.com/apache/camel-k/pkg/install"
+	"github.com/apache/camel-k/pkg/util/defaults"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/openshift"
+	console "github.com/openshift/api/console/v1"
+	"github.com/stretchr/testify/assert"
+	"reflect"
+	"strings"
 	"testing"
+	"text/template"
 
 	. "github.com/onsi/gomega"
 
@@ -77,6 +87,59 @@ func TestSkipRegistryInstallation(t *testing.T) {
 	})
 }
 
+type templateArgs struct {
+	Version  string
+	Platform string
+}
+
+func TestConsoleCliDownload(t *testing.T) {
+	ocp, err := openshift.IsOpenShift(TestClient())
+	assert.Nil(t, err)
+
+	ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name())
+	assert.Nil(t, err)
+
+	if !ocp || !ok {
+		t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4 only.")
+		return
+	}
+
+	name := GetEnvOrDefault("CAMEL_K_CONSOLE_CLI_DOWNLOAD_NAME", install.KamelCLIDownloadName)
+	downloadUrlTemplate := GetEnvOrDefault("CAMEL_K_CONSOLE_CLI_DOWNLOAD_URL_TEMPLATE", "https://github.com/apache/camel-k/releases/download/v{{ .Version}}/camel-k-client-{{ .Version}}-{{ .Platform}}-64bit.tar.gz")
+
+	args := templateArgs{Version: defaults.Version}
+	templt, err := template.New("downloadLink").Parse(downloadUrlTemplate)
+	assert.Nil(t, err)
+
+	WithNewTestNamespace(t, func(ns string) {
+		// make sure there is no preinstalled CliDownload resource
+		cliDownload := ConsoleCLIDownload(name)()
+		if cliDownload != nil {
+			Expect(TestClient().Delete(TestContext, cliDownload)).To(Succeed())
+		}
+
+		Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+		Eventually(ConsoleCLIDownload(name), TestTimeoutMedium).Should(Not(BeNil()))
+
+		cliDownload = ConsoleCLIDownload(name)()
+		links := cliDownload.Spec.Links
+
+		for _, link := range links {
+			var buf bytes.Buffer
+			if strings.Contains(link.Text, "for Linux") {
+				args.Platform = "linux"
+			} else if strings.Contains(link.Text, "for Mac") {
+				args.Platform = "mac"
+			} else if strings.Contains(link.Text, "for Windows") {
+				args.Platform = "windows"
+			}
+
+			templt.Execute(&buf, args)
+			Expect(link.Href).To(MatchRegexp(buf.String()))
+		}
+	})
+}
+
 func TestInstallSkipDefaultKameletsInstallation(t *testing.T) {
 	WithNewTestNamespace(t, func(ns string) {
 		Expect(Kamel("install", "-n", ns, "--skip-default-kamelets-setup").Execute()).To(Succeed())
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 4c856b163..96495250e 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -28,6 +28,8 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	consoleV1 "github.com/openshift/api/console/v1"
+	"github.com/stretchr/testify/assert"
 	"io"
 	"io/ioutil"
 	"os"
@@ -42,8 +44,6 @@ import (
 	"github.com/onsi/gomega/format"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"github.com/stretchr/testify/assert"
-
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/api/batch/v1beta1"
 	coordination "k8s.io/api/coordination/v1"
@@ -1223,6 +1223,18 @@ func CRDs() func() []metav1.APIResource {
 	}
 }
 
+func ConsoleCLIDownload(name string) func() *consoleV1.ConsoleCLIDownload {
+	return func() *consoleV1.ConsoleCLIDownload {
+		cliDownload := consoleV1.ConsoleCLIDownload{}
+		if err := TestClient().Get(TestContext, ctrl.ObjectKey{Name: name}, &cliDownload); err != nil && !k8serrors.IsNotFound(err) {
+			panic(err)
+		} else if err != nil && k8serrors.IsNotFound(err) {
+			return nil
+		}
+		return &cliDownload
+	}
+}
+
 func OperatorPod(ns string) func() *corev1.Pod {
 	return func() *corev1.Pod {
 		lst := corev1.PodList{
diff --git a/e2e/support/test_util.go b/e2e/support/test_util.go
index d95599cdb..2b8cc3189 100644
--- a/e2e/support/test_util.go
+++ b/e2e/support/test_util.go
@@ -25,6 +25,7 @@ package support
 import (
 	. "github.com/onsi/gomega"
 	. "github.com/onsi/gomega/gstruct"
+	"os"
 
 	"github.com/onsi/gomega/types"
 )
@@ -36,3 +37,12 @@ func EqualP(expected interface{}) types.GomegaMatcher {
 func MatchFieldsP(options Options, fields Fields) types.GomegaMatcher {
 	return PointTo(MatchFields(options, fields))
 }
+
+func GetEnvOrDefault(key string, deflt string) string {
+	env, exists := os.LookupEnv(key)
+	if exists {
+		return env
+	} else {
+		return deflt
+	}
+}
diff --git a/pkg/cmd/local_build_test.go b/pkg/cmd/local_build_test.go
new file mode 100644
index 000000000..8519bd1a4
--- /dev/null
+++ b/pkg/cmd/local_build_test.go
@@ -0,0 +1,49 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"testing"
+
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/spf13/cobra"
+)
+
+func addTestLocalBuildCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localBuildCmdOptions {
+	// add a testing version of build Command
+	localBuildCmd, localBuildCmdOptions := newCmdLocalBuild(rootCmdOptions)
+	localBuildCmd.RunE = func(c *cobra.Command, args []string) error {
+		return nil
+	}
+	localBuildCmd.Args = test.ArbitraryArgs
+	rootCmd.AddCommand(localBuildCmd)
+	return localBuildCmdOptions
+}
+
+func TestLocalBuildAcceptsTraits(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+
+	addTestLocalBuildCmd(options, rootCmd)
+
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "build", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+}
diff --git a/pkg/cmd/local_inspect_test.go b/pkg/cmd/local_inspect_test.go
new file mode 100644
index 000000000..993ea88b9
--- /dev/null
+++ b/pkg/cmd/local_inspect_test.go
@@ -0,0 +1,49 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"testing"
+
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/spf13/cobra"
+)
+
+func addTestLocalInspectCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localInspectCmdOptions {
+	// add a testing version of inspect Command
+	localInspectCmd, localInspectCmdOptions := newCmdLocalInspect(rootCmdOptions)
+	localInspectCmd.RunE = func(c *cobra.Command, args []string) error {
+		return nil
+	}
+	localInspectCmd.Args = test.ArbitraryArgs
+	rootCmd.AddCommand(localInspectCmd)
+	return localInspectCmdOptions
+}
+
+func TestLocalInspectAcceptsTraits(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+
+	addTestLocalInspectCmd(options, rootCmd)
+
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "inspect", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+}
diff --git a/pkg/cmd/local_run_test.go b/pkg/cmd/local_run_test.go
index d79a09d48..1e4c08093 100644
--- a/pkg/cmd/local_run_test.go
+++ b/pkg/cmd/local_run_test.go
@@ -94,3 +94,16 @@ func TestLocalRunAdditionalDependenciesFlag(t *testing.T) {
 		t.Fatalf("Additional dependencies expected to be: \n %v\nGot:\n %v\n", "[mvn:camel-component-1, mvn:camel-component-2]", localRunCmdOptions.AdditionalDependencies)
 	}
 }
+
+func TestLocalRunAcceptsTraits(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+
+	addTestLocalRunCmd(options, rootCmd)
+
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+}