ããã«ã¡ã¯ãã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã® Engineering Manager ããã¦ãã @ywada526 ã§ãã
ä»åã¯ãç¾å¨æå»ã«ä¾åããæ©è½ã®åä½ç¢ºèªã³ã¹ããä¸ããåºç¤ã«ã¤ãã¦ç´¹ä»ãã¾ãããã®åºç¤ã¯ã社å ã§ã¯ã³ã¼ãä¸ã®ååãã¨ã£ã¦ãTime Injectionãã¨ããæ称 1 ã§å¼ã°ãã¦ãã¾ãããã®è¨äºå ã§ã Time Injection ã¨ããååã使ã£ã¦èª¬æãã¾ãã
ã¿ãªããã¯ãç¾å¨æå»ã«ä¾åããæ©è½ã®åä½ç¢ºèªãå質ä¿è¨¼ã¯ã©ã®ããã«è¡ãªã£ã¦ãã¾ããããæå»ãåºå®ããç°å¢ãç¨æãããããã¼ã¿ãå¼ãããã¦ããããã¹ãã§æ ä¿ããããåä½ç¢ºèªã¯ããªãããã³ã¼ãããã£ã¨è¦ã¤ãã¦åé¡ãªãã¨è¨ãåã 2ããªã©è²ã ããã¨æãã¾ããããã¾ã§ãã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã§ãåæ§ã®æ段ã§åä½ç¢ºèªãè¡ãªã£ã¦ãã¾ããããåä½ç¢ºèªã³ã¹ãã課é¡ã§ãã£ããããTime Injection ãå°å ¥ãããã¨ã«ãã¾ããã
Time Injection ã¯ä¸è¨ã§ããã¨ãã¢ã«ã¦ã³ããã¨ã«ä»»æã®æå»ãç¾å¨æå»ã¨ãã¦è¨å®ã§ããæ©è½ãã§ãéæ¬çªç°å¢ã«å°å ¥ãã¦ãã¾ããæå»ãè¨å®ããããã® GUI ãæä¾ãã¦ããééçºè ã«ãå©ç¨ããã¦ãã¾ãã
æ¬è¨äºã§ã¯ãç¾å¨æå»ä¾åæ©è½ã®ãã¹ãã®ãããããã«ã¤ãã¦æ´çããTime Injection ã®å®è£ ã¨å°å ¥ã«ããã注æç¹ã«ã¤ãã¦èª¬æãã¾ãããåç½®ãã¯ããããã¨ã«ããæ¬é¡ãèªã¿ãããã¨ããæ¹ã¯ãåæã¯é£ã°ãã¦ãå®è£ ã®ãã¼ãããèªã¿é²ãã¦ãã ããã
ç¾å¨æå»ã«ä¾åããæ©è½ã®ãã¹ãã®ããããã
ã¾ãã¯ãç¾å¨æå»ã«ä¾åããæ©è½ã®ãã¹ãã®ãããããã«ã¤ãã¦æ´çãã¾ãããã®ãããããã¯ããç¾å¨æå»ã®ãµãã¾ããé決å®çãªãããç¹å®ã®æ¡ä»¶ã®åç¾ãããããããã¨ãããã¨ã«æè¨ã§ãã¾ãã
ç°¡åãªå®è£ ã§èãã¦ã¿ã¾ãããã
ç¾å¨æå»ã¨ã¦ããããã¹ã
å¹³æ㯠'Hello!' æååãè¿ãããã¯ãªã¹ãã¹ã«ã¯ 'Merry Christmas!' æååãè¿ã greet ã¡ã½ãããå®è£ ãã¾ããã³ã¼ã㯠Ruby ã§ãã
def greet now = Time.now if now.month == 12 && now.day == 25 'Merry Christmas!' else 'Hello!' end end
ãã¦ããã®ã¡ã½ãããã¯ãªã¹ãã¹ã« 'Merry Christmas!' æååãè¿ããã¨ããã¹ãããã«ã¯ã©ãããã°ããã§ãããããåç´ã«é¢æ°ãå®è¡ãã¦è¿ãå¤ãæ¤è¨¼ããã®ã§ã¯ãæ¬å½ã«ã¯ãªã¹ãã¹ã«å®è¡ããã»ãããã¾ãããããããç¹å®ã®ç¶æ³ã®åç¾ãããããããã¨ãããã¨ã§ãã
ã§ã¯ããã®ã³ã¼ãã®ãã¹ããæ¸ãã«ã¯ã©ãããã°ããã§ããããã大å¥ããã¨ä»¥ä¸ã® 2 ã¤ã®ãã¿ã¼ã³ãããã¾ãã
- ç¾å¨æå»ã¸ã®ä¾åãéé¢ãã
- ç¾å¨æå»ãæ±ãã©ã¤ãã©ãªã¸ä»å ¥ãã
1 ã¯ãç¾å¨æå»ã greet ã¡ã½ããã®å¼æ°ã¨ãã¦æ¸¡ãå®è£ ã«ãªãã¾ãããããã¦ããã°ãã¹ãã³ã¼ãã§æå®ã®æå»ã渡ã㦠greet ã¡ã½ãããå®è¡ã§ãã¾ãã
2 ã¯ããã¹ãã®ãã«ãã¼ã©ã¤ãã©ãªãªã©ãå©ç¨ãã¦ãTime ã¯ã©ã¹ã® now ã¡ã½ããã®ã¹ã¿ããä½æããå®è£ ã«ãªãã¾ãããã¹ãã³ã¼ãã§ã¹ã¿ããåç¾ãããæå»ãè¿ãããã«å®è£ ãã¾ãã
ç§ã¯ãåºæ¬çã«ã¯ 1 ãé¸æããã¹ãã¨èãã¦ãã¾ããé決å®çãªãµãã¾ããããç¾å¨æå»ã«ç´æ¥ä¾åãããã¸ãã¯ã¯ããèªä½ãé決å®çãªãµãã¾ãããããã¨ã«ãªãããã®ãã¸ãã¯ã«ä¾åãããã¸ãã¯ãã¾ãé決å®çãªãµãã¾ãã... ã¨æ¬¡ã ã«å¼ã³åºãå ã«æ³¢åãã¦ããã¾ãããã¹ã¿ããªãã£ãã¡ã³ããããªãã£ã確ä¿ããããã«ãããããä¾åã¯ã§ãããã¨ãªãéé¢ããã¹ãã§ãã3
ä¾å¤çã«ãã·ã°ããã£ãå¤æ´ããããªãããããããä¾åãå¤ãã渡ããã¨ãã§ããªãããªã©ã®çç±ã§ 2 ãé¸æãããã¨ãããã¨ã¯æãã¾ãã
ç¾å¨æå»ã«é¢ããã¦ããããã¹ãã«ã¤ãã¦æ·±ãç¥ãããæ¹ã¯ããã¡ãã®è¨äºãç¾å¨æå»ãé¢ããã¦ããããã¹ãããããã¹ã容ææ§è¨è¨ãå¦ã¶ - t-wadaã®ããã°ãã®åæã¨èª¬æã大å¤ããããããã®ã§åèã«ãã¦ã¿ã¦ãã ããã
ç¾å¨æå»ã¨ E2E ãã¹ããåä½ç¢ºèª
ã¦ããããã¹ãã§ããã°ããã¹ããããã¨èªä½ã¯ç°¡åã«ã§ãããã¨ããããã¾ãããä»®ã«ç¾å¨æå»ã¸ã®ä¾åãéé¢ã§ããªãã£ãã¨ãã¦ããç¾å¨æå»ãæ±ãã©ã¤ãã©ãªã«ä»å ¥ãããã¨ã§ãã¹ããããã¨ãã§ãã¾ããã§ã¯ããã£ã¨çµ±åããããã¹ãããã¨ãã° E2E ãã¹ããåä½ç¢ºèªã§ã¯ã©ãã§ããããã
ã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã§å®éã«ãã£ãä¾ã 2 ã¤ããã¾ãã
- å¤ä¼ã¿è¬åº§ãªã©æééå®ã³ã³ãã³ãã®åä½ç¢ºèªãè¡ããã
- ä»é±ã®å¦ç¿é²æã«å¿ãã¦ç¿é±ã®ã·ã¹ãã ã®æåãå¤ããæ©è½ã®åä½ç¢ºèªãè¡ããã
ã¾ã 1 ã«é¢ãã¦ã¯ãå è¿°ã®ã¯ãªã¹ãã¹ã®ä¾ã¨åãã§ãããæç¹ã§ã®æåãåç¾ã§ããã°ããããã§ããããã«ãã¦ããããã¹ãã®ã¨ãã¨åãæ¦ç¥ãã¨ããã¨ãã§ãã¾ãã
ãã ãE2E ã§ã¯ã¦ãããã¬ãã«ã§ç¾å¨æå»ãã³ã³ããã¼ã«ããã°ããããã§ã¯ããã¾ãããåºæ¬çã«ã¯ã·ã¹ãã å ¨ä½ã§ç¾å¨æå»ãã³ã³ããã¼ã«ãããã¨ã«ãªãã¾ãããã®ä¾ã§ã¯ãã·ã¹ãã å ¨ä½ã§ç¾å¨æå»ãå¤ä¼ã¿ã«åºå®ããå¿ è¦ãããã¾ãã
ãµã¤ããæ¤è¨¼ç¨ã®ç°å¢ã¯ä¸äººã§å æã§ãããã®ã§ã¯ãªãããã¼ã ãçµç¹ã§ã·ã§ã¢ããã¦ããã¨æãã¾ããã·ã§ã¢ãã¦ããç°å¢ã®ç¾å¨æå»ãæ¹å¤ããããã«ã¯ããã¾ãããç¾å¨æå»ãåºå®ããå°ç¨ã®ç°å¢ãç«ã¡ä¸ããã°ããã§ãããæºåããã³ã¹ãããããã®ãé£ç¹ã§ãã
次㫠2 ã®ã±ã¼ã¹ãè¦ã¦ã¿ã¾ãããã
ãã®ã±ã¼ã¹ã§ã¯ãä»é±ãã¨ãç¿é±ãã¨ãã 2 ã¤ã®æç¹ãç»å ´ãã¦ãã¾ããã¤ã¾ããããæç¹ã®ã¦ã¼ã¶ã¼ã®è¡åãæªæ¥ã®ã·ã¹ãã ã®æåã«å½±é¿ããããã¿ã¼ã³ã§ããç¾å®åé¡ã¨ãã¦ããã®ãããªä»æ§ãæã¤ãããã¯ãã¯å¤ãã¨æãã¾ãã
ããããã¹ãããã«ã¯ãä»é±ãã«æ¡ä»¶ãä½ãããã®è¡åããã¦ãç¿é±ãã«ç¢ºèªãããå¿ è¦ãããã¾ããåä½ç¢ºèªæ¹æ³ã®ä¾ã¯ä»¥ä¸ã®éãã§ãã
- ãä»é±ãã«ç¾å¨æå»ãåºå®ããç°å¢ãç¨æããä¸ã§æ¡ä»¶ãåç¾ããè¡åãã¨ãããç¿é±ãã«ç¾å¨æå»ã移åãåä½ã確èªãã
- æ¡ä»¶ãåç¾ããããã«ãã¼ã¿ãã¼ã¹ãç·¨éãã¦åä½ã確èªãã
- æ¡ä»¶ãåç¾ããè¡åãã¨ã£ãä¸ã§ãç¿é±ãã¾ã§ãã£ã¨å¾ ã£ã¦ 4 åä½ã確èªãã
ãããã®æ¹æ³ã§ããå ã»ã©ã®ã±ã¼ã¹ãããåä½ç¢ºèªã®é£æ度ãä¸ãã£ã¦ããã®ããããã¨æãã¾ããã¾ãããã¼ã¿ãã¼ã¹ãç·¨éãã¦ç¢ºèªãããæ¹æ³ã§ã¯ãç·¨éããä½æ¥ã«ãã¹ãæ··å ¥ããå¯è½æ§ããããããã¹ãçµæã®ä¿¡é ¼æ§ãä¸ããã¾ãã
E2E ã§ã®æ¤è¨¼ã®å ´åãã¦ãããã¬ãã«ã§ã®æ¤è¨¼ã«æ¯ã¹ãæºåã®ã³ã¹ããé«ãé£æ度ãã°ãã¨ä¸ãããã¨ãããã£ãã¨æãã¾ããã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã§ã¯ãã®æã®åä½ç¢ºèªã®ã³ã¹ããé«ããã¨ã«åº¦ã æ©ã¾ããã¦ãã¾ããã
ç¾å¨æå»ã«ä¾åããæ©è½ã®åä½ç¢ºèªã³ã¹ããä¸ããåºç¤ã®å®è£
ãã¦ããããããæ¬é¡ã§ããç¾å¨æå»ä¾åæ©è½ã®åä½ç¢ºèªã³ã¹ããä¸ããããã«å°å ¥ãã Time Injection ã«ã¤ãã¦èª¬æãã¾ãã
ãããããã¨ã®æ´ç
ããããã¦ãããããã¨ãæ´çãã¾ãã
- ãã¡ãã¡ç¾å¨æå»ãåºå®ããç°å¢ãç¨æããã¨ãæ¢åã®æ¤è¨¼ç°å¢ã§åä½ç¢ºèªãããã
- ä¸ã¤ã®ã·ããªãªã®ä¸ã§ãç¾å¨æå»ã移åãããã¿ã¼ã³ (ãã¨ãã°å è¿°ã®å¤ä¼ã¿è¬åº§) ã«ã対å¿ããã
- ãããã¯ãããã¼ã¸ã£ã¼ãå¦ç¿ã³ã³ãã³ãå¶ä½æ å½è ãQA æ å½è ãªã©ãééçºè ãåä½ç¢ºèªãããã
ãããç°¡åã«è¦ä»¶ã«è½ã¨ãã¾ãã
- æ¢åã®æ¤è¨¼ç°å¢ã«ã¦ãã¦ã¼ã¶ã¼ãã¨ã«ãä»»æã®æå»ãç¾å¨æå»ã¨ãã¦è¨å® / æ´æ°ã§ãããã¨
- ééçºè ãå©ç¨ãããããGUI ã§ç¾å¨æå»ãè¨å®ã§ãããã¨
æ¢åã®æ¤è¨¼ç°å¢ã§ãç°å¢èªä½ã®ç¾å¨æå»ãæ¹å¤ãããã¨ãªãåä½ç¢ºèªãå¯è½ã«ããããã«ãã¦ã¼ã¶ã¼ (æ¤è¨¼ã¢ã«ã¦ã³ã) ãã¨ã«ç¾å¨æå»ãè¨å®ã§ããããã«ããã¨ããæ¹éãã¨ããã¨ã¨ãã¾ããã
å®è£
ãã¦ãè¦ä»¶ãæºããããã«å®è£ ãããã¨ã¯å¤§ãã以ä¸ã® 3 ã¤ã§ãã
- è¨å®æå»ãã¦ã¼ã¶ã¼ãã¨ã«æ°¸ç¶åãããã¼ã¿ã¹ãã¢ãç¨æãã
- æå»ã®åç § / è¨å®ãã§ããããã«ãã
- ã¢ããªã±ã¼ã·ã§ã³ã§è¨å®ãããæå»ãå©ç¨ãã
ã¾ãã¯ããã¼ã¿ã¹ãã¢ã®ç¨æã§ãããã¼ã¿ã¹ãã¢ã«ã¤ãã¦ã¯ãã¦ã¼ã¶ã¼ ID ã¨è¨å®æå» (ãã¨ãã° ISO 8601 å½¢å¼ã® String) ã®ãã¢ãç»é²ã§ããã°ä½ãå©ç¨ãã¦ãããã¨æãã¾ããã·ã³ãã«ãª KVS ã§ååãªã®ã§ãç§ãã¡ã¯ä½¿ãæ £ãã¦ãã Redis ãé¸æãã¾ããã
次ã«ãæå»ã®åç § / è¨å®ã§ããåç §ãè¨å®ãã»ã¨ãã©åããªã®ã§ãè¨å®ã®ã±ã¼ã¹ã説æãã¾ãã以ä¸ãã·ã¼ã±ã³ã¹ã§ãã
å è¿°ã®éããééçºè ãå©ç¨ããããæå»è¨å®ç¨ã® GUI ãä½æãã¾ããã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã§ã¯ãæ¢ã«ãéæ¬çªç°å¢ã® /debug ãã¹ã«ãããã°ç»é¢ãç¨æãã¦ãããããããã«æå»è¨å®æ©è½ã追å ãã¾ããã
(1) ã§ãè¨å®ãããæå»ã Body ã«è©°ã㦠/injected_time ã« POST ãã¾ããã³ã¼ããã¼ã¹ä¸ã§ã¯è¨å®æå»ã injected_time ã¨è¡¨ç¾ãã¦ãã¾ããæå»ã®å½¢å¼ã¯ãªãã§ãããã§ãããISO 8601 å½¢å¼ãæ¨æºåããã¦ããã©ã¤ãã©ãªçã§æ±ããããã®ã§ããããã§ãã(2) ã§ãèªè¨¼ã¦ã¼ã¶ã¼ã® id ã¨è¨å®æå»ã®ãã¢ã Data Store ã«ä¿åãã¾ãã
æå¾ã«ãã¢ããªã±ã¼ã·ã§ã³ã§è¨å®ãããæå»ãå©ç¨ããå®è£ ã§ãã以ä¸ãã·ã¼ã±ã³ã¹ã§ãã
(2) ã§ãã³ã³ããã¼ã©ã¼ã®å ±éå¦çãªã©ã§èªè¨¼ã¦ã¼ã¶ã¼ã®è¨å®æå»ããã¼ã¿ã¹ãã¢ããåå¾ãã¾ãã(4) ã§ãåå¾ããè¨å®æå»ããã¸ãã¹ãã¸ãã¯ã«æ¸¡ãã¾ãã
ããã§éè¦ã«ãªãã®ããç¾å¨æå»ã«ä¾åãããã¸ãã¹ãã¸ãã¯ã¯å¼æ°ãªã©ã§æå»ãåãã¨ããããã«ä¾åãéé¢ãã¦ãããã¨ã§ããå é¨ã§ç´æ¥ç¾å¨æå»ã«ä¾åãã¦ãã¾ãã¨è¨å®æå»ãåæ ãããã¨ãã§ããªããªãããã§ããlint ãªã©ãæ´»ç¨ãã¦å é¨ã§ã®ç´æ¥ä¾åãç¦æ¢ããã¨ãã¿ã¼ã§ããä»é² 2 ã«ã¦ Ruby ã® lint ãã¼ã«ã§ãã RuboCop ã§ã®å®è£ ä¾ãç´¹ä»ãã¾ãã
å©ç¨ã¤ã¡ã¼ã¸
Time Injection ã使ãã°ãç¾å¨æå»ã«ä¾åããæ©è½ããç¹å¥ãªç°å¢ããã¼ã¿ãç¨æããããããã¨ãªããç°¡åã«åä½ç¢ºèªãã§ããããã«ãªãã¾ãã
å®éã®å©ç¨ã¤ã¡ã¼ã¸ãã¿ã¦ã¿ã¾ãããã
ã¹ã¿ãã£ãµããªå°å¦è¬åº§ã®ãã¼ã ç»é¢ã¯ãæ¯æå£ç¯ã«å¿ãã¦èæ¯ãå¤ããç´ æµãªä»æ§ã§ããç¾å¨ 12 æã¯ã¯ãªã¹ãã¹ã®èæ¯ 5 ã§ãã
Time Injection ã使ã£ã¦ 1 æãè¨å®ãã¦ã¿ã¾ããæå»è¨å®ç¨ã® GUI ããã¡ãã§ãã
input ã«ç¾å¨æå»ãå ¥åã㦠Update ãã¿ã³ãæ¼ããã¨ã§è¨å®ã§ãã¾ããä»ã¯æªè¨å®ã®ç¶æ ãã¤ã¾ãå·çæç¹ã®æ¬å½ã®æå»ã2024-12-10ãã®æåã«ãªãã¾ãã
1 æã«ãããã®ã§ã2025-01-01ããè¨å®ãã¾ãã
ããã§è¨å®ãã§ããã®ã§å°å¦è¬åº§ã®ãã¼ã ç»é¢ãè¦ãã¦ã¿ã¾ãããã
1 æã®ãæ£æã®èæ¯ 6 ã«å¤ããã¾ãããä¸è¶³æ©ããæ£æãæéæ è¡ã®æ°åã§ãã
1 å¹´ééç¨ãã¦ã¿ã¦ããã£ããã¨
Time Injection ã®å°å ¥ãããã®ã¯ 2023 å¹´ 6 æãªã®ã§ããã 1 年以ä¸éç¨ããã¦ãã¾ããéç¨ããä¸ã§ããã£ããã¨ãããã¤ãç´¹ä»ãã¾ãã
äºæ³ä»¥ä¸ã«å©ç¨ããã¦ãã
Time Injection ã®å©ç¨ã·ã¼ã³ã¯å¤å²ã«æ¸¡ã£ã¦ãã¦ãQAãE2E ãã¹ããåãåããã®èª¿æ»å¯¾å¿ãééçºè ã«ããåä½ç¢ºèªãªã©ã§ã使ããã¦ãã¾ãã
ç¹ã«åãçºæ®ãã¦ããã®ããééçºè ã«ããåä½ç¢ºèªã§ãããã¨ãã°ãå¦ç¿ã³ã³ãã³ãå¶ä½æ å½è ããæå³éãã«ã³ã³ãã³ãã表示 / ã¬ã³ã¡ã³ãããããã¨ã確èªãããããããã¯ãããã¼ã¸ã£ã¼ãä»æ§æ´çã®ããã«æå確èªãããã¨ããªã©ã«ä½¿ããã¦ãã¾ãã
ããã¾ã§ã¯ããããã£ãåä½ç¢ºèªã¯éçºè ã«ä¾é ¼ããã¦ãã¾ãããéçºè ã¨ãã¦ã¯ãæå»ä¾åã®æ©è½ã®èª¿æ»ã確èªã¯æéãããã£ã¦ãããããããã¶ãã¨æ¥½ã«ãªãã¾ãããééçºè ç®ç·ã§ããããããéçºè ã«èããã¨ãèªåã§ç¢ºèªãã§ããã®ã¯ããä½é¨ã¨æãã¾ãã
éå»ã¸æ»ãã®ã¯ããããã
å½ããåã®è©±ã§ã¯ããã®ã§ãããæå»ãèªç±ã«è¨å®ã§ããã¨ãã£ã¦ããéå»ã¸æ»ãæä½ã¯ãã¼ãã«ãããã¾ããã·ã¹ãã ã¨ãã¦ã¯ãå½ç¶ãæéãå·»ãæ»ããã¨ãªãã¦èæ ®ãã¦ããªããããä½ãããã®ä¸å ·åãèµ·ããå¯è½æ§ãé«ãã§ãã
ããããéç¨ãã¦ã¿ãã¨ãéå»ã«æ»ã£ã¦åä½ç¢ºèªãããã±ã¼ã¹ããããªãã«ãããã¨ããããã¾ãããåãåããã®èª¿æ»ãªã©ã§éå»æç¹ã®ç¶æ ãåç¾ãããå ´åãªã©ã§ãã
éå»ã®æå»ã Time Injection ã§è¨å®ããã¨ãã«ä¸å ·åãèµ·ããã®ãèµ·ãããªãã®ããã©ã対å¦ããã°ããã®ããããã¯ã±ã¼ã¹ãã¤ã±ã¼ã¹ã§å®è£ ã®è©³ç´°ã«ããã¾ããéç¨ã¨ãã¦ã¯ãéå»æ¥ä»ãè¨å®ãããã¨ããå ´åã¯æ³¨æåèµ·ã®ã¢ã©ã¼ããåºãããã«ããå¿ è¦ã§ããã°éçºè ã¸ç¸è«ãã¦ãããããã«ãã¦ãã¾ãã
æå»ãå¼æ°ã§æ¸¡ããã¨ã®æ¯é
Time Injection ã®å°å ¥ã®éã«ãæå»ãå¼æ°ã§æ¸¡ãã¨ãªãã¨ãæ·±ãå¼ã³åºãå ã§æå»ãå¿ è¦ãªå ´åã«ããã±ããªã¬ã¼ã§æ¸¡ããã¨ã«ãªãè¨è¿°ãåé·ã«ãªãã®ã§ã¯ãªãããã¨ããæ¸å¿µãããã¾ããã
çµè«ã¨ãã¦ã¯ 1 å¹´ééç¨ããç¯å²ã§ã¯ãç¹ã«åé¡ã«ã¯ãªã£ã¦ãã¾ããã
å è¿°ããéããåºæ¬çã«ã¯ç¾å¨æå»ã¸ã®ä¾åã¯éé¢ããã¹ãã ã¨èãã¦ãã¾ãããããããã±ããªã¬ã¼åé¡ã¯ã³ã¼ãã大è¦æ¨¡ã«ãªãã°éçºä½é¨ã«æªå½±é¿ãåã¼ãå¯è½æ§ãããã¾ããããä»å¾åé¡ã¨ãªãã°ãä¾åæ³¨å ¥ã®ããæ¹ã工夫ãããªã©ãä½ãçãè¬ãããã¨ã«ãªãã¨æãã¾ãã
å°å ¥ã«ããã注æç¹
Time Injection ã¯ãããã¯ãã®éç¨ã³ã¹ãåæ¸ã«å¤§ãã«å½¹ç«ã£ã¦ãã¾ãããããã¤ã注æç¹ãããã¾ãã
ãããã¯ã·ã§ã³ã³ã¼ãã¸ã®æ±æ
ãããã¯ã·ã§ã³ã³ã¼ãã¸ã®æ±æã¨ã¯ãåä½ãã¹ãã®èãæ¹/使ãæ¹ãã§ç´¹ä»ããã¦ããã¢ã³ããã¿ã¼ã³ã§ãã
ãããã¯ã·ã§ã³ã»ã³ã¼ãã¸ã®æ±æã¨ã¯ããã¹ãã§ã®ã¿å¿ è¦ã¨ãããã³ã¼ãããããã¯ã·ã§ã³ã»ã³ã¼ãã«å ãããã¨ãæãã¾ãã
ãã®ã¢ã³ããã¿ã¼ã³ã®åé¡ã¯ããããã¯ã·ã§ã³ã³ã¼ãã®ä¿å®ã³ã¹ãã大ãããªã£ã¦ãã¾ããã¨ã§ãããã ãããããã¯ã·ã§ã³ã³ã¼ãã¸ã®æ±æã常ã«æªãããã§ã¯ãªãããããã¯ã·ã§ã³ã³ã¼ãã®ä¿å®ã³ã¹ãã®å¢å ã¨å¾ããããªã¿ã¼ã³ã®ãã©ã³ã¹ãè¦ãã¹ãã ã¨ãã話ã§ãã
Time Injection ããããã¯ã·ã§ã³ã³ã¼ãã¸ã®æ±æã«ä»ãªãã¾ãããä¿å®ã³ã¹ããçºçããããã§ãããããªã¿ã¼ã³ãå¾ããããã©ãããèããå¿ è¦ãããã¾ãã
ç§ãã¡ã®å®è£ ã§ãããã®ãã©ã³ã¹ã®è¦³ç¹ã§ããã¤ãå²ãåã£ã¦ãããã¨ãããã¾ããä¸ã¤ã¯ããªã³ã©ã¤ã³å¦çã®ã¿ã§è¨å®ãããæå»ãå©ç¨ãããããã¸ã§ãã§ã¯è¨å®ãããæå»ãèæ ®ãã¦ããªãç¹ã§ãããªã³ã©ã¤ã³å¦çã®ã¿ã§ãã»ã¨ãã©ã®ã¦ã¼ã¹ã±ã¼ã¹ãã«ãã¼ã§ããããããããã¸ã§ãã§ã¯å®è£ ãããªãææ決å®ããã¦ãã¾ãã
ãã®ããã«ãå°å ¥ããéã¯ãæ¬å½ã«ãã¼ãºããããªã¿ã¼ã³ãå¾ãããã®ãã«æ³¨æãã¦ãã ããã
E2E ãã¹ãã®æ¸ãããã«æ³¨æ
æå»ä¾åã®æ©è½ã® E2E ãã¹ããæ¸ãã®ã¯é常ããããããã»ã¨ãã©ç¡çã¨ãã£ã¦ããã±ã¼ã¹ãå¤ãã§ãã
Time Injection ãå°å ¥ãããã¨ã§æå»ä¾åã®æ©è½ã® E2E ãã¹ããç°¡åã«æ¸ããããã«ãªãã¾ãã
ãããããã¹ãã®æ¯éã E2E ãã¹ãã«ããããã¨ãå§ãã¦ããããã§ã¯ããã¾ãããããã注æããããã¤ã³ãã§ããåºæ¬ã«åããã¦ããããã¹ãã§ã§ãããã¨ããããã E2E ãã¹ãã§æ¸ããªããããã¾ããããæ¬å½ã« E2E ãã¹ããå¿ è¦ããèãã¾ãããã
ç§ã¯ãTime Injection ãç価ãçºæ®ãã¦ããã®ã¯ E2E ãã¹ãã§ã¯ãªããæåã§ã®åä½ç¢ºèªã ã¨æãã¦ãã¾ããèªåãã¹ãã«èµ·ããã¾ã§ã§ã¯ãªã (ãªã°ã¬ãã·ã§ã³ãæ°ã«ãã¦ããããã§ã¯ãªã) ããåä½ç¢ºèªããããã¨ãããã¼ãºã¯ããããã¾ãã
ãããã«
ä»åã¯ãç¾å¨æå»ã«ä¾åããæ©è½ã®åä½ç¢ºèªã®ãããããã¨ãããã解決ããããã®åºç¤ãTime Injectionãã«ã¤ãã¦ç´¹ä»ãã¾ãããåæ§ã®èª²é¡ã«æ©ãã§ããæ¹ã®åèã«ãªãã°ããããã§ãã
ä»é²
ä»é² 1. ãã¤ã¯ããµã¼ãã¹ã¢ã¼ããã¯ãã£ã¸ã®å¿ç¨
å®è£ ã®é ã®èª¬æã§ã¯ãã·ã³ãã«ãª backend ãæ³å®ãã¦èª¬æãã¾ããããã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã®å®éã®æ§æã§ã¯è¤æ°ã® backend service ãå調ãã¦ãã¾ãã
ã¹ã¿ãã£ãµããªå°å¦ã»ä¸å¦è¬åº§ã®æ§æã大èã«çç¥ããã®ãä¸ã®å³ã§ãã
ãã®ãããªãã¤ã¯ããµã¼ãã¹ã¢ã¼ããã¯ãã£ã§ã¯ãå backend service 㧠Time Injection ã§è¨å®ããæå»ãå©ç¨ããå¿ è¦ãããã¾ããå®è£ ã¨ãã¦ã¯ä»¥ä¸ã®éãã§ãã
- gateway ã§ãã¼ã¿ã¹ãã¢ã¸æå»ã®èªã¿æ¸ãããã
- 以éã®ã¢ããã¹ããªã¼ã ãµã¼ãã¹ã¸ã®ãªã¯ã¨ã¹ãã§è¨å®æå»ã HTTP ãããã¼ 'X-Injected-Time' ã¨ãã¦å¼ãåã
- å backend service 㯠HTTP ãããã¼ 'X-Injected-Time' ã®å¤ãå©ç¨ãã
å®éã®æ§æã§ã¯ãã£ã¨å¤ãã® backend service ãåå¨ãã¦ãã¾ãããå ¨ã¦ã®ãµã¼ãã¹ã§ Time Injection ãå®è£ ãã¦ããããã§ã¯ããã¾ããããããã¯ã·ã§ã³ã³ã¼ãã¸ã®æ±æã®é ã§èª¬æããéãã管çã³ã¹ãã®å¢å ã¨ãªã¿ã¼ã³ã®ãã©ã³ã¹ãèãã¦ã主è¦ãª service ã®ã¿ã§å®è£ ããã¦ãã¾ãã
ä»é² 2. ç¾å¨æå»ã¸ã®ç´æ¥ä¾åãç¦æ¢ãã lint
å®è£ ã®é ã§ãç¾å¨æå»ã«ä¾åãããã¸ãã¹ãã¸ãã¯ã¯å¼æ°ãªã©ã§æå»ãåãã¨ããããã«ä¾åãéé¢ãã¦ãããã¨ãã¨èª¬æãã¾ããããlint ãä½æãããã¨ã§ãããå¼·å¶ãããã¨ãã§ãã¾ããä¾ã¨ã㦠Ruby ã®éç解æãã¼ã«ã® RuboCop ã®ãµã³ãã«ã³ã¼ããç´¹ä»ãã¾ãã
# lib/custom_cops/no_get_current_time.rb module CustomCops class NoGetCurrentTime < ::RuboCop::Cop::Base MESSAGE = 'Do not use methods that get current time (e.g. `Time.current`). You may use `context[:current_time]` instead.'.freeze def_node_matcher :get_current_time_by_date?, '(send (... :Date) { :new :yesterday :today :tomorrow :current })' def_node_matcher :get_current_time_by_datetime?, '(send (... :DateTime) { :new :now :today :current })' def_node_matcher :get_current_time_by_time?, '(send (... :Time) { :new :now :current :current })' def_node_matcher :get_current_time_by_time_zone?, '(send (send (... :Time) :zone) { :now :today })' def on_send(node) return unless get_current_time_by_date?(node) || get_current_time_by_datetime?(node) || get_current_time_by_time?(node) || get_current_time_by_time_zone?(node) add_offense(node, message: MESSAGE) end end end
# spec/custom_cops/no_get_current_time_spec.rb require 'rails_helper' require 'rubocop' require 'rubocop/rspec/support' require 'custom_cops/no_get_current_time' RSpec.configure do |config| config.include(RuboCop::RSpec::ExpectOffense) end RSpec.describe CustomCops::NoGetCurrentTime do describe 'on_send' do subject(:cop) { CustomCops::NoGetCurrentTime.new } context 'methods that get current time' do [ 'Date.new', 'Date.new()', 'Date.today', 'Date.yesterday', 'Date.tomorrow', 'DateTime.new', 'DateTime.new()', 'DateTime.now', 'DateTime.today', 'DateTime.current', 'Time.new', 'Time.now', 'Time.current', 'Time.zone.now', ].each do |source| context "#{source}" do it do expect_offense(<<~EOS, source:) %{source} ^{source} CustomCops/NoGetCurrentTime[...] EOS end end end end context 'methods that do not get current time' do [ 'Date.new(2024, 1, 1)', 'Date.parse', 'DateTime.new(2024, 1, 1)', 'DateTime.parse', 'Time.new(2024, 1, 1)', 'Time.zone', 'Time.zone.parse', ].each do |source| context "#{source}" do it { expect_no_offenses(source) } end end end end end
# .rubocop.yml require: - ./lib/custom_cops/no_get_current_time.rb AllCops: DisabledByDefault: true CustomCops/NoGetCurrentTime: Enabled: true Include: - app/lib/**/*.rb - app/models/**/*.rb - app/services/**/*.rb - spec/**/*.rb # and so on...
- ã¶ã»ã¯ã¼ã«ãã¨å¼ã°ãããã¨ãã↩
- 決ãã¦åè«ã§ã¯ãªãç§èªèº«ããã£ããã¨ãããã¾ãã↩
- ãªãä¾åãæ³¨å ¥ããã®ã DI ã®åçã»ååã¨ãã¿ã¼ã³ ã§ãããããé決å®çãªãµãã¾ãã¸ã®ä¾åã¯ãæ®çºæ§ä¾åãã¨ãã¦ä¾åæ³¨å ¥ã®å¯¾è±¡ã¨ããã¹ãã¨æ´çãã¦ãã¾ãã↩
- ãããåè«ã§ã¯ãªããå®éã«è¡ããããã¨ã®ããæ¹æ³ã§ãã↩
- ã¹ã¯ãªã¼ã³ã·ã§ããã§ä¼ãããªãã®ãæ®å¿µã§ãããå®éã®ã¢ããªã§ã¯éªãéã£ã¦ãµã³ã¿ãåãã¢ãã¡ã¼ã·ã§ã³ãããã¾ãããããã°ã¢ããªã使ã£ã¦ã¿ã¦ãã ããã↩
- ã¹ã¯ãªã¼ã³ã·ã§ããã®å·¦ä¸ã«ã¡ãã£ã¨ããã«ã¼ãã®ãããªãã®ãè¦ããã¨æãã¾ããããã«è¨å®æå»ã表示ãã¦ãã¾ããTime Injection ã使ã£ã¦ãããã¨ãå¿ãã¦ãä½ããããããã¨æ©ããã¨ãã話ãä½åº¦ããã£ããããè¨å®æå»ã表示ãã¦ä½¿ã£ã¦ãããã¨ãå¿ããªãããã«ãã¦ãã¾ãã↩