diff --git a/core/commands/ls.go b/core/commands/ls.go index 31a57f001..72dd254ba 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -44,6 +44,7 @@ type LsOutput struct { const ( lsHeadersOptionNameTime = "headers" lsResolveTypeOptionName = "resolve-type" + lsSizeOptionName = "size" lsStreamOptionName = "stream" ) @@ -66,6 +67,7 @@ The JSON output contains type information. Options: []cmdkit.Option{ cmdkit.BoolOption(lsHeadersOptionNameTime, "v", "Print table headers (Hash, Size, Name)."), cmdkit.BoolOption(lsResolveTypeOptionName, "Resolve linked objects to find out their types.").WithDefault(true), + cmdkit.BoolOption(lsSizeOptionName, "Resolve linked objects to find out their file size.").WithDefault(true), cmdkit.BoolOption(lsStreamOptionName, "s", "Enable exprimental streaming of directory entries as they are traversed."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -79,9 +81,10 @@ The JSON output contains type information. return err } - resolve, _ := req.Options[lsResolveTypeOptionName].(bool) + resolveType, _ := req.Options[lsResolveTypeOptionName].(bool) + resolveSize, _ := req.Options[lsSizeOptionName].(bool) dserv := nd.DAG - if !resolve { + if !resolveType && !resolveSize { offlineexch := offline.Exchange(nd.Blockstore) bserv := blockservice.New(nd.Blockstore, offlineexch) dserv = merkledag.NewDAGService(bserv) @@ -131,7 +134,7 @@ The JSON output contains type information. } outputLinks := make([]LsLink, len(links)) for j, link := range links { - lsLink, err := makeLsLink(req, dserv, resolve, link) + lsLink, err := makeLsLink(req, dserv, resolveType, resolveSize, link) if err != nil { return err } @@ -165,7 +168,7 @@ The JSON output contains type information. return linkResult.Err } link := linkResult.Link - lsLink, err := makeLsLink(req, dserv, resolve, link) + lsLink, err := makeLsLink(req, dserv, resolveType, resolveSize, link) if err != nil { return err } @@ -224,16 +227,18 @@ func makeDagNodeLinkResults(req *cmds.Request, dagnode ipld.Node) <-chan unixfs. return linkResults } -func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ipld.Link) (*LsLink, error) { +func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolveType bool, resolveSize bool, link *ipld.Link) (*LsLink, error) { t := unixfspb.Data_DataType(-1) + var size uint64 switch link.Cid.Type() { case cid.Raw: // No need to check with raw leaves t = unixfs.TFile + size = link.Size case cid.DagProtobuf: linkNode, err := link.GetNode(req.Context, dserv) - if err == ipld.ErrNotFound && !resolve { + if err == ipld.ErrNotFound && !resolveType && !resolveSize { // not an error linkNode = nil } else if err != nil { @@ -245,13 +250,18 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip if err != nil { return nil, err } - t = d.Type() + if resolveType { + t = d.Type() + } + if d.Type() == unixfs.TFile && resolveSize { + size = d.FileSize() + } } } return &LsLink{ Name: link.Name, Hash: link.Cid.String(), - Size: link.Size, + Size: size, Type: t, }, nil } @@ -259,6 +269,7 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip func tabularOutput(req *cmds.Request, w io.Writer, out *LsOutput, lastObjectHash string, ignoreBreaks bool) string { headers, _ := req.Options[lsHeadersOptionNameTime].(bool) stream, _ := req.Options[lsStreamOptionName].(bool) + size, _ := req.Options[lsSizeOptionName].(bool) // in streaming mode we can't automatically align the tabs // so we take a best guess var minTabWidth int @@ -282,17 +293,28 @@ func tabularOutput(req *cmds.Request, w io.Writer, out *LsOutput, lastObjectHash fmt.Fprintf(tw, "%s:\n", object.Hash) } if headers { - fmt.Fprintln(tw, "Hash\tSize\tName") + s := "Hash\tName" + if size { + s = "Hash\tSize\tName" + } + fmt.Fprintln(tw, s) } lastObjectHash = object.Hash } for _, link := range object.Links { - if link.Type == unixfs.TDirectory { - link.Name += "/" + s := "%[1]s\t%[3]s\n" + + switch { + case link.Type == unixfs.TDirectory && size: + s = "%[1]s\t-\t%[3]s/\n" + case link.Type == unixfs.TDirectory && !size: + s = "%[1]s\t%[3]s/\n" + case size: + s = "%s\t%v\t%s\n" } - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) + fmt.Fprintf(tw, s, link.Hash, link.Size, link.Name) } } tw.Flush() diff --git a/test/sharness/t0045-ls.sh b/test/sharness/t0045-ls.sh index 4d3fb296c..b39585fae 100755 --- a/test/sharness/t0045-ls.sh +++ b/test/sharness/t0045-ls.sh @@ -45,18 +45,41 @@ EOF test_expect_success "'ipfs ls ' output looks good" ' cat <<-\EOF >expected_ls && QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: -QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/ -QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 13 f1 -QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 13 f2 +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: -QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1035 1024 -QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: -QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128 -QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a +EOF + test_cmp expected_ls actual_ls + ' + + test_expect_success "'ipfs ls --size=false ' succeeds" ' + ipfs ls --size=false QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls + ' + + test_expect_success "'ipfs ls ' output looks good" ' + cat <<-\EOF >expected_ls && +QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M f2 + +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL a + +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN a EOF test_cmp expected_ls actual_ls ' @@ -69,20 +92,20 @@ EOF cat <<-\EOF >expected_ls_headers && QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: Hash Size Name -QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/ -QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 13 f1 -QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 13 f2 +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: Hash Size Name -QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1035 1024 -QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: Hash Size Name -QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128 -QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a EOF test_cmp expected_ls_headers actual_ls_headers ' @@ -124,18 +147,41 @@ EOF test_expect_success "'ipfs ls --stream ' output looks good" ' cat <<-\EOF >expected_ls_stream && QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: -QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/ -QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 13 f1 -QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 13 f2 +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: -QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1035 1024 -QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: -QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128 -QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a +EOF + test_cmp expected_ls_stream actual_ls_stream + ' + + test_expect_success "'ipfs ls --size=false --stream ' succeeds" ' + ipfs ls --size=false --stream QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream + ' + + test_expect_success "'ipfs ls --size=false --stream ' output looks good" ' + cat <<-\EOF >expected_ls_stream && +QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M f2 + +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL a + +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN a EOF test_cmp expected_ls_stream actual_ls_stream ' @@ -148,20 +194,20 @@ EOF cat <<-\EOF >expected_ls_stream_headers && QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: Hash Size Name -QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/ -QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 13 f1 -QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 13 f2 +QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ +QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 +QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: Hash Size Name -QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1035 1024 -QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a +QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 +QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: Hash Size Name -QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128 -QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a +QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 +QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a EOF test_cmp expected_ls_stream_headers actual_ls_stream_headers ' @@ -172,18 +218,27 @@ test_ls_cmd_raw_leaves() { mkdir -p somedir && echo bar > somedir/foo && ipfs add --raw-leaves -r somedir/ > /dev/null && - ipfs ls QmThNTdtKaVoCVrYmM5EBS6U3S5vfKFue2TxbxxAxRcKKE > ls-actual + ipfs ls '$1' QmThNTdtKaVoCVrYmM5EBS6U3S5vfKFue2TxbxxAxRcKKE > ls-actual echo "zb2rhf6GzX4ckKZtjy8yy8iyq1KttCrRyqDedD6xubhY3sw2F 4 foo" > ls-expect test_cmp ls-actual ls-expect ' } test_ls_object() { + test_expect_success "ipfs add medium size file then 'ipfs ls --size=false' works as expected" ' + random 500000 2 > somefile && + HASH=$(ipfs add somefile -q) && + echo "QmPrM8S5T7Q3M8DQvQMS7m41m3Aq4jBjzAzvky5fH3xfr4 " > ls-expect && + echo "QmdaAntAzQqqVMo4B8V69nkQd5d918YjHXUe2oF6hr72ri " >> ls-expect && + ipfs ls --size=false $HASH > ls-actual && + test_cmp ls-actual ls-expect + ' + test_expect_success "ipfs add medium size file then 'ipfs ls' works as expected" ' random 500000 2 > somefile && HASH=$(ipfs add somefile -q) && - echo "QmPrM8S5T7Q3M8DQvQMS7m41m3Aq4jBjzAzvky5fH3xfr4 262158 " > ls-expect && - echo "QmdaAntAzQqqVMo4B8V69nkQd5d918YjHXUe2oF6hr72ri 237870 " >> ls-expect && + echo "QmPrM8S5T7Q3M8DQvQMS7m41m3Aq4jBjzAzvky5fH3xfr4 262144 " > ls-expect && + echo "QmdaAntAzQqqVMo4B8V69nkQd5d918YjHXUe2oF6hr72ri 237856 " >> ls-expect && ipfs ls $HASH > ls-actual && test_cmp ls-actual ls-expect ' @@ -193,6 +248,7 @@ test_ls_object() { test_ls_cmd test_ls_cmd_streaming test_ls_cmd_raw_leaves +test_ls_cmd_raw_leaves --size test_ls_object # should work online @@ -200,6 +256,7 @@ test_launch_ipfs_daemon test_ls_cmd test_ls_cmd_streaming test_ls_cmd_raw_leaves +test_ls_cmd_raw_leaves --size test_kill_ipfs_daemon test_ls_object @@ -225,24 +282,32 @@ test_expect_success "remove a file in dir" ' ipfs block rm $FILE ' -test_expect_success "'ipfs ls --resolve-type=false ' ok" ' - ipfs ls --resolve-type=false $DIR > /dev/null +test_expect_success "'ipfs ls --resolve-type=false ' fails" ' + test_must_fail ipfs ls --resolve-type=false $DIR > /dev/null ' test_expect_success "'ipfs ls' fails" ' test_must_fail ipfs ls $DIR ' +test_expect_success "'ipfs ls --resolve-type=true --size=false' fails" ' + test_must_fail ipfs ls --resolve-type=true --size=false $DIR +' + test_launch_ipfs_daemon --offline -test_expect_success "'ipfs ls --resolve-type=false' ok" ' - ipfs ls --resolve-type=false $DIR > /dev/null +test_expect_success "'ipfs ls --resolve-type=false --size=false' ok" ' + ipfs ls --resolve-type=false --size=false $DIR > /dev/null ' test_expect_success "'ipfs ls' fails" ' test_must_fail ipfs ls $DIR ' +test_expect_success "'ipfs ls --resolve-type=false --size=true' fails" ' + test_must_fail ipfs ls --resolve-type=false --size=true $DIR +' + test_kill_ipfs_daemon test_launch_ipfs_daemon @@ -252,8 +317,8 @@ test_launch_ipfs_daemon # it does it should eventually fail as the content is random and # should not exist on the network, but we don't want to wait for a # timeout so we will kill the request after a few seconds -test_expect_success "'ipfs ls --resolve-type=false' ok and does not hang" ' - go-timeout 2 ipfs ls --resolve-type=false $DIR +test_expect_success "'ipfs ls --resolve-type=false --size=false' ok and does not hang" ' + go-timeout 2 ipfs ls --resolve-type=false --size=false $DIR ' test_kill_ipfs_daemon diff --git a/test/sharness/t0051-object.sh b/test/sharness/t0051-object.sh index 70058be4a..1687ba956 100755 --- a/test/sharness/t0051-object.sh +++ b/test/sharness/t0051-object.sh @@ -292,7 +292,7 @@ test_object_cmd() { ' test_expect_success "output looks good" ' - echo "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn 4 foo/" > patched_exp && + echo "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn - foo/" > patched_exp && test_cmp patched_exp patched_output ' diff --git a/test/sharness/t0260-sharding.sh b/test/sharness/t0260-sharding.sh index 6fb3cf657..02d528fa9 100755 --- a/test/sharness/t0260-sharding.sh +++ b/test/sharness/t0260-sharding.sh @@ -65,15 +65,16 @@ test_expect_success "ipfs cat error output the same" ' test_cmp sharded_err unsharded_err ' -test_expect_success "'ipfs ls --resolve-type=false' admits missing block" ' +test_expect_success "'ipfs ls --resolve-type=false --size=false' admits missing block" ' ipfs ls "$SHARDED" | head -1 > first_file && + ipfs ls --size=false "$SHARDED" | sort > sharded_out_nosize && read -r HASH _ NAME missing_out && - test_cmp sharded_out missing_out + ipfs ls --resolve-type=false --size=false "$SHARDED" | sort > missing_out && + test_cmp sharded_out_nosize missing_out ' test_launch_ipfs_daemon