搜尋此網誌

2017年9月25日 星期一

小魚舖大奇蹟 讀後心得


這本書主要是在介紹西雅圖舉世聞名派克魚舖的工作哲學
裡面有許多派克魚鋪員工的實際經驗分享。
主要的核心概念從一句”全在於你自己”開始。
講到”全在於你自己”就讓我想起 佛經裡面講的一句相由心生 以前我老媽 常跟我提到相由心生什麼的,我總是很 不以為然 ,心裡想難到別人揍我一拳, 痛的我愛愛叫,也是心理作用嗎?
隨著年紀漸長對許多事情的理解也有所不同,所謂的全在於你自己,其實講的就是每個人都可以做自己的主人 ,遇到一件事情,會有不同的感受,有高興難過悲傷快樂,但我們的心可以去選擇 要如何 去面對 這樣的事情。 這也就是所謂全在於你自己 別人的 所作所為你可能無法改變,但是至少你可以改變你自己。
書中的另一個重要的觀念就是所謂的目標與承諾 訂定目標勇敢承諾 可以 讓你的眼光變得不同。就如同派克魚舖 ,他們的目標是 要讓派克魚舖成為舉世聞名的魚舖,於是團隊中的每個人都徹底的投入以成為舉世聞名的目標而努力 。一旦有了這個目標, 讓許多好的事情開始發生, 彷彿宇宙 也聽到他們的聲音,新的機會也隨著出現。
仔細想想 從小到大都是跟著別人的要求過日子, 從來沒有仔細想過自己的目標是什麼,只是隨波逐流。 現在開始可以為自己訂立一個目標,勇於承諾,活在當下。

2017年9月15日 星期五

面對問題時該有的態度和方法

工作上總會遇到問題和困難,這時保持正確態度和方法就非常重要.
底下是看完 "沒了名片,你還剩下什麼?"書後再搭配工作經驗得到的一些感想.
1. 樂觀面對,相信問題一定有解決的方法
2. 跳脫舊有思維,換個角度看問題.
3. 尋求他人協助
4. 讓問題飛一會
5. 別急著找戰犯,一味的追究責任是無法解決問題的.
以上若想再深入了解,坊間有許多書籍可以參考.
建議大家平常有空可以去書局或圖書館逛逛~
或許有意想不到的收穫~

2017年8月22日 星期二

利用sipp 模擬voip client

一般VoIP閘道器常遇到和不同SIP伺服器之間有相容性的問題.

若無法透過遠端解決,常需要在本地端進行分析
常用的方式是請客戶抓包,再用wireshark 去解析.
但若看不出所以然,就需要去模擬客戶的行為.
sipp是一個蠻簡單的工具,可以去模擬UAC 或 UAS的行為.
把需要的scenario, header等寫入script ,再去執行即可.

安裝和基本教學在官網裏有詳細的介紹,這裏就不多說了.
http://sipp.sourceforge.net/

底下是以sipp模擬UAC,也就是一般俗稱的CALLER(發話端)

命令如下:
sipp [remote_ip]:[remote_port] -i [local_ip] -p [local_port] -s [service] -sf xxx.xml -l 1
其中 remote_ip為受話IP,可以是SIP SERVER,或CALLEE(受話端)
local ip則為 UAC本身的ip
-s 則為UAC的電話號碼
-sf 則為 script file,
-l 1 指的是執行一次.



<?xml version="1.0" encoding="ISO-8859-1" ?>

<!--  Start Register -->
<!-- usage: sipp [remote_ip]:[remote_port] -i [local_ip] -p [local_port] -s [service] -sf xxx.xml -l 1 -->
<!-- usage: sipp 10.10.10.100:5060 -i 10.10.10.100 -p 5061 -s 5422818 -sf UAC_BasicCaller.xml -r 1 -m 1-->

<scenario name="BasicCaller">  
    <send>
        <![CDATA[
            INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
            Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]
            From: <sip:7010@[local_ip]:[local_port]>;tag=[call_number]
            To: <sip:[service]@[remote_ip]:[remote_port]>
            Call-ID: [call_id]
            CSeq: [cseq] INVITE
            Contact: <sip:7010@[local_ip]:[local_port]>
            Max-Forwards: 70
            User-Agent: fredspqa
            Content-Type: application/sdp
            Content-Length: [len]

            v=0
            o=SIPP 31094920 31094920 IN IP4 [local_ip]
            s=Session
            c=IN IP4 [local_ip]
            t=0 0
            m=audio 33302 RTP/AVP 8
            a=rtpmap:8 PCMA/8000
      ]]>
    </send>
   
    <recv response="100" rtd="true">
    </recv>
   
    <recv response="180" optional="true">
    </recv>

    <recv response="183" optional="true">
    </recv>

    <recv response="200" rtd="true">
        <action>
            <ereg regexp=".*" search_in="hdr" header="To:" assign_to="2"/>
            <ereg regexp=".*" search_in="hdr" header="From:" assign_to="3"/>
            <ereg regexp=".*" search_in="hdr" header="Via:" assign_to="4"/>
        </action>
    </recv>   
   
    <send>
        <![CDATA[
            ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
            Via:[$4]
            From: [$2]
            To: [$3]
            Call-ID: [call_id]
            CSeq: [cseq] ACK
            Contact: <sip:7010@[local_ip]:[local_port]>
            Max-Forwards: 70
            User-Agent: fredspqa
            Content-Length: 0
        ]]>
    </send>
   
   
    <!-- wait another port ready        --> 
    <pause milliseconds="3000">
    </pause>
   
    <send retrans="30000">
        <![CDATA[
            BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
            Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]
            From: <sip:7010@[local_ip]:[local_port]>;tag=[call_number]
            To: <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
            Call-ID: [call_id]
            CSeq: [cseq] BYE
            Contact: <sip:7010@[local_ip]:[local_port]>
            Max-Forwards: 70
            User-Agent: fredspqa
            Content-Length:  [len]
            Content-Type: application/PulseCharge+xml

            <?xml version="1.0"?>
            <charging-info state="stop">
            </charging-info>
        ]]>
    </send>
   
    <recv response="200">
    </recv>

</scenario>


底下範例則為 以 sipp 當為UAS(受話端或 SIP server)
 命令為
sipp -i 10.10.10.10 -sf uas.xml

這個scenario一開始會持續的等待INVITE.
收到INVITE後會回180RING,
等0.5SEC後回 200 OK
最後再送BYE模擬掛電話的動作


<?xml version="1.0" encoding="windows-1252"?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<!-- usage:                                                                         -->
<!-- sipp 10.10.10.10:5060 -i 10.10.10.10 -p 5061 -sf register.xml -r 1 -m 1    -->
<!-- sipp -i 10.10.10.10 -sf uas.xml                                          -->
<!--                                                                    -->
<scenario name="Basic UAS responder">
  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
  <!-- are saved and used for following messages sent. Useful to test   -->
  <!-- against stateful SIP proxies/B2BUAs.                             -->
  <recv request="INVITE" crlf="true">
  </recv>

  <!-- The '[last_*]' keyword is replaced automatically by the          -->
  <!-- specified header if it was present in the last message received  -->
  <!-- (except if it was a retransmission). If the header was not       -->
  <!-- present or if no message has been received, the '[last_*]'       -->
  <!-- keyword is discarded, and all bytes until the end of the line    -->
  <!-- are also discarded.                                              -->
  <!--                                                                  -->
  <!-- If the specified header was present several times in the         -->
  <!-- message, all occurences are concatenated (CRLF seperated)        -->
  <!-- to be used in place of the '[last_*]' keyword.                   -->

  <send>
    <![CDATA[

      SIP/2.0 180 Ringing
      [last_Via:]
      [last_From:]
      [last_To:];tag=[call_number]
      [last_Call-ID:]
      [last_CSeq:]
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Length: 0

    ]]>
  </send>

  <send retrans="500">
    <![CDATA[

      SIP/2.0 200 OK
      [last_Via:]
      [last_From:]
      [last_To:];tag=[call_number]
      [last_Call-ID:]
      [last_CSeq:]
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Type: application/sdp
      Content-Length: [len]

      v=0
      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
      s=-
      c=IN IP[media_ip_type] [media_ip]
      t=0 0
      m=audio [media_port] RTP/AVP 0
      a=rtpmap:0 PCMU/8000

    ]]>
  </send>

  <recv request="ACK" optional="true" rtd="true" crlf="true">
  </recv>

  <recv request="BYE">
  </recv>

  <send>
    <![CDATA[

      SIP/2.0 200 OK
      [last_Via:]
      [last_From:]
      [last_To:]
      [last_Call-ID:]
      [last_CSeq:]
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Length: 0

    ]]>
  </send>

  <!-- Keep the call open for a while in case the 200 is lost to be     -->
  <!-- able to retransmit it if we receive the BYE again.               -->
  <pause milliseconds="4000"/>


  <!-- definition of the response time repartition table (unit is ms)   -->
  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>

  <!-- definition of the call length repartition table (unit is ms)     -->
  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>

</scenario>

2017年8月4日 星期五

網通產品測試常用的Linux Service

最Popular的Linux Server distribution 為Ubuntu Server
最新長期支援(穩定)版為 16.04 LTS(2016 年 04 月發表,五年支援,至 2021 年 04 月)
下載: https://www.ubuntu.com/download/server

常用的 Service:

Python for UI automation (Selenium )

利用Python 來實現UI 自動化的功能.
適合需要反覆設定的測試.
例如設定WiFi Channel 的場合或是讓待測物反覆重開機.



1. Installation

1.1  Install python3 on Windows 7
     https://www.python.org/downloads/
1.2 
1.3  If "api-ms-win-crt-runtime-l1-1-0.dll" error occurs, install VC++2015
1.4  Install pip
        https://jerrynest.io/windows-install-pip/
1.5  Install selenium via pip
     pip install selenium
1.6  Install editor Thonny
        http://thonny.org/
1.7  install selenium firefox web driver
    http://selenium-python.readthedocs.io/installation.html
    https://github.com/mozilla/geckodriver/releases
1.8  Install selenium IDE on firefox
    https://addons.mozilla.org/zh-TW/firefox/addon/selenium-ide/

2. Script example


1.      (Selenium module) Basic - get UI with JS
#優點: like browser and can record web via selenium IDE
#缺點: Slow and complex
from selenium import webdriver
import time

url="http://192.168.0.1//cgi-bin/luci/"
driver = webdriver.Firefox()
driver.get(url)
driver.find_element_by_xpath(u"//input[@type='button' and @value='reboot']").click()
time.sleep(2)
driver.quit()



2.      (Selenium module) Reboot device via UI 10000 times
# -*- coding: utf-8 -*-
# Function1: Login to UI
# Function2: Reboot device
# Function3: Print result output to file
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re, sys, os

class Test(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_ip = "192.168.2.3"
        self.username = "admin"
        self.password = "123"
        self.base_url = "http://"+ self.base_ip
        self.verificationErrors = []
        self.accept_next_alert = True
   
    def test_(self):
        driver = self.driver
        driver.get("http://"+self.username+":"+self.password+"@"+self.base_ip)
        driver.switch_to_alert()
        self.close_alert_and_get_its_text()





        time.sleep(5)
        i = 0
        now = time.strftime("%c")
        now1 = "Current date & time : " + now
        self.wfile("\r\n")
        self.wfile(now1)
        self.wfile("reboot times is ")
        while i <= 10000:
            driver.get(self.base_url + "/cgi-bin/luci/content/system_settings/initialization")
            driver.find_element_by_xpath(u"//input[@type='button' and @value='reboot']").click()
            time.sleep(80)
            i += 1
            self.wfile(", ")
            self.wfile(str(i))
           
    def wfile(self,a):
        wfile=os.path.splitext(__file__)[0]+".txt"
        self.f = open(wfile, 'a', encoding = 'UTF-8')
        f=self.f
        with f as g:
            print(a, end=" ")

            print(a, end=" ", file=g)
        f.close()

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
   
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
   
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
       
if __name__ == "__main__":


    unittest.main(exit=False)