-
Notifications
You must be signed in to change notification settings - Fork 213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix CLI port argument bug. #407
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking at this issue!
I think this PR is generally good, though I also think there are some areas that we should fix. I've highlighted these areas in comments, along with some suggestions. I'd be interested to hear your thoughts.
Cheers!
@@ -139,15 +140,19 @@ import qualified Data.Text as T | |||
import qualified Data.Text.Encoding as T | |||
import qualified Network.Wai.Handler.Warp as Warp | |||
|
|||
|
|||
data PortOption = RandomPort | ExactPort (Maybe Warp.Port) | |||
deriving Show |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By using the Maybe
type here, I think it's not obvious what the semantics are if we specify ExactPort Nothing
.
Perhaps we can make this clearer by using the following options:
-- | Specifies a port on which the application server will listen.
data PortOption
= DefaultPort
-- ^ Listen on the default port (see 'defaultPort').
| RandomPort
-- ^ Select an unused port at random on which to listen.
| SpecificPort Warp.Port
-- ^ Listen on a specific port.
deriving Show
And then separately define:
-- | The default port on which to listen. The application server will listen
-- on this port if 'start' is called with 'DefaultPort'.
defaultPort :: Warp.Port
defaultPort = 9080
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been addressed 👍
@@ -762,6 +769,8 @@ createWalletViaCLI args mnemonics secondFactor passphrase = do | |||
err <- TIO.hGetContents stderr | |||
return (c, T.unpack out, err) | |||
|
|||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here there should only be one blank line, rather than three.
@@ -139,15 +140,19 @@ import qualified Data.Text as T | |||
import qualified Data.Text.Encoding as T | |||
import qualified Network.Wai.Handler.Warp as Warp | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T.unpack err `shouldContain` "Ok.\n" | ||
out `shouldContain` walletName | ||
checkSimpleCreateWallet | ||
(Just "1337") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the relevance of the number 1337
? Is it an arbitrarily-chosen number, or should it be the same as a number somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid the hard-coded number here indeed. Or at the very least, avoid repeating it through the whole file 🙏
lib/core/test/integration/Test/Integration/Scenario/CLI/Wallets.hs
Outdated
Show resolved
Hide resolved
lib/core/test/integration/Test/Integration/Scenario/CLI/Wallets.hs
Outdated
Show resolved
Hide resolved
lib/core/test/integration/Test/Integration/Scenario/CLI/Wallets.hs
Outdated
Show resolved
Hide resolved
fb2f74a
to
160a1dc
Compare
exe/launcher/Main.hs
Outdated
] ++ dbArg | ||
] ++ portArg ++ bridgePortArg ++ dbArg | ||
portArg = maybe ["--random-port"] (\p -> ["--port", T.unpack (toText p)]) wp | ||
bridgePortArg = ["--bridge-port", T.unpack (toText np)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bridgePortArg = ["--bridge-port", T.unpack (toText np)] | |
args = mconcat | |
[ [ "server" ] | |
, [ "--network", if net == "local" then "testnet" else net ] | |
, maybe ["--random-port"] (\p -> ["--port", showT p]) wp | |
, [ "--bridge-port", showT np ] | |
] | |
showT = T.unpack . toText |
exe/wallet/Main.hs
Outdated
@@ -140,7 +140,7 @@ and can be run "offline". (e.g. 'generate mnemonic') | |||
⚠️ Options are positional (--a --b is not equivalent to --b --a) ! ⚠️ | |||
|
|||
Usage: | |||
cardano-wallet server [--network=STRING] [--port=INT] [--bridge-port=INT] [--database=FILE] | |||
cardano-wallet server [--network=STRING] [--port=INT] [--random-port] [--bridge-port=INT] [--database=FILE] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here about --port=INT
and --random-port
being mutually exclusive.
T.unpack err `shouldContain` "Ok.\n" | ||
out `shouldContain` walletName | ||
checkSimpleCreateWallet | ||
(Just "1337") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid the hard-coded number here indeed. Or at the very least, avoid repeating it through the whole file 🙏
Just port -> | ||
[ "exec", "--", "cardano-wallet" | ||
, "wallet", "create", "--port", port | ||
] ++ args |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
] ++ args | |
let portArg = | |
maybe [] (\p -> ["--port", p]) portM | |
let fullArgs = | |
[ "exec", "--", "cardano-wallet", "wallet", "create" ] | |
++ portArg ++ args |
db <- MVar.newDBLayer | ||
let tl = HttpBridge.newTransactionLayer | ||
wallet <- newWalletLayer nullTracer block0 db nl tl | ||
Server.start (putMVar port) walletListen wallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea and a good way to test that the random port binding works as expected 🎉
@@ -158,6 +168,8 @@ main = hspec $ do | |||
-- some places where it's less annoying. | |||
(UseHandle h) | |||
|
|||
mkBaseUrl port = "http://localhost:" <> T.pack (show port) <> "/" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably need toText
here instead of show
since we have port :: Port
I believe.
@@ -71,13 +77,17 @@ main = hspec $ do | |||
describe "Cardano.WalletSpec" Wallet.spec | |||
describe "Cardano.Wallet.HttpBridge.NetworkSpec" HttpBridge.spec | |||
describe "CLI commands not requiring bridge" MnemonicsCLI.spec | |||
beforeAll startCluster $ afterAll killCluster $ after tearDown $ do | |||
beforeAll (startCluster ListenOnRandomPort) $ afterAll killCluster $ after tearDown $ do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be a problem for the API spec as long as we sort out the baseUrl in the manager, but the CLI specs also need to know about the port; So we probably gotta add it to the Context
I believe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change it from IO ()
to IO Warp.Port
in start Server in Cardano.Wallet.Api.Server
now we need to accommodate it in integration tests. And we will be able to use it when random port mode is ON in integration tests
|
||
let defaultPort = 8090 | ||
beforeAll (startCluster (ListenOnPort defaultPort)) $ afterAll killCluster $ after tearDown $ do | ||
describe "Port tests using wallets CLI" (WalletsCLI.specPorts defaultPort) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale for making this one completely separated ? It's quite heavy to start a whole new cluster. Perhaps what we really need here is simply to start another wallet server listening on given port. That can be tested without requiring a new cluster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. That'd also, sort of, test the case of two wallet's attached to a single server.
-> String | ||
-> (ExitCode -> IO ()) | ||
-> (String -> IO ()) | ||
-> (String -> IO ()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not found of this helper, it's really "stringly-typed" and is more cryptic than readable IMO. I'd rather inline it in all the test above as it reads better inlined.
exe/launcher/Main.hs
Outdated
@@ -118,16 +123,16 @@ nodeHttpBridgeOn stateDir port net = | |||
] ++ networkArg | |||
networkArg = maybe [] (\d -> ["--networks-dir", d]) stateDir | |||
|
|||
walletOn :: Maybe FilePath -> Port "Wallet" -> Port "Node" -> String -> Command | |||
walletOn :: Maybe FilePath -> Maybe (Port "Wallet") -> Port "Node" -> String -> Command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is now too long (https://github.com/input-output-hk/cardano-wallet/wiki/Coding-Standards#limit-line-length-to-80-characters).
Suggest:
walletOn :: Maybe FilePath -> Maybe (Port "Wallet") -> Port "Node" -> String -> Command | |
walletOn | |
:: Maybe FilePath | |
-> Maybe (Port "Wallet") | |
-> Port "Node" | |
-> String | |
-> Command |
@@ -170,17 +179,17 @@ startOnSocket settings socket wl = Warp.runSettingsSocket settings socket | |||
application :: Application | |||
application = serve (Proxy @("v2" :> Api t)) server | |||
|
|||
-- | Run an action with a TCP socket bound to a port. If no port is specified, | |||
-- | Run an action with a TCP socket bound to a port. If random port is chosen | |||
-- then an unused port will be selected at random. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment sounds a bit tautological. Suggest:
-- then an unused port will be selected at random. | |
-- | Run an action with a TCP socket bound to a port specified by the `Listen` | |
-- parameter. |
describe "Wallets API endpoint tests" Wallets.spec | ||
describe "Transactions API endpoint tests" Transactions.spec | ||
describe "Addresses API endpoint tests" Addresses.spec | ||
describe "Wallets CLI tests" WalletsCLI.spec | ||
describe "Transactions CLI tests" TransactionsCLI.spec | ||
describe "Addresses CLI tests" AddressesCLI.spec | ||
|
||
let defaultPort = 8090 | ||
beforeAll (startCluster (ListenOnPort defaultPort)) $ afterAll killCluster $ after tearDown $ do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to keep lines to the length specified by https://github.com/input-output-hk/cardano-wallet/wiki/Coding-Standards#limit-line-length-to-80-characters
(c, out, err) <- createWalletViaCLI [walletName] mnemonics "\n" passphrase portM | ||
exitCodeCheck c | ||
errCheck (T.unpack err) | ||
outCheck out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that this check just landed here in this method, because it was there in the code in the first place :) Actually it is quite poor and I was planning to add more detailed checks (like here: https://github.com/input-output-hk/cardano-wallet/blob/master/lib/core/test/integration/Test/Integration/Scenario/CLI/Transactions.hs#L92-L97) but didn't get there yet for Wallets.sh
. (ofc that's not in scope of this pr)
For that matter, I'd be rather for separating action and assertion not to be in a single method (but perhaps, that's just a personal preference)
Rationale here is to simplify a bit the requirement and busy work with the launcher that we're going to remove / merge into the wallet cli soon.
d1c9f90
to
eb32f30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM. I've picked up the PR to resolve issues with the integration tests and reworked a bit the way integration scenario receive their corresponding port and made sure to thoroughly test every CLI commands.
comments have been addressed or are now outdated 👍
@piotr-iohk May you have another quick look at the PR 🙏 , especially the integration test part. I used some generic-lens magic to avoid making numerous changes to the rest of the code. It's pretty neat in the end and enables a great coverage for all commands of the CLI:
let me know. |
There's a bit of Haskell lens magic here. But that's for a greater good.
eb32f30
to
264c31f
Compare
Issue Number
#401
Overview
Comments