Saturday, September 26, 2015

The protocols of the Elders of Zion

הפרוטוקולים של זקני ציון

המוצר אותו אני בודק עושה, בגדול, שני דברים - הוא ממלא תפקיד בתוך פרוטוקול קשיח ומוגדר (שלא אנחנו הגדרנו) והוא מספק מגוון כלי ניהול כדי לאפשר ללקוחות שלנו לנהל את הדרך בה אנחנו מגיבים בשמם לבקשות. הפרוטוקול הזה הוגדר בערך לפני חמש עשרה שנה ולא השתנה יותר מדי מאז. העולם, לצערם של כל המעורבים, השתנה לא מעט מאז ומגוון בעיות בפרוטוקול הפכו למשמעותיות יותר. דברים כמו חוסר תמיכה ב"מכשירים חכמים" (טלפונים, טאבלטים), תלונות מהשטח וכמה חולשות אבטחה הפכו למשמעותיים יותר ככל שהזמן חלף. 
בסופו של דבר, הוחלט על פיתוח גרסה חדשה לפרוטוקול. הודעות יצאו לעיתונות, ומסתבר שלא מעט אנשים גם התחילו לעבוד. 
אחרי זמן מה, טיוטה נשלחה אל מגוון שחקני מפתח ונערכו כמה ישיבות של כל מיני גורמים מעוניינים. לאחת הישיבות הללו נשלחו גם כמה נציגים מאצלנו, וכך הזדמן לי לקרוא את הגרסה החדשה של הפרוטוקול ולשלוח הערות, מה שהתברר להיות חוויה די מעניינת מבחינתי.
מלכתחילה, ניגשתי למשימת הקריאה הזו כמו שאני ניגש לכל קריאת מסמך דרישות (וזה לא משנה אם המסמך הזה מכיל מאה וחמישים עמוד כמו במקרה הזה או שהוא סתם שיחה קצרה עם אחד המפתחים על מה אנחנו רוצים לעשות) - אני מרכיב תמונה בראש של מה הדרישות מתארות, מלביש את התמונה הזו על העולם כמו שאני מכיר אותו, ומתחיל לחשוב איפה דברים לא יושבים כמו שצריך, מה לא ברור או דו משמעי ואיפה יכולות לצוץ בעיות.
תוך כדי קריאה התחלתי לכתוב את ההערות שלי בטופס הייעודי (הם השקיעו וכתבו טיוטה מפורטת, מה זה כבר עוד טבלה אחת?).באחת הבעיות שרציתי להעיר עליהן, שמתי לב שאין לי באמת דרך לנסח אותה כך שתיכנס לתוך הטבלה. יכולתי להצביע על עמוד ופסקה, אבל כשהגעתי לחלק של הצעת שינוי, או של הערה שמסבירה למה השינוי הזה חשוב, הבנתי שזה לא באמת בעיה בפרוטוקול, זו התנהגות שתהפוך את העבודה של המוצר שלי לקשה יותר. בנקודה הזו נפל לי האסימון והבנתי שני דברים:
הראשון - בניגוד למוצר אמיתי שאני יכול להמשיך לבדוק תוך כדי פיתוח, מרגע שהפרוטוקול נחתם והופך לרשמי, אין יותר עם מי לדבר ועד הגרסה הבאה של הפרוטוקול, אי אפשר לשנות כלום. אם זוכרים שהפרוטוקול הזה מגדיר התנהלות של תעשייה שלמה, זה משאיר המון כוח בידיים של כל מי שיכול להשפיע עליו (מה? לא, אני לא מחכך ידיים בזדוניות, זה רק נראה ככה... תראו ציפור!)
השני - בנוסף לבדיקה הסטנדרטית שמחפשת טעויות תמימות, אני צריך להרכיב זוג משקפיים נוסף ולזכור לחפש את האינטרסים של המוצר שלי בתוך הפרוטוקול, גם את הנקודות בהן מישהו משנה את מאזן הכוחות לרעתנו, וגם את הנקודות בהן שינוי קטן יכול לתת לנו יתרון, ולכן אולי כדאי לנו ללחוץ קצת כדי לגרום לשינוי הזה לקרות. נכון, זו לא בדיוק משימת בדיקה, אבל זה מעניין לא פחות( וגם דומה למדי).  

שאלה נוספת שעלתה היא - מה אני עושה עם ההערות הלא בדיוק-קשורות האלה?  לשלוח אותן בתוך המשוב הרשמי לא בהכרח יעזור, כי ההנמקה המרכזית שאני יכול לתת היא "זה מתאים יותר למוצר שלי", ומי שיקרא את ההערות האלה שייך לגוף אחר עם נקודת מבט אחרת ואינטרסים אחרים. בחלק מהמקרים, ההערות יכוונו לכיוון שנוח רק לי, ואפילו לא תואם את הרצונות של מתחרים שממלאים את אותו תפקיד כמוני בתוך הפרוטוקול.  
בסופו של דבר, החלטתי שאת השאלה הזו אשאיר לאלו שמגיעים לישיבה. לפעמים, קל יותר לומר דברים פנים אל פנים מאשר לכתוב אותם. צירפתי את ההערות מהסוג הזה לדוא"ל ששלחתי לנציגים שלנו, ומשיחה איתם אחרי שהם חזרו - אני גם יודע שהם השתמשו בהערות האלה והעלו חלק מהן בקול.

בקיצור, למרות שפרוטוקולים נוטים להיות די משמימים, זה היה תרגיל מעניין למדי בשבילי, ואני מחכה לשלב הבא (שכנראה יקח כמה חודשים לפחות).
-------------------------------------------------

The product on which I'm working does, in essence, two things: It fills a role within a rigid protocol (that is not controlled by us), and it provides our customers a variety of administrative tools to manage the software's behavior. The protocol, which is the core of our product, was released some 15 years ago, and has not changed much since. The world, unfortunately, has changed quite a bit, and several issues with the protocol (ranging from support of "smart" devices, through inherent security problems and to complaints from the field) became more important as time went by. Somewhere around January this year, the development of a new protocol was announced - some notifications were sent to the press, and apparently, some teams began working. 
A while ago, a draft of the protocol was sent to some key players and some meetings were held with relevant stakeholders. We were invited to one of theses meetings (and by "we" I mean our product manager and our Dev lead), and so I got to look at the draft of the new version of the protocol, and even send some comments, which proved to be very interesting for me. 
Initially, I got to the reading task in a way very similar to the way I get to any requirements document reading (regardless if this document is 150 pages longs, as was the case here, or if this "document" is a short conversation with a developer discussing what we want to do): I start reading, assembling a picture of what is being described as I go. Once I have even a sketchy image sitting in my mind, I try to superposition it on "reality" and see how well does it play with the existing components in our system and the flow of events as I have experienced it. Additionally, once in context, I can more easily spot weak points that might go wrong, find ambiguities and missing or wrong requirements. 
As I was reading and doing that, I added my comments to a the provided table for feedback (After all, the great bureaucrats has produced a lengthy protocol draft, what's one tiny table for them?). Formalizing the comments helped me notice one comment did not actually belong there, not even under "general" label. I could pinpoint the problematic page, paragraph and diagram that were problematic, but when I got to "proposed change" and to the comment justifying the change, I understood that I was not pointing a problem in the protocol, but rather a behavior I knew would make life more difficult for our product. At this point, the penny has dropped, and I realized two things: 
First - Unlike a piece of software I can always look at and ask for a retroactive change, once the protocol is released and becomes official - it is set in stone. No one can change it until the next version of the protocol. If we remember that this specific protocol is defining behavior for an entire industry, we see that this leaves a lot of power in the hands of anyone that can affect it (what? no, I'm not mischievously rubbing my hands. It only looks this way... behind you! a three headed monkey!)
Second - In addition to the "regular" testing\review that looks for honest mistakes, I need to put on another pair of glasses and look out also for  my company's interests: Both the points where someone has shifted the current balance towards them a bit more, or points where a small change could be beneficial for our product (and so we might want to try and push in that direction a bit). True, this isn't a testing work per-se, but it was just as interesting (and pretty similar).

Another question that rose was how to present those points I found wearing my other spectacles - Sending them in the official feedback document won't necessarily drive the desired change, as those comments are justified mainly by "My product likes it better this way", and those reading the comments belong to another company, with a different perspective and different interests. In some of the cases, the comments might not even represent the interests of some of our competitors that fill the same role in the protocol (though most of the time, our interests in the protocol align). 
I decided to leave this question to the team taking part in the meeting, since some feedback is more easy to convey in person, so I attached those comments separately for their use. Speaking with them afterwards, I know they chose to raise some of them during the meeting. 

To sum it up - Despite protocols being rather tedious, it was a very interesting exercise for me, and I look forward to the next phase (which will probably happen in a few months at least).  


Sunday, September 13, 2015

עבודה שחורה

Working in the dirt

אני מניח שלכל בודק תוכנה יצא מדי פעם להיתקל בבעיה, לפעמים היא קשורה למה שנבדק כרגע, לפעמים זה סתם משהו שצץ ברקע תוך כדי. כך או כך - אחרי שחוקרים ומבינים את הסיבה לבאג, צץ ועולה לו המשפט "מה? אין שום סיכוי שהייתי עולה על זה בכוונה!". השבוע, גם לי זה קרה (שוב):
בתוך המערכת הסבוכה שלנו, יש תהליך אחד שבאופן חריג למדי, קל מאוד לתיאור - כל מה שעושה התהליך הזה הוא לעבור על שורות בתוך טבלה במסד הנתונים שלנו, לסדר כל שורה בתוך פורמט מוגדר מראש ולשלוח אותה לשרת מסויים. לא מסובך, נכון?
כרגע יש לנו בעיה אחת עם המערכת הזו - היא לא פועלת מהר מספיק. אנחנו עומדים בקצב השליחה הרצוי בכל יום רגיל, אבל אם מסיבה כזו או אחרת אנחנו לא שולחים הודעות במשך זמן מה קשה לנו מאוד להשלים את הפער. נו, אז מה עושים? מריצים את התהליך במקביל ומקווים לטוב. לא? אחד המתכנתים שלנו התחיל לעבוד על המשימה, ואחרי ניסיון לפתרון אחד שלא צלח,הגיע לפתרון הבא - כל אחד מהתהליכים "ינעל" חלון זמן כזה או אחר, ויטפל בשליחה של כל מה שנמצא בפנים. עברנו חמישה או שישה סבבים של שחרור קוד מוכן אלי, איתור בעיות (כולל OBOB חביב אחד) והשבת הקוד למפתח. בסך הכל, יצא שעבדנו על פיסת התוכנה הזו בערך חודש, כשהתכנון המקורי היה שלושה או ארבעה ימים. וזה לא שסיימנו, עדיין נשארו כמה פינות לתקן, אלא שהיו דברים דחופים יותר.
כשחזרנו למשימה אחרי חודש וחצי של הפסקה, שמתי לב שהאוטומציה שכתבתי לפני למעלה משנה, כדרכה בקודש, נכשלת באופן מוזר. באופן עקבי לא נשלחות הודעות מסויימות. אחרי שלושה ימים של חקירה גילינו את הסיבה - איפשהו בטבלת הניהול היו כמה ערכים שנשארו מהרצות קודמות ושיבשו את הכל (בפרט, הם גרמו לתהליך שלנו ללכת לישון ליום שלם). 
בדיעבד - היו כל מיני דרכים בהן יכולתי לבדוק את הנקודה הזו, אבל סביר מאוד שלא הייתי פועל באף אחת מהן. את מנגנון תפיסת החלונות (שלא השתנה) כבר בדקתי חמש פעמים, ובעקבות ממצאים קודמים הוספנו מחיקה של חלונות בזמן עליית התהליך, וגם את זה בדקתי באופן שטחי. בנוסף, כל החלק של החלונות וניהולם לא היה מאוד מרכזי ואת עיקר מאמצי הבדיקה השקעתי במקום אחר. איך מצאתי את הכל? בפוקס. 
הפוקס הזה גרם לי לחשוב קצת. לא מעט פעמים יצא לי לשמוע שבדיקה, במיוחד בדיקה אוטומטית, צריכה להתחיל בהגדרת הסביבה ולסיים בניקיון כדי לא לשבש בדיקות שירוצו אחר כך. אבל בעצם - אילו הייתי מנקה אחרי כמו שצריך, הייתי מחמיץ את הבעיה הזו בקוד. אני עוד צריך לחשוב קצת כדי להבין בדיוק איפה ואיך ליישם את זה, אבל הרעיון של לעבוד בסביבה "מלוכלכת" כשאפשר דווקא מוצא חן בעיני מאוד. אחרי הכל, התוכנה שלכם לא תרוץ בסביבה סטרילית, אז למה לבדוק אותה רק בסביבה סטרילית? לפעמים נתקלים בדברים מעניינים.

בנוסף, יצא שסיימתי לכתוב את הפוסט כמה דקות לפני כניסת ראש השנה - שנה טובה לכולם!

--------------------------

I assume that every software tester has faced here and there the following situation: Sometime you stumble upon a bug. it might be related to what you were currently testing, or it might not be, at any rate - it is something important enough to invest some time in investigating it. It turns out to be a bit complicated, but once you understand what has caused this to happen you can hear yourself saying "I would have never *intentionally* try testing this scenario!"
Such a case happened to me (again) this week - I was going over some changes in a rather simple part in our over-complicated system: it reads a line from a table in our database, formats it nicely and sends it to a designated server. couldn't be simpler, right?
As it happens, we have one problem with this process - it's not fast enough. It works kind of o.k. under the normal state of affairs, but if for some reason, this process was down for a while, or we have a busy day, this process has a hard time catching up. So, what do you do when you want something to work faster? The easiest answer is - you multi-thread and hope it works. One of our developers took up the task, and after several attempts came up with a nice idea - each thread will "lock" a time window and handle all the work that should be done there.
In the process of getting to this solution, we went through another one that didn't quite work as we hoped, and by the time we got to this implementation we were already working on this task for three weeks instead of the planned 3 or 4 days we assumed the original fix would take us. And, as every new implementation is, this one didn't work perfectly the first time (including a cute OBOB), so after toying with this for a month or so, we finally ditched it for higher priority items. When we got back to this feature after over a month of dealing with those higher priories, I noticed that the automation checking this is failing. Three days later we found the issue - apparently, I had some junk in my database that caused the time-window locking mechanism to fail, sending the process to sleep for a day.
Now, in retrospect, I think there were some ways I could go hunting specifically for this type of bug. However, the locking mechanism was not the priority target of my tests (I was more interested in the potential throughput), it was tested before and seemed reliable enough at the time, so I did not invest too much effort on checking every edge case. I got lucky.
The way I got lucky sent me thinking:  When I made my first steps in the testing world, I learned that at least in theory, each "test case", and especially those automated scenarios, has three steps - setup, where all the necessary preparations are being done, the actual test case, and then cleanup - where the test makes sure it will not affect other tests running after it. However, I stumbled across my bug when not cleaning it, and had I cleaned my data properly, I would not have found the bug at all.
So, I probably need to think about it a bit to understand how to implement it, but I rather like the idea of working in a "dirty" environment, after all - while a clean environment sure helps a lot in debugging, your production system won't run in sterile conditions, so why not test it with dirty data?, you might be able to find some interesting stuff.

And, is it happens, I finish writing just as the Jewish new year is approaching,
Have a great year!