Commit Graph

309 Commits

Author SHA1 Message Date
Adam Simpkins
d922d6cec5 add a flag to disable flatmanifest fallback
Summary:
Add a command line flag to control whether or not Eden should ever try falling
back to import tree data using flatmanifest if an error occurs trying to import
it directly via treemanifest, in repositories that support treemanifest.

This is particularly useful for tests, where we usually do not want to fall
back to flatmanifest import if an error occurs during treemanifest import.  The
fallback can otherwise mask real issues that should trigger test failures.

This is probably also a good thing to have in general.  Supporting
flatmanifest+treemanifest data in a single Eden repository has some unfortunate
problems today: we compute hashes differently for flatmanifest trees vs
treemanifest trees.  As a result, we can end up with identical trees that have
different hashes.  This can result in unfortunate performance consequences in
some cases where Eden assumes it must scan a directory for differences if the
hashes are different.

I have left flatmanifest import enabled by default for now, but we may want to
disable it by default in the future.  I would be more inclined to disable it by
default if we did added a thrift method to explicitly re-enable it (or to
import a single commit using flatmanifest), so that users could work around
this setting if necessary without having to fully restart edenfs.

Reviewed By: wez

Differential Revision: D6993791

fbshipit-source-id: 6e091a426cf1e7c973df5a641d2f8a1101011346
2018-02-15 22:11:38 -08:00
Adam Simpkins
93309989d4 have hg_import_helper.py use the local mercurial code during tests
Summary:
Update the integration tests to build `hg_import_helper` into a python archive
that includes the current mercurial sources from the local repository.  This
way hg_import_helper will use the local mercurial code rather than whatever
mercurial modules are installed on the system.  This will help ensure that we
detect any breakages caused by changes in the mercurial source when the
mercurial changes are made rather than when they are deployed.

Reviewed By: wez

Differential Revision: D6993790

fbshipit-source-id: f3ad404583cadcf07156bac1ce6bc869bd1160e1
2018-02-15 22:11:38 -08:00
Adam Simpkins
9dbdeaa4f4 add the ability to run some integration tests in treeonly mode
Summary:
Update the `hg_test` decorator to accept additional parameters specifying the
list of test modes.  e.g., `hg_test('Treemanifest')` asks to only run the test
in the Treemanifest configuration.  With no arguments tests are still run with
both the Flatmanifest and Treemanifest configurations by default.

This also enables the TreeOnly configuration mode, which appears to work now.
(It was previously disabled since `hg init` would fail in treeonly
repositories.)

This new changes allows tests to explicitly opt-in to running in `TreeOnly`
mode.

Reviewed By: wez

Differential Revision: D6993789

fbshipit-source-id: 9ee51318d0f661038fe29f246b2b14eebbb1c3d9
2018-02-15 11:41:28 -08:00
Adam Simpkins
70abf56f40 add an option to leave behind the integration test directory
Summary:
Update the integration tests so that they do not delete the temporary test
directories if the environment variable `EDEN_TEST_NO_CLEANUP` is set.

This makes it easier to manually examine the repository state after a test
fails.

Reviewed By: chadaustin

Differential Revision: D6986217

fbshipit-source-id: 727321c2c3da4d19d9edf8ed20b2aca3449779de
2018-02-15 11:41:28 -08:00
Adam Simpkins
ab05c494b9 update the integration tests to run hg from the local repository
Summary:
Update the logic for how the Eden integration tests find the hg binary:
- Use the contents of the EDEN_HG_BINARY environment variable if set.  When
  running tests via `buck test` buck will pass the hg.par output location in
  this variable.
- If EDEN_HG_BINARY is not set, use libfb.py.pathutils to find the location of
  the //scm/hg:hg rule output.  This makes sure the integration tests still
  prefer this par path even when run manually without EDEN_HG_BINARY set.  This
  is convenient when running individual tests not through buck.

If for some reason the hg python_binary() output cannot be found then we still
search through $PATH for hg.real or hg as usual.  For internal fbsource builds
we generally shouldn't hit this fallback case, though.

Reviewed By: wez, quark-zju

Differential Revision: D6986221

fbshipit-source-id: 982cb99112405a674dbc45df4ada73a990536489
2018-02-15 11:41:28 -08:00
Wez Furlong
8ecd58130b fixup messaging in eden daemon --takeover
Summary:
We would immediately satisfy the health check and
tell the user that the system is healthy and show the pid of
the prior incarnation rather than the one for the instance
that we just launched.

This diff refactors the health checking code so that we can
share the implementation between the cli and the integration
tests; the integration tests already had code to do the right
thing for this.

Reviewed By: simpkins

Differential Revision: D6944989

fbshipit-source-id: 7c0f02c875b1b81f8f1b7521add67928200b27ed
2018-02-12 12:21:12 -08:00
Wez Furlong
3903de8e2f allow integration tests to select a storage engine
Summary:
This makes the default `memory` for speed and minimal
flakiness, but allows a test to select a different engine where
appropriate (eg: restart and remount tests).

Reviewed By: chadaustin

Differential Revision: D6944207

fbshipit-source-id: 1fb11387beda02d059a796dad5a42d56ddcf6e88
2018-02-08 20:06:55 -08:00
Wez Furlong
eaeaf8f23c add SqliteLocalStore
Summary:
Adds a SQLite storage implementation and makes it the
default engine for integration tests; this requires fewer resources
to run and the integration tests thus run faster and more reliably.

In the future we may add a configuration option to remember the
storage engine that was used as it is currently not "safe" to switch
from one to the other because the hgproxyhash data cannot be
recreated without re-importing a revision.

Reviewed By: simpkins

Differential Revision: D6919456

fbshipit-source-id: 3afbfafb190cca0e3c797cd9b7cd051768575a8c
2018-02-08 20:06:55 -08:00
Wez Furlong
72243b218a remove hypothesis timeout setting
Summary:
This was causing flakiness in the form of premature timeouts
generating failure status.  Looking at the docs for hypothesis, this
option is deprecated and slated to be replaced with an infinite timeout
in the future:

http://hypothesis.readthedocs.io/en/latest/settings.html#hypothesis.settings.timeout

Those docs suggest using `hypothesis.unlimited` instead, but I couldn't import
that symbol (maybe our version is too old?) so I'm just using 0 which means
that no timeout will be applied.

Reviewed By: simpkins

Differential Revision: D6908200

fbshipit-source-id: 1143d4745fc84d9c14b29ff5a2906a4e776d14fe
2018-02-05 19:35:55 -08:00
Wez Furlong
afac32487a enable integration tests on sandcastle
Summary:
A little bit of plumbing to enable the watchman<->eden integration tests on sandcastle.

I noticed that we were still referencing the lame thrift par that I removed a little while back,
so let's clean that up.

Reviewed By: simpkins

Differential Revision: D6863221

fbshipit-source-id: 026f3d316d9ac52fe359cedc4e3c88394ec5c7c4
2018-01-31 15:53:40 -08:00
Wez Furlong
53b84df124 allow running integration tests on sandcastle
Summary:
This is a fairly minimal attempt at asking sandcastle to
run our tests as root.  This is inspired by D6608746 but is for
the moment pretty coarse; I just want to see how successful this
is before finishing this off nicely, which means splitting our
contbuild config into two pieces along similar lines as D6608746;
one piece would run the tests as usual without root privileges
whilst the other would run just the integration tests with root
privs.

Reviewed By: chadaustin

Differential Revision: D6612669

fbshipit-source-id: 9a730b02424e939dd3509310b6265d50d1102e77
2018-01-31 11:48:21 -08:00
Wez Furlong
d6adcfc058 add fsattr utility for testing purposes
Summary:
This is the spiritual successor to D3302706 which originally
wanted to solve this by adding a python extension.  That would prove
to be too painful for the opensource build so it was shelved.

We now need to be able to run our tests in an environment that doesn't
have the `attr` rpm installed so this is a good time to fix this
in a more portable way.

This diff adds a little wrapper around the functions that we already
have for consuming extended attribute information and augments them
with another to list attributes.

The utility emits output in json format and is intended to be fed
directly into the helper functions we have in `fs.py`.

Reviewed By: chadaustin

Differential Revision: D6851182

fbshipit-source-id: 3d1d1a351f2e01405645d45658d1c8bc61a659a4
2018-01-30 21:50:39 -08:00
Michael Bolin
7673f16536 Add support for a more complete set of options to hg status.
Summary:
This adds support for the following flags for `hg status` in the Rust wrapper:

* `--all`
* `--modified`
* `--added`
* `--removed`
* `--deleted`
* `--clean`
* `--unknown`
* `--ignored`
* `--no-status`
* `--copies`

There is now a `create_print_config()` function that takes the parsed arguments
and distills them into a `PrintConfig`, which describes the net configuration
as a result of all the flags. (Note that some flags can interfere with each other,
e.g., `--no-status` forces `--copies` to be disabled.)

While here, I cleaned up a bunch of duplication in the code that prints the
status to stdout. Much of the duplication in the old implementation has been
encapsulated in a closure within the new `print_status()` function.
This also made it easier to implement `--copies` for all of the different status
types.

Incidentally, this helps us specify `listIgnored` correctly when calling the
`getScmStatus()` Thrift method as we now keep track of whether the user
specified `--ignored`. This is particularly important for the Eden integration
test suite because its `assert_status()` helper method calls
`hg status --print0 -mardui` by default, so `buck test eden/...` makes much
greater use of the Rust wrapper than it did before.

Reviewed By: wez

Differential Revision: D6770916

fbshipit-source-id: fea1a159addca6d16caa1b7019dc11dc2dcb3e1b
2018-01-26 17:52:14 -08:00
Sergey Zhupanov
1d219b5dc2 Removed unnecessary check and dir creation in edenclient.py for clone.
Summary: removed check for target dir of eden clone in edenclient

Reviewed By: simpkins

Differential Revision: D6770615

fbshipit-source-id: 4f480c2a494673179d92c0571082b9be895cf51b
2018-01-22 17:04:40 -08:00
Michael Bolin
b6639e37a5 Updated Rust wrapper so that hg status works again in Eden.
Summary:
The storage format for dirstate data in Eden changed substantially in D6179950.
Although `status.rs` was modified as part of that change, it was only updated to
make it so the rust wrapper still compiled, but it did not maintain the
correctness of the overall function.

This revision is a port of the logic in `eden/py/dirstate.py` and
`eden/hg/eden/EdenThriftClient.py` so that the Python code in the Eden/Hg
extension behaves the same as that of the Rust wrapper.

The current implementation of `hg status` in Rust does not relativize paths to `$PWD`, so
it always behaves as if `--root-relative` was specified. This should be fixed in a
follow-up revision.

Reviewed By: jsgf

Differential Revision: D6717211

fbshipit-source-id: ca900e251d392a77c07cb7305c4d4a62def1c7ab
2018-01-19 12:35:46 -08:00
Adam Simpkins
319b991379 rename stdout_charset to encoding for hg() and git() functions
Summary:
Rename the `stdout_charset` parameter to `encoding` now that we also use this
for encoding the stdin contents.

Reviewed By: wez

Differential Revision: D6757300

fbshipit-source-id: f79fc760e0f9fdcd6af559fcdad34976aaf16412
2018-01-18 20:24:08 -08:00
Adam Simpkins
6ed5a601cc improve passing stdin to hg in integration tests
Summary:
Update the `hg split` tests to pass input to the split command using
the `input` argument to `subprocess.run()` rather than running the command
through the shell and using a shell "here document".

Reviewed By: bolinfest, chadaustin

Differential Revision: D6746815

fbshipit-source-id: b607c554a249f702758dcad2ac4d863d1c1c7bad
2018-01-18 20:24:08 -08:00
Sergey Zhupanov
0b4fea5374 change eden clone to check out master commit in both git and hg.
Summary:
Changed `eden clone` to check out master commit in both git and hg.
Previously, it checked out the current commit for the repo.

Reviewed By: simpkins

Differential Revision: D6663754

fbshipit-source-id: 92b185ccca5d082dc2bde9c8b191c82a2a4f06b4
2018-01-13 14:26:32 -08:00
Adam Simpkins
9e162c71ca add type annotations to edenclient.py
Summary: Update this module with python type annotations.

Reviewed By: chadaustin

Differential Revision: D6665271

fbshipit-source-id: c24adacfeb20340fe55839b3ca65654dec1fb12c
2018-01-05 13:53:23 -08:00
Adam Simpkins
009d94353b fix integration tests after eden list output changes
Summary:
Update the integration tests to understand the new `eden list` output format
changes introduced in D6661303.

Reviewed By: chadaustin

Differential Revision: D6665272

fbshipit-source-id: 13f65a7a66f997e6b8135436811fe3fc396eb38f
2018-01-05 13:53:23 -08:00
Wez Furlong
fe3b0a6a70 fix edenfs_logging_settings in integration tests
Summary:
We're unconditionally emitting a `--` above, so the `--`
down here doesn't get stripped out by the logic in `do_daemon`
in the CLI and that renders it invisible to gflags:

Here's our `eden cli` invocation:

```
['/data/users/wez/eden-fbsource/fbcode/buck-out/gen/eden/cli/cli.par', '--config-dir', '/var/tmp/eden_test.15oico01/homedir/local/.eden', '--etc-eden-dir', '/var/tmp/eden_test.15oico01/etc-ed
en', '--home-dir', '/var/tmp/eden_test.15oico01/homedir', 'daemon', '--daemon-binary', '/data/users/wez/eden-fbsource/fbcode/buck-out/gen/eden/fs/service/edenfs', '--foreground', '--', '--num
_hg_import_threads', '2', '--', '--logging=eden.fs.store.hg=DBG9,eden.strace=DBG7']
```

This is what `eden cli` passes to `edenfs`:

```
edenfs_args ['--num_hg_import_threads', '2', '--', '--logging=eden.fs.store.hg=DBG9,eden.strace=DBG7']
```

Reviewed By: bolinfest

Differential Revision: D6628253

fbshipit-source-id: 2c6806e69baff52d14ca64194f1bf7d916833844
2017-12-22 12:36:25 -08:00
Philip Jameson
8604b8f5b0 Migrate TARGETS files from @/ to //
Summary:
This is a codemod to change from using @/ to // in basic cases.
- TARGETS files with lines starting with @/ (but excluding @/third-party:
- autodeps lines in source and TARGETS files ( (dep|manual)=@/ ), excluding @/third-party
- Targets in string macros

The only thing left of the old format should be @/third-party:foo:bar

drop-conflicts

Reviewed By: ttsugriy

Differential Revision: D6605465

fbshipit-source-id: ae50de2e1edb3f97c0b839d4021f38d77b7ab64c
2017-12-20 16:57:41 -08:00
Chad Austin
c57a490e74 only use 2 hg import processes in tests
Summary:
My devvm was running out of memory when running `buck test eden/...`.
Because Buck farms out tests across cores and each Eden integration
test launches 8 hg import daemons, there were over a hundred importer
processes live on the system.

Reviewed By: bolinfest, wez

Differential Revision: D6598276

fbshipit-source-id: d26916af79c24aa73abfa4c3ef9be3178657b6e7
2017-12-18 17:38:08 -08:00
Chad Austin
bbdac6e7fd bump edenfs startup timeout to 60 for integration tests
Summary:
I am seeing occasional timeouts on my smaller devvm when
running `buck test eden/integration/...`.

Reviewed By: bolinfest

Differential Revision: D6541864

fbshipit-source-id: 401deb8b44adae8cc362bbba8b638fe08abb9b1e
2017-12-12 10:52:19 -08:00
Adam Simpkins
42d5654314 make sure hg update --clean clears merge conflict state
Summary:
Make sure `hg update --clean` clears the merge state data.  In non-clean
updates this is performed in `mercurial.merge.applyupdates()`.  However, we
never call `applyupdates()` on clean updates in eden.

Reviewed By: bolinfest

Differential Revision: D6456720

fbshipit-source-id: b40d02ca0fb677bcde82822a8eafd5fcf926dae6
2017-12-01 16:35:57 -08:00
Michael Bolin
5e2afa735f Change how the UNTRACKED_ADDED conflict and merges are handled.
Summary:
Previously, we used the Mercurial code `g` when faced with an `UNTRACKED_ADDED`
file conflict, but that was allowing merges to silently succeed that should not
have. This revision changes our logic to use the code `m` for merge, which
unearthed that we were not honoring the user's `update.check` setting properly.

Because we use `update.check=noconflict` internally at Facebook, we changed the
Eden integration tests to default to verifying Hg running with this setting. To
support it properly, we had to port this code from `update.py` in Mercurial to
our own `_determine_actions_for_conflicts()` function:

```
if updatecheck == 'noconflict':
    for f, (m, args, msg) in actionbyfile.iteritems():
        if m not in ('g', 'k', 'e', 'r', 'pr'):
            msg = _("conflicting changes")
            hint = _("commit or update --clean to discard changes")
            raise error.Abort(msg, hint=hint)
```

However, this introduced an interesting issue where the `checkOutRevision()`
Thrift call from Hg would update the `SNAPSHOT` file on the server, but
`.hg/dirstate` would not get updated with the new parents until the update
completed on the client. With the new call to `raise error.Abort` on the client,
we could get in a state where the `SNAPSHOT` file had the hash of the commit
assuming the update succeeded, but `.hg/dirstate` reflected the reality where it
failed.

To that end, we changed `checkOutRevision()` to take a new parameter,
`checkoutMode`, which can take on one of three values: `NORMAL`, `DRY_RUN`, and
`FORCE`. Now if the user tries to do an ordinary `hg update` with
`update.check=noconflict`, we first do a `DRY_RUN` and examine the potential
conflicts. Only if the conflicts should not block the update do we proceed with
a call to `checkOutRevision()` in `NORMAL` mode.

To make this work, we had to make a number of changes to `CheckoutAction`,
`CheckoutContext`, `EdenMount`, and `TreeInode` to keep track of the
`checkoutMode` and ensure that no changes are made to the working copy when a
`DRY_RUN` is in effect.

One minor issue (for which there is a `TODO`) is that a `DRY_RUN` will not
report any `DIRECTORY_NOT_EMPTY` conflicts that may exist. As `TreeInode` is
implemented today, it is a bit messy to report this type of conflict without
modifying the working copy along the way.

Finally, any `UNTRACKED_ADDED` conflict should cause an update to
abort to match the behavior in stock Mercurial if the user has the following
config setting:

```
[commands]
update.check = noconflict
```

Though the original name for this setting was:

```
[experimental]
updatecheck = noconflict
```

Although I am on Mercurial 4.4.1, the `update.check` setting does not seem to
take effect when I run the integration tests, but the `updatecheck` setting
does, so for now, I set both in `hg_extension_test_base.py` with a `TODO` to
remove `updatecheck` once I can get `update.check` to do its job.

Reviewed By: simpkins

Differential Revision: D6366007

fbshipit-source-id: bb3ecb1270e77d59d7d9e7baa36ada61971bbc49
2017-11-29 21:50:34 -08:00
Adam Simpkins
a3aa8d11e7 add python type information to more integration test code
Summary: Annotate more integration test functions with type information.

Reviewed By: bolinfest

Differential Revision: D6434358

fbshipit-source-id: b88351eebee58561465752378c6771b7b1f9554e
2017-11-29 14:36:39 -08:00
Adam Simpkins
e64baf16db add a --takeover flag to allow graceful takeover
Summary:
This begins implementing the "client-side" portion of graceful takeover in
edenfs.  When the --takeover flag is specified, if edenfs finds that another
edenfs process is already running it will attempt to gracefully take over its
mount points rather than exiting with an error.

This does not yet actually take over the mount points themselves--it still
sends dummy mount information during shutdown, and does not use this data
during startup.  However, we do perform takeover of the eden lock file and the
thrift server socket.

Reviewed By: bolinfest

Differential Revision: D6038944

fbshipit-source-id: 42406a0559367cec79af088b4ca84c22de3f3ef3
2017-11-20 11:35:49 -08:00
Wez Furlong
06039c260f unmount defaults to non-destructive mode
Summary:
This flips the sense of the unmount command; previously
we would default to destroying the mount and associated state,
but this was a bit of a massive sharp edge to our UX.

Now the default is non-destructive and you have to explicitly
pass in `--destroy` to enable destructive mode.

Reviewed By: chadaustin

Differential Revision: D6346013

fbshipit-source-id: ce612e7d8a70540d63217a97f96bc5760f3951af
2017-11-16 09:07:31 -08:00
Adam Simpkins
a5991f1e4c add type annotations to some more integration test functions
Summary:
Add type annotations necessary to make `mypy --strict` pass cleanly on
`status_deadlock_test.py`

Reviewed By: bolinfest

Differential Revision: D6268257

fbshipit-source-id: b35db4b171c8a3631b5d7a1f1298fb9e68670ff1
2017-11-09 19:05:52 -08:00
Adam Simpkins
017f636ad3 add an integration test to exercise importing during "hg status"
Summary:
This adds an integration test that exercises a deadlock we could encounter in
the past.  An "hg status" operation could trigger many trees and files to be
imported.  Unfortunately the file import code currently blocks waiting for file
import futures to complete.  This could result in a state where all threads in
the pool were waiting for a file import to complete, and the file import was
waiting for a free thread to complete.

Reviewed By: bolinfest

Differential Revision: D6216871

fbshipit-source-id: e1795a543a71fccbed035febb159e126e27d1950
2017-11-07 19:04:20 -08:00
Michael Bolin
836b0e7f18 Minor cleanup to eden/integration/lib/hgrepo.py.
Summary:
A few fixes:

* Fix a bug where `date_str` would not get set when `date` was specified.
* Remove `from __future__ import` stuff since this code is Python 3.
* Add type annotations to the `commit()` method.

Reviewed By: simpkins

Differential Revision: D6261874

fbshipit-source-id: 5f942d01c107cd0265c2d6ec6e1f46295bb3ec24
2017-11-07 19:04:20 -08:00
Michael Bolin
250ee8c1eb Fix hg grep so it works when run from a subdirectory.
Summary:
It turns out that we had a small bug with our matcher code that did not account
for pattern normalization. I discovered this while dogfooding Eden and using
`hg grep <pattern> <directory>` from a subdirectory in my working copy. Given
that the fix was to patterns, in general, this likely fixes other `hg` commands
that take a file pattern when used someplace other than the repo root.

Reviewed By: wez

Differential Revision: D5825483

fbshipit-source-id: 0d639cbb2fc678c5459e02e965bf6fc6d7c10959
2017-09-13 12:57:40 -07:00
Michael Bolin
83b3c38095 Fix for hg split in Eden.
Summary:
Before this change, `hg split` crashed complaining that `node` was a
`changectxwrapper` instead of a 20-byte hash when it was sent as `parent1`
of `WorkingDirectoryParents` in `resetParentCommits()`. Now we use `node()` to
get the hash from the `destctx` that we have already extracted via this line
earlier in `merge_update()`:

    destctx = repo[node]

The change to `eden/hg/eden/__init__.py` eliminated the crash, but was
not sufficient on its own to make `hg split` work correctly. There was also a fix
required in `Dirstate.cpp` where the `onSnapshotChanged()` callback was clearing out
entries of both `NotApplicable` and `BothParents` from `hgDirstateTuples`.
It appears that only `NotApplicable` entries should be cleared. (I tried leaving
`NotApplicable` entries in there, but that broke `eden/integration/hg/graft_test.py`.)

I suspected that the logic to clear out `hgDestToSourceCopyMap` in
`Dirstate::onSnapshotChanged` was also wrong, so I deleted it and all of the
integration tests still pass. Admittedly, we are pretty weak in our test coverage
for use cases that write to the `hgDestToSourceCopyMap`. In general, we should
rely on Mercurial to explicitly remove entries from `hgDestToSourceCopyMap`.
We have a Thrift API, `hgClearDirstate()`, that `eden_dirstate` can use to categorically
clear out `hgDirstateTuples` and `hgDestToSourceCopyMap`, if necessary.

Finally, creating a proper integration test for `hg split` required creating a value for
`HGEDITOR` that could write different commit messages for different commits.
To that end, I added a `create_editor_that_writes_commit_messages()` utility as a
method of `HgExtensionTestBase` and updated its `hg()` method to take `hgeditor`
as an optional parameter.

Reviewed By: wez

Differential Revision: D5758236

fbshipit-source-id: 5cb8bf4207d4e802726cd93108fae4a6d48f45ec
2017-09-06 21:20:45 -07:00
Wez Furlong
948b584229 ensure that HGUSER doesn't impact the tests
Summary:
I had this set and it broke some of the integration tests.
Force it to be unset before running the tests.

Reviewed By: simpkins

Differential Revision: D5712624

fbshipit-source-id: 7d4aef86ef56f5880180b417e356e8a85abf11d7
2017-08-25 21:57:28 -07:00
Braden Watling
ab43c66a8d Add test to verify that eden debug getpath indicates when inodes are unloaded
Summary:
This test was supposed to be a part of D5627411 but it was causing strange behaviour so was brought to a separate diff for further investigation.

After investigating, the test didn't pass because the UnloadedInodeData struct only contained the name of the file, not the path to it. The fix for this was to implement a way to get the relative path of the file even after the inode is unloaded.

Reviewed By: simpkins

Differential Revision: D5646929

fbshipit-source-id: f166398a651e8aea49da7e4474a5ad7fde2eaa4e
2017-08-25 08:34:31 -07:00
Adam Simpkins
227d851a9b update integration tests to support multiple hg configs
Summary:
Update the integration test framework so that we can run the hg integration
tests with several different hg config settings, using different sets of
mercurial extensions.

This adds code to test using flat manifest, treemanifest in hybrid mode, and
treemanifest in tree only mode.  However, the treeonly configuration is
disabled at the moment due to some bugs in treeonly behavior preventing it from
being able to create test repositories in treeonly mode.

Reviewed By: bolinfest

Differential Revision: D5685880

fbshipit-source-id: 081ead4e77cd14a7feb03381783395bd5a8fef4f
2017-08-23 18:49:33 -07:00
Adam Simpkins
4d5a58444d add a new integration test for hg commit --amend
Summary: Add an test that runs `hg commit --amend`

Reviewed By: bolinfest

Differential Revision: D5685875

fbshipit-source-id: d23f760bf0ab3517d16d3b4658b1128d07577951
2017-08-23 16:53:36 -07:00
Adam Simpkins
9b6759e9d7 update hg.log() behavior in the integration tests
Summary:
This makes some minor tweaks to the behavior of the HgRepository.log() helper
function in the integration tests.

Previously this command did not take a revset argument, and instead relied on
the Facebook tweakdefaults extension to use the `--follow` behavior when no
revset was specified.  (Without tweakdefaults mercurial uses `tip:0` by
default, which is not what the histedit tests expect.)

I added a revset parameter now, and updated it to default to `::.`.  This is
close to the previous behavior, although I intentionally left it reporting
commits from oldest to newest now.

I also updated the log code to add its own delimiter to the template, rather
than requiring callers to always append an escaped nul byte to the template.

Reviewed By: bolinfest

Differential Revision: D5685876

fbshipit-source-id: 01578f62d553be1cd8002b5718d7f12a2f41d4d8
2017-08-23 16:53:36 -07:00
Adam Simpkins
8327c003e4 update integration tests to edit the repo .hgrc file
Summary:
Fix the integration tests to store hg config settings in the .hg/hgrc file in
the backing repository.  Previously the tests saved settings to a temporary
file, and then always invoked hg with HGRCPATH pointing at this temporary file.

Unfortunately this resulted in the integration test code using different hg
settings than edenfs, since edenfs was never aware of this temporary file.

Defining the settings in the backing repository's normal .hg/hgrc file means
that edenfs will be able to see these settings as well.  The eden post-clone
hooks will also automatically copy these settings in to the mount point, so
that we do not need to use a custom HGRCPATH setting inside the eden mount
either.

Reviewed By: bolinfest

Differential Revision: D5685877

fbshipit-source-id: 1857554d0cf1a585fe55577eb48a87686f9476ca
2017-08-23 15:06:47 -07:00
Michael Bolin
303655c4b1 Add integration test for hg copy.
Summary:
Note that this feature was mostly implemented before this commit, but never
tested. Unsurprisingly, there were bugs.

This change also introduces a new `eden debug hg_copy_map_get_all` subcommand
because that was a straightforward way to verify the internal state of the copy
map on the server side from an integration test.

Adding this test uncovered a key copy/paste bug in `EdenThriftClient.py`
(`hgCopyMapGet` was being invoked instead of `hgCopyMapPut`.)

It also uncovered a bug in `LameThriftClient` because the `compile()` and
`eval()` calls on the output are not appropriate when the return type of the
Thrift endpoint is `string`.

Reviewed By: simpkins

Differential Revision: D5686114

fbshipit-source-id: f0093d2b67062c01982dc5bc1f0db2774b3a9356
2017-08-22 21:06:07 -07:00
Michael Bolin
31eac649e2 Add integration test for rebasing in Hg.
Summary:
This is a relatively simple test that takes two branches with no conflicts and
rebases one on top of the other. It also provides modest checks to ensure Eden
does not load a bunch of inodes unnecessarily when updating to the new head.

This also introduces `EdenServerInspector`, which provides convenience methods
for inspecting the Eden server via Thrift.

Reviewed By: simpkins

Differential Revision: D5504741

fbshipit-source-id: 6636c431658f24a850d0e5404d1a0e4f0528a781
2017-07-27 17:24:01 -07:00
Adam Simpkins
128787b01b allow the hg_import_helper script to access pending commits
Summary:
This updates hg_import_helper.py to override
`mercurial.txnutil._mayhavepending()` to always return True.  This allows it
access to commits that are still part of a pending transaction, as long as
`writepending()` has been called on the transaction.  (We could have set the
`HG_PENDING` environment variable to the repository root path instead of
monkey-patching `_mayhavepending()`, but this felt more fragile--it requires
normalizing the repository root the same way that mercurial does, and making
sure we get the correct repository root when using the share extension.)

This allows us to remove our override of `commitctx.markcommitted()` in the hg
extension.  Previously we replaced this method to defer calling
`dirstate.setparents()` until the transaction was complete.  We no longer have
to do this since eden can now access the pending commit.

This should also help fix bugs in the rebase workflow where we previously
failed trying to checkout a still-pending commit.

Reviewed By: wez

Differential Revision: D5345451

fbshipit-source-id: 9c32ab655254c79f030c10b7c9d02563decb04f7
2017-07-07 18:45:02 -07:00
Adam Simpkins
d214153a34 add some extra logging in integration tests
Summary:
Add some extra logging to the eden integration to report event timing during
tests.  For now I have added some basic logging during set up and tear down.

Test setup is pretty slow for most of our tests.  It looks like some of this is
spent waiting for the eden daemon to start up, but a lot of it is just waiting
on hg commands.  A lot of tests currently make separate "hg add" calls for each
file they create during repository setup, and this is unfortunately really
slow.  Changing these tests to make fewer "hg add" calls would probably speed
things up a fair amount.

Reviewed By: wez

Differential Revision: D5367620

fbshipit-source-id: 99270c1dc4f072b7a0c0eaed7be7730e78b9bb8c
2017-07-07 15:43:42 -07:00
Adam Simpkins
b0dde83ff2 update logging flags in integration tests
Summary:
Update integration tests to pass logging settings in via the new `--logging`
argument instead of using `--vmodule`.  Now that eden log messages have all
been switched from glog to folly logging, the `--logging` flag needs to be
used.

Reviewed By: wez

Differential Revision: D5367618

fbshipit-source-id: 299f73a8376863e46b7fffe59c539e54c78caed4
2017-07-07 15:43:42 -07:00
Jyothsna Konisa
299f7d1373 Integration Test for UnnloadFreeInodes
Summary:
1. Moved read, write, mkdir, rm methods in hg/lib/hg_extension_test_base.py to lib/test_case.py.
2. Added integration test case to test unload free inodes.

Reviewed By: simpkins

Differential Revision: D5277870

fbshipit-source-id: b93b6049a10357cf8c92366e6dca3968f7f30c30
2017-06-22 22:38:47 -07:00
Andrew Gallagher
03bdaff954 codemod: format TARGETS with buildifier [4/5] (D5092623)
Reviewed By: igorsugak

fbshipit-source-id: 277a9d2bdc1d7e3ff3075bfe2d7307502fd0a507
2017-06-01 17:52:40 -07:00
Michael Bolin
57f5d72a27 Reimplement dirstate used by Eden's Hg extension as a subclass of Hg's dirstate.
Summary:
This is a major change to Eden's Hg extension.

Our initial attempt to implement `edendirstate` was to create a "clean room"
implementation that did not share code with `mercurial/dirstate.py`. This was
helpful in uncovering the subset of the dirstate API that matters for Eden. It
also provided a better safeguard against upstream changes to `dirstate.py` in
Mercurial itself.

In this implementation, the state transition management was mostly done
on the server in `Dirstate.cpp`. We also made a modest attempt to make
`Dirstate.cpp` "SCM-agnostic" such that the same APIs could be used for
Git at some point.

However, as we have tried to support more of the sophisticated functionality
in Mercurial, particularly `hg histedit`, achieving parity between the clean room
implementation and Mercurial's internals has become more challenging.
Ultimately, the clean room implementation is likely the right way to go for Eden,
but for now, we need to prioritize having feature parity with vanilla Hg when
using Eden. Once we have a more complete set of integration tests in place,
we can reimplement Eden's dirstate more aggressively to optimize things.

Fortunately, the [[ https://bitbucket.org/facebook/hg-experimental/src/default/sqldirstate/ | sqldirstate ]]
extension has already demonstrated that it is possible to provide a faithful
dirstate implementation that subclasses the original `dirstate` while using a different
storage mechanism. As such, I used `sqldirstate` as a model when implementing
the new `eden_dirstate` (distinguishing it from our v1 implementation, `edendirstate`).

In particular, `sqldirstate` uses SQL tables as storage for the following private fields
of `dirstate`: `_map`, `_dirs`, `_copymap`, `_filefoldmap`, `_dirfoldmap`. Because
`_filefoldmap` and `_dirfoldmap` exist to deal with case-insensitivity issues, we
do not support them in `eden_dirstate` and add code to ensure the codepaths that
would access them in `dirstate` never get exercised. Similarly, we also implemented
`eden_dirstate` so that it never accesses `_dirs`. (`_dirs` is a multiset of all directories in the
dirstate, which is an O(repo) data structure, so we do not want to maintain it in Eden.
It appears to be primarily used for checking whether a path to a file already exists in
the dirstate as a directory. We can protect against that in more efficient ways.)

That leaves only `_map` and `_copymap` to worry about. `_copymap` contains the set
of files that have been marked "copied" in the current dirstate, so it is fairly small and
can be stored on disk or in memory with little concern. `_map` is a bit trickier because
it is expected to have an entry for every file in the dirstate. In `sqldirstate`, it is stored
across two tables: `files` and `nonnormalfiles`. For Eden, we already represent the data
analogous to the `files` table in RocksDB/the overlay, so we do not need to create a new
equivalent to the `files` table. We do, however, need an equivalent to the `nonnormalfiles`
table, which we store in as Thrift-serialized data in an ordinary file along with the `_copymap`
data.

In our Hg extension, our implementation of `_map` is `eden_dirstate_map`, which is defined
in a Python file of the same name. Our implementation of `_copymap` is `dummy_copymap`,
which is defined in `eden_dirstate.py`. Both of these collections are simple pass-through data
structures that translate their method calls to Thrift server calls. I expect we will want to
optimize this in the future via some client-side caching, as well as creating batch APIs for talking
to the server via Thrift.

One advantage of this new implementation is that it enables us to delete
`eden/hg/eden/overrides.py`, which overrode the entry points for `hg add` and `hg remove`.
Between the recent implementation of `dirstate.walk()` for Eden and this switch
to the real dirstate, we can now use the default implementation of `hg add` and `hg remove`
(although we have to play some tricks, like in the implementation of `eden_dirstate.status()`
in order to make `hg remove` work).

In the course of doing this revision, I discovered that I had to make a minor fix to
`EdenMatchInfo.make_glob_list()` because `hg add foo` was being treated as
`hg add foo/**/*` even when `foo` was just a file (as opposed to a directory), in which
case the glob was not matching `foo`!

I also had to do some work in `eden_dirstate.status()` in which the `match` argument
was previously largely ignored. It turns out that `dirstate.py` uses `status()` for a number
of things with the `match` specified as a filter, so the output of `status()` must be filtered
by `match` accordingly. Ultimately, this seems like work that would be better done on the
server, but for simplicity, we're just going to do it in Python, for now.

For the reasons explained above, this revision deletes a lot of code `Dirstate.cpp`.
As such, `DirstateTest.cpp` does not seem worth refactoring, though the scenarios it was
testing should probably be converted to integration tests. At a high level, the role of
`DirstatePersistence` has not changed, but the exact data it writes is much different.
Its corresponding unit test is also disabled, for now.

Note that this revision does not change the name of the file where "dirstate data" is written
(this is defined as `kDirstateFile` in `ClientConfig.cpp`), so we should blow away any existing
instances of this file once this change lands. (It is still early enough in the project that it does
not seem worth the overhead of a proper migration.)

The true test of the success of this new approach is the ease with which we can write more
integration tests for things like `hg histedit` and `hg graft`. Ideally, these should require very
few changes to `eden_dirstate.py`.

Reviewed By: simpkins

Differential Revision: D5071778

fbshipit-source-id: e8fec4d393035d80f36516ac050cad025dc3ba31
2017-05-26 12:05:29 -07:00
Michael Bolin
2286e9fb14 Perform a basic histedit command and add an integration test.
Summary:
I had to add simple implementations to various things in `edendirstate`
in order to be able to run `hg histedit`. There is still a lot more to do, but
at least this gives us a starting point to iterate and a test to demonstrate
the most simple functionality.

Reviewed By: wez

Differential Revision: D5049308

fbshipit-source-id: 34727f633c003cacae44108eb3ece06590098c7b
2017-05-16 12:36:17 -07:00
Michael Bolin
145ca986a7 Specify HGRCPATH for Hg integration tests to make test environment hermetic.
Summary:
Note that we must specify quite a few extensions to get behavior that is
representative of how Hg works at Facebook.

Reviewed By: DurhamG

Differential Revision: D5057478

fbshipit-source-id: ee774a9b8dcebe82e4b19cc52f9b0b5a53e6420c
2017-05-15 11:11:00 -07:00
Adam Simpkins
5da361f55b improve building and importing of the eden hg extension
Summary:
This updates how we build and package the eden hg extension, and how we find it
during integration tests.

- Update the extension to always look relative to its current location to find
  the other modules it depends on.  This ensures that the integration tests
  always find modules from the local repository, and do not use the modules
  installed on the system.

- Add a buck rule to unpack the python archive at build time.  This is needed
  for integration tests to use the local version of the module.

- Ensure that we install a correct `hgext3rd/__init__.py` module in the eden
  extension directory.  This is required to correctly set up `hgext3rd` as a
  namespace package.  This also unfortunately needs to be a `.py` file, and not
  just a .pyc file.  (The pkgutil.expand_path() code looks specifically for
  directories containing `__init__.py` files, and does not check for
  `__init__.pyc`.)

- Update the extension to only try importing the native thrift modules if we
  are running python 2.7.6 or greater.  Python 2.7.6 is the first that supports
  unicode arguments to `struct.pack()`, which thrift requires.  Python 2.7.5 can
  import the thrift modules, but throws errors when trying to run them.

Reviewed By: bolinfest

Differential Revision: D4935279

fbshipit-source-id: 9af81736124c55476a5eb5beba9474a4371a639b
2017-04-24 11:14:34 -07:00
Adam Simpkins
ce0ce6fa4e move eden/fs/cli to eden/cli
Summary:
Move the code for the command-line tool up one directory, out of eden/fs.
This better separates the code so that eden/fs contains code for the edenfs
daemon, while eden/cli contains code for the command line tool.

Reviewed By: bolinfest

Differential Revision: D4888633

fbshipit-source-id: 5041e292c5353d05122eefe5db3257289e31239a
2017-04-14 11:39:01 -07:00
Adam Simpkins
8fcaefe6b2 implement hg reset
Summary:
Update the hg extension to implement dirstate.rebuild().  This is necessary for
the `hg reset` command.  This also now implements dirstate.setparents() for
cases when there is only one parent.

Reviewed By: wez

Differential Revision: D4823780

fbshipit-source-id: 802de006e03860995095dc3af17acb2eb05f4e8b
2017-04-06 17:50:43 -07:00
Adam Simpkins
78b42e4208 make vlog settings controllable on a per-test basis
Summary:
Update the integration test code to allow TestCase classes to control the
--vmodule settings used when starting the edenfs daemon.

D3851805 initially set the vlog level for RequestData to 5 to help debug
issues.  However, this log level doesn't really make sense for most of the
mercurial integration tests: most mercurial commands checks for the existence
of lots of files, causing the logs to be filled with useless ENOENT messages
when the RequestData log level is this high.

Reviewed By: wez

Differential Revision: D4814402

fbshipit-source-id: 1127c0a25b656ea1a710ca54a59a9407d66a5659
2017-03-31 18:21:44 -07:00
Adam Simpkins
8751f1b702 print stderr when an hg command fails in integration tests
Summary:
Update HgRepository.hg() to catch subprocess.CalledProcessError exceptions and
translate them into subclass that returns a more helpful message.

The CalledProcessError includes the command stderr as a member variable, but
unfortunately does not include this in the output from `__str__()`.  The stderr
output is usually important for helping debug test failures.

Reviewed By: wez

Differential Revision: D4814401

fbshipit-source-id: 4f010bb3ce33833c55d18768997d2d1bb6a001b8
2017-03-31 18:21:44 -07:00
Adam Simpkins
080134ea84 ignore ENOENT errors when invalidating FUSE inode entries
Summary:
The kernel can return ENOENT in response to invalidation notification if we
have never told the kernel about the inode in question.  This resulted in
spurious errors during checkout when updating files that were loaded internally
by edenfs rather than via FUSE call.  For instance, this was commonly triggered
by .gitignore files, which eden loads on its own to perform ignore processing.

Reviewed By: bolinfest

Differential Revision: D4752630

fbshipit-source-id: d4e092643a8d33cf33709f7e3664289f167ac093
2017-03-31 14:07:14 -07:00
Adam Simpkins
a18e042e1c tweak the hg integration test base class
Summary:
I found it rather awkward in HgExtensionTestBase that self.repo is not actually
the repository being tested.  It was instead the repostiory used as the backing
store for the mercurial data, and self.repo_for_mount was the repository being
tested.

This diff renames the two repository classes, so that self.backing_repo is now
the backing store repository, and self.repo is the repository being tested.

In order to do this I changed HgExtensionTestBase to derive directly from
EdenTestCase.  Previously it derived from EdenHgTest, and was letting
EdenHgTest set up self.repo.  It seemed more understandable to avoid deriving
EdenHgTest now since self.repo is not the repository that needs to be set up
initially.

Reviewed By: bolinfest

Differential Revision: D4752631

fbshipit-source-id: d8b542b0ecead66b965af1a582085345e28b2908
2017-03-31 11:39:48 -07:00
Adam Simpkins
49adc9c96b fix the behavior of "hg update --clean ."
Summary:
Previously the eden hg extension short-circuited the checkout operation if the
destination commit was the same as the one currently checked out.  This was
incorrect if --clean was specified, since we do need to reset the working
directory state in this case.

This updates the extension code to always make the thrift checkout() call when
doing a force checkout.

This also avoids calling applyupdates() to resolve conflicts when force=True.
When doing a force checkout, eden reports files with conflicts that it
overwrote, but these do not need to be resolved by mercurial.

Additionally, this also updates a couple other APIs that have recently been
changed in upstream mercurial: merge.update() now takes an updatecheck
argument, and repo.join() should now be written as repo.vfs.join().

Reviewed By: bolinfest

Differential Revision: D4752510

fbshipit-source-id: e1ee92d086315e35a1378f674e668876a667c0ce
2017-03-31 11:39:48 -07:00
Adam Simpkins
8884b46b3f move integration tests to eden/integration
Summary:
Move the integration tests from eden/fs/integration up one directory, to
eden/integration.

The main benefit is that this makes it easy to run just the edenfs unit tests
by running "buck test eden/fs/...".  These unit tests complete much more
quickly than the full set of integration tests, providing a faster test suite
to re-run repeatedly during development.  The integration tests can be run with
"buck test eden/integration/...", and the full set of tests can still be run
with "buck test eden/..."

Reviewed By: wez

Differential Revision: D4490247

fbshipit-source-id: 5ceb5a19526f56e1cb926f352fa30ad2f1212c05
2017-01-31 14:41:14 -08:00