Feeds:
文章
评论

Environments

Openshift cartridges: python 2.7

Django 1.8

According to this thread, “Files in $OPENSHIFT_REPO_DIR/wsgi/static folder are served by Apache directly”, so we have the following setting works well.

setting.py

STATIC_URL = ‘/static/’

STATIC_ROOT = os.path.join(DJ_PROJECT_DIR, ‘../../static’)

STATICFILES_FINDERS = (

    ‘django.contrib.staticfiles.finders.FileSystemFinder’,

    ‘django.contrib.staticfiles.finders.AppDirectoriesFinder’,

)

STATICFILES_DIRS = (

    os.path.join(DJ_PROJECT_DIR, ‘../../dist’),

)

Note:

1) STATIC_URL and STATIC_ROOT map yourdomain.com/static/ to the $OPENSHIFT_REPO_DIR/wsgi/static.

2) We also set STATICFILES_DIRS to wsgi/dist as we also use browserify to bundle the sources, which are in /wsgi/static_src

3) Collecting static files to STATIC_ROOT is part of openshift’s deploy job. See the 4th step of this instruction.

 

React.js unit test

The recent project uses React.js, and React Bootstrap library. We found the following unittest setting works well:

  • runner: karma
  • framework:  mocha
  • JSX transformer: babel
  • dependency management: webpack

Setup

 

SUT (subject under test) : e.g. ./static/js/components/myComponent.js
tests: e.g. /static/js/components/__tests__/myComponent-test.js

package.json

"devDependencies": {
"babel-core": "^5.3.0",
"babel-loader": "^5.3.0",     # default install babel 6.+, but we need version 5.3+ to compile react-booststrap library
"expect": "^1.13.4",
"karma": "^0.13.16",
"karma-chrome-launcher": "^0.2.2",
"karma-cli": "^0.1.2",
"karma-mocha": "^0.2.1",
"karma-webpack": "^1.7.0",
"mocha": "^2.3.4",
"react": "^0.14.3",
"react-addons-test-utils": "*",
"react-bootstrap": "*",
"react-dom": "~0.14.0",
"webpack": "^1.12.9",
}

karma.conf.js

var webpack = require(‘webpack’);

module.exports = function (config) {
    config.set({
        browsers: [‘Chrome’],
        singleRun: true,
        frameworks: [‘mocha’],
        files: [
            ‘tests.webpack.js’
        ],
        preprocessors: {
            ‘tests.webpack.js’: [‘webpack’]
        },
        reporters: [‘dots’],
        webpack: {
            module: {
                loaders: [
                    {test: /\.jsx?$/, exclude: /node_modules/, loader: ‘babel-loader’}
                ]
            },
            watch: true
        },
        webpackServer: {
            noInfo: true
        }
    });
};

tests.webpack.js

var context = require.context(‘./static/js/components’, true, /-test\.jsx?$/);
context.keys().forEach(context);

Run test

npm test

Test strategies

Render the SUT

var myComponent = TestUtils.renderIntoDocument(<MyComponent prop1={prop1}/>);

Verify the SUT

expect(myComponent.state.state1).toBe(‘someState’);
expect(myComponent.props.prop1).toBe(‘someProp’);

Verify SUT’s DOM

// assume SUT is rendered as

contents

var node = ReactDOM.findDOMNode(myComponent);
expect(node.childNode.textContent).toBe(‘contents’);

 

Verify SUT’s child component

Several ways to access SUT’s child nodes:

  • Using React component’s ref property
  • Via the rendered DOM
  • TestUtils methods, e.g. TestUtils.scryRenderedDOMComponentsWithClass

Need to distinguish between an React component instance and a DOM node instance.

var childComponent = myComponent.refs.childRef;
expect(childComponent).toExist();
expect(childComponent.state.state1).toBe(‘someState’);
expect(childComponent.props.prop1).toBe(‘someProp’);

Verify SUT’s multiple child components of the same class/tag

var childNodes = TestUtils.scryRenderedDOMComponentsWithClass(myComponent, ‘label’); 
expect(childNodes.length).toBe(3);

Verify SUT’s child node

var childComponent = myComponent.ref.childRef;
var childNode = ReactDOM.findDOMNode(childComponent);
expect(childNode.textContent).toBe(‘something’);

Simulate SUT event

// assume SUT is rendered as

contents

var nodeHavingOnClickEvent = ReactDOM.findDOMNode(myComponent).firstChild;
TestUtils.Simulate.click(nodeHavingOnClickEvent);    // invoke node <span>’s onClick event

Simulate changes to SUT’ properties or state

myComponent.state.state1 = ‘anotherState’;
TestUtils.Simulate.change(myComponent);

Simulate changes to ReactBootstrap.Input’s value

/** e.g. render() : function() {
      return (
       

           
       

    );
}

*//

var input = myComponent.refs.input;
input.getInputDOMNode().value = ‘newValue’;
TestUtils.Simulate.change(input.getInputDOMNode());

Test ReactBooststrap’s modal

/**

ReactBooststrap’s modal has many child components, e.g. title, body, etc.
e.g. MyModal
render: function() {
        return (
           

               
                   
                        {this.props.title}
                   
                   
                        {this.props.body}
                   
                   
                   
               
           

        );
    }
*/   
    it(‘does not render when props.show is false’, ()=>{
        // render in the document
        var modal = TestUtils.renderIntoDocument(
            <MyModal show={false} />
        );
        var notFound = ReactDOM.findDOMNode(modal.refs.title);
        expect(notFound).toNotExist();
    });
    it(‘renders when props.show is true’, () => {
        // render in the document
        var modal = TestUtils.renderIntoDocument(
            <MyModal show={true} />
        );
        var found = ReactDOM.findDOMNode(modal.refs.title);
        expect(found).toExist();
    });

 

References

I prefer a comfort-for-eye background colour:  C7EDCC. Edit Sublime Text 3 Colour Theme is surprisingly easy.

 

Install PackageResourceViewer.

 

PackageResourceViewer: OpenResource

image

Then walk through the package resources, we need to open:

Color Scheme – Default

IDLE.tmTheme

Edit the the background value, and that’s it!

Winking smile

 

There is also an amazing cool colour theme editor:

http://tmtheme-editor.herokuapp.com

I bought TP-LINK AV500 wifi Powerline extender starter kits, including one TL-PA4010 and two TL-WPA4220. The best part of this solution is to extend the network as far as power line covers, and wifi clone.

The setup should be as easy as the following diagram and several button pressing. Unified Home Network

But, it was not. I could not tell why/how, but it did not work for me…

Lucky we can do it hard way, which guarantee success.

We need TP-LINK Powerline Scan tool (find in the product CD or this link). We then plug all powerline devices into wall sockets. We need at least one Ethernet cable.

We need to accomplish the following two tasks:

1) Add two TL-WPA4220 to TL-PA4010’s network.

Connect laptop to any TL-WPA4220 using Ethernet cable. Use the Powerline Scan tool to find and connect to the device. Login user and password are both ‘admin’. In the page, write down ‘Device Password’ and ‘Mac Address’. Find the info for the two TL-WPA4220.

Then connect to TL-PA4010 using Ethernet cable. Use the Powerline Scan tool to find and connect to the device. Login user and password are both ‘admin’. Click ‘Powerline’ -> ‘Station Setting’ in the left side menu. On the right side main page, click ‘Add New…’, enter a TL-WPA4220’s  Device Password, and any Device Name. And we are done adding TL-WPA4220 to TL-PA4010’s network.

2) Set TL-WPA4220 to clone home wifi. (necessary if home wifi router does not support WPS feature)

Use Ethernet cable to connect to TL-WPA4220. In the admin website, Click ‘Wireless’ -> ‘Wireless Setting’, edit SSID the same as home wifi SSID. ‘Wireless’ -> ‘Wireless Security’ to set the same authentication method and login password. Reboot the device to save the settings. Then we are done to set TL-WPA4220 to clone home wifi.

That’s it. I now have strong wifi signal in garden.

Google chromecast

Google Chromecast + Google Chrome brower + unlock youku extension. Ultimate solution. 🙂

Key words include: Windows 7 64bit, MinGW, Sublime Text 2 and CMake. github has this sublime text 2 c++ project boilerplate, which includes a CMakeLists.txt demonstrating linking to the Boost regex library.

Install MinGW

Download from MinGW Distro. This distribution includes up-to-date MinGW, as well as several often used libraries, e.g. Boost. Installation is as easy as extracting. Note that, GCC’s mode is C++11 by default since v11.2.

After extracting to C:\, add the following paths to the system environment variable PATH: (If not installed to C:\MinGW, we need further update cmake commond’s CMAKE_MAKE_PROGRAM in the project boilerplate.)

  • C:\MinGW\bin
  • C:\MinGW\lib
  • C:\MinGW\include

Install CMake

Download the Windows installer (only 32bit) from the official site.

After installed to the default path, add C:\Program Files (x86)\CMake 2.8\bin to PATH.

Set up Sublime Text 2

Assume Sublime Text 2 and Package Manager installed.

Use Package Manager to install CMake Syntax.

Download the project boilerplate.

Use the project boilerplate

Set the default Build System as make (Tools -> Build System –> make).

Ctrl+Shift+P –> cmake to run cmake

Ctrl+B to make

 

Will add “run” and “debug” two commands. And perhaps add auto complete suggestions supports for Sublime Text 2.

Reference Sites

今天,一个同事嘴唇上火了,我问他怎么了,他回答,但我没听懂。上网查了查“嘴唇上火”英文怎么说,有各种讨论和回复,但没找到准确的。然后,我向这位同事认真的请教:他曾经是一名GP。然后,我明白了,翻译“嘴唇上火”实际上是一个相当专业的医学术语问题,而且,中医“上火”概念的极大的影响了这个翻译(以及网上各种讨论)。

先抛出翻译:

  • Herpes labialis,中文意思是唇疱疹。这个是SNOMED CT推荐的术语。也是“嘴唇上火”的医学术语。
  • Herpes simplex,中文的意思是单纯疱疹,唇疱疹的更一般病症表述。
  • 略微口语化的表达可以是Cold sore或者Fever blister。值得一提的是,这两个略微口语化的表达是非常准确且有医学专业背景的。Cold sore是NHS官网上的。同时,两者都被SNOMED CT收录为Herpes labialis的同义词。

稍微分析一下:网上对“嘴唇上火”的翻译,大都从“火”来直译,这个是受中医“上火”的概念影响的。

我的分析,要从症状入手翻译:嘴唇上火的症状是嘴唇上起燎泡。水泡或者燎泡译为blister是准确的。其次,要从医学术语入手寻找翻译,那些燎泡是一种疱疹(herpes)。进一步,唇部的疱疹,即嘴唇上火,就是Herpes labialis。其中,labialis是唇的意思。

 

题外话:在确认“嘴唇上火”怎么翻译的过程中,也简单了解了这个病症:嘴唇上火,即唇疱疹,或者单纯疱疹,是一种病毒引起的局部病变。初次感染后,病毒会永远潜伏在人体内(感觉神经细胞内),然后因为某种诱因,再度发作。西医发现感冒/发烧是常见的诱因,所以被称作Cold sore或者Fever blister。

此外,我们熟知的“出水痘”也和“嘴唇上火”有点联系:水痘是病毒引起的,这个我们都知道了。而水痘的后遗症(远期并发症),叫做带状疱疹(Herpes Zoster,或者shingles),中医称作“缠腰龙”。“缠腰龙”的发作和“嘴唇上火”的发作原因类似,是因为长期潜伏在人体内的病毒(水痘病毒Varicella Zoster)再度发作引起的。

 

Reference:

  1. SNOMED CT: Systematized Nomenclature of Medicine Clinical Terms。是一个医学术语的国际标准。
  2. Wikipedia (小心各种疱疹的照片,比较恶心)
  3. “嘴唇上火”英文翻译的讨论:http://bbs.tianya.cn/post-english-126757-1.shtml
  4. Cord sore NHS page: http://www.nhs.uk/conditions/Cold-sore/Pages/Introduction.aspx

I was surprised there is no straight setting to automate unit tests after build for Visual C# projects. (Visual Studio 2010 Professional)

Quick answer: Set the Post-build event command line of the Test Project’s Build Events to the following script:

"$(DevEnvDir)mstest.exe" /runconfig:"$(SolutionDir)\Local.testsetting"s /testcontainer:"$(TargetPath)"

The idea is to use mstest.exe to run the Test Project automatically after build. If any of the unit tests fails, the build fails.

 

Long answer:

Say we have a simple Visual C# Console Application. The template generates a Program class. We add a member function int Program::Foo(int i), as the following:

public int Foo(int i)
{
    return i * 2;
}

We then add unit test(s) for this method, by right clicking on the Foo method, and selecting Create Unit Tests. Accept to create a new Visual C# Test Project.

image

 

Edit the unit test as needed.

Edit the Test Project’s Post-build event property: Project-> TestProject1 Properties … –> Build Events, and add the mstest.ext script from the top of this article.

Now press F7 to build the solution. You may find the following output of executing the unit tests.

Starting execution…
 
  Results               Top Level Tests
  ——-               —————
  Passed                TestProject1.ProgramTest.FooTest
  1/1 test(s) Passed
 
  Summary
  ——-
  Test Run Completed.
    Passed  1
    ———
    Total   1
  Results file:  … 

Test Settings: Local

Build succeeded.

 

Note that, if any of the unit tests fails, the build fails.

Nagios troubleshooting

1. 确认各个plugin单独能执行,往往是因为某些环境相关的设置(例如路径、例如权限)导致脚本本身不能执行。

2. 以非dameon的方式运行nagios,nagios.log的信息就显示在console上了。

bin/nagios etc/nagios.cfg

3. 检查nagios.log,nagios.cfg的log_file配置指定了nagios.log的位置。如果nagios.log并没有出现,可能是运行nagios的用户(在安装nagios时指定)没有对nagios.log所指定的目录的写权限。

4. 加速nagios启动后的查询的执行,在nagios.cfg中有如下配置影响nagios启动后的查询执行。

service_inter_check_delay_method

max_service_check_spread

service_interleave_factor

max_concurrent_checks

5. 设置nagios.cfg的debug_level配置,输出debug信息。debug信息输出到nagios.debug,其配置见debug_file。比较有用的是Macros,可以nagios处理Macros的结果,用于验证命令是否正确执行。

6. 自定义的plugin做好log输出,便于检查是否执行以及是否正确执行。

JavaScript and ActionScript can talk to each other via ExternalInterface API. It would be convenient to make this channel ready in the html-template of Flash Builder.

html-template can be found at {Flash Builder installation root path}/sdks/{Application’s default SDK}/templates/swfobject/index.template.html.

Add the following codes to after <body> tag

   <script type="text/javascript">
        function getSWF()
        {
            if (navigator.appName.indexOf("Microsoft") != -1)
            {
                return window["${application}"];
            }
            else
            {
                return document["${application}"];
            }
        }
        
        function jsLog(param)
        {
            console.log(param);
        }
    </script>

getSWF method returns the loaded SWF object. jsLog method is a default JavaScript method for ActionScript to call.

For example, say we implement a method called asLog in ActionScript, which is registered to ExternalInterface as:

ExternalInterface.addCallback("asLog", asLog); 

So, once the application is fired (we set Firefox as the default browser for Flash Builder), we can type the following code in Firefox Firebug console to call SWF’s asLog method:

swfObj = getSWF();
swfObj.asLog("something");

It’s handy to make this little change to Flash Builder’s default html-template.