Commit Graph

23 Commits

Author SHA1 Message Date
Michael Bolin
28214295bb Add some extra assertions to GraftTest.
Summary:
In practice, if the `hg graft` succeeds in a weird way, `assert_status_empty()`
tells a lot more about what went wrong than the number of commits not matching up.

While here, I also added the following entry to the default `.hgrc` used in integration tests:

```
[ui]
origbackuppath=.hg/origbackups
```

I needed this for the change to `graft_test.py`. As we were already setting this option in
the `histedit_command.py` utility as a one-off and this is the default value of this setting
for our internal Mercurial use at Facebook, it seemed best to make it the default for all
of our integration tests. As such, I removed the one-off setting in `histedit_command.py`.

Reviewed By: simpkins

Differential Revision: D6180342

fbshipit-source-id: 6f0487624a1824459403126997ea52d1a7921feb
2017-10-30 21:38:14 -07:00
Adam Simpkins
74c1027bba flush pending transaction data in eden_dirstate_map.setparents()
Summary:
Previously we flushed the pending transaction data in
eden_dirstate.setparents().  However, some dirstate code paths (particularly
dirstate.rebuild()) can directly call eden_dirstate_map.setparents().

We need to make sure the transaction data is flushed in this case.

Reviewed By: bolinfest

Differential Revision: D6175410

fbshipit-source-id: 256cb07f57ada02d6c1f118ec5075fb8ac93506c
2017-10-27 14:26:30 -07:00
Michael Bolin
a286ad53e5 Introduce eden debug hg_dirstate command.
Summary:
Add an `eden debug hg_dirstate` command to dump the contents of the Hg dirstate.
This data is stored in a binary format, so we need a custom command to view it
easily.

Reviewed By: simpkins

Differential Revision: D6139172

fbshipit-source-id: 622c0b7bcaa471a88483c6c4ddef7e0be95a3dfa
2017-10-25 22:36:06 -07:00
Adam Simpkins
2e6ed25612 flush kernel caches properly for empty directories removed by checkout
Summary:
When performing an source control checkout operation, we attempt to remove
directories that are empty after the checkout.  However, this code path was
missing a call to flush the kernel cache for these directories.

As a result, even though eden thought the directory not longer existed, and
would not report it in `readdir()` results, the kernel would return stale
information from its cache when explicitly accessing this path.

Reviewed By: bolinfest

Differential Revision: D6151543

fbshipit-source-id: 6031feb268ff6f980c885efb26c3d43243dec3f4
2017-10-25 16:51:56 -07:00
Michael Bolin
264d6fa9b7 Fix bug where hg histedit --abort does not restore file as "normal".
Summary:
This ports some logic from Mercurial's `dirstate.py` to our `eden_dirstate.py`.
It was known that Eden was missing this behavior (D5686636), but we did not have
an integration test that demonstrated the importance of this logic until now.

Admittedly, the current implementation ports the logic verbatim from
`dirstate.py`, though this will yield quite a number of Thrift calls in the Eden
implementation. We will address this in a subsequent revision.

Reviewed By: simpkins

Differential Revision: D6046273

fbshipit-source-id: f7a27ba6dca36cddac898f19637f29f3bc79a0cb
2017-10-12 19:28:11 -07: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
Michael Bolin
442feff98f Add integration test for hg move.
Summary:
Fortunately, this passed on the first try: it did not require any bug fixes in
Eden! Though admittedly, most of the relevant fixes were presumably done in
D5686114.

(Note: this ignores all push blocking failures!)

Reviewed By: simpkins

Differential Revision: D5696055

fbshipit-source-id: 0099db501ae1a5d72528d222dee0176fc1fc4332
2017-08-24 14:23:38 -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
14c865bb88 disable evolve and fsmonitor extensions in integration tests
Summary:
Update the integration tests to no longer enable the evolve or fsmonitor
extensions in the test repositories.

evolve has been deprecated at Facebook for a while now and isn't even shipped
as part of our mercurial installation any more.  This settings was just causing
a warning to be printed that this extension could not be found.

The fsmonitor extension also didn't have any real effect, even in the backing
repository.  We don't create .watchmanconfig files in the test repositories, so
watchman won't watch them.  Therefore fsmonitor simply printed warnings that
watchman wasn't watching this repository.

Reviewed By: bolinfest

Differential Revision: D5685879

fbshipit-source-id: 85b8a725bd17890a93be5c71dd5a0f3f1d744598
2017-08-23 15:06:47 -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
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
33ec2b7526 Add directaccess to the list of extensions we enable during integration tests.
Summary:
I was working on a new test and I got an error that `directaccess` must be
enabled for `inhibit` to work.

Reviewed By: simpkins

Differential Revision: D5077133

fbshipit-source-id: cc5235c845e3f299f96e1c901ef4aea18ca57b76
2017-05-18 20:35:36 -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
Michael Bolin
85a107c550 Set ui.username in ~/.hgrc in integration tests.
Summary:
Recall that we override `$HOME` in integration tests, so this will not overwrite
your personal `~/.hgrc` when you run an integration test.

An upcoming integration test for `hg histedit` that I am working on requires
this value to be set.

Reviewed By: wez

Differential Revision: D5051112

fbshipit-source-id: 2fd8541aa6504640b08337fdc22160e243beaae3
2017-05-12 13:05:50 -07:00
Michael Bolin
f766fe0a87 Update Hg integration tests to use assert_status().
Summary:
`HgExtensionTestBase.assert_status()` was added in D4814422, but it was only
applied to `update_test.py`. This change updates the docstring (it appears to
have been copy/pasted from a nearby method), and makes use of it in the other
integration tests.

Reviewed By: wez

Differential Revision: D5050775

fbshipit-source-id: bb70740b6f455a84e7a22c3286c8ddbe2462f816
2017-05-12 09:19:57 -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
879fabdcc8 add an assert_status() method to the hg integration tests
Summary:
Add an assert_status() method to the hg integration tests that runs "hg
status", parses the output, then compares it to expected results.

Reviewed By: wez

Differential Revision: D4814422

fbshipit-source-id: 24ebdc2e0239c4833953c31e5786cc320bcd9d62
2017-03-31 18:21:44 -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