tests/test-racy-mutations.t
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 07 Feb 2023 13:14:59 +0100
changeset 49991 3997c64eff8b
parent 49047 c827bb7b5806
child 50029 28dfb2df4ab9
permissions -rw-r--r--
test: use a more direct approach to test racy mutation The previous test was relying on implementation details and harder to maintain. The new version is closer to the initial intend : "What happens the file get overwritten from under the current process" This change is motivated by further changes around the transaction and dirstate logic that would break the fragile equilibrium that existed before this patch. Making this change early make it easier to review on its own and remove noise in future larger changes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     1
#testcases skip-detection fail-if-detected
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     2
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     3
Test situations that "should" only be reproducible:
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     4
- on networked filesystems, or
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     5
- user using `hg debuglocks` to eliminate the lock file, or
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     6
- something (that doesn't respect the lock file) writing to the .hg directory
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     7
while we're running
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
     8
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
     9
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    10
Initial setup
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    11
-------------
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    12
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    13
  $ hg init base-repo
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    14
  $ cd base-repo
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    15
49047
c827bb7b5806 run-tests: introduce "forward-slash" version of everything on windows
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49046
diff changeset
    16
  $ cat > "$TESTTMP_FORWARD_SLASH/waitlock_editor.sh" <<EOF
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    17
  >     [ -n "\${WAITLOCK_ANNOUNCE:-}" ] && touch "\${WAITLOCK_ANNOUNCE}"
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    18
  >     f="\${WAITLOCK_FILE}"
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    19
  >     start=\`date +%s\`
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    20
  >     timeout=5
49047
c827bb7b5806 run-tests: introduce "forward-slash" version of everything on windows
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49046
diff changeset
    21
  >     "$RUNTESTDIR_FORWARD_SLASH/testlib/wait-on-file" "\$timeout" "\$f"
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    22
  >     if [ \$# -gt 1 ]; then
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    23
  >         cat "\$@"
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    24
  >     fi
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    25
  > EOF
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    26
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    27
Things behave differently if we don't already have a 00changelog.i file when
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    28
this all starts, so let's make one.
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    29
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    30
  $ echo r0 > r0
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    31
  $ hg commit -qAm 'r0'
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    32
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    33
  $ cd ..
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    34
  $ cp -R base-repo main-client
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    35
  $ cp -R base-repo racing-client
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    36
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    37
  $ mkdir sync
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    38
  $ EDITOR_STARTED="$TESTTMP_FORWARD_SLASH/sync/.editor_started"
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    39
  $ MISCHIEF_MANAGED="$TESTTMP_FORWARD_SLASH/sync/.mischief_managed"
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    40
  $ JOBS_FINISHED="$TESTTMP_FORWARD_SLASH/sync/.jobs_finished"
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    41
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    42
Actual test
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    43
-----------
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    44
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    45
Start an hg commit that will take a while
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    46
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    47
  $ cd main-client
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    48
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    49
#if fail-if-detected
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    50
  $ cat >> $HGRCPATH << EOF
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    51
  > [debug]
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    52
  > revlog.verifyposition.changelog = fail
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    53
  > EOF
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    54
#endif
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    55
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    56
  $ echo foo > foo
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    57
  $ (
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    58
  >    unset HGEDITOR;
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    59
  >    WAITLOCK_ANNOUNCE="${EDITOR_STARTED}" \
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    60
  >    WAITLOCK_FILE="${MISCHIEF_MANAGED}" \
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    61
  >    hg commit -qAm 'r1 (foo)' --edit foo \
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    62
  >    --config ui.editor="sh $TESTTMP_FORWARD_SLASH/waitlock_editor.sh" \
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    63
  >    > .foo_commit_out 2>&1 ;\
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    64
  >    touch "${JOBS_FINISHED}"
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    65
  > ) &
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    66
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    67
Wait for the "editor" to actually start
49047
c827bb7b5806 run-tests: introduce "forward-slash" version of everything on windows
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49046
diff changeset
    68
  $ sh "$RUNTESTDIR_FORWARD_SLASH/testlib/wait-on-file" 5 "${EDITOR_STARTED}"
49046
dd384ad01d88 tests-racy-mutation: pass the editor through config instead of env variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48977
diff changeset
    69
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    70
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    71
Do a concurrent edition
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    72
  $ cd ../racing-client
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    73
  $ touch ../pre-race
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    74
  $ sleep 1
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    75
  $ echo bar > bar
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    76
  $ hg --repository ../racing-client commit -qAm 'r2 (bar)' bar
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    77
  $ hg --repository ../racing-client debugrevlogindex -c
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    78
     rev linkrev nodeid       p1           p2
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    79
       0       0 222799e2f90b 000000000000 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    80
       1       1 6f124f6007a0 222799e2f90b 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    81
49991
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    82
We simulate an network FS race by overwriting raced repo content with the new
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    83
content of the files changed in the racing repository
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    84
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    85
  $ for x in `find . -type f -newer ../pre-race`; do
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    86
  >    cp $x ../main-client/$x
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    87
  > done
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    88
  $ cd ../main-client
3997c64eff8b test: use a more direct approach to test racy mutation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49047
diff changeset
    89
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    90
Awaken the editor from that first commit
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    91
  $ touch "${MISCHIEF_MANAGED}"
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    92
And wait for it to finish
49047
c827bb7b5806 run-tests: introduce "forward-slash" version of everything on windows
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49046
diff changeset
    93
  $ WAITLOCK_FILE="${JOBS_FINISHED}" sh "$TESTTMP_FORWARD_SLASH/waitlock_editor.sh"
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    94
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    95
#if skip-detection
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    96
(Ensure there was no output)
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    97
  $ cat .foo_commit_out
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    98
And observe a corrupted repository -- rev 2's linkrev is 1, which should never
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
    99
happen for the changelog (the linkrev should always refer to itself).
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   100
  $ hg debugrevlogindex -c
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   101
     rev linkrev nodeid       p1           p2
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   102
       0       0 222799e2f90b 000000000000 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   103
       1       1 6f124f6007a0 222799e2f90b 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   104
       2       1 ac80e6205bb2 222799e2f90b 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   105
#endif
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   106
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   107
#if fail-if-detected
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   108
  $ cat .foo_commit_out
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   109
  transaction abort!
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   110
  rollback completed
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   111
  note: commit message saved in .hg/last-message.txt
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   112
  note: use 'hg commit --logfile .hg/last-message.txt --edit' to reuse it
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   113
  abort: 00changelog.i: file cursor at position 249, expected 121
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   114
And no corruption in the changelog.
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   115
  $ hg debugrevlogindex -c
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   116
     rev linkrev nodeid       p1           p2
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   117
       0       0 222799e2f90b 000000000000 000000000000
47214
906a7bcaac86 revlog: introduce a mandatory `_writing` context to update revlog content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47065
diff changeset
   118
       1       1 6f124f6007a0 222799e2f90b 000000000000 (missing-correct-output !)
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   119
And, because of transactions, there's none in the manifestlog either.
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   120
  $ hg debugrevlogindex -m
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   121
     rev linkrev nodeid       p1           p2
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   122
       0       0 7b7020262a56 000000000000 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   123
       1       1 ad3fe36d86d9 7b7020262a56 000000000000
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   124
#endif
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents:
diff changeset
   125