From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 080BB43E43; Thu, 11 Apr 2024 12:31:13 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CE06C4029C; Thu, 11 Apr 2024 12:31:12 +0200 (CEST) Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) by mails.dpdk.org (Postfix) with ESMTP id AC09F40268 for ; Thu, 11 Apr 2024 12:31:09 +0200 (CEST) Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-a46ea03c2a5so119375866b.1 for ; Thu, 11 Apr 2024 03:31:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pantheon.tech; s=google; t=1712831469; x=1713436269; darn=dpdk.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=1nk8Fr9DLO94IpFNLztuob0kPQE5Zvh+FeTyPSYS5Uw=; b=ZxOj88t69n9DAfM02Yp0UKGyqNQ0C6y30AzDKhCmi2tzBfUwpLMcZKJueRi0cN6kHw cOsBtpFmB+U6ncvFkHAkgcbYpENBLAHULwqqmbvBiZ22ZKFyQsKM5i8Sy1NPrbBBpZnp 1XA81Jm2IBfHiDIMJTtS7vPfwqkxAA/9roxvVSpVnpwPtXhYfn/OfR/ASnH7Pp0VWOtq ci/I+bWp6HuT8ofgZCvJTTW9YFDLcKX3xnZITNDANJY8Wy4ROWUCP7pf14AFQ9a4AYzq mIey/khrgk2SPGl9cbC1lNPde6Lx36zE4m563bUTfAObaY/twFi/fYa4ylpX4Qfb3Wpv jHxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712831469; x=1713436269; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1nk8Fr9DLO94IpFNLztuob0kPQE5Zvh+FeTyPSYS5Uw=; b=ffbSvCM+up5YCvacj3Td3cjk/KS5GVSE3Wfjcdj7BsP0MeyTX2QaHwldyhS6cVf5BM 3OTp//lF9gRrRtbJ8TXukOA1KKq/xe81nwEu3eXktGSZCDzKzXJPsIdnBPOGPGIuP0YZ SeAvSwB+VfueNQhAQvP0WGNamRAdxiv65NmdpICkn6afCZZWoSvLrYnamhggORiE6KEe gTLps0ywDYSEYrI5OKtSdlDXzefXimu6jXaAnCz2Rxv4X6iRqkmtxcMIfuKSCvyj85Sg rVOYNRThjKDdkprK15XRIuIqwhpdrnWd1tuGe6LSjnTmpNIMuVkBI+u6wX5U4e+7Eay0 +soQ== X-Forwarded-Encrypted: i=1; AJvYcCWIdCCB3z27If0J+2L9kEs5adG/YLYJJoMuhL1FLT4kXhhLHFdOCcDjOVcmLzUhazupT5bLMIfZMJ2TRIs= X-Gm-Message-State: AOJu0YxqZqnl/va7NK8RrcJ8I1s8vZrmqZvQHgMGTPl1zgSTGbkew0We +SpNd391Lul/aUr12GQozCEQRYm0yCBsNTPT5P9hrWsHM+8rMG5c1XFlGRuRIsrCztpTnONyFzF U1lsQ7+pooKQSIVsIScJ7Azf39kOdEbVpX1Af+A== X-Google-Smtp-Source: AGHT+IELgU/tNv6OJ/CzMtu8sMXvzNqvfjJ6h+oi2P1FU7O41YutdVeUmyp3MborK8ovLm5eAcW7uxp3czfgrcbXDws= X-Received: by 2002:a17:906:6a20:b0:a52:b65:e978 with SMTP id qw32-20020a1709066a2000b00a520b65e978mr2169103ejc.5.1712831469463; Thu, 11 Apr 2024 03:31:09 -0700 (PDT) MIME-Version: 1.0 References: <20240326190422.577028-1-luca.vizzarro@arm.com> <20240326190422.577028-7-luca.vizzarro@arm.com> <1db1b2b8-fac0-41ad-9ba2-911365385a9b@arm.com> In-Reply-To: <1db1b2b8-fac0-41ad-9ba2-911365385a9b@arm.com> From: =?UTF-8?Q?Juraj_Linke=C5=A1?= Date: Thu, 11 Apr 2024 12:30:58 +0200 Message-ID: Subject: Re: [PATCH 6/6] dts: add statefulness to TestPmdShell To: Luca Vizzarro Cc: Jeremy Spewock , dev@dpdk.org, Jack Bond-Preston , Honnappa Nagarahalli Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org I overlooked this reply initially. On Wed, Apr 10, 2024 at 1:35=E2=80=AFPM Luca Vizzarro wrote: > > On 10/04/2024 08:41, Juraj Linke=C5=A1 wrote: > >> > >>> @@ -723,7 +731,13 @@ def _start_application(self, get_privileged_comm= and: Callable[[str], str] | None > >>> if self._app_args.app_params is None: > >>> self._app_args.app_params =3D TestPmdParameters() > >>> > >>> - self.number_of_ports =3D len(self._app_args.ports) if self._= app_args.ports is not None else 0 > >>> + assert isinstance(self._app_args.app_params, TestPmdParamete= rs) > >>> + > >> > >> This is tricky because ideally we wouldn't have the assertion here, > >> but I understand why it is needed because Eal parameters have app args > >> which can be any instance of params. I'm not sure of the best way to > >> solve this, because making testpmd parameters extend from eal would > >> break the general scheme that you have in place, and having an > >> extension of EalParameters that enforces this app_args is > >> TestPmdParameters would solve the issues, but might be a little > >> clunky. Is there a way we can use a generic to get python to just > >> understand that, in this case, this will always be TestPmdParameters? > >> If not I might prefer making a private class where this is > >> TestPmdParameters, just because there aren't really any other > >> assertions that we use elsewhere and an unexpected exception from this > >> (even though I don't think that can happen) could cause people some > >> issues. > >> > >> It might be the case that an assertion is the easiest way to deal with > >> it though, what do you think? > >> > > > > We could change the signature (just the type of app_args) of the init > > method - I think we should be able to create a type that's > > EalParameters with .app_params being TestPmdParameters or None. The > > init method would just call super(). > > > > Something like the above is basically necessary with inheritance where > > subclasses are all extensions (not just implementations) of the > > superclass (having differences in API). > > > > I believe this is indeed a tricky one. But, unfortunately, I am not > understanding the solution that is being proposed. To me, it just feels > like using a generic factory like: > > self.sut_node.create_interactive_shell(..) > > is one of the reasons to bring in the majority of these complexities. > I've been thinking about these interactive shell constructors for some time and I think the factory pattern is not well suitable for this. Factories work well with classes with the same API (i.e. implementations of abstract classes that don't add anything extra), but are much less useful when dealing with classes with different behaviors, such as the interactive shells. We see this here, different apps are going to require different args and that alone kinda breaks the factory pattern. I think we'll need to either ditch these factories and instead just have methods that return the proper shell (and the methods would only exist in classes where they belong, e.g. testpmd only makes sense on an SUT). Or we could overload each factory (the support has only been added in 3.11 with @typing.overload, but is also available in typing_extensions, so we would be able to use it with the extra dependency) where different signatures would return different objects. In both cases the caller won't have to import the class and the method signature is going to be clearer. We have this pattern with sut/tg nodes. I decided to move away from the node factory because it didn't add much and in fact the code was only clunkier. The interactive shell is not quite the same, as the shells are not standalone in the same way the nodes are (the shells are tied to nodes). Let me know what you think about all this - both Luca and Jeremy. > What do you mean by creating this new type that combines EalParams and > TestPmdParams? Let me illustrate this on the TestPmdShell __init__() method I had in mind: def __init__(self, interactive_session: SSHClient, logger: DTSLogger, get_privileged_command: Callable[[str], str] | None, app_args: EalTestPmdParams | None =3D None, timeout: float =3D SETTINGS.timeout, ) -> None: super().__init__(interactive_session, logger, get_privileged_command) self.state =3D TestPmdState() Where EalTestPmdParams would be something that enforces that app_args.app_params is of the TestPmdParameters type. But thinking more about this, we're probably better off switching the params composition. Instead of TestPmdParameters being part of EalParameters, we do it the other way around. This way the type of app_args could just be TestPmdParameters and the types should work. Or we pass the args separately, but that would likely require ditching the factories and replacing them with methods (or overloading them). And hopefully the imports won't be impossible to solve. :-)