# # # rename "tests/automate_netsync/jane_key.packet" # to "tests/common/jane_key.packet" # # rename "tests/automate_netsync/john_key.packet" # to "tests/common/john_key.packet" # # add_dir "tests/automate_netsync_dryrun" # # add_file "tests/automate_netsync_dryrun/__driver__.lua" # content [ca68f0025c9eb2fbd1043c4a152fe72c5eda0656] # # add_file "tests/automate_netsync_dryrun/pull_r1.expected" # content [73f339b0c882ae1687137f3d021117a1ef914912] # # add_file "tests/automate_netsync_dryrun/push_cert.expected" # content [964ccf3ee21eea2cf511ec47a1309268ef1709d4] # # add_file "tests/automate_netsync_dryrun/send_branch.expected" # content [60a25e5e0344c9fdc84c156dbd0bc5a10fe4f26a] # # add_file "tests/automate_netsync_dryrun/sync_keys.expected" # content [561ef6ed396b07ac8d3a21ba9795cc07e751afd5] # # patch "NEWS" # from [0ef5a7f2c0f7f40491a4cdf80dfa7e5ce018f07e] # to [09469621df692727d8fd9ec46e98dfbefeec841b] # # patch "cmd_netsync.cc" # from [9ff90bdafea9d32b59192a61962444af61297762] # to [5afb2d0575d8b78d7a67a8f794ef34d6b0f13f9d] # # patch "monotone.texi" # from [cef86f0bb34fe38ee63025be30ae8264e069242a] # to [fd2c367ee743580b501a662fb7b7cc1a9b35cf2b] # # patch "netxx_pipe.cc" # from [de1705064a6a63fb9a82ef8a6cf55b232bb9a685] # to [d2ef2b7c0c1ac1a47d13fd7f0dc7428909342e4a] # ============================================================ --- NEWS 0ef5a7f2c0f7f40491a4cdf80dfa7e5ce018f07e +++ NEWS 09469621df692727d8fd9ec46e98dfbefeec841b @@ -4,6 +4,11 @@ Xxx Xxx 99 99:99:99 UTC 2010 Changes + - Normal and automate sync, push, and pull now take a + --dry-run option; no data is transferred, but the connection + is made and a summary of what would be transferred is + output. + - Automate sync, push, and pull now output information about each transferred revision, cert and key, in basic_io format. @@ -17,7 +22,7 @@ Xxx Xxx 99 99:99:99 UTC 2010 - 'automate genkey' is renamed to 'automate generate_key' - Selectors are much more powerful now, and the characters '(', - ')', and ';' need to be quoted if mean literally (just like + ')', and ';' need to be quoted if meant literally (just like '/'). See section 3.2 in the documentation for details. (fixes monotone bug #18302). ============================================================ --- monotone.texi cef86f0bb34fe38ee63025be30ae8264e069242a +++ monotone.texi fd2c367ee743580b501a662fb7b7cc1a9b35cf2b @@ -8500,9 +8500,9 @@ @section Automation @end table address@hidden mtn automate pull [--[no-]set-default] address@hidden address@hidden mtn automate push [--[no-]set-default] address@hidden address@hidden address@hidden mtn automate sync [--[no-]set-default] address@hidden address@hidden address@hidden mtn automate pull [--[no-]set-default] [--dry-run] address@hidden address@hidden mtn automate push [--[no-]set-default] [--dry-run] address@hidden address@hidden address@hidden mtn automate sync [--[no-]set-default] [--dry-run] address@hidden address@hidden @itemx mtn automate pull [--[no-]set-default] address@hidden address@hidden [...] address@hidden @strong{deprecated} @itemx mtn automate push [--[no-]set-default] address@hidden address@hidden address@hidden [...] address@hidden @strong{deprecated} @itemx mtn automate sync [--[no-]set-default] address@hidden address@hidden address@hidden [...] address@hidden @strong{deprecated} @@ -8510,15 +8510,15 @@ @section Automation @table @strong @item Arguments: -The automate versions of pull, push and sync have the same set of arguments and -options compared to the non-automate versions. Please check this manual in the -appropriate section for a full explanation. +The automate versions of pull, push and sync have the same set of +arguments and options as the non-automate versions. See @ref{Network} +for a full explanation. @item Changes: @itemize @item -FIXME -- add sent/received revision, cert, and key output +FIXME -- add sent/received revision, cert, and key output; add --dry-run. @item 12.0 -- added @@ -8529,7 +8529,7 @@ @section Automation Pushes, pulls or syncs (push & pull) revisions, certificates and keys of the given database to, from or with the given netsync server. address@hidden Sample output (stdio): address@hidden Sample output (stdio, non-dry-run): Output consists of sent and received revisions, certs, and keys in the main stdio channel, progress messages, and ticker data for bytes, revisions, certs and keys. @@ -8601,6 +8601,20 @@ @section Automation key [05c26b6cb109ca39bc48bbbdce83564c97796155] @end verbatim +The following is example dry-run main channel data: address@hidden + dryrun + receive +revision "0" + cert "1" + key "1" + send +revision "1" + cert "6" + key "1" + branch "foo2" "1" address@hidden verbatim + The following shows the progress and ticker data for a pull which transferred two revisions and eight certs. @@ -8633,8 +8647,8 @@ @section Automation @item Output format: -All stanzas are optional; they are only output if the data they -describe is transferred. +For non-dry-run, all stanzas are optional; they are only output if the +data they describe is transferred. If revisions are received, a header stanza @code{receive revision}. For each revision, a stanza containing the revision id. For @@ -8677,6 +8691,10 @@ @section Automation @item @code{R}: The number of outgoing revisions (only push and sync) @end itemize +For dry-run, two optional stanzas are output, giving the revision, +cert, and key counts for send and receive. For send, the branch names +of sent revisions are also output. + @item Error conditions: If a netsync error occurs, the command outputs an error and exits with status 1. ============================================================ --- cmd_netsync.cc 9ff90bdafea9d32b59192a61962444af61297762 +++ cmd_netsync.cc 5afb2d0575d8b78d7a67a8f794ef34d6b0f13f9d @@ -332,7 +332,6 @@ namespace { symbol const branch("branch"); symbol const cert("cert"); - symbol const dryrun("dryrun"); symbol const estimate("estimate"); symbol const key("key"); symbol const receive("receive"); @@ -350,13 +349,11 @@ print_dryrun_info_auto(protocol_role rol { // print dry run info for automate session basic_io::printer pr; - basic_io::stanza st; - st.push_symbol(syms::dryrun); - if (role != source_role) { // sink or sink_and_source; print sink info + basic_io::stanza st; st.push_symbol(syms::receive); if (counts->keys_in.can_have_more_than_min) @@ -370,10 +367,13 @@ print_dryrun_info_auto(protocol_role rol boost::lexical_cast(counts->certs_in.min_count)); st.push_str_pair(syms::key, boost::lexical_cast(counts->keys_in.min_count)); + pr.print_stanza(st); } + if (role != sink_role) { // source or sink_and_source; print source info + basic_io::stanza st; st.push_symbol(syms::send); st.push_str_pair(syms::revision, @@ -399,8 +399,9 @@ print_dryrun_info_auto(protocol_role rol { st.push_str_triple(syms::branch, i->first(), boost::lexical_cast(i->second)); } + pr.print_stanza(st); } - pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); } ============================================================ --- netxx_pipe.cc de1705064a6a63fb9a82ef8a6cf55b232bb9a685 +++ netxx_pipe.cc d2ef2b7c0c1ac1a47d13fd7f0dc7428909342e4a @@ -113,7 +113,14 @@ pipe_and_fork(int fd1[2], int fd2[2]) else if (!result) { - // fd1[1] for writing, fd2[0] for reading + // child process; replace our stdin, stdout with the child side of the + // pipes. + // + // fd1[1] for writing (stdout, file descriptor 1), + // fd2[0] for reading (stdin, file descriptor 0) + // + // Note that stderr is not affected; child writes to stderr go + // directly to parent stderr stream. close(fd1[0]); close(fd2[1]); if (dup2(fd2[0], 0) != 0 || ============================================================ --- /dev/null +++ tests/automate_netsync_dryrun/__driver__.lua ca68f0025c9eb2fbd1043c4a152fe72c5eda0656 @@ -0,0 +1,121 @@ +-- Test automate sync/pull/push --dry-run +-- +-- Same structure as non-dry-run test, but all executions are --dry-run +-- (ediff-directories "../automate_netsync" "../automate_netsync_dry-run") + +include("/common/netsync.lua") +include("/common/automate_stdio.lua") + +mtn_setup() +netsync.setup() + +-- Create a base revision, in test.db branch 'foo' +-- Override date so we can compare it below +function mtn_date(...) + return mtn("--date=2010-09-01T12:00:00", ...) +end + +addfile("testfile", "blah stuff") +commit("foo", "R1", mtn_date) +R1 = base_revision() + +-- Serve test.db +srv = netsync.start() + +-- Pull branch 'bar' from test.db to test2.db; nothing to transfer, so +-- all zeros on stdout. stderr has progress messages, ticker +check(mtn2("automate", "pull", "--dry-run", "mtn://" .. srv.address .. "?bar"), 0, true, false) +check(readfile("stdout") == " receive \nrevision \"0\"\n cert \"0\"\n key \"0\"\n") + +-- Pull branch 'foo', confirm dryrun output +get("pull_r1.expected") +check(mtn2("automate", "pull", "--dry-run", "mtn://" .. srv.address .. "?foo"), 0, true, false) +canonicalize("stdout") +check(samefile("pull_r1.expected", "stdout")) +-- stderr has ticker; we don't check that here + +-- check that test.db does _not_ have R1, due to --dry-run +check(mtn2("automate", "get_revision", R1), 1, nil, true) +check(qgrep("no revision 114f6aa58c7707bf83516d4080ca6268c36640ad found in database", "stderr")) + +-- Push a cert from test2.db to test.db; test 2 +-- We need a revision to put a cert on, so pull R1 for real +check(mtn2("automate", "pull", "mtn://" .. srv.address .. "?foo"), 0, false, false) + +get("push_cert.expected") +check(mtn2("automate", "cert", R1, "test", "value"), 0, nil, nil) +check(mtn2("automate", "push", "--dry-run", "mtn://" .. srv.address .. "?foo"), 0, true, false) +canonicalize("stdout") +check(samefile("push_cert.expected", "stdout")) + +srv:stop() + +-- check that the test cert did _not_ get transfered +check(mtn("au", "certs", R1), 0, true, nil) +check(not (qgrep("name \"test\"", "stdout"))) + +-- Test 'automate stdio sync --dry-run' output and ticker + +-- New file on a new branch in test2.db; tests 1 +-- Test ticker output; no ticks for dryrun +writefile("testfile2", "blah foo") +check(mtn2("add", "testfile2"), 0, nil, false) +check(mtn2("commit", "--branch=foo2", "--message=R2", "--date=2010-09-01T12:00:00"), 0, nil, false) +R2 = base_revision() + +srv = netsync.start() +local cmd = make_stdio_cmd({"sync", "mtn://" .. srv.address .. "?foo*"}, {{"dry-run", ""}}) + +check(mtn2("automate", "stdio"), 0, true, false, cmd) +output = parse_stdio(readfile("stdout"), 0, 0, "m") +tickers = parse_stdio(readfile("stdout"), 0, 0, "t") + +get("send_branch.expected") +check(readfile("send_branch.expected") == output) + +function any_of(tbl, val) + for _,v in pairs(tbl) do + if string.find(v, val) then + return true + end + end + return false +end + +check(any_of(tickers, "c:certificates;k:keys;r:revisions;")) +check(any_of(tickers, "c;k;r;")) + +check(any_of(tickers, ">:bytes in")) +check(any_of(tickers, "<:bytes out")) +check(any_of(tickers, "r:revs in")) +check(any_of(tickers, "c:certs in")) +check(any_of(tickers, "C:certs out")) + +check(not any_of(tickers, "R#1")) +check(not any_of(tickers, "r#1")) +check(not any_of(tickers, "C#1")) +check(not any_of(tickers, "c#1")) + +srv:stop() + +-- push and pull a key; test 3 and 6. Note that keys are not sent +-- unless they are used to sign something; we sign another test cert; +-- tests 5. Can't use 'genkey'; that gives a random key signature +getstd("common/john_key.packet", "john_key.packet") +getstd("common/jane_key.packet", "jane_key.packet") +check(mtn("read", "john_key.packet"), 0, nil, false) +check(mtn2("read", "jane_key.packet"), 0, nil, false) + +check(mtn("address@hidden", "cert", R1, "test", "value2"), 0, nil, nil) +check(mtn2("address@hidden", "cert", R2, "test", "value2"), 0, nil, nil) + +srv = netsync.start() +local cmd = make_stdio_cmd({"sync", "mtn://" .. srv.address .. "?*"}, {{"dry-run", ""}}) +check(mtn2("automate", "stdio"), 0, true, false, cmd) +get("sync_keys.expected") + +output = parse_stdio(readfile("stdout"), 0, 0, "m") + +check(readfile("sync_keys.expected") == output) + +-- end of file ============================================================ --- /dev/null +++ tests/automate_netsync_dryrun/pull_r1.expected 73f339b0c882ae1687137f3d021117a1ef914912 @@ -0,0 +1,4 @@ + receive +revision "1" + cert "4" + key "1" ============================================================ --- /dev/null +++ tests/automate_netsync_dryrun/push_cert.expected 964ccf3ee21eea2cf511ec47a1309268ef1709d4 @@ -0,0 +1,4 @@ + send +revision "0" + cert "1" + key "0" ============================================================ --- /dev/null +++ tests/automate_netsync_dryrun/send_branch.expected 60a25e5e0344c9fdc84c156dbd0bc5a10fe4f26a @@ -0,0 +1,10 @@ + receive +revision "0" + cert "0" + key "0" + + send +revision "1" + cert "5" + key "0" + branch "foo2" "1" ============================================================ --- /dev/null +++ tests/automate_netsync_dryrun/sync_keys.expected 561ef6ed396b07ac8d3a21ba9795cc07e751afd5 @@ -0,0 +1,10 @@ + receive +revision "0" + cert "1" + key "1" + + send +revision "1" + cert "6" + key "1" + branch "foo2" "1"