Repository: zeppelin Updated Branches: refs/heads/master fdbfff209 -> 2842251b7
[ZEPPELIN-2693] Test: interpreter mode action test ### What is this PR for? Adding to interpreter mode (globally shared mode, Per user/Scoped mode, Per user/isolated mode) action case on Selenium test. Here is for checking scenario. #### 1. globally in shared mode ``` admin : set 'globally in shared' mode of python interpreter User 1: create new note User 1: Code â%python user = user1â in the first paragraph User 1: Code â%python print userâ in the second paragraph and run it User 1: Check if the result is user1 in the second paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 2: create new note User 2: Code â%python user = user2â in the first paragraph User 2: Code â%python print userâ in the second paragraph and run it User 2: Check if the result is user2 in the second paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 1: Run the second paragraph again. User 1: Check if the result is user2 in the second paragraph User 1: Restart python interpreter in the note. System: Check if the number of python interpreter and python process is 0 ``` #### 2. Per user in scoped mode ``` admin : set 'Per user in scoped' mode of python interpreter User 1: create new note User 1: Code â%python user = user1â in the first paragraph User 1: Code â%python print userâ in the second paragraph and run it User 1: Check if the result is user1 in the second paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 2: create new note User 2: Code â%python user = user2â in the first paragraph User 2: Code â%python print userâ in the second paragraph and run it User 2: Check if the result is user2 in the second paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 2 User 1: Run the second paragraph again. User 1: Check if the result is user1 in the second paragraph User 1: Restart python interpreter in the note. System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 2: Restart python interpreter in the note. System: Check if the number of python interpreter process is 0 System: Check if the number of python process is 0 User 1: Run the first paragraph User 2: Run the first paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 2 admin: Restart python interpreter in interpreter tab System: Check if the number of python interpreter process is 0 System: Check if the number of python process is 0 ``` #### 2. Per user in isolated mode ``` admin : set 'Per user in isolated' mode of python interpreter User 1: create new note User 1: Code â%python user = user1â in the first paragraph User 1: Code â%python print userâ in the second paragraph and run it User 1: Check if the result is user1 in the second paragraph System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 2: create new note User 2: Code â%python user = user2â in the first paragraph User 2: Code â%python print user" in the second paragraph and run it User 2: Check if the result is user 2 in the second paragraph System: Check if the number of python interpreter process is 2 System: Check if the number of python process is 2 User 1: Run the second paragraph again. User 1: Check if the result is user1 in the second paragraph User 1: Restart python interpreter in the note. System: Check if the number of python interpreter process is 1 System: Check if the number of python process is 1 User 2: Restart python interpreter in the note. System: Check if the number of python interpreter process is 0 System: Check if the number of python process is 0 User 1: Run the first paragraph User 2: Run the first paragraph System: Check if the number of python interpreter process is 2 System: Check if the number of python process is 2 admin : Restart python interpreter in interpreter tab System: Check if the number of python interpreter process is 0 System: Check if the number of python process is 0 ``` ### What type of PR is it? [ Test ] ### Todos - * [x] - add logic to check process - interpreter process and python process - * [x] - add logic to restart python interpreter button in note - * [x] - add logic to restart python interpreter in interpreter tab 1. * [x] - update and complete `Globally in shared mode` scenario 2. * [x] - make and complete `Per user in scoped mode` scenario 3. * [x] - make and complete `Per user in isolated mode` scenario ### What is the Jira issue? * [adding Interpreter mode test](https://issues.apache.org/jira/browse/ZEPPELIN-2693) ### How should this be tested? 1. build zeppelin with `mvn clean package -DskipTests` 2.1. total test : run `TEST_SELENIUM='true' mvn test -pl 'zeppelin-server' --am -DfailIfNoTests=false -Dtest=InterpreterModeActionsIT` 2.2. globally mode - `TEST_SELENIUM='true' mvn test -pl 'zeppelin-server' --am -DfailIfNoTests=false -Dtest=InterpreterModeActionsIT#testGloballyAction` 2.3. Per user in scoped mode - `TEST_SELENIUM='true' mvn test -pl 'zeppelin-server' --am -DfailIfNoTests=false -Dtest=InterpreterModeActionsIT#testPerUserScopedAction` 2.4. Per user in isolated mode - `TEST_SELENIUM='true' mvn test -pl 'zeppelin-server' --am -DfailIfNoTests=false -Dtest=InterpreterModeActionsIT#testPerUserIsolatedAction` ### Questions: * Does the licenses files need update? No * Is there breaking changes for older versions? No * Does this needs documentation? No Author: soralee <[email protected]> Closes #2438 from soralee/ZEPPELIN-2693_adding_Interpreter_mode_test and squashes the following commits: 1bca7f4e [soralee] fix: fix typo 40ecbe91 [soralee] fix: complete 3.Per user in isolated mode scenario 38e27f38 [soralee] fix: improve code 52aa05a2 [soralee] fix: complete 2.Per user in scoped mode scenario edb41a72 [soralee] fix: complete 1.globally in shared mode scenario b3e3bf93 [soralee] fix: add permission to user1 and user2, add todo annotation 8a1e8116 [soralee] Test: adding initial interpreter mode action test Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/2842251b Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/2842251b Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/2842251b Branch: refs/heads/master Commit: 2842251b77b48a66a022d84b2d43f0455e6a9419 Parents: fdbfff2 Author: soralee <[email protected]> Authored: Fri Jun 30 10:20:50 2017 +0900 Committer: Jongyoul Lee <[email protected]> Committed: Thu Jul 6 10:12:22 2017 +0900 ---------------------------------------------------------------------- .../integration/InterpreterModeActionsIT.java | 893 +++++++++++++++++++ 1 file changed, 893 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/2842251b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java new file mode 100644 index 0000000..212b04b --- /dev/null +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java @@ -0,0 +1,893 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zeppelin.integration; + +import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.CommandExecutor; +import org.apache.zeppelin.ProcessData; +import org.apache.zeppelin.AbstractZeppelinIT; +import org.apache.zeppelin.WebDriverManager; +import org.apache.zeppelin.ZeppelinITUtils; +import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.hamcrest.CoreMatchers; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.TimeoutException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.io.FileUtils; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import static org.junit.Assert.assertTrue; + +public class InterpreterModeActionsIT extends AbstractZeppelinIT { + private static final Logger LOG = LoggerFactory.getLogger(InterpreterModeActionsIT.class); + + @Rule + public ErrorCollector collector = new ErrorCollector(); + static String shiroPath; + static String authShiro = "[users]\n" + + "admin = password1, admin\n" + + "user1 = password2, admin\n" + + "user2 = password3, admin\n" + + "[main]\n" + + "sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager\n" + + "securityManager.sessionManager = $sessionManager\n" + + "securityManager.sessionManager.globalSessionTimeout = 86400000\n" + + "shiro.loginUrl = /api/login\n" + + "[roles]\n" + + "admin = *\n" + + "[urls]\n" + + "/api/version = anon\n" + + "/** = authc"; + + static String originalShiro = ""; + static String interpreterOptionPath = ""; + static String originalInterpreterOption = ""; + + static String cmdPsPython = "ps aux | grep 'zeppelin_python-' | grep -v 'grep' | wc -l"; + static String cmdPsInterpreter = "ps aux | grep 'zeppelin/interpreter/python/*' |" + + " sed -E '/grep|local-repo/d' | wc -l"; + + @BeforeClass + public static void startUp() { + if (!endToEndTestEnabled()) { + return; + } + try { + System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_HOME.getVarName(), "../"); + ZeppelinConfiguration conf = ZeppelinConfiguration.create(); + shiroPath = conf.getRelativeDir(String.format("%s/shiro.ini", conf.getConfDir())); + interpreterOptionPath = conf.getRelativeDir(String.format("%s/interpreter.json", conf.getConfDir())); + File shiroFile = new File(shiroPath); + if (shiroFile.exists()) { + originalShiro = StringUtils.join(FileUtils.readLines(shiroFile, "UTF-8"), "\n"); + } + FileUtils.write(shiroFile, authShiro, "UTF-8"); + + File interpreterOptionFile = new File(interpreterOptionPath); + if (interpreterOptionFile.exists()) { + originalInterpreterOption = StringUtils.join(FileUtils.readLines(interpreterOptionFile, "UTF-8"), "\n"); + } + } catch (IOException e) { + LOG.error("Error in InterpreterModeActionsIT startUp::", e); + } + ZeppelinITUtils.restartZeppelin(); + driver = WebDriverManager.getWebDriver(); + } + + @AfterClass + public static void tearDown() { + if (!endToEndTestEnabled()) { + return; + } + try { + if (!StringUtils.isBlank(shiroPath)) { + File shiroFile = new File(shiroPath); + if (StringUtils.isBlank(originalShiro)) { + FileUtils.deleteQuietly(shiroFile); + } else { + FileUtils.write(shiroFile, originalShiro, "UTF-8"); + } + } + if (!StringUtils.isBlank(interpreterOptionPath)) { + File interpreterOptionFile = new File(interpreterOptionPath); + if (StringUtils.isBlank(originalInterpreterOption)) { + FileUtils.deleteQuietly(interpreterOptionFile); + } else { + FileUtils.write(interpreterOptionFile, originalInterpreterOption, "UTF-8"); + } + } + } catch (IOException e) { + LOG.error("Error in InterpreterModeActionsIT tearDown::", e); + } + ZeppelinITUtils.restartZeppelin(); + driver.quit(); + } + + private void authenticationUser(String userName, String password) { + pollingWait(By.xpath( + "//div[contains(@class, 'navbar-collapse')]//li//button[contains(.,'Login')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + ZeppelinITUtils.sleep(500, false); + pollingWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName); + pollingWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password); + pollingWait(By.xpath("//*[@id='NoteImportCtrl']//button[contains(.,'Login')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + ZeppelinITUtils.sleep(1000, false); + } + + private void logoutUser(String userName) throws URISyntaxException { + pollingWait(By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + + userName + "')]"), MAX_BROWSER_TIMEOUT_SEC).click(); + pollingWait(By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + + userName + "')]//a[@ng-click='navbar.logout()']"), MAX_BROWSER_TIMEOUT_SEC).click(); + + By locator = By.xpath("//*[@id='loginModal']//div[contains(@class, 'modal-header')]/button"); + WebElement element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + driver.findElement(By.xpath("//*[@id='loginModal']//div[contains(@class, 'modal-header')]/button")).click(); + } + driver.get(new URI(driver.getCurrentUrl()).resolve("/#/").toString()); + ZeppelinITUtils.sleep(1000, false); + } + + private void setPythonParagraph(int num, String text) { + setTextOfParagraph(num, "%python\\n " + text); + runParagraph(num); + try { + waitForParagraph(num, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(num, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while setPythonParagraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + } + + @Test + public void testGloballyAction() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + //step 1: (admin) login, set 'globally in shared' mode of python interpreter, logout + InterpreterModeActionsIT interpreterModeActionsIT = new InterpreterModeActionsIT(); + interpreterModeActionsIT.authenticationUser("admin", "password1"); + pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]")); + pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"), + MAX_BROWSER_TIMEOUT_SEC).sendKeys("python"); + ZeppelinITUtils.sleep(500, false); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//button[contains(@ng-click, 'valueform.$show();\n" + + " copyOriginInterpreterSettingProperties(setting.id)')]")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]/div[2]/div/div/div[1]/span[1]/button")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//li/a[contains(.,'Globally')]")); + JavascriptExecutor jse = (JavascriptExecutor)driver; + jse.executeScript("window.scrollBy(0,250)", ""); + ZeppelinITUtils.sleep(500, false); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//div/form/button[contains(@type, 'submit')]")); + clickAndWait(By.xpath( + "//div[@class='modal-dialog']//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + clickAndWait(By.xpath("//a[@class='navbar-brand navbar-title'][contains(@href, '#/')]")); + interpreterModeActionsIT.logoutUser("admin"); + + //step 2: (user1) login, create a new note, run two paragraph with 'python', check result, check process, logout + //paragraph: Check if the result is 'user1' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + By locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + WebElement element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + String user1noteId = driver.getCurrentUrl().substring(driver.getCurrentUrl().lastIndexOf("/") + 1); + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user1\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user1")); + String resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + + interpreterModeActionsIT.logoutUser("user1"); + + //step 3: (user2) login, create a new note, run two paragraph with 'python', check result, check process, logout + //paragraph: Check if the result is 'user2' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user2\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user2")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 4: (user1) login, come back note user1 made, run second paragraph, check result, check process, + //restart python interpreter, check process again, logout + //paragraph: Check if the result is 'user2' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + waitForParagraph(2, "FINISHED"); + runParagraph(2); + try { + waitForParagraph(2, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(2, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart python interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not testGloballyAction"); + boolean invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + locator = By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + } + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("0")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("0")); + interpreterModeActionsIT.logoutUser("user1"); + } catch (Exception e) { + handleException("Exception in InterpreterModeActionsIT while testGloballyAction ", e); + } + } + + @Test + public void testPerUserScopedAction() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + //step 1: (admin) login, set 'Per user in scoped' mode of python interpreter, logout + InterpreterModeActionsIT interpreterModeActionsIT = new InterpreterModeActionsIT(); + interpreterModeActionsIT.authenticationUser("admin", "password1"); + pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + + clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]")); + pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"), + MAX_BROWSER_TIMEOUT_SEC).sendKeys("python"); + ZeppelinITUtils.sleep(500, false); + + clickAndWait(By.xpath("//div[contains(@id, 'python')]//button[contains(@ng-click, 'valueform.$show();\n" + + " copyOriginInterpreterSettingProperties(setting.id)')]")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]/div[2]/div/div/div[1]/span[1]/button")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//li/a[contains(.,'Per User')]")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]/div[2]/div/div/div[1]/span[2]/button")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//li/a[contains(.,'scoped per user')]")); + + JavascriptExecutor jse = (JavascriptExecutor)driver; + jse.executeScript("window.scrollBy(0,250)", ""); + ZeppelinITUtils.sleep(500, false); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//div/form/button[contains(@type, 'submit')]")); + clickAndWait(By.xpath( + "//div[@class='modal-dialog']//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + clickAndWait(By.xpath("//a[@class='navbar-brand navbar-title'][contains(@href, '#/')]")); + + interpreterModeActionsIT.logoutUser("admin"); + + //step 2: (user1) login, create a new note, run two paragraph with 'python', check result, check process, logout + //paragraph: Check if the result is 'user1' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + By locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + WebElement element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + String user1noteId = driver.getCurrentUrl().substring(driver.getCurrentUrl().lastIndexOf("/") + 1); + + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user1\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user1")); + + String resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user1"); + + //step 3: (user2) login, create a new note, run two paragraph with 'python', check result, check process, logout + // paragraph: Check if the result is 'user2' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '2' + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + String user2noteId = driver.getCurrentUrl().substring(driver.getCurrentUrl().lastIndexOf("/") + 1); + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user2\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user2")); + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("2")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 4: (user1) login, come back note user1 made, run second paragraph, check result, + // restart python interpreter in note, check process again, logout + //paragraph: Check if the result is 'user1' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + runParagraph(2); + try { + waitForParagraph(2, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(2, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user1")); + + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart python interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserScopedAction"); + boolean invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + locator = By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user1"); + + //step 5: (user2) login, come back note user2 made, restart python interpreter in note, check process, logout + //System: Check if the number of python interpreter process is '0' + //System: Check if the number of python process is '0' + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart python interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserScopedAction"); + invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + locator = By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("0")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("0")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 6: (user1) login, come back note user1 made, run first paragraph,logout + // (user2) login, come back note user2 made, run first paragraph, check process, logout + //System: Check if the number of python process is '2' + //System: Check if the number of python interpreter process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + waitForParagraph(1, "FINISHED"); + runParagraph(1); + try { + waitForParagraph(1, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(1, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + interpreterModeActionsIT.logoutUser("user1"); + + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + runParagraph(1); + try { + waitForParagraph(1, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(1, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("2")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 7: (admin) login, restart python interpreter in interpreter tab, check process, logout + //System: Check if the number of python interpreter process is 0 + //System: Check if the number of python process is 0 + interpreterModeActionsIT.authenticationUser("admin", "password1"); + pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + + clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]")); + pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"), + MAX_BROWSER_TIMEOUT_SEC).sendKeys("python"); + ZeppelinITUtils.sleep(500, false); + + clickAndWait(By.xpath("//div[contains(@id, 'python')]" + + "//button[contains(@ng-click, 'restartInterpreterSetting(setting.id)')]")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart this interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserScopedAction"); + invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("0")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("0")); + + interpreterModeActionsIT.logoutUser("admin"); + + } catch (Exception e) { + handleException("Exception in InterpreterModeActionsIT while testPerUserScopedAction ", e); + } + } + + @Test + public void testPerUserIsolatedAction() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + //step 1: (admin) login, set 'Per user in isolated' mode of python interpreter, logout + InterpreterModeActionsIT interpreterModeActionsIT = new InterpreterModeActionsIT(); + interpreterModeActionsIT.authenticationUser("admin", "password1"); + pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]")); + pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"), + MAX_BROWSER_TIMEOUT_SEC).sendKeys("python"); + ZeppelinITUtils.sleep(500, false); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//button[contains(@ng-click, 'valueform.$show();\n" + + " copyOriginInterpreterSettingProperties(setting.id)')]")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]/div[2]/div/div/div[1]/span[1]/button")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//li/a[contains(.,'Per User')]")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]/div[2]/div/div/div[1]/span[2]/button")); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//li/a[contains(.,'isolated per user')]")); + JavascriptExecutor jse = (JavascriptExecutor)driver; + jse.executeScript("window.scrollBy(0,250)", ""); + ZeppelinITUtils.sleep(500, false); + clickAndWait(By.xpath("//div[contains(@id, 'python')]//div/form/button[contains(@type, 'submit')]")); + clickAndWait(By.xpath( + "//div[@class='modal-dialog']//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + clickAndWait(By.xpath("//a[@class='navbar-brand navbar-title'][contains(@href, '#/')]")); + interpreterModeActionsIT.logoutUser("admin"); + + //step 2: (user1) login, create a new note, run two paragraph with 'python', check result, check process, logout + //paragraph: Check if the result is 'user1' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + By locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + WebElement element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + String user1noteId = driver.getCurrentUrl().substring(driver.getCurrentUrl().lastIndexOf("/") + 1); + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user1\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user1")); + + String resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user1"); + + //step 3: (user2) login, create a new note, run two paragraph with 'python', check result, check process, logout + // paragraph: Check if the result is 'user2' in the second paragraph + //System: Check if the number of python interpreter process is '2' + //System: Check if the number of python process is '2' + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//div[contains(@class, 'col-md-4')]/div/h5/a[contains(.,'Create new" + + " note')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + createNewNote(); + } + String user2noteId = driver.getCurrentUrl().substring(driver.getCurrentUrl().lastIndexOf("/") + 1); + waitForParagraph(1, "READY"); + interpreterModeActionsIT.setPythonParagraph(1, "user=\"user2\""); + waitForParagraph(2, "READY"); + interpreterModeActionsIT.setPythonParagraph(2, "print user"); + + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user2")); + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("2")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("2")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 4: (user1) login, come back note user1 made, run second paragraph, check result, + // restart python interpreter in note, check process again, logout + //paragraph: Check if the result is 'user1' in the second paragraph + //System: Check if the number of python interpreter process is '1' + //System: Check if the number of python process is '1' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + runParagraph(2); + try { + waitForParagraph(2, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(2, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + collector.checkThat("The output field paragraph contains", + driver.findElement(By.xpath( + getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("user1")); + + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart python interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserIsolatedAction"); + boolean invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + locator = By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("1")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("1")); + interpreterModeActionsIT.logoutUser("user1"); + + //step 5: (user2) login, come back note user2 made, restart python interpreter in note, check process, logout + //System: Check if the number of python interpreter process is '0' + //System: Check if the number of python process is '0' + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart python interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserIsolatedAction"); + invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + locator = By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("0")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("0")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 6: (user1) login, come back note user1 made, run first paragraph,logout + // (user2) login, come back note user2 made, run first paragraph, check process, logout + //System: Check if the number of python process is '2' + //System: Check if the number of python interpreter process is '2' + interpreterModeActionsIT.authenticationUser("user1", "password2"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + waitForParagraph(1, "FINISHED"); + runParagraph(1); + try { + waitForParagraph(1, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(1, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + interpreterModeActionsIT.logoutUser("user1"); + + interpreterModeActionsIT.authenticationUser("user2", "password3"); + locator = By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"); + element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.visibilityOfElementLocated(locator)); + if (element.isDisplayed()) { + pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + } + runParagraph(1); + try { + waitForParagraph(1, "FINISHED"); + } catch (TimeoutException e) { + waitForParagraph(1, "ERROR"); + collector.checkThat("Exception in InterpreterModeActionsIT while running Python Paragraph", + "ERROR", CoreMatchers.equalTo("FINISHED")); + } + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("2")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("2")); + interpreterModeActionsIT.logoutUser("user2"); + + //step 7: (admin) login, restart python interpreter in interpreter tab, check process, logout + //System: Check if the number of python interpreter process is 0 + //System: Check if the number of python process is 0 + interpreterModeActionsIT.authenticationUser("admin", "password1"); + pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); + + clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]")); + pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"), + MAX_BROWSER_TIMEOUT_SEC).sendKeys("python"); + ZeppelinITUtils.sleep(500, false); + + clickAndWait(By.xpath("//div[contains(@id, 'python')]" + + "//button[contains(@ng-click, 'restartInterpreterSetting(setting.id)')]")); + clickAndWait(By.xpath("//div[@class='modal-dialog']" + + "[contains(.,'Do you want to restart this interpreter?')]" + + "//div[@class='bootstrap-dialog-footer-buttons']//button[contains(., 'OK')]")); + locator = By.xpath("//div[@class='modal-dialog'][contains(.,'Do you want to restart python interpreter?')]"); + LOG.info("Holding on until if interpreter restart dialog is disappeared or not in testPerUserIsolatedAction"); + invisibilityStatus = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) + .until(ExpectedConditions.invisibilityOfElementLocated(locator)); + if (invisibilityStatus == false) { + assertTrue("interpreter setting dialog visibility status", invisibilityStatus); + } + + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsPython, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python process is", resultProcessNum, CoreMatchers.equalTo("0")); + resultProcessNum = (String) CommandExecutor.executeCommandLocalHost(cmdPsInterpreter, + false, ProcessData.Types_Of_Data.OUTPUT); + resultProcessNum = resultProcessNum.trim().replaceAll("\n", ""); + collector.checkThat("The number of python interpreter process is", resultProcessNum, CoreMatchers.equalTo("0")); + interpreterModeActionsIT.logoutUser("admin"); + } catch (Exception e) { + handleException("Exception in InterpreterModeActionsIT while testPerUserIsolatedAction ", e); + } + } +}
