博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nagios集成Selenium
阅读量:6708 次
发布时间:2019-06-25

本文共 23027 字,大约阅读时间需要 76 分钟。

Nagios与Selenium结合可以执行更复杂的页面检查,检测网站运行状态、任务运行情况等。

Nagios集成Selenium步骤:

  1. 编写一个用来调用测试用例的Java Main函数
  2. 编写运行测试用例的shell脚本check_selenium.sh
  3. 定义Nagios Command和Service

Java测试程序

说明:Java Main函数使用了 的CallSeleniumTest类,略作修改。

完整源码可从下载。

POM

4.0.0
org.itrunner
nagios-selenium
1.0
jar
UTF-8
1.8
3.141.5
maven-clean-plugin
3.1.0
maven-compiler-plugin
3.8.0
${jdk.version}
${jdk.version}
${project.encoding}
maven-resources-plugin
3.1.0
${project.encoding}
maven-jar-plugin
3.1.0
org.itrunner.tests.CallSeleniumTest
true
maven-assembly-plugin
3.1.0
src/assembly/assembly.xml
make-assembly
package
single
org.sonarsource.scanner.maven
sonar-maven-plugin
3.5.0.1254
org.seleniumhq.selenium
selenium-firefox-driver
${selenium.version}
org.seleniumhq.selenium
selenium-chrome-driver
${selenium.version}
org.seleniumhq.selenium
selenium-support
${selenium.version}
com.codeborne
phantomjsdriver
1.4.4
junit
junit
4.12
commons-cli
commons-cli
1.4
commons-io
commons-io
2.6

测试调用类

调用测试的入口类。

CallSeleniumTest

package org.itrunner.tests;import org.apache.commons.cli.*;import org.openqa.selenium.TimeoutException;import org.openqa.selenium.firefox.NotConnectedException;public class CallSeleniumTest {    private static int timeout = 30;    private static final int NAGIOS_OK = 0;    private static final int NAGIOS_WARNING = 1;    private static final int NAGIOS_CRITICAL = 2;    private static final int NAGIOS_UNKNOWN = 3;    private static final String NAGIOS_TEXT_OK = "OK";    private static final String NAGIOS_TEXT_WARNING = "WARNING";    private static final String NAGIOS_TEXT_CRITICAL = "CRITICAL";    private static final String NAGIOS_TEXT_UNKNOWN = "UNKNOWN";    private Options options = null;    private TestResult runTest(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {        Class
seleniumTestClass = (Class
) Class.forName(className); return seleniumTestClass.newInstance().run(); } public static void main(String[] args) { CallSeleniumTest seTest = new CallSeleniumTest(); Option optionClass = new Option("c", "class", true, "full classname of test case (required) e.g. \"org.itrunner.tests.hosts.Baidu\""); Option optionTimeout = new Option("t", "timeout", true, "timeout, default is 30"); Option optionVerbose = new Option("v", "verbose", false, "show a lot of information (useful in case of problems)"); Option optionHelp = new Option("h", "help", false, "show this help screen"); seTest.options = new Options(); seTest.options.addOption(optionClass); seTest.options.addOption(optionTimeout); seTest.options.addOption(optionVerbose); seTest.options.addOption(optionHelp); CommandLineParser parser = new DefaultParser(); CommandLine cmd = null; String output = NAGIOS_TEXT_UNKNOWN + " - Upps"; int nagios = NAGIOS_UNKNOWN; try { cmd = parser.parse(seTest.options, args); // has to be checked manually, otherwise you can't access the help message without specifying correct parameters if (cmd.hasOption("h") || !cmd.hasOption("c")) { usage(seTest.options); System.exit(nagios); //NOSONAR } if (cmd.hasOption("t")) { timeout = Integer.parseInt(cmd.getOptionValue("t")); } TestResult result = seTest.runTest(cmd.getOptionValue("c")); output = NAGIOS_TEXT_OK + " - " + cmd.getOptionValue("c") + " Tests passed - " + result.toString(); nagios = NAGIOS_OK; } catch (ParseException e) { output = NAGIOS_TEXT_UNKNOWN + " - Parameter problems: " + e.getMessage(); nagios = NAGIOS_UNKNOWN; usage(seTest.options); } catch (ClassNotFoundException e) { output = NAGIOS_TEXT_UNKNOWN + " - Test case class: " + e.getMessage() + " not found!"; nagios = NAGIOS_UNKNOWN; } catch (TimeoutException | CriticalException e) { output = NAGIOS_TEXT_CRITICAL + " - Test Failures: " + e.getMessage(); nagios = NAGIOS_CRITICAL; } catch (Exception e) { output = NAGIOS_TEXT_WARNING + " - Test Failures: " + processException(cmd, e); nagios = NAGIOS_WARNING; } finally { println(output); System.exit(nagios); //NOSONAR } } private static String processException(CommandLine cmd, Exception e) { if (cmd != null && cmd.hasOption("v")) { e.printStackTrace(); //NOSONAR } if (isCausedBy(e, NotConnectedException.class)) { return "Failed to connect to binary FirefoxBinary"; } return e.getMessage(); } private static void usage(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("check_selenium", options); println("This version of check_selenium was tested with:"); println(" - selenium 3.14.0"); println(" - selenium ide 3.3.1"); println(" - test case exported as Java / JUnit 4 / WebDriver"); println("Some example calls:"); println(" ./check_selenium.sh -c \"org.itrunner.tests.hosts.Baidu\""); println(" ./check_selenium.sh --class \"org.itrunner.tests.hosts.Baidu\""); } public static int getTimeout() { return timeout; } private static void println(String x) { System.out.println(x); //NOSONAR } private static
boolean isCausedBy(final Throwable exception, Class
clazz) { Throwable cause = exception; while (cause != null) { if (clazz.isInstance(cause)) { return true; } cause = cause.getCause(); } return false; }}

Shell脚本

check_selenium.sh

#!/bin/bashJAVA_HOME=/opt/java/jdk1.8.0_191$JAVA_HOME/bin/java -Djava.util.logging.config.file=logging.properties -jar $(dirname $0)/lib/nagios-selenium-1.0.jar $@

基础配置

config.ini

# drive type - chrome, firefox or phantomjsdriver.type=chromelog.file=chrome.loglog.level=FATALchrome.driver=/home/nagios/chrome/chromedrivergecko.driver=/home/nagios/gecko/geckodriverphantomjs.binary.path=/home/nagios/phantomjs/bin/phantomjsphantomjs.ghostdriver.path=/home/nagios/ghostdriver-master/src/main.jsproxy.host=baidu.url=https://www.baidu.combaidu.username=xxxxxx@163.combaidu.password=xxxxxx

Config

import java.io.FileReader;import java.io.IOException;import java.util.Properties;public enum Config {    CONFIG;    private static final String FILE_NAME = "config.ini";    private Properties properties;    Config() {        properties = new Properties();        try {            properties.load(new FileReader(CommonUtil.getJarPath() + FILE_NAME));        } catch (IOException e) { //NOSONAR            e.printStackTrace(); //NOSONAR        }    }    public String getDriverType() {        return getProperty("driver.type");    }    public String getLogFile() {        return getProperty("log.file");    }    public String getLogLevel() {        return getProperty("log.level");    }    public String getChromeDriver() {        return getProperty("chrome.driver");    }    public String getGeckoDriver() {        return getProperty("gecko.driver");    }    public String getPhantomJsBinaryPath() {        return getProperty("phantomjs.binary.path");    }    public String getPhantomJsGhostDriverPath() {        return getProperty("phantomjs.ghostdriver.path");    }    public String getProxyHost() {        return getProperty("proxy.host");    }    public String getBaiduUrl() {        return getProperty("baidu.url");    }    public String getBaiduUsername() {        return getProperty("baidu.username");    }    public String getBaiduPassword() {        return getProperty("baidu.password");    }    public String getProperty(String key) {        return properties.getProperty(key);    }}

测试用例

在nagios中运行Selenium测试时,为避免浪费资源,提高性能,一般不使用图形界面。

Selenium支持的Headless Web Driver:

  • HtmlUnitDriver

轻量级的Web Driver实现,基于HtmlUnit,纯Java、支持JavScript。HtmlUnit可以模拟Chrome、Firefox或IE浏览器,默认为Chrome。HtmlUnit使用了JavaScript引擎Rhino,主流浏览器没有采用Rhino的,测试时可能会有JavaScript兼容性问题。

org.seleniumhq.selenium
htmlunit-driver
2.33.1
public static WebDriver createHtmlUnitDriver() {    HtmlUnitDriver htmlUnitDriver = new HtmlUnitDriver(true);    if (hasProxy()) {        htmlUnitDriver.setProxySettings(getProxy());    }    return htmlUnitDriver;}
  • PhantomJSDriver

基于Headless Browser PhantomJS,对JavaScript的支持好,常用于网络监控,但PhantomJS项目现已暂停,selenium 3.8.1以后不再支持。

使用PhantomJSDriver时,需下载和,配置“phantomjs.binary.path”和“phantomjs.ghostdriver.path”。

  • FirefoxDriver

启用Headless模式:

FirefoxOptions options = new FirefoxOptions();options.setHeadless(true);

Selenium 3 FirefoxDriver提供两种DriverService:GeckoDriverService和XpiDriverService,默认使用GeckoDriverService,需安装firefox,下载,配置GeckoDriver路径。

FirefoxDriver与Nagios集成,若Driver没有正常执行quit(),会造成大量进程不能终止,临时目录堆积大量profile文件。

  • ChromeDriver

启用Headless模式:

ChromeOptions options = new ChromeOptions();options.setHeadless(true);

使用ChromeDriver,需安装Chrome,下载,配置ChromeDriver路径。

DriverFactory
创建ChromeDriver、FirefoxDriver或PhantomJSDriver。

package org.itrunner.tests;import org.openqa.selenium.Proxy;import org.openqa.selenium.chrome.ChromeDriverService;import org.openqa.selenium.chrome.ChromeOptions;import org.openqa.selenium.firefox.FirefoxDriverLogLevel;import org.openqa.selenium.firefox.FirefoxOptions;import org.openqa.selenium.firefox.GeckoDriverService;import org.openqa.selenium.phantomjs.PhantomJSDriver;import org.openqa.selenium.remote.DesiredCapabilities;import org.openqa.selenium.remote.RemoteWebDriver;import org.openqa.selenium.remote.service.DriverService;import java.io.File;import java.util.ArrayList;import java.util.List;import static org.itrunner.tests.utils.Config.CONFIG;import static org.openqa.selenium.phantomjs.PhantomJSDriverService.*;public class DriverFactory {    private static DriverService service;    private static RemoteWebDriver driver;    private DriverFactory() {    }    public static RemoteWebDriver createDriver() {        String driverType = CONFIG.getDriverType();        if (driverType.equals("phantomjs")) {            return createPhantomJSDriver();        }        if (driverType.equals("firefox")) {            return createFirefoxDriver();        }        return createChromeDriver();    }    public static RemoteWebDriver createChromeDriver() {        try {            service = new ChromeDriverService.Builder()                    .usingDriverExecutable(new File(CONFIG.getChromeDriver()))                    .usingAnyFreePort()                    .withSilent(true)                    .withVerbose(false)                    .withLogFile(new File(CONFIG.getLogFile()))                    .build();            service.start();            ChromeOptions options = new ChromeOptions();            options.setHeadless(true);            if (hasProxy()) {                options.setProxy(getProxy());            }            driver = new RemoteWebDriver(service.getUrl(), options);        } catch (Exception e) {            // do nothing        }        return driver;    }    public static RemoteWebDriver createFirefoxDriver() {        try {            service = new GeckoDriverService.Builder()                    .usingDriverExecutable(new File(CONFIG.getGeckoDriver()))                    .usingAnyFreePort()                    .withLogFile(new File(CONFIG.getLogFile()))                    .build();            service.start();            FirefoxOptions options = new FirefoxOptions();            options.setHeadless(true);            options.setLogLevel(FirefoxDriverLogLevel.fromString(CONFIG.getLogLevel()));            if (hasProxy()) {                options.setProxy(getProxy());            }            driver = new RemoteWebDriver(service.getUrl(), options);        } catch (Exception e) {            // do nothing        }        return driver;    }    public static RemoteWebDriver createPhantomJSDriver() {        DesiredCapabilities capabilities = new DesiredCapabilities();        capabilities.setJavascriptEnabled(true);        capabilities.setCapability(PHANTOMJS_EXECUTABLE_PATH_PROPERTY, CONFIG.getPhantomJsBinaryPath());        capabilities.setCapability(PHANTOMJS_GHOSTDRIVER_PATH_PROPERTY, CONFIG.getPhantomJsGhostDriverPath());        List
cliArgs = new ArrayList<>(); cliArgs.add("--web-security=false"); cliArgs.add("--ssl-protocol=any"); cliArgs.add("--ignore-ssl-errors=true"); capabilities.setCapability(PHANTOMJS_CLI_ARGS, cliArgs); // Control LogLevel for GhostDriver, via CLI arguments String[] ghostDriverCliArgs = {"--logFile=" + CONFIG.getLogFile(), "--logLevel=" + CONFIG.getLogLevel()}; capabilities.setCapability(PHANTOMJS_GHOSTDRIVER_CLI_ARGS, ghostDriverCliArgs); if (hasProxy()) { capabilities.setCapability("proxy", getProxy()); } driver = new PhantomJSDriver(capabilities); return driver; } public static void quit() { if (driver != null) { driver.quit(); } if (service != null) { service.stop(); } driver = null; service = null; } private static Proxy getProxy() { Proxy proxy = new Proxy(); proxy.setHttpProxy(CONFIG.getProxyHost()); return proxy; } private static boolean hasProxy() { return CONFIG.getProxyHost() != null && !CONFIG.getProxyHost().equals(""); }}

说明:

  1. 使用DriverService + RemoteWebDriver方式创建FirefoxDriver和ChromeDriver,退出时分别执行driver.quit()和service.stop(),这样可以避免单独使用driver.quit()时不能正常退出的问题。为了提高性能,也可以通过shell启动DriverService。
  2. 要禁用firefox日志,设置logfile路径为/dev/null
  3. 如未配置phantomjs.ghostdriver.path,则使用PhantomJS内部的GhostDriver。
  4. 如配置PhantomJS logLevel,必须设置phantomjs.ghostdriver.path才能启作用。

TestBase

测试基类

package org.itrunner.tests;import org.apache.commons.io.FileUtils;import org.junit.After;import org.junit.Before;import org.openqa.selenium.By;import org.openqa.selenium.NoSuchElementException;import org.openqa.selenium.TimeoutException;import org.openqa.selenium.remote.RemoteWebDriver;import org.openqa.selenium.support.ui.ExpectedCondition;import org.openqa.selenium.support.ui.WebDriverWait;import java.io.File;import java.io.IOException;import java.nio.charset.Charset;import java.util.concurrent.TimeUnit;import static java.lang.System.currentTimeMillis;import static org.openqa.selenium.OutputType.BYTES;import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;public abstract class TestBase {    protected RemoteWebDriver driver;    private long startTime;    private TestResult result = new TestResult();    @Before    public void setup() {        startTime = currentTimeMillis();        nextStep(this::createDriver, "init");        setTimeout();        addShutdownHook();    }    TestResult run() {        setup();        test();        tearDown();        setTotalTime();        return result;    }    @After    public void tearDown() {        nextStep(() -> DriverFactory.quit(), "destroy");    }    private void createDriver() {        driver = DriverFactory.createDriver();    }    public abstract void test();    protected void savePageSource(String host) {        try {            File sourceFile = new File("reports/" + host + ".html");            FileUtils.writeStringToFile(sourceFile, driver.getPageSource(), Charset.defaultCharset());        } catch (IOException e) { //NOSONAR            // do nothing        }    }    protected void takeScreenshot(String host) {        File imageFile = new File("reports/" + host + ".png");        try {            FileUtils.writeByteArrayToFile(imageFile, driver.getScreenshotAs(BYTES));        } catch (IOException e) { //NOSONAR            // do nothing        }    }    protected void nextStep(TestStep step, String stepName) {        long beginTime = currentTimeMillis();        try {            step.run();        } catch (TimeoutException | NoSuchElementException e) {            throw new CriticalException(stepName + " failed: " + e.getMessage(), e);        }        result.putStepTime(stepName, currentTimeMillis() - beginTime);    }    public boolean isElementPresent(By by) {        try {            return waitForElementPresent(by);        } catch (TimeoutException e) { //NOSONAR            return false;        }    }    protected void open(final String url) {        nextStep(() -> driver.get(url), "loading page");    }    public void click(final By by, String stepName) {        nextStep(() -> driver.findElement(by).click(), stepName);    }    protected void waitForTitlePresent(final String title) {        nextStep(() -> waitForCondition(titleIs(title)), "finding title");    }    private boolean waitForElementPresent(By by) {        return waitForCondition(visibilityOfElementLocated(by)).isDisplayed();    }    private 
T waitForCondition(ExpectedCondition
condition) { return (new WebDriverWait(driver, CallSeleniumTest.getTimeout())).until(condition); } private void setTimeout() { driver.manage().timeouts().implicitlyWait(CallSeleniumTest.getTimeout(), TimeUnit.SECONDS); } private void setTotalTime() { result.setTotalTime(currentTimeMillis() - startTime); } private void addShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread("Selenium Quit Hook") { @Override public void run() { DriverFactory.quit(); } }); }}

示例代码记录了每步执行的时间。

网站测试

package org.itrunner.tests.hosts;import org.itrunner.tests.TestBase;import org.junit.Test;import org.openqa.selenium.By;import static org.itrunner.tests.utils.Config.CONFIG;public class Baidu extends TestBase {    @Override    @Test    public void test() {        open(CONFIG.getBaiduUrl());        waitForTitlePresent("百度一下,你就知道");        nextStep(() -> {            driver.findElement(By.linkText("登录")).click();            driver.findElement(By.id("TANGRAM__PSP_10__footerULoginBtn")).click();            driver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys(CONFIG.getBaiduUsername());            driver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys(CONFIG.getBaiduPassword());            driver.findElement(By.id("TANGRAM__PSP_10__submit")).click();        }, "login");    }}

log配置

在nagios中运行是不需要selenium日志的,将其关闭。

logging.properties

org.openqa.selenium.level=OFF

打包装配

使用maven assembly打包,为便于随时调整配置,将配置文件放在Jar外。

bin
dir
libexec
true
lib
src/main/resources
.
check_selenium.sh
target/classes
lib
config.ini

打包后的结构如下:

Nagios集成Selenium
部署时将libexec目录下的内容拷贝到nagios/libexec目录即可。

配置Command和Service

Command

define command {    command_name  check_selenium    command_line  $USER1$/check_selenium.sh -c $ARG1$  }

Service

define service {    service_description  selenium_baidu   use                  service-check-05min    host_name            www.baidu.com    check_command        check_selenium!org.itrunner.tests.hosts.Baidu}

常见问题

  1. Error: Package: perl-Net-SNMP-6.0.1-7.el7.noarch (epel) Requires: perl(Crypt::DES)

    在RHEL 7安装perl-Net-SNMP时,报这个错误,请先到下载安装perl-Crypt-DES-2.05-20.el7.x86_64.rpm

  2. CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages

    Install nrpe:
    ./configure --enable-command-args

  3. NRPE installation error: configure: error: Cannot find ssl headers

    yum install openssl-devel

  4. (Service check timed out after 60.01 seconds)
    在nagios.cfg配置中service_check_timeout=60,如果页面检查超时,nagios将停止检查,根据实际情况调整参数

附录

安装Chrome

  1. 启用Google YUM repository

创建文件/etc/yum.repos.d/google-chrome.repo,内容如下:

[google-chrome]name=google-chromebaseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearchenabled=1gpgcheck=1gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
  1. 安装Signing Key
$ wget https://dl.google.com/linux/linux_signing_key.pub$ sudo rpm --import linux_signing_key.pub
  1. 安装Chrome
$ sudo yum install google-chrome-stable

参考资料

转载于:https://blog.51cto.com/7308310/2289762

你可能感兴趣的文章
iOS-<UITabBarControllerDelegate> 代理不执行
查看>>
easyui实现datagrid列标题拖动
查看>>
crm服务调用测试
查看>>
gitlab clone时出现HTTP Basic: Access denied的错误
查看>>
CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境
查看>>
在Websphere上修改项目的web.xml中的配置后不起作用
查看>>
JAVA 数据计算、取整、+1、四舍五入
查看>>
wshell修改了upload功能,増加显示图片功能
查看>>
ERP中标准成本的差异分析控制
查看>>
linux 中断的上半部和下半部
查看>>
单例模式的七种写法
查看>>
好用到吐血!APP设计利器Sketch
查看>>
Android TensorFlow环境搭建
查看>>
【细品架构1/100】架构之缘起
查看>>
在js中获取后台传出的json数据
查看>>
Drools的JSR94实现形式
查看>>
oracle的nvl和nvl2
查看>>
hdfs 写orc
查看>>
1.9 xz压缩和解压缩
查看>>
IDEA如何自动提示并补全syso和main呢?
查看>>