æåã®éšåã¯ãå¯èœæ§ã®æŠèŠã§ããã ãããŠããã®ããŒãã§ã¯ãã©ã®ãã¹ãã€ã³ã¿ãŒãã§ã€ã¹ãæ¢ã«å®è£
ãããŠããããç¬èªã®ãã¹ãã€ã³ã¿ãŒãã§ã€ã¹ãè¿œå ããæ¹æ³ã«ã€ããŠæ€èšããŸãã
ã©ã¡ãããšããã°ãããã«
èšäºã®æåã®éšåãžã®ãªã³ã¯
ããããŸãçŸåšãuniset2-testsuiteã¯3ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ããµããŒãããŠããŸãã
- ãŠãã»ãã
- modbus
- snmp
ã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ã=ãunisetã
æåã®éšåã§æžããããã«ã
uniset2-testsuiteå
šäœ
ã¯ãæåã¯
libunisetã䜿çšããŠãããžã§ã¯ãããã¹ãããããã«éçºãã
ãŸãã ã ãããã£ãŠã
type =â unisetâã¯ãéçºãããæåã®ã¡ã€ã³ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã ãŠãã»ãããããžã§ã¯ãã§ã¯ãäž»ãªèŠçŽ ã¯ãã»ã³ãµãŒãã§ãããäžæã®èå¥åïŒæ°å€ã§ãããæåååã䜿çšã§ããŸãïŒãšãèšå®ãŸãã¯åä¿¡ã§ããå€ããããŸãã ãããã£ãŠããã¹ãã·ããªãªã§ã¯ããã¹ãŠããããã®ã»ã³ãµãŒãšãã®å€ã®ãã§ãã¯ãäžå¿ã«å±éããŸãã ããã§èª¬æãããã¢ã«ãŽãªãºã ãå®è£
ããç°¡åãªã¹ã¯ãªããã®äŸ
ã§ã ã
<?xml version = '1.0' encoding = 'utf-8'?> <TestScenario> <TestList type="uniset"> <test name="Processing" comment=" "> <action set="OnControl_S=1" comment=" ' '"/> <check test="CmdLoad_C=1" comment=" ''"/> <check test="CmdUnload_C=0" comment=" ''"/> <check test="Level_AS>=90" comment=" .." timeout="15000"/> <check test="CmdLoad_C=0" comment=" ''"/> <check test="CmdUnload_C=1" comment=" ''"/> <check test="Level_AS<=10" comment=" .." timeout="15000"/> </test> <test name="Stopped" comment=" "> <action set="OnControl_S=0" comment=" ' '"/> <check test="CmdLoad_C=0" comment=" '' " holdtime="3000"/> <check test="CmdUnload_C=0" comment=" '' " holdtime="3000"/> <check test="Level_AS<=80" comment=" " holdtime="10000"/> </test> </TestList> </TestScenario>
ã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ã=ãmodbusã
ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãæšæºã®
Modbus TCPãããã³ã«ã䜿çšããŠãã¹ãäžã®ã·ã¹ãã ãšéä¿¡ã§ãããããåºç¯å²ã®äœ¿çšã«ãšã£ãŠããèå³æ·±ããã®
ã§ã ã ããã䜿çšãããã¹ãã·ããªãªã¯æ¬¡ã®ãšããã§ãã
<?xml version = '1.0' encoding = 'utf-8'?> <TestScenario type="modbus"> <Config> <aliases> <item type="modbus" alias="mb1" mbslave="localhost:2048" default="1"/> <item type="modbus" alias="mb2" mbslave="localhost:2049"/> </aliases> </Config> <TestList > <test name="Test simple read"> <check test="0x10!=0"/> <check test="0x24:0x04!=0"/> <check test="0x24!=0"/> <check test="0x1@0x02:0x02!=0" config="mb2"/> <check test="0x24:0x06!=0"/> </test> <test name="Test simple write"> <action set="0x25=10"/> <action set="0x25:0x10=10"/> <action set="0x25@0x02=10" config="mb2"/> <action set="0x25@0x02:0x05=10" config="mb2"/> </test> <test name="Test other 'check'"> <check test="0x20=0x20" timeout="1000" check_pause="100"/> <check test="0x20=0x20"/> </test> <test name="Test 'great'"> <action set="109=10"/> <check test="109>=5"/> <check test="109>=10"/> </test> <test name="Test 'less'"> <action set="109=10"/> <check test="109<=11"/> <check test="109<=10"/> </test> <test name="Test other 'action'"> <action set="20@2=1,21@0x02:5=1,103@2:0x10=12" config="mb2"/> </test> </TestList> </TestScenario>
æåã«ã
æ§æã»ã¯ã·ã§ã³ã§ãäœæ¥ãå®è¡ããã2ã€ã®ããŒãã®ãã©ã¡ãŒã¿ãŒãå®çŸ©ãããŸãã æ¡ä»¶ä»ãã§ããããã«ã¯
mb1ããã³
mb2ãšããååãå²ãåœãŠãããŸãã ãããã®1ã€ã
ããã©ã«ããšããŠå²ãåœãŠãã
ãŸãdefault = "1" ã ãããã£ãŠãããã¹ãã®ã©ãã§ãããã©ã¡ãŒã¿ãŒ
config = ".."ãæå®ãããŠããªãå Žåãããã©ã«ãã®ããŒãã䜿çšãããŸãã
ãã¹ãèšé²åœ¢åŒèªäœã¯æ¬¡ã®ããã«ãªããŸãã
"mbreg@mbaddr:mbfunc:nbit:vtype"
ã©ãã§ïŒ
- mbaddr-ãã¹äžã®ããã€ã¹ã¢ãã¬ã¹ã ããã©ã«ãïŒ0x01
- mbfunc-ããŒãªã³ã°ãŸãã¯èšé²æ©èœã ããã©ã«ãã§ã¯ãmbfunc = 0x04ãããŒãªã³ã°ã«äœ¿çšãããmbfunc = 0x06ãèšé²ã«äœ¿çšãããŸã
- nbit-ãããçªå·[0 ... 15]ã 調æ»ããåèªããèªã¿åãæ©èœã«ãã£ãŠå®è¡ãããå ŽåãããŒã¿ã¯äœããã®ãããã«æ ŒçŽãããŸãã ããã©ã«ãã§ã¯ãnbit = -1-䜿çšããªãããšãæå³ããŸãã
- vtype-æååå€ã§èšå®ããããèŠæ±ãããå€ã®ã¿ã€ãã ããã©ã«ãã¯ã眲åä»ããã§ãã
ãµããŒããããŠããvtype- F2-ããã«ã¯ãŒããããŒãïŒ4ãã€ãïŒ
- F4-8ãã€ãã¯ãŒãïŒããã«ïŒ
- ãã€ã -ãã€ã
- 笊å·ãªã -笊å·ãªãæŽæ°ïŒ2ãã€ãïŒ
- 笊å·ä»ã -笊å·ä»ãæŽæ°ïŒ2ãã€ãïŒ
- I2-æŽæ°ïŒ4ãã€ãïŒ
- U2-笊å·ãªãæŽæ°ïŒ4ãã€ãïŒ
泚æïŒçŸåšã®å®è£
ã§ã¯ãäœæ¥ã¯æŽæ°å€ã®ã¿ã§å®è¡ãããããããã¹ãŠã®ãæµ®åãå€ã¯æŽæ°ã«äžžããããããšã«
泚æããŠãã ããã
mbadrr ã
mbfunc ã
nbit ãããã³
vtypeãã£ãŒã«ãã¯ãªãã·ã§ã³ã§ãããããã©ã«ãå€ãããããšã«æ³šæããŠãã ããã
ãã®çµæããã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããšãå€ãã®ããã€ã¹ãæäœããããã®ãã¹ãã¹ã¯ãªãããäœæã§ããŸãã ããšãã°ãäžéšã®ãã¹ããªã°ã管çããŠããã¹ãã¢ã¯ã·ã§ã³ãããã€ã¹ã«éä¿¡ãããã®åå¿ã確èªã§ããŸãã ããã¯ãã¹ãŠãModbus TCPãããã³ã«ã«æºæ ããŠããŸããããã¯ãACSã ãã§ãªããACSã§äœ¿çšãããããã€ã¹ã®ã»ãŒãã¹ãŠã®ã¡ãŒã«ãŒã«ãã£ãŠãµããŒããããŠããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ã=ãsnmpã
ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãSNMPãããã³ã«ãä»ããŠãã¹ã察象ã®ã·ã¹ãã ã§åäœããããã«èšèšãããŠããŸãã
ããã€ãã®å®è£
ã®è©³çŽ°Pythonã¢ãžã¥ãŒã«pysnmpãnetsnmpã«åºã¥ããå®è£
ãããã€ããããŸããã ããããæçµçã«ã¯ãããŸããŸãªãã©ãããã©ãŒã ã®ããŸããŸãªããŒãžã§ã³ã§çºçããåé¡ã«ããã
ããå€ãã®ããªãŒã¯ããœãªã¥ãŒã·ã§ã³ã ã€ãŸãã net-snmp-clientsãã¡ããªãŒã®ãŠãŒãã£ãªãã£ãžã®åŒã³åºãã®äœ¿çšãšpopenã«ããçµæã®åŠçã é説çã«èããããããããŸãããããã®ã¡ãœããã¯çŽç²ãªpythonã¢ãžã¥ãŒã«ã䜿çšããããããããŒã¿ãã«ãã§ããããšãå€æããŸããã
snmpã䜿çšãããã¹ãã±ãŒã¹ã®äŸã以äžã«ç€ºããŸãã
<?xml version="1.0" encoding="utf-8"?> <TestScenario type="snmp"> <Config> <aliases> <item type="snmp" alias="snmp1" snmp="conf/snmp.xml" default="1"/> <item type="snmp" alias="snmp2" snmp="conf/snmp2.xml"/> </aliases> </Config> <TestList> <test name="SNMP read tests" comm=" snmp"> <check test="uptime@node1>1" comment="Uptime"/> <check test="uptimeName@node2>=1" comment=" " config="snmp2"/> </test> <test name="SNMP: FAIL READ" ignore_failed="1"> <check test="sysServ2@node2>=1" comment="fail read test" config="snmp2"/> </test> <test name="SNMP write tests" comm=" snmp"> <action set="sysName@ups3=10" comment="save sysName"/> <action set="sysServ2@ups3=10" comment="save sysServ"/> </test> <test name="SNMP: FAIL WRITE" ignore_failed="1"> <action set="sysServ2@node1=10" comment="FAIL SAVE TEST"/> </test> </TestList> </TestScenario>
ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããã«ã¯ãç¹å¥ãªæ§æãã¡ã€ã«ãå¿
èŠã§ããããã¯ã
Configã»ã¯ã·ã§ã³ã«ç€ºãããŠã
ãŸã ïŒ
snmp = ".." ïŒã
SNMPã¹ã¯ãªããã®Snmp.xmlæ§æãã¡ã€ã« <?xml version='1.0' encoding='utf-8'?> <SNMP> <Nodes defaultProtocolVersion="2c" defaultTimeout='1' defaultRetries='2' defaultPort='161'> <item name="node1" ip="192.94.214.205" comment="UPS1" protocolVersion="2" timeout='1' retries='2'/> <item name="node2" ip="test.net-snmp.org" comment="UPS2"/> <item name="node3" ip="10.16.11.3" comment="UPS3"/> </Nodes> <MIBdirs> <dir path="conf/" mask="*.mib"/> <dir path="conf2/" mask="*.mib"/> </MIBdirs> <Parameters defaultReadCommunity="demopublic" defaultWriteCommunity="demoprovate"> <item name="uptime" OID="1.3.6.1.2.1.1.3.0" r_community="demopublic"/> <item name="uptimeName" ObjectName="sysUpTime.0"/> <item name="bstatus" OID="1.3.6.1.2.1.33.1.2.1.0" ObjectName="BatteryStatus"/> <item name="btime" OID=".1.3.6.1.2.1.33.1.2.2.0" ObjectName="TimeOnBattery"/> <item name="bcharge" OID=".1.3.6.1.2.1.33.1.2.4.0" ObjectName="BatteryCharge"/> <item name="sysName" ObjectName="sysName.0" w_community="demoprivate" r_community="demopublic"/> </Parameters> </SNMP>
Nodesã»ã¯ã·ã§ã³ã¯ã亀æãè¡ãããããŒãïŒããã€ã¹ïŒã®ãªã¹ããèšå®ããŸãã ãã®å Žåã次ã®ãã©ã¡ãŒã¿ãŒãèšå®ã§ããŸãã
- name-åŸã§ãã¹ãã§äœ¿çšãããããŒãã®åå
- ip-ããã€ã¹ã¢ãã¬ã¹ïŒipãŸãã¯ãã¹ãåïŒ
- timeout -1åã®æ¥ç¶è©Šè¡ã®ã¿ã€ã ã¢ãŠãïŒç§åäœïŒã ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã ããã©ã«ãã¯1ç§ã§ãã
- retries-ãã©ã¡ãŒã¿ãŒã®èªã¿åãã®è©Šè¡åæ° ã ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã ããã©ã«ãã¯2ã§ãã
- port-ããã€ã¹ãšã®éä¿¡çšã®ããŒã ã ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã ããã©ã«ãã¯161ã§ãã
- ã³ã¡ã³ã -ã¿ã€ãã«ã«é¢ããã³ã¡ã³ãã çŸåšäœ¿çšãããŠããªããªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã
[
ããŒã]ã»ã¯ã·ã§ã³ã§çŽæ¥ããã¹ãŠã®ããŒãã®ããã©ã«ããã©ã¡ãŒã¿ãèšå®ã§ããŸãã
- defaultProtocolVersion
- defaultTimeout
- defaultRetries
- defaultPort
MIBdirsã»ã¯ã·ã§ã³ã§ã¯ãmibãã¡ã€ã«ãå«ããã£ã¬ã¯ããªãèšå®ãããOIDã®æ£ç¢ºæ§ããã§ãã¯ãããŸãã
- path-ãã£ã¬ã¯ããªãã¹
- mask-ãã¡ã€ã«ã®ãã¹ã¯ã æå®ããªãå Žåããã£ã¬ã¯ããªãããã¹ãŠã®ãã¡ã€ã«ãããŠã³ããŒããããŸã
Parametersã»ã¯ã·ã§ã³ã§ã¯ããã¹ãã«åå ãããã©ã¡ãŒã¿ãŒã®ãªã¹ããèšå®ããŸãã
- name-ãã¹ãã§åŸã§äœ¿çšããããã©ã¡ãŒã¿ãŒå
- r_community-ãã©ã¡ãŒã¿ãŒã®èªã¿åãæã«ãã³ãã¥ããã£ã¹ããªã³ã°ããèšå®ããŸãïŒsnmpãããã³ã«ãåç
§ïŒã
- w_community-ãã©ã¡ãŒã¿ãŒãæžã蟌ãããã®ãã³ãã¥ããã£ãŒæååãã®èšå®ïŒsnmpãããã³ã«ãåç
§ïŒã
- OID -SNMPãããã³ã«ã«åŸã£ããã©ã¡ãŒã¿ãŒèå¥åã
- ObjectName -SNMPãããã³ã«ã«åŸã£ããã©ã¡ãŒã¿ãŒåã ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã
- ignoreCheckMIB -mibãã¡ã€ã«ã«å¯ŸããŠãã©ã¡ãŒã¿ãŒããã§ãã¯ããŸããïŒ--check-scenarioã¢ãŒãïŒ
OIDãã©ã¡ãŒã¿ãŒãš
ObjectNameãã©ã¡ãŒã¿ãŒã¯äº€æå¯èœã§ãã äž¡æ¹ã®ãã©ã¡ãŒã¿ãŒãæå®ãããŠããå ŽåãOIDã䜿çšãããŸãã [
ãã©ã¡ãŒã¿]ã»ã¯ã·ã§ã³ã§ããã¹ãŠã®ããŒãã®ããã©ã«ããã©ã¡ãŒã¿ãçŽæ¥èšå®ã§ããŸãã
- defaultReadCommunity
- defaultWriteCommunity
1ã€ã®ã·ããªãªã§è€æ°ã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãã
äŸã瀺ããŸãã
<?xml version="1.0" encoding="utf-8"?> <TestScenario> <Config> <aliases> <item type="uniset" alias="u" confile="configure.xml" default="1"/> <item type="modbus" alias="mb" mbslave="localhost:2048"/> <item type="snmp" alias="snmp" snmp="conf/snmp.xml"/> </aliases> </Config> <RunList after_run_pause="5000"> ... </RunList> <TestList> <test name="check: Equal test"> <action set="111=10"/> <check test="111=10"/> <check test="uptime@node1>1" config="snmp"/> <check test="0x10!=0" config="mb"/> </test> </TestList> </TestScenario>
ã€ãŸã ãã§ãã¯ããšã«ã
config = "aliasname"ãèšå®ããŠã䜿çšããã€ã³ã¿ãŒãã§ã€ã¹ãæå®ã§ããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããæ¹æ³
å
¥é
åºæ¬çãªã€ã³ã¿ãŒãã§ã€ã¹ã®äœæ¥äžã«ãuniset2-testsuiteã«åã蟌ãããã®ãã¹ãã€ã³ã¿ãŒãã§ã€ã¹ã®æå°APIã«é¢ããããžã§ã³ã圢æãããŸããã ãããŠãäž»ãªæ©èœã«ã€ããŠã¯2ã€ã®æ©èœãå®è£
ããã ãã§ååã§ããããšãããããŸããïŒ
ãŸããã»ãŒ ïŒ
def get_value(self, name, context): ... def set_value(self, name, value, context): ...
ããã¯åçŽãªã¢ã€ãã¢ã«åºã¥ããŠããŸãã ãã¹ãã·ããªãªãèŠããšãäžè¬çã«ããã§ãã¯ãŸãã¯ã¢ã¯ã·ã§ã³ã¯æ¬¡ã®ããã«èšè¿°ã§ããããšãããããŸãã
heck="[NAME]=[VALUE]"
ã
ã=ãã®ä»£ããã«
ãå®éã«ã¯ãããã®1ã€ã[=ã>ã> =ã<ã<= ,! =]ã§ããå ŽåããããŸãã
ã€ãŸã ãã§ãã¯ãããã©ã¡ãŒã¿ãŒã®ååãšããŠç¹å®ã®
[NAME]ããããŸãã ãããŠãç¹å®ã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ããã解æããæ¹æ³ãç¥ã£ãŠããŸãã
[VALUE]ããããŸã-ããã¯ãçµæãæ¯èŒããå€ãŸãã¯èšå®ããå€ã§ãã ãã®çµæãuniset2-testsuiteã¯ãNAMEããã³VALUEã®ãã¹ãã解æããã¿ã¹ã¯ã
åŒãåããç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹å®è£
ã®
get_valueãŸãã¯
set_valueé¢æ°ãåŒã³åºããŸãã åæã«ãã€ã³ã¿ãŒãã§ã€ã¹èªäœã¯ã[NAME]ãã£ãŒã«ãã§äœæ¥ãå®è¡ããããã©ã¡ãŒã¿ãŒã®
æå·åæ¹æ³ãæ
åœããŸãã äŸïŒ
- ãunisetã圢åŒNAME ïŒ
id@node
- ãmodbusãã®åœ¢åŒã¯NAME ïŒ
"mbreg@mbaddr:mbfunc:nbit:vtype"
- ãsnmpã圢åŒNAME ïŒ
"varname@node"
ã€ãŸã ã€ã³ã¿ãŒãã§ãŒã¹éçºè
ã¯ã
NAMEã®ã©ã®ãã©ãŒããããéžæãããã決å®ããŸãã
çŸåšã®å®è£
ã§ã¯ã
timeout ã
check_time ã
holdtimeãªã©ã®ãã¹ã
ã±ãŒã¹ãã©ã¡ãŒã¿ãuniset2-testsuiteã¬ãã«ã§åŠçã
ããããšã«çæããããšãéèŠã§ãã ãããã£ãŠããã¹ãã§
<check test="varname=34" timeout="15000" check_time="3000"/>
ãšç€ºãããŠããå Žåãããã¯get_valueïŒvarnameïŒé¢æ°ãã¿ã€ã ã¢ãŠããæéåãã«ãªããŸã§3ç§ããšã«åŒã³åºãããããšãæå³ããŸã34ã®å€ãååŸãããŸãã
ãã1ã€ã®éèŠãªå¶éã¯ãçŸåšã®å®è£
ã§ã¯ã[VALUE]ãæ°å€ãšããŠã®ã¿ãµããŒããããŠããããšã§ãã å®éããä»»æã®åãïŒ
åºæ¬çã«æåå ïŒããµããŒãããããã«ãªã¡ã€ã¯ããããšã¯ããã»ã©é£ãããããŸãããVALUEãµããŒããæ°å€ãšããŠå®è£
ããå¿
èŠã¯ãããŸããã§ããã å
compareã®ãã§ãã¯ãããããšãæãåºãããŠ
ãã ãã ãããã«ãããæ°å€ã§ã¯ãªããå¥ã®ãã©ã¡ãŒã¿ãŒã®å€ãšæ¯èŒã§ããŸãã
æ§æ
åã€ã³ã¿ãŒãã§ãŒã¹èªäœããåäœã«å¿
èŠãªæ§æãã©ã¡ãŒã¿ãŒã決å®ããŸãã uniset2-testsuiteã§ã¯ãããããèšè¿°ããããã®
Config /
aliasesã»ã¯ã·ã§ã³ãæäŸãããŸããããã§ã¯ããã©ã¡ãŒã¿ãŒãxmlããããã£ãšããŠæžã蟌ãããšãã§ããŸãã ã€ã³ã¿ãŒãã§ãŒã¹ãäœæãããšãæ§æããŒãã圌ã«è»¢éãããããããå¿
èŠãªãã®ãã¹ãŠãèæ
®ãããŸãã äœåãªãã®ãã¹ãŠãå®çŸ©ããå¿
èŠãããå Žåãããšãã°ãæ§æããŒãã®snmpã€ã³ã¿ãŒãã§ãŒã¹ã§ãæ§æãã¡ã€ã«ïŒsnmp.xmlïŒãååŸããå Žæã®ã¿ã決å®ã§ããã€ã³ã¿ãŒãã§ãŒã¹ãæ©èœããããã«å¿
èŠãªãã®ã¯ãã¹ãŠããã§ãã§ã«å®çŸ©ãããŠããŸãã åæ§ã«ãããšãã°modbusã€ã³ã¿ãŒãã§ãŒã¹ã®å Žåãããã€ã¹ãšã®éä¿¡çšã«IPãšããŒããå®çŸ©ããã ãã§ååã§ããããããã®ãã©ã¡ãŒã¿ãŒã¯
Configã»ã¯ã·ã§ã³ã«çŽæ¥æžã蟌ãŸããŸãã
ãã©ã°ã€ã³ïŒã€ã³ã¿ãŒãã§ã€ã¹ïŒãããŠã³ããŒããã
ã€ã³ã¿ãŒãã§ãŒã¹ã®ããŒãã¯ãåçŽãªååã«åºã¥ããŠããŸãã ãã£ã¬ã¯ã㪠'
plugins.d 'ãããããããããã¹ãŠã®ã€ã³ã¿ãŒãã§ãŒã¹ãããŒããããŸãã ãã·ã¹ãã ããã£ã¬ã¯ããªãããããã©ã°ã€ã³ã¯ãã¹ããå®è¡ãããŠããçŸåšã®ãã£ã¬ã¯ããªã®
plugins.dãµããã£ã¬ã¯ããªã§ãæ€çŽ¢ãããŸãã ãããã£ãŠããŠãŒã¶ãŒã¯ãã¹ããé
眮ãããŠããå Žæã«ãã©ã°ã€ã³ãé
眮ããã ãã§ããã©ã°ã€ã³ã¯èªåçã«ååŸãããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹ã®åå®è£
ã¯ãåå¥ã®pythonãã¡ã€ã«ãšããŠäœæãããŸãããã®ãã¡ã€ã«ã«ã¯ã
uts_plugin_nameïŒïŒé¢æ°ãå«ãŸããŠãã
å¿
èŠã
ãããŸãã ããšãã°ãSNMPã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯æ¬¡ã®ããã«ãªããŸã
def uts_plugin_name(): return "snmp"
ãã®çµæãã€ã³ã¿ãŒãã§ã€ã¹èªäœã®ããŒãã¯æ¬¡ã®ã¡ã«ããºã ã«åºã¥ããŠããŸãã
.. <Config> <aliases> <item type="uniset" alias="u" confile="configure.xml" default="1"/> <item type="modbus" alias="mb" mbslave="localhost:2048"/> <item type="snmp" alias="snmp" snmp="conf/snmp.xml"/> </aliases> </Config> ...
ãã¹ãã¹ã¯ãªããã®åŠçãéå§ãããšãuniset2-testsuiteã¯äœ¿çšå¯èœãªãã©ã°ã€ã³ã®ãªã¹ããååã§ã³ã³ãã€ã«ãã
plugins.dãã£ã¬ã¯ããªããããŒãããŸãã æž¡ããšã次
type =â xxxxâã¯
Configã»ã¯ã·ã§ã³ã調ã¹ã察å¿ããã€ã³ã¿ãŒãã§ãŒã¹ãæ€çŽ¢ãããŸãã
ç¹å¥ãªé¢æ°ãåŒã³åºããã®ãäœæããã«ã¯
xmlããŒããæž¡ããã
uts_create_from_xml(xmlConfNode)
ãã©ã¡ãŒã¿ãšããŠã ããã«ãã€ã³ã¿ãŒãã§ãŒã¹ã®äœæãšãã®åæåããã§ã«å®è£
ããŠããŸãã
èŠããã«ïŒ
uts_plugin_name() - type="..." uts_create_from_xml(xmlConfNode) -
æ§æãã©ã¡ãŒã¿ãŒã®æ€èšŒ
ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããã«ã¯ã2ã€ã®é¢æ°
set_valueïŒïŒãš
get_valueïŒïŒã®ã¿ãå®è£
ããã°ååã§ãããšäžèšã§æžããŸããã å®éãããã«2ã€å®è£
ããããšãæãŸããïŒãã ããå¿
é ã§ã¯ãªãïŒïŒ
def validate_parameter(self, name): ... def validate_configuration(self): ...
ãããã¯ã-check-scenarioã¢ãŒãã®å Žåã«å¿
èŠã§ãããã¹ãã¢ãŒãã®æ£ç¢ºæ§ãå®éã«å®è¡ãããã«ãã§ãã¯ãããå Žåã
validate_parameter- ååãã©ã¡ãŒã¿ãŒãæ€èšŒããããã«åŒã³åºãããŸãã ãããŠããã¹ãå
ã®åãã¹ãã«å¯ŸããŠåŒã³åºãããããšã«æ³šæããŠãã ããã
validate_configurationã¯ããã¹ãå
šäœã®æ§æãã©ã¡ãŒã¿ãŒã確èªããããã«1ååŒã³åºãããŸãã ããšãã°ãsnmp-interfaceã§ã¯ãããŒãã®å¯çšæ§ãããã³mibãã¡ã€ã«ã«ããOIDãšObjectNameã®æå¹æ§ã確èªããŸãïŒå¯Ÿå¿ãããã£ã¬ã¯ããªãã©ãã«ãããã瀺ãããŠããå ŽåïŒã
å®è£
ããŠãæåŸã«ãå®è£
ã«çããŸããã å®äŸãšããŠã©ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããããèããŠãå¯èœãªã€ã³ã¿ãŒãã§ã€ã¹ã®ãæãæ®éçãªããã€ãŸãããã§ãã¯ãšããŠã¹ã¯ãªãããå®è¡ããã€ã³ã¿ãŒãã§ã€ã¹ãéçºããããšã«ããŸããã ããã
ãã¹ã¯ãªããããšåŒã³ãŸãã ãã¹ã¯ãªããããšããèšèã¯ãbashã ãã§ãªãããå®è¡ã§ããããã¹ãŠãæå³ããããšãããã«æ³šæããããšæããŸãã ãªããªã
ãã¹ãããšã«ã·ã§ã«
ãä»ããŠããã°ã©ã ãå®éã«å®è¡
ããŸãã
ã ããã
ãŸããNAMEã®åœ¢åŒãèãåºãå¿
èŠããããŸãïŒäžèšãåç
§ïŒã å°ãèããŠã
æ£çŽã«èšã£ãŠãè©ŠããŠã¿ããšãã ããã®åçŽãªåœ¢åŒã«ãªããŸããã
<test name="check scripts"> <check test="scriptname.sh >= VALUE" params="param1 param2 param3" ../> <check test="../myscritps/scriptname.sh >= VALUE" params="param1 param2 param3" ../> .. </test>
ãã©ãŒãããæ€çŽ¢ã«ã€ããŠæåã«ãGETãªã¯ãšã¹ãã®ãããªåœ¢åŒãäœæãããã£ãïŒ scriptname?param1¶m2¶m3.
ããããxmlããããšããå¶éã«ééããŸããã ãããŠãã ïŒ ãããã®ãŸãŸäœ¿çšããããšã¯ã§ããŸããã ãïŒãã¢ã³ããšããŠèšè¿°ãããŠããå Žåã®ã¿ã ã ãã¡ãããããã¯ãã¹ãŠã®äŸ¿å©ãããã§ã«ç¡å¹ã«ããŠããã
ã€ãŸã in
test = ".."ã¹ã¯ãªãã
ã®ååãæžã蟌ãŸããŸãïŒãã¹ãæå®ã§ããŸãïŒã ãªããªã çµå±ã®ãšãããã¹ã¯ãªããã«ãã©ã¡ãŒã¿ãŒãæž¡ããããããç¹å¥ãªãã£ãŒã«ãïŒæ¡åŒµïŒ
params = "..."ãå°å
¥ã
ãŸã ã
次ã«
ãçµæã
ååŸããæ¹æ³ãç解ããå¿
èŠããããŸãã ãªããªã ããã°ã©ã ã0ãè¿ãããšã¯åãå
¥ããããŸã-æåã®å Žåã倱æã®å Žåã¯ããŒãã§ã¯ãªããå ŽåãçµæãšããŠæ»ãã³ãŒãã䜿çšããããšã¯ãè¯ãèãã§ã¯ãªãããã§ãã æçµçã«ãããã°ã©ã ãçµæãå«ãç¹å¥ãªããŒã«ãŒãæšæºåºåã«åºåããã®ãæãç°¡åãªæ¹æ³ã§ãããšå€æããŸããã ã€ãŸã äžæ¹ã§ã¯ãããã°ã©ã ãç¬èªã®ã¡ãã»ãŒãžã衚瀺ããããšãçŠæ¢ããŠããŸããããä»æ¹ã§ã¯ãããããçµæãååŸããå¿
èŠããããŸãã ããŒã«ãŒã¯æ¬¡ã®åœ¢åŒã®è¡ã«ãªããŸãïŒ
TEST_SCRIPT_RESULT: VALUE
ã€ãŸã ã¹ã¯ãªãããå®è¡ããåºåã§ããŒã«ãŒããã£ããããŠãããããçµæãåãåããŸãã
ãããã¯ãããã以äžè¯ããã®ã¯æãã€ããŸããã次ã®è³ªåã¯
ãšã©ãŒåŠçã§ãã ããã§ã¯ãã¹ãŠãæšæºã§ãã æ»ãã³ãŒãïŒ= 0ã®å Žåããšã©ãŒã ãšã©ãŒã®è©³çŽ°ãšããŠãstderrã®ããã°ã©ã ã«ãã£ãŠè¡šç€ºããããã¹ãŠã®ãã®ã䜿çšããŸãã
ã°ããŒãã«ã€ã³ã¿ãŒãã§ãŒã¹
èšå®ãã©ã¡ãŒã¿ãŒ ïŒä»ã®ãšãããåçŽãªã€ã³ã¿ãŒãã§ãŒã¹ã«ã¯å¿
èŠãªããšèããŠããŸãã ããããç§ã¯äŸãã°1ã€ãããŸããã
ããã§ç©èªã®çµããã§ãã ã©ããã
- ãã¹ã
<check test="testscript=VALUE" params="param1 param2 param3..".../>
ïŒ <check test="testscript=VALUE" params="param1 param2 param3..".../>
- çµæïŒçµæãšããŠãã¹ã¯ãªããã¯ç»é¢ïŒstdoutïŒã«
TEST_SCRIPT_RESULT: VALUE
ãšããè¡ã衚瀺ããã¯ãTEST_SCRIPT_RESULT: VALUE
- ãšã©ãŒïŒæ»ãã³ãŒãïŒ= 0ã®å Žåããšã©ãŒãçºçãããšèŠãªãããŸãïŒ æåããå Žåãã¹ã¯ãªããã¯æ»ãã³ãŒã0ãè¿ããŸãã
- æ§æïŒãªã
次ã«ãå®è£
ã«é²ã¿ãŸã...
ã¢ãžã¥ãŒã«ãããŒãããã«ã¯ã2ã€ã®ã°ããŒãã«é¢æ°
uts_create_from_xmlïŒ..ïŒãš
uts_plugin_nameïŒïŒãå®è£
ããå¿
èŠ
ããããŸãã
圌ãã¯ç°¡åã§ã def uts_create_from_xml(xmlConfNode): """ :param xmlConfNode: xml- :return: UTestInterface """ return UTestInterfaceScripts(xmlConfNode=xmlConfNode) def uts_plugin_name(): return "scripts"
ã€ã³ã¿ãŒãã§ã€ã¹èªäœã¯ãåºæ¬ã¯ã©ã¹UTestInterfaceããç¶æ¿ããå¿
èŠãªæ©èœãå®è£
ããå¿
èŠããããŸãã æåã«ãUTestInterface.pyã¯ã©ã¹ãã©ã®ããã«èŠãããã瀺ããŸãã
ã¡ã€ã³é¢æ°
get_value(self, name, context)
å®è£
ããããšããå§ã
get_value(self, name, context)
ã
ååãæž¡ãããŸã-ç§ãã¡ã®å Žåãããã¯åºæ¬çã«ã¹ã¯ãªããã®ååã§ãã
ãã ããè¿œå ã®paramsãã£ãŒã«ããå°å
¥ãããŠãããããåæ§ã«åŠçããå¿
èŠããããŸãã
è¿œå ã®ãã£ãŒã«ãã«å°éããããã«ããã®ãããªäŸ¿å©ãªãã©ã¡ãŒã¿ãŒã
contextãšããŠäœ¿çšã
ãŸã ã
ããã¥ã¡ã³ãã«ä»ã«èå³æ·±ããã®ãæžãããŠããŸãããããã§ãªããããããªããšããäºå®ãèæ
®ããŠãçŸåšã®ãã¹ãã®xmlããŒããåŒãåºããŸãïŒãããŠäŸå€ãã¹ããŒããŸãïŒã
def get_value(self, name, context): xmlnode = None if 'xmlnode' in context: xmlnode = context['xmlnode'] if not xmlnode: raise TestSuiteException("(scripts:get_value): Unknown xmlnode for '%s'" % name) ...
䟿å®äžãååãšã³ã³ããã¹ããå
¥åãšããŠåãåãã
scriptnameãš
parametersãè¿ãå¥ã®é¢æ°ïŒåœ¢åŒãåŸã§å€æŽããããã©ããïŒã匷調ããŸããã
ããã«ãããŸãïŒ
parse_nameïŒïŒ @staticmethod def parse_name(name, context): """ : <check test="scriptname=XXX" params="param1 param2 param3" .../> :param name: ( scriptname) :param context: :return: [scriptname, parameters] """ if 'xmlnode' in context: xmlnode = context['xmlnode'] return [name, uglobal.to_str(xmlnode.prop("params"))] return [name, ""]
次ã«ãget_valueïŒïŒã¯
- ã¹ã¯ãªãããå®è¡ãã
- ãšã©ãŒãåŠçãã
- çµæã解æãã
å®å
šã«å®è£
ããã ãã§ã
get_valueïŒïŒ def get_value(self, name, context): xmlnode = None if 'xmlnode' in context: xmlnode = context['xmlnode'] if not xmlnode: raise TestSuiteException("(scripts:get_value): Unknown xmlnode for '%s'" % name) scriptname, params = self.parse_name(name, context) if len(scriptname) == 0: raise TestSuiteException("(scripts:get_value): Unknown script name for '%s'" % name) test_env = None if 'environment' in context: test_env = context['environment'] s_out = '' s_err = '' cmd = scriptname + " " + params try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=test_env, close_fds=True, shell=True) s_out = p.stdout.read(self.max_read) s_err = p.stderr.read(self.max_read) retcode = p.wait() if retcode != 0: emessage = "SCRIPT RETCODE(%d) != 0. stderr: %s" % (retcode, s_err.replace("\n", " ")) raise TestSuiteException("(scripts:get_value): %s" % emessage) except subprocess.CalledProcessError, e: raise TestSuiteException("(scripts:get_value): %s for %s" % (e.message, name)) if xmlnode.prop("show_output"): print s_out ret = self.re_result.findall(s_out) if not ret or len(ret) == 0: return None lst = ret[0] if not lst or len(lst) < 1: return None return uglobal.to_int(lst)
å°ã説æã
ã¹ã¯ãªãããå®è¡ããããã«ãç°å¢å€æ°ãã¹ã¯ãªããã«æž¡ãããšãã§ããŸããã ããã¯
ãã¹ã¯ãªããã«é¢ããããã¥ã¡ã³ãã®ã»ã¯ã·ã§ã³
ã«ãããŸããç¹°ãè¿ããŸãããã³ã³ããã¹ãããç°å¢å€æ°ãå«ãèŸæžãååŸããŸãïŒ
test_env = context['environment']
å®è£
ã«2ã€ã®è¿œå ãã©ã¡ãŒã¿ãŒ
show_output = "1"ãè¿œå ããããšãèš±å¯ããŸãã-ããã¯
ãã§ãã¯ã¬ãã«ãã©ã¡ãŒã¿ãŒã§ãã ã¹ã¯ãªãããstdoutã«è¡šç€ºãããã¹ãŠã®ç»é¢ãžã®åºåãå«ããã ããã©ã«ãã§ã¯ãã¹ã¯ãªããã¯åºåãç¡å¹ã«ããŠå®è¡ãããŸãã ãããŠãå
¥åãã2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ã°ããŒãã«ãª
max_readèšå®ã§ããããã¯ãçµæãååŸããããã«èªã¿åãå¿
èŠãããåºåã®ïŒæåã®ïŒãã€ãæ°ã決å®ããŸãã ãŸããã°ããŒãã«èšå®ã®äœ¿çšæ¹æ³ã瀺ãå¿
èŠããããŸããã 第äºã«ãèªã¿åãçšã®ãããã¡ãå¶éããããšã¯è¯ãèãã ãšæããŸããã ããã«ããµã€ãºã0以äžã«èšå®ãããŠããå Žåã¯ããã¹ãŠå®è¡ã§ããŸãã
ãªã¿ãŒã³ã³ãŒãã®åŠçã§ãã³ãŒããnullã§ãªãå Žåããšã©ãŒããã¹ããšããŠstderrã䜿çšããŸãïŒåãè¡ã«æ²¿ã£ãŠäœæããŸãïŒã
æ£èŠè¡šçŸã䜿çšããParsimã®çµæã
现éšãã®å Žåãå®è¡äžã®ããã°ã©ã ã®å®äºãåŸ
ã£ãŠããããšãããããŸãã ã€ãŸã ããã°ã©ã ã¯éåžžã«ç°¡æœã§ã
ããã«çµäºããŸãã ããã§ããããã°ã©ã ããäœæéãç¶ããŠãåäœããå Žåã¯å¥åŠã§ãã äžæ¹ãã¿ã€ã ã¢ãŠãã«ãã£ãŠããã°ã©ã ã匷å¶çµäºããããšãå¯èœã§ãã
ã€ã³ã¿ãŒãã§ã€ã¹ããã¹ãããã«ã¯ã
plugins.dãã£ã¬ã¯ããªãäœæããããã«ã¢ãžã¥ãŒã«ãé
眮ããŸãã ãŸããå°ããªãã¹ããæžã
ã€ã³ã¿ãŒãã§ã€ã¹ããã¹ããããã¹ã <?xml version="1.0" encoding="utf-8"?> <TestScenario> <Config> <environment> <item name="MyTEST_VAR1" value="MyTEST_VALUE1"/> <item name="MyTEST_VAR2" value="MyTEST_VALUE2"/> <item name="MyTEST_VAR3" value="MyTEST_VALUE3"/> </environment> <aliases> <item type="scripts" alias="s" default="1"/> </aliases> </Config> <TestList type="scripts"> <test name="Test run script" ignore_failed="1"> <check test="./test-script.sh != 10" params="--param1 3 --param2 4" timeout="2000"/> <check test="./test-script.sh = 100" params="param1=3,param2=4"/> <check test="./test-script-negative-number.sh = -20" show_output="1"/> <check test="./test-script-longtime.sh = 100" timeout="3000"/> <check test="./test-script-error.sh > 10"/> </test> </TestList> </TestScenario>
Configã»ã¯ã·ã§ã³ã§ã¯ãããã©ã«ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ãããscriptsãã§ããããšã瀺ãããŠããããšã«æ³šæããŠãã ãããTestListã¿ã°ã§ã¯ãã¹ã¯ãªããå
šäœããã®ã¿ã€ãã§ããããšã瀺ãããŠããŸããã¹ã¯ãªããã«å ããŠã次ã®ãããªæå®ãããbashã¹ã¯ãªãããäœæããããšãå¿ããªãã§ãã ãããåæã«ãç°å¢å€æ°ãå°åºããŠãããã調ã¹ãŸãtest-script-negative-number.sh ãã®çµæãæã
ã¯ïŒãã©ã¡ãŒã¿ãå«ãç»åã衚瀺ãããŸãç§ãã¡ã®ã¹ã¯ãªãããå®è¡ããå Žåshow_output =«1»ããã¹ãã§ã®ã¹ã¯ãªããããã©ã¡ãŒã¿ignore_failed =«1»ã®äžã€ã§ã¯ïŒïŒå®è¡ããã³ãã³ã uniset2-testsuite-xmlplayer --testfile tests-scripts-interface.xml --log-show-actions --log-show-tests
ããããããã ãã§ã¯ãããŸããããããŸã§ã1ã€ã®é¢æ°ã®ã¿ãå®è£
ããŸããget_value(...)
ãããšããã€ãæ®ã£ãŠããŸããæ¯æŽæŽ»åã¯ã©ãã§ããïŒã€ãŸã
set_valueïŒïŒé¢æ°ã®å®è£
...ç§ãã¡ã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ã¯ããµããŒããè¡ãæå³ããªããšå€æããŸãã <action set="..."/>
å®æçãªã¡ã«ããºã ããããã <action script=".."/>
ãããã£ãŠãé¢æ°ã¯æ¬¡ã®ããã«ãªããŸããset_valueïŒ..ïŒ def set_value(self, name, value, context): raise TestSuiteException("(scripts:set_value): Function 'set' is not supported. Use <action script='..'> for %s" % name)
ããã«é²ãã§ãã ãã...testsuiteã«ã¯--check-scenarioã¢ãŒãããããŸãããã®ã¢ãŒãã§ã¯ãå®éã«å®è¡ããããšãªããèšå®ãšãã¹ãã®æ£ç¢ºæ§ããã§ãã¯ãããŸãããã®ã¢ãŒãããµããŒãããã«ã¯ãvalidate_parameterãšvalidate_configurationã® 2ã€ã®é¢æ°ãå®è£
ããå¿
èŠããããŸããmax_output_readãé€ããã°ããŒãã«æ§æãã©ã¡ãŒã¿ãŒããªããããæ§æããã§ãã¯ã€ã³ããããã®ç¹å¥ãªãã®ã¯ãããŸããããããã£ãŠãvalidate_configurationé¢æ°ã¯äœãããŸããããããvalidate_parameterããå°ãé¢çœãã§ããå®éãã¹ã¯ãªããã«ãããšãïŒå®éã«å®è¡ããã«ïŒæ€èšŒã§ããæ倧å€ã¯æ¬¡ã®ãšããã§ãã- 圌ã¯ãŸã£ããå°ããããŸãã
- æå®ãããã¹ã¯ãªããã¯ååšããŸãã
ããã¯ãã¹ãŠå®è£
ã«åæ ãããŸããvalidate_parameterïŒïŒããã³validate_configurationïŒïŒã®å®è£
def validate_configuration(self, context): return [True, ""] def validate_parameter(self, name, context): """ :param name: scriptname :param context: ... :return: [Result, errors] """ err = [] xmlnode = None if 'xmlnode' in context: xmlnode = context['xmlnode'] scriptname, params = self.parse_name(name, context) if not scriptname: err.append("(scripts:validate): ERROR: Unknown scriptname for %s" % str(xmlnode)) if not is_executable(scriptname): err.append("(scripts:validate): ERROR: '%s' not exist" % scriptname) if len(err) > 0: return [False, ', '.join(err)] return [True, ""]
ãšã©ãŒåºåã®äŸãšããŠãã¹ã¯ãªããã«ãååšããªããã¹ã¯ãªãããžã®åŒã³åºããæ¿å
¥ããŸããã調æŽãããã·ããªãª <?xml version="1.0" encoding="utf-8"?> <TestScenario> <Config> <environment> <item name="MyTEST_VAR1" value="MyTEST_VALUE1"/> <item name="MyTEST_VAR2" value="MyTEST_VALUE2"/> <item name="MyTEST_VAR3" value="MyTEST_VALUE3"/> </environment> <aliases> <item type="scripts" alias="s" default="1"/> </aliases> </Config> <TestList type="scripts"> <test name="Test run script" ignore_failed="1"> <check test="./test-script.sh != 10" params="--param1 3 --param2"/> <check test="./test-script.sh = 100" params="param1=3,param2=4"/> <check test="./test-script-negative-number.sh = -20" show_output="1"/> <check test="./test-script-longtime.sh = 100" timeout="3000"/> <check test="./test-script-error.sh > 10"/> <check test="./non-existent-script.sh > 10"/> </test> </TestList> </TestScenario>
ãŸããã¹ã¯ãªãããã§ãã¯ãå®è¡ãããšã次ã®ããã«ãªããŸãå®è¡ããã³ãã³ã uniset2-testsuite-xmlplayer --testfile tests-scripts-interface.xml --log-show-actions --log-show-tests --check-scenario
ããŠãããã§ãã¹ãŠãè¿œå ããã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ã®æçµããŒãžã§ã³ã確èªã§ããŸãããŸãšã
uniset2-testsuiteã¯åçŽãªèªè»¢è»ã§ãã»ãšãã©ã®å Žåããã¹ãããé©çšãåå¿ã確èªããšããã¹ããŒã ã«é©åããŠããã°ååã§ãããã¹ãçšã®ã¡ã«ããºã ã®æå°ã»ãããååšããŸãã- ãã¹ãã®åã«å¿
èŠãªãã¹ãŠãå®è¡ããæ©èœ
- ãã¹ããã°ã«ãŒãåããæ©èœ
- ãã¹ããåå©çšããæ©èœïŒãã³ãã¬ãŒãã®ã¡ã«ããºã ãšå€éšãã¡ã€ã«ãžã®ãªã³ã¯ïŒ
- ã«ã¹ã¿ã ãã¹ãå®äºåŠç
ããã«ããã©ã°ã€ã³ã·ã¹ãã ã®ååšã«ãããå¿
èŠã«å¿ããŠæ©èœãç°¡åã«æ¡åŒµãã䜿çšå¯èœãªãããã³ã«ïŒREST APIãŸãã¯RS485ïŒã䜿çšããŠãã¹ãã·ã¹ãã ãšã®å¯Ÿè©±ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ã§ããŸããããã€ãã®æ©èœãå®è£
ããã ãã§ããå°ããªè¿œå - python . C++. , python - . .
é¢é£ãªã³ã¯ïŒ