Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(#2655): Race condition in activity status #2656

Merged
merged 4 commits into from
Feb 26, 2020
Merged

fix(#2655): Race condition in activity status #2656

merged 4 commits into from
Feb 26, 2020

Conversation

Curiousite
Copy link
Contributor

@Curiousite Curiousite commented Dec 3, 2019

Changelog Entry

Fixed

Description

Added check to prevent race-condition in activity status.

Specific Changes

Now state will only transfer to "connectingslow" if the previous state is "reconnecting".


  • Testing Added

@Curiousite
Copy link
Contributor Author

This is probably more of a workaround than a fix, since it doesn't address the underlying problem. It probably adds stability anyway since a state transition from anything else than "reconnecting" to "connectingslow" doesn't seem to make a lot of sense.

@cwhitten
Copy link
Member

cwhitten commented Dec 3, 2019

Hi @Curiousite, the failing test is below.

FAIL __tests__/offlineUI.js (118.225s)
  ● offline UI › should show "Taking longer than usual to connect" UI when connection is slow

    Expected image to match or be a close match to snapshot but was 0.1918402777777778% different from snapshot (442 differing pixels).
    �[1m�[31mSee diff for details:�[39m�[22m �[31m/home/vsts/work/1/s/__tests__/__image_snapshots__/chrome-docker/__diff_output__/offline-ui-js-offline-ui-should-show-taking-longer-than-usual-to-connect-ui-when-connection-is-slow-1-diff.png�[39m

      73 |     const base64PNG = await driver.takeScreenshot();
      74 | 
    > 75 |     expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
         |                       ^
      76 |   });
      77 | 
      78 |   test('should show "unable to connect" UI when credentials are incorrect', async () => {

      at _callee$ (__tests__/offlineUI.js:75:23)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:271:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)

@Curiousite
Copy link
Contributor Author

Hi @cwhitten, thnx for the reply. How can I run those tests locally? When I try npm test, I am greeted with the error message: "ECONNREFUSED connect ECONNREFUSED 127.0.0.1:4444" for most of the tests. I didn't find additional information on testing in the CONTRIBUTING.md

When I tested the behaviour itself it seems to work. After 15s the warning appears.

@corinagum
Copy link
Contributor

@Curiousite, please take a look at the README.md found in __tests__. If you could also take a look at CONTRIBUTING.md, that would be great.
With your fixes, could you also add an entry to the CHANGELOG.md? Please follow the format of the 'Fix' example at the top, and add it to the Unreleased Fixed section. Thank you!

@msftclas
Copy link

msftclas commented Dec 3, 2019

CLA assistant check
All CLA requirements met.

@Curiousite
Copy link
Contributor Author

Curiousite commented Dec 3, 2019

Hi @corinagum,
thanks for the fast reply and pointing me in the right direction. The tests should work now and I've included the the line in CHANGELOG.md.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 63.712% when pulling dd1b429 on Curiousite:master into 0fcd7fe on microsoft:master.

@compulim
Copy link
Contributor

compulim commented Dec 4, 2019

Although your fix is a workaround, it is also defensive programming. 😉

ECONNREFUSED localhost:4444 is because it tries to hit your local Docker. We use Chrome inside Docker to run tests for stability. If you follow Corina's suggestion, you should be able to set it up.

Can you add a test to show it's working? We write E2E tests and you can follow __tests__/offlineUI.js. You can consider: forcing Web Chat into error, and dispatch CONNECT_STILL_PENDING, and check that the UI is still showing error when your fix is applied. And when you remove your fix, the test should fail.

@Curiousite
Copy link
Contributor Author

Hi @compulim,
you're right, thanks. 😄

I tried to implement an E2E-Test, but somehow I can't wrap my head around the test suite. For example, when I setup a test like this (copy-pasted from the reconnection test):

test('should not show "Taking longer than usual to connect" when connection is (re/)established', async () => {
    const { driver } = await setupWebDriver({
      createDirectLine: options => {
        const reconnectingDirectLine = window.WebChat.createDirectLine(options);

        return {
          activity$: reconnectingDirectLine.activity$,
          postActivity: reconnectingDirectLine.postActivity.bind(reconnectingDirectLine),

          connectionStatus$: new Observable(observer => {
            const subscription = reconnectingDirectLine.connectionStatus$.subscribe({
              complete: () => observer.complete(),
              error: err => observer.error(err),
              next: connectionStatus => {
                observer.next(connectionStatus);
                // connectionStatus === ONLINE && observer.next(CONNECTING);
              }
            });

            return () => subscription.unsubscribe();
          })
        };
      },
      pingBotOnLoad: false,
      setup: () =>
        Promise.all([
          window.WebChatTest.loadScript('https://unpkg.com/core-js@2.6.3/client/core.min.js'),
          window.WebChatTest.loadScript('https://unpkg.com/lolex@4.0.1/lolex.js')
        ]).then(() => {
          window.WebChatTest.clock = lolex.install();
        })
    });

    await driver.executeScript(() => {
      window.WebChatTest.clock.tick(400); // "Connecting" will be gone after 400ms
      window.WebChatTest.clock.tick(14600); // Go to t=15s
    });
    
    await driver.executeScript(() => {
      window.WebChatTest.clock.tick(1); // Shortly after 15s, it will show "Taking longer than usual to connect"
    });
    
    const base64PNG = await driver.takeScreenshot()
    expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
  });

The screenshot shows the "Taking longer than usual to connect" message. But I just pass through the connectionstatus. Shouldn't it then be connected after the initial login? It doesn't seem to make a difference if the commented out line is in there or not. 🤔

@corinagum corinagum added the R8 label Dec 16, 2019
@corinagum corinagum added the QOL label Dec 17, 2019
@corinagum corinagum added this to the R8 milestone Jan 15, 2020
@compulim
Copy link
Contributor

I am updating your PR with a fix that target the root cause. Will rebase and merge in soon.

@compulim
Copy link
Contributor

compulim commented Feb 26, 2020

Rebased. Will merge once test succeeded.

@compulim compulim merged commit a9d020f into microsoft:master Feb 26, 2020
@Curiousite
Copy link
Contributor Author

@compulim Great! Thanks for looking into this and fixing it. 💯 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Race condition: "Taking longer than usual to connect"
6 participants