tag:blogger.com,1999:blog-283833372024-03-13T07:49:25.603-04:00Thoughts and IdeasThe power of software is the power of thoughts and ideas.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comBlogger314125tag:blogger.com,1999:blog-28383337.post-79415768384496808652016-02-11T14:48:00.001-05:002016-02-11T14:48:16.590-05:00Blogging on medium.com/@hartsock I'm trying out blogging on <a href="http://medium.com/@hartsock">medium.com/@hartsock</a> for a while.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-88628074459827215462015-08-26T12:30:00.000-04:002015-08-26T12:30:01.439-04:00Promotion, pyVmomi & future updatesI was recently promoted at VMware and I have new duties. The new <i>day job</i> (as I lovingly call it) is taking a great deal of time that I would normally devote to side projects like <a href="https://github.com/vmware/pyvmomi">pyVmomi</a>. I am hoping we will be able to find others inside VMware that I can delegate duties to.<br />
<br />
In the mean time, I'm unable to predict project velocity because I'm unable to predict how much focus I can direct at the project. My next major action on the project will be to attempt to release an <i>alpha</i> release of pyVmomi with some spot-fixes embedded.<br />
<br />
When I have a few hours to steal away for this I'll post here and talk about how to get this version and a disclaimer that the release is <i>alpha</i> quality and may put your own systems at risk should you use it. However, I also want to put <i>something</i> into user and administrator hands sooner rather than later.<br />
<br />
Thanks to the community for continuing on as I'm working heads down.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-19447591786224483242015-07-22T12:30:00.000-04:002015-07-22T12:30:00.760-04:00Return on Investment: high, low, and durability.I'm heads down focusing on delivering a critical new feature to another team. But, I wanted to stop a moment and mention some of what drives how I prioritize things, how on occasion I'm directed privately to deprioritize some tasks that were very high priority previously and what the thought process behind these choices are.<br />
<br />
We all have 24 hours in a day and 7 days in a week. Studies show that from a pure numerical stand point working more hours <i>beyond a certain point</i> produces a <a href="http://www.economist.com/blogs/freeexchange/2014/12/working-hours?fsrc=scn%2Ffb%2Fwl%2Fbl%2Fworkinghours">net loss in output.</a> That is to say, plugging away at a job beyond a certain point produces a net negative return due to increased defects, mistakes, and general fatigue and a phenomena we call <i><a href="https://www.psychologytoday.com/blog/high-octane-women/201311/the-tell-tale-signs-burnout-do-you-have-them">burnout</a></i>.<br />
<br />
Part of your own self-management should be guarding against burnout and working for net-positive output. The other part of this is to ensure that you are working in an area that will yield the best return for your personal investment. In this case, I'm talking about choosing a project and place to sink your time and effort.<br />
<h3>
Classical Prioritizing</h3>
We take a project and walk it through our <a href="http://hartsock.blogspot.com/2015/05/how-to-make-choice.html">decision making process</a> then, we prioritize it based on its return on investment. Most folks are familiar with this decision making grid:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-GX2-5UTEShU/Va09SeDOXWI/AAAAAAAAqaM/SOEyhnpLw3E/s1600/Priority_Matrix.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-GX2-5UTEShU/Va09SeDOXWI/AAAAAAAAqaM/SOEyhnpLw3E/s1600/Priority_Matrix.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Source: http://www.ashpfoundation.org/leadershipprimer/Primer19.html (which I thought had nice graphics but don't necessarily endorse)</td></tr>
</tbody></table>
... in which we make sure we keep doing the things that are <i>important</i> and never allow ourselves to dig into the unimportant and never urgent things.<br />
<br />
I'm going to tell you that this particular grid is a great idea for <i>business people</i> in general. But <i>we are not business people</i>. We're <i>innovators </i>by definition. For us there's one more <b>dimension</b><i> </i>that should influence our decision making.<br />
<br />
<h3>
Durability and priority</h3>
<div>
As an engineer, software developer, or innovator your job isn't merely to do your job. <i>Your job </i>is also to <i>invent the future</i>. That means <i>if you are forever under the tyranny of the present you'll never get around to inventing the future.</i> You absolutely must make room to invest part of your time into things that seem like a waste of time now on that 2D chart but will <i>make more time</i> later.</div>
<div>
<br /></div>
<div>
For example:</div>
<div>
<ul>
<li>automation</li>
<li>invention</li>
<li>mentoring</li>
</ul>
<div>
If it is repetitious, it is in a computer or involves a computer, and it is well understood... <i>why isn't it automated?</i> If you answer "because I don't have time" then take a moment to calculate the total time you and/or your colleges will spend doing this task over the total projected life-span of the technology stack. Then calculate a rough order-of-magnitude estimate of how long it will take to automate the task. If the two number are at all close <i>you should automate</i>. That's because even if you <i>personally</i> don't create the automation there's a high probability one of your less experienced peers might be able to use the project as a learning tool allowing you to <i>mentor</i> them into a higher level of proficiency. This process in turn leads to invention and innovation of the problem space.</div>
</div>
<div>
<br /></div>
<div>
This is the property of <i>durability</i> of an investment. It may be a low yield on the traditional return on investment style calculation you might perform but sometimes these apparent time-sinks when used properly enable a long term durable return. </div>
<div>
<br /></div>
<div>
That automation that took 3 months to invent and deliver (delaying another project like pyVmomi for example) will eventually yield a savings of 5 minutes a day over 300 engineers or a dividend of something in the neighborhood of 375,000 engineer minutes over a year. Break it down another way and you could call it 375,000 minutes <i>(divided by 60 minutes in an hour & 8 hours in a work day & 4 work weeks per month)</i> = 195 <a href="https://en.wikipedia.org/wiki/The_Mythical_Man-Month">mythical man-months</a> or in other words, delay now and save a whole year of effort over the next decade. </div>
<div>
<br /></div>
<div>
Is it worth the trade? Keeping in mind that having a wonderful 10 year plan does you no good if you're dead in the water tomorrow. So we do still have to consider the classical decision making matrix but we should also pull our 3rd dimension of <i>durability</i> into consideration when two opportunities look the same otherwise <i>the more durable</i> investment of energy should win since it will pay us back for longer.</div>
<div>
<br /></div>
<div>
The next question is whether <i>you</i> should do the task or if you should <i>delegate</i> the task. This is a slightly different set of calculations. We've established that the task (whatever it is) should be automated, just not precisely how. That's highly dependent on what resources you have available for performing the separate tasks of inventing the automations you need to eliminate the initial task we were considering. If the personal savings exceeds the personal expense then you should definitely perform the automation. If the group savings exceeds the group expense then the <i>group</i> should <i>have someone</i> perform the automation. Incidentally, when the personal benefit doesn't match the group benefit, we've got the potential for conflict.</div>
<div>
<br /></div>
<div>
At the moment I'm personally pinned working on only the #1 quadrant of important <i>and</i> urgent.</div>
<div>
<br /></div>
<div>
More on this later as I get more room to delegate.</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-79026907153033382092015-05-05T11:43:00.001-04:002015-05-05T11:43:15.908-04:00How to make a choiceToday's post is just general life philosophy. Nothing technical, and just some fatherly advice of the kind I might pass to my sons. Here's a simple set of things I ask myself before I choose to invest myself personally in something. This came up because my eldest son is working on his college career and making hard choices about what classes he'll take and which jobs he'll work.<br />
<br />
These days I follow this process instinctively. I don't consciously think about it. I do this in everything from marriage to Open Source projects. And, when there's a crisis or decision to make I will stop and work through this set of questions again. That's because <i>things change</i> and sometimes we have to as well in response. It's advice, take it or leave it. I think it probably applies to relationships just as well, but I'll focus on career choices for the sake of clarity and brevity.<br />
<h3>
Will <i>it</i> work?</h3>
The first step to evaluating whether or not to invest yourself in a project, a technology stack, a start-up, or a community is to really honestly ask yourself if this hare-brained <i>thing</i> will actually work. When I interview for a job, talk to start-up founders, or even projects at big multi-national multi-billion dollar corporations I ask: <i>will this actually work?</i> If everything is <i>perfect</i> but the core idea is completely unworkable it's time to move on, no other factors (like love or money) will really matter.<br />
<i><br /></i>
It's hilarious to me that so many people trying to convince me to spend my blood, sweat, tears, and years on their project don't bother to explain to me wether their wonderful idea is going to work or not. There's usually a two sided argument to this first part of my decision making process. It's got to be a dance. The first side of the dance is the optimistic side that believes the idea, the other side is the pessimistic side that doubts. For me, I need to see that both sides have played a part in the dance. If I see only one side entertained, I'm likely to leave feeling that I've been deceived at some point. That sense of deception will likely make things unworkable later.<br />
<br />
On the other hand, if you dwell only on the pessimistic reasons something won't work, you'll never entertain any new ideas. I was all pessimism when I reviewed Netflix in the early 2000's. I had been solicited by someone (I forget who) before Netflix's IPO and I didn't follow through on pursuing the job because all I could think of were the reasons Netflix would fail. I was terribly wrong. They succeeded wonderfully but I couldn't see how at the time, and that's a bit of a shame.<br />
<br />
These same instincts also prevented me from taking jobs at companies that really were truly total disasters. There's a few dozen risky moves I could have taken that I won't bother listing that really would have tanked my career. So, there's a careful balance, a dance or courtship with a new idea. You have to allow for the good and account for the bad. You can't be terribly precise at this phase, but you should at least stop and evaluate in dispassionate isolation the <i>idea</i> first.<br />
<br />
If you don't have the tools to answer this question, you might have to just own that inability and decide whether you're an optimist or a pessimist. Now, you're just going with your gut. At least <i>know</i> that's what you're doing. It's practically a defining trait of being human, we don't know things and sometimes we jump without knowing. Know that you don't know and that you're taking a leap of faith.<br />
<br />
Answer this question from all the wisdom you have, not bravado, not fear.<br />
<h3>
Can <i>you</i> do it?</h3>
Just because an idea will work, it doesn't mean <i>you</i> personally can make it work. You may not have the skills, training, or talent to make a good idea actually fly. There are plenty of wonderful ideas and opportunities in the world but if it requires a skill that you can't possibly gain there's no point in pursuing it.<br />
<br />
In some ways, this question too comes down to being wise enough to balance bravado and fear. You are a quantifiable value to yourself. You should have done some work already in this area. Sometimes this is learning to do something a bit scary or a bit hard for you and seeing how you overcome obstacles and what trips you up.<br />
<br />
Are you bad at math? Is math going to be key to making this idea work? Are you bad at working with people? Is this idea going to sink or swim based on people-skills? You need to have as accurate a picture as you can of what <i>you do</i> well and play to your <i>strengths.</i><br />
<i><br /></i>
That doesn't mean you have to carry the whole project, idea, relationship, community, or whatever it is all by your lonesome. You'll hopefully have a group of others along with you for this experience. You'll need to assess whether you and that group can work together, overcome together, and if the group of you have the right skills, in the right place, and at the right time to actually pull this thing off.<br />
<br />
Answer this question from a deep understanding of yourself and your partners in this enterprise. You don't have to be able to do it all right now, you just have to be able to grow into it. You may have to continually evaluate and adjust this part as things change.<br />
<h3>
Is it <i>worth</i> it?</h3>
<div>
Since, I've already mentioned Netflix, I'll mention them again. The second time I talked to Netflix was post IPO. I had a son in High School and even though I think we all thought I was a good "fit" for Netflix at the time, I wasn't prepared to sacrifice <i>his</i> high school and potentially college experience for <i>my personal</i> career satisfaction. To me, my son's continuity of community was more valuable than the amazing opportunity Netflix was potentially offering me. Part of me is wistful about that choice, but I made it knowing that my sons are the most valuable thing in the world to me and I was sacrificing for them. When I look back at it in that light I'm actually proud of the choice I made even though a potentially great future <i>died</i> because of it.</div>
<div>
<br /></div>
<div>
Most of the people I've known are great at sacrificing profoundly for something they really believed was worth it. I save this for last because it's too easy to answer blindly. A great idea might self-evidently work and the reward for making it work might ostensibly be worth it ... "we'll be rich!" ... "we'll be famous!" ... some move or sacrifice might seem worth it when viewed in isolation. The trick is, you never get to do anything in isolation.</div>
<div>
<br /></div>
<div>
You are always going to be you. You will always care the most about the things that you care the most about. If you don't count those things up first before you ask "is it worth it?" then you don't really know what you're selling to be able to buy this shiny new thing. I personally believe this is the source of many people's regret. They chose without knowing what it was they were doing and ended up giving up something they, in their inner most core, thought was more valuable for something that was simply not worth the thing that they exchanged.</div>
<div>
<br /></div>
<div>
I've known women that sacrificed family for career. I've known men who have sacrificed career for family. These people are happy or depressed depending on whether they understood the value of these trades and whether they chose the thing that was truly the most valuable to <i>them</i>. For some, children are worth more than billions of dollars and a place in history, for others a place in history is worth more than any personal comfort. Which are you? Which are you <i>really</i>? These things change.</div>
<div>
<br /></div>
<div>
The final question of what is worth your sacrifice relies on having answered the other two well and on knowing yourself well. If you know the idea works and you work with the idea... when all is said and done, will you be proud or ashamed of the sacrifices you made? Choose well, you can't know the end from the beginning.</div>
<div>
<br /></div>
<div>
Will you be proud to have <i>failed</i> at this?</div>
<h3>
Conclusion</h3>
<div>
If you're into this sort of thing, my three questions are based on the parables from <a href="http://biblehub.com/niv/luke/14.htm">Luke 14:25 to 15:32</a> just dressed in modern clothes and removed from the period language and concepts. It's not a complicated set of ideas. I'm sure other faiths have similar teachings, but I don't know enough other scriptures to tie them in I would love to hear other faith's teachings on this topic. </div>
<div>
<br /></div>
<div>
These parables in particular are about being human, making choices, and living with the consequences. They're valuable in practical ways for making us think about what we're doing and how we're living. As a collection of teachings they're an invitation to live deliberately wether or not you ascribe supernatural meanings to them.</div>
<div>
<br /></div>
<div>
Another analogy I've invented for this particular lesson is:</div>
<blockquote class="tr_bq">
Imagine you are old and spent. There's a child you care about. You can't lie to them. You have to tell them your life's story. What will you tell them about this moment? What will you tell them you gave up? What will you tell them you chased after? Was it worth it?</blockquote>
Knowing that you can't tell if you'll win or lose yet, you have to be comfortable discussing the loss. Live deliberately, not accidentally. Choose well, and live well.<br />
<br />
<div>
</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-13623525086689150872015-04-17T15:59:00.002-04:002015-04-17T15:59:14.838-04:00pyVmomi and VMware’s internal R&D Innovation Offsite for 2015I've been invited to speak at <a href="http://blogs.vmware.com/cto/tag/radio/">VMware’s internal R&D Innovation Offsite</a> (<a href="https://www.facebook.com/media/set/?set=a.10151640524839204.1073741833.361013714203">RADIO</a>) on the topic of my experiences with <a href="http://vmware.github.io/pyvmomi-community-samples/">pyVmomi</a>. This is a rare honor, and I'm very pleased even just to be invited. For the pyVmomi community this potentially is a big boost to our visibility.<br />
<br />
I expect to be sharing the stage with some heavy hitting presenters with big ideas to share in a <i>fast-paced</i> <a href="http://speakupforsuccess.com/10135/how-are-ted-talks-and-business-presentations-different/">TED Talk </a>like format. So, I'm spending a good deal of effort making sure I make the most of the opportunity.<br />
<br />
I only have so many hours in a work week. That extra effort in one area means other areas slow down a bit. For you, that translates into a bit less predictability in <i>when</i> things are going to happen on <a href="https://github.com/vmware/pyvmomi">pyVmomi</a> in the near term. Right now, the plan of action looks something like this:<br />
<ul>
<li>Roll out a beta of <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%202015.1">v5.5.0.2015.1</a> by the end of Q2 2015 as a bug fix only release</li>
<li>Begin alpha work of <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%202015.2">v6.0.0.2015.2</a> for alpha release by the end of Q3 2015</li>
</ul>
The links above are to the issue tracker for issues targeted to their respective releases and these lists may change in real time as the community works through the release. Naturally, these are <i>aspirational </i>statements at the moment so the plan may have to change as we roll forward. But, I think this flexibility is the strength of our process on this project.<br />
<br />
I have also resolved to spend more time <b>mentoring</b> new developers. That kind of work may cut into my actual code output and slow things down a bit when it comes to things that I personally code. The return for that slow down will be that we will grow a larger <i>core group</i> of developers who will be highly skilled and capable of executing projects like this one in the broader community. That's something the world just needs more of in general, so I think it's a good investment.<br />
<br />
In a nutshell in 2015, I want to focus on mentoring more developers who can help drive this type of work forward. If you want to help and don't know how to get started, reach out to me and I'll do my best to connect you to the right places depending on your skill level. If you just want to start cutting code, feel free to jump into the <a href="https://github.com/vmware/pyvmomi-community-samples/issues?q=is%3Aopen+is%3Aissue+label%3A%22low+hanging+fruit%22">samples project</a> and start slinging away.<br />
<br />
Either way, welcome to the party... it's just getting started.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-28938820983630478222015-02-13T17:18:00.001-05:002015-02-13T17:20:23.417-05:00retrospective and prospectivesYou're busy, I'm busy, so here's a Summary of the post's points.<br />
<ul>
<li>I'm focusing on pyVmomi for a Q2 release (hopefully earlier)</li>
<li>I'll be assisting in on boarding rbVmomi contributors from inside VMware in Q2 (I hope, no solid commitments there yet.)</li>
<li>Both rbVmomi and pyVmomi will have samples of the vSphere 6.0 API some time in 2015</li>
</ul>
<h3>
Retrospective</h3>
<div>
If we look back at <a href="https://github.com/vmware/pyvmomi/graphs/contributors?from=2013-12-08&to=2014-12-31&type=c">the amazing output</a> we saw in 2014, it was driven by a clear targeted focus. We knew that pyVmomi needed to be future proof. It had to be able to survive into the <a href="https://wiki.python.org/moin/Python2orPython3">Python 3 era</a>. A quick survey of the pyVmomi code base reveals that the project has existed <a href="https://github.com/vmware/pyvmomi/blob/v5.1.0/pyVmomi/Cache.py#L2">since 2008</a>. (I've personally been doing integrations with vSphere on some level since that time without knowledge that pyVmomi existed.) This was a big step for VMware to Open Source the project.</div>
<div>
<br /></div>
<div>
Today pyVmomi is a fork of that internal project. The idea of a vibrant and collaborative Open Source community improving vSphere is a novel idea. It's one that I hope will catch on. That said, 2008 was a long time ago in <a href="http://en.wikipedia.org/wiki/Internet_time">internet time</a>. The future is coming and it's called vSphere 6.0</div>
<div>
<br /></div>
<div>
Much of this goes for <a href="https://github.com/vmware/rbvmomi/graphs/contributors?from=2014-01-01&to=2014-12-31&type=c">rbVmomi</a> too. I have a mental <a href="http://en.wikipedia.org/wiki/OODA_loop">cycle</a> that I use when approaching a project. When I enter a new project there is always a period of observation and orientation before I make decisions and start acting. When my attention is divided that forces me to lengthen my input phase before I make a decision and then act.</div>
<div>
<br /></div>
<div>
On the pyVmomi project I've come to trust the judgement of a select handful of contributors. If they like the submission I'm more likely to accept it. I've not built relationships like that on rbVmomi. It takes time to form that kind of trust and I'm actively soliciting VMware staff who are <i>deeply </i>experienced Rubyists for help in forming those.</div>
<h3>
Prospective</h3>
Most VMware followers will know the company had a <a href="http://vmwareemeablog.com/uk/vmwares-biggest-online-announcement-for-2015-live/">big launch in February</a>. Some of what I've been doing is coming along side folks who needed a fresh pair of eyes just before release. The <a href="http://blogs.vmware.com/vmtn/2015/02/vsphere-6-0-vexpert-blog-articles.html">launch of vSphere 6.0</a> is a <a href="http://www.dcig.com/2013/10/vmware-takes-big-step-up-in-virtual-server-backup.html">big step</a> toward a <a href="http://blogs.vmware.com/tribalknowledge/software-defined-data-center">new future</a> for VMware. There are many new features and new ways to integrate, converge, and innovate with these offerings. The new vSphere 6.0 API collectively point the way to how VMware of the future will deliver API, I am eager to hear people's reactions and to help adjust these offerings.<br />
<br />
I'm currently juggling pyVmomi, rbVmomi, and a separate academic research project that I made commitments to. I've been talking to folks about delegating some of this work. Each of these projects deserves my full attention right now, but I can only divide myself so much. In the case of pyVmomi and rbVmomi your participation is vital and I view my job in this area as supporting the community's desire to get things done on vSphere.<br />
<br />
I'm not the primary mover here, you are. That includes work on getting pyVmomi into the hands of python developers <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1132971">however</a> <a href="https://launchpad.net/ubuntu/+source/python-pyvmomi">they manage</a> <a href="https://pypi.python.org/pypi/pyvmomi">libraries</a>. That is all work initiated by and driven by folks like you. As I dig deeper into <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%202015.1">what needs to happen in 2015</a>, I would welcome your participation. If you want to take on one of the fixes that need to happen, let me know via GitHub or via IRC.<br />
<br />
I've also gotten an early look at the vSphere 6.0 SDK and I know that there are a few new API features that developers will find immensely useful. There is also a grand SDK vision to be worked out and its early days to be talking about that yet. Remember that pyVmomi is currently a <a href="https://labs.vmware.com/about">Fling</a> from VMware so it's living in slightly different product support space than most VMware products do.<br />
<h3>
Project Goals</h3>
Both rbVmomi and pyVmomi will have code samples available that will show off the new vSphere 6.0 API and I can talk about that more as we come up on the release. In the mean time I'll be firming up what we're going to deliver in our rapid succession 1st and 2nd releases of 2015.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-77394759936333518702014-12-19T12:53:00.000-05:002014-12-19T12:53:19.811-05:00Projects status for Q4 2014I'm presently allocated to several other vmware projects that are running up against hard deadlines in January 2015. Because of these resource constraints, I've been forced to remove the time lines from my other projects including the public GitHub facing projects. Both <a href="https://github.com/vmware/pyvmomi/">pyVmomi</a> and <a href="https://github.com/vmware/rbvmomi/">rbVmomi</a> presently do not have time lines for release anymore. I can't control my velocity on these projects, therefore I can't reliably forecast release time lines.<br />
<br />
<blockquote class="tr_bq">
I will revisit both <a href="https://github.com/vmware/pyvmomi/">pyVmomi</a> and <a href="https://github.com/vmware/rbvmomi/">rbVmomi</a> in February of 2015 and update the projects respective time lines when I gain clarity on what can be done and how long it will take.</blockquote>
<br />
It is important to note that these particular versions of these projects are not officially supported VMware products and do not have purchasable support plans at this time. I will continue advocating inside VMware for the inclusion of these Open Source projects as part of the over-all product suite and API plans, however, at the moment these are <a href="https://labs.vmware.com/about">Flings</a> under the VMware labs umbrella.<br />
<br />
I have truly relished working on pyVmomi in this very open manner and I'm actively looking for ways to make the best parts of this project parts of every project that I work on. I have already presented to various groups the wonderful lessons we've learned from both <a href="https://github.com/vmware/pyvmomi/">pyVmomi</a> and <a href="https://github.com/vmware/rbvmomi/">rbVmomi</a>. I feel some of my audiences were truly enlightened by my frank assessments of the lives of both these projects.<br />
<br />
That reaction to these experiments encourages me in my pursuit of finding better ways to make impactful software. What every developer should be after is impact, not volume. We should pursue not creating more code, nor more refined code, but creating code that makes a bigger impact with lesser effort. By the term 'impact' I mean various permutations of the words 'useful', 'efficient', 'important', 'delightful', and 'powerful'.<br />
<br />
I will post more updates in the first three months of 2015 as I have them. Progress will be quite slow between now and then as I will have to address a number of other duties and deadlines. Happy New Year to you all and I look forward to getting back down to business in 2015.Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-1411437280939408552014-10-16T16:27:00.003-04:002014-10-16T17:46:18.964-04:00This week on pyVmomi/rbVmomiLast week, I took on a high priority task for VMware so my work on pyVmomi and rbVmomi had to move down in priority for me. I'll continue to post regular updates on progress but the velocity will have slowed on both project until I have cleared my higher priority tasks.<br />
<h3>
rbVmomi</h3>
<br />
<ul>
<li>I have slid out the next release until November 15th</li>
<li>I have begun learning how to upstream the github changes into the VMware git repos for rbVmomi</li>
<ul>
<li>we will need to determine the upstreaming process' impact on the public repo</li>
<li>I need to get any merge requests peer reviewed by VMware internal folks before proceeding</li>
</ul>
</ul>
<h3>
pyVmomi</h3>
<div>
<ul>
<li>I have triaged 2 new bugs</li>
<ul>
<li><a href="https://github.com/vmware/pyvmomi/issues/176">issue 176</a> is an interesting issue we've seen directly impact integrations like OpenStack, SaltStack, and Ansible. I would like to find a clean answer.</li>
<li><a href="https://github.com/vmware/pyvmomi/issues/180">issue 180</a> is a problem I've heard reported before, it has to do with a newer vCenter server speaking to an older ESXi host. The current work-around is to ask the programmer to select a lowest acceptable version number (ie: 5.1) and use that namespace exclusively. The bug reporter has done a good job of breaking down the problem. We need to have a solution that will work robustly and impact client code minimally. <i style="background-color: #f4cccc;">EDIT: This issue is only known to impact ESXCLI use at this time</i></li>
</ul>
<li>I wrote a simple sample for an IRC user today describing <a href="https://github.com/vmware/pyvmomi-community-samples/issues/124">how to navigate a virtual machine's hardware devices.</a> The sample is rather straight forward and I was glad to get to write a sample after having neglecting samples for so long</li>
<li>I revisited pyVmomi-tools and started a testing refactor using VCRpy</li>
</ul>
<div>
<br /></div>
</div>
<div>
Thursdays will be my rbVmomi/pyVmomi day and I'll alternate between the projects. This week I spent most of my time on pyVmomi so next week I'll try to focus on rbVmomi.</div>
<div>
<br /></div>
<div>
More next week...</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-46148486219118703882014-10-10T13:26:00.001-04:002014-10-10T13:26:09.521-04:00Software Engineering at scale is Social EngineeringThis week, I spent time at VMware's HQ in Silicon Valley. I gave a number of talks on my lessons learned with pyVmomi and rbVmomi and gave several calls to action. This week, I'd like to share one of the more profound lessons from the project. It has to do with how tools impact social interactions.<br />
<br />
The first social networks were the ones that built software. The Software Development Life Cycle (SDLC) were social actions of developers directed, enabled, and enforced through the software tools that they used. If you take this view of creating software, then you it's natural to view any conflicts between departments or teams of developers as an opportunity to invent and apply new technology.<br />
<br />
Let's examine something really interesting and profound about Travis CI that may not even have been intentional. The way that Travis CI shifts responsibilities through a tiny change in how builds are specified. The magic is in that <span style="font-family: Courier New, Courier, monospace;">.travis.yaml</span> file and any build system that emulated the <span style="font-family: Courier New, Courier, monospace;">.travis.yaml</span> file strategy would exhibit the same magical effects (even without using yaml). To understand the profundity of the change, let's revisit the bad-old-days of Developer Operations for a moment.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-gDvmN3oKFFc/VDgGMGMYYlI/AAAAAAAAdzc/D1odniQVgEI/s1600/IMG_20141010_085637554.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-gDvmN3oKFFc/VDgGMGMYYlI/AAAAAAAAdzc/D1odniQVgEI/s1600/IMG_20141010_085637554.jpg" height="180" width="320" /></a></div>
<br />
On the left, our developer builds some code and designs a build system to build their module. On the right an operations person builds a CI server to match. This process has some issues with it already. First off, the operations person must be told what the developer needs in a CI server. This requires a conversation and frequently its one that the operations person isn't directly incentivized to pay much attention to since this isn't likely to be their primary job.<br />
<br />
The Operations person may even feel that their cooperation with the developer is a <i>gift. </i>That comes from the fact that the developer likely isn't in the Operations persons direct line of report and their collaboration is a cross-functional team. What is the Operations person really on the hook for?<br />
<br />
Let's assume the previous gift from the Operations person lead to success. There's a working build. Over time the build works and breaks as you would expect. The developer is quite happy to fix their code to repair the build problems. Until one day... the build breaks <i>permanently</i>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-An6lIdasicA/VDgGMEaDCOI/AAAAAAAAdzg/SaWS0Zb3CjQ/s1600/IMG_20141010_085701849.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-An6lIdasicA/VDgGMEaDCOI/AAAAAAAAdzg/SaWS0Zb3CjQ/s1600/IMG_20141010_085701849.jpg" height="180" width="320" /></a></div>
<br />
First the developer will try their normal work-around tricks. These won't work. The build environment is operationally broken now because the developer changed a library dependency or some other build criteria. Or, perhaps, our developer is <i>spinning their wheels </i>this effort is pointless, because something in the data center is broken.<br />
<br />
What's the problem?<br />
<br />
<ul>
<li>if the fault is in the build service we waste time debugging code that isn't broken</li>
<li>the developer is helpless to do their job without direct intervention from operations</li>
<li>the operations people have no view into when a build is broken because of a service problem</li>
<li>Operations may exercise their right to change how the server is running and break the build without notice to the developers</li>
</ul>
<br />
In the most extreme cases, the Operations person is going to be bothered during a crisis. This will result in loss of developer time as they wait on Operations (at best), or it will result in the Developer <i>demanding more services </i>from an already busy operations crew what the Operations person thought was a <i>gift.</i> And, often the timing is terrible. Both parties are blocked from doing their jobs effectively.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-CcnDmw2_W2k/VDgGMLuJgXI/AAAAAAAAdz0/vwvzwuyFphc/s1600/IMG_20141010_085834640.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-CcnDmw2_W2k/VDgGMLuJgXI/AAAAAAAAdz0/vwvzwuyFphc/s1600/IMG_20141010_085834640.jpg" height="180" width="320" /></a></div>
<br />
I've known at least one developer who would handle this by <i>screaming</i> "This is your job! Do your damn job!" Not only did this not get people to do their "damn jobs" but it also made them defensive viewing development as an enemy to defend against. This developer was not pleasant to be around.<br />
<br />
Demanding people do their jobs and threatening their livelihoods doesn't exactly setup a safe place for innovation. Not all of us are <a href="http://www.goodreads.com/quotes/300099-churchill-madam-would-you-sleep-with-me-for-five-million">high-priced-prostitutes</a> and instead aspire to other motivations. (By the way, if you think I'm talking about <i>you</i> ... I'm not. <a href="http://youtu.be/b6UAYGxiRwU">I'm really really not</a>.) If you find yourself here, start asking how to keep people from feeling like they need pitch-forks and torches.<br />
<br />
Let's tear down this conflict. What are the <i>facts</i> in this scenario?<br />
<br />
<ul>
<li>The developer specifies the build's operational requirements</li>
<ul>
<li>building software is their job</li>
<li>running build servers is not their job</li>
</ul>
<li>The operations person runs the build server</li>
<ul>
<li>running workloads, servers, and Infrastructure is their job</li>
<li>deciding how software is built is not their job</li>
</ul>
</ul>
<div>
Does this about cover it?</div>
<div>
<br /></div>
<div>
With these facts consider the following:</div>
<div>
<ul>
<li>The developer </li>
<ul>
<li>can't build software without asking for permission from operations</li>
</ul>
<li>Operations can't create the build server on their own</li>
<ul>
<li>ops has to stop a dev and ask for direction</li>
</ul>
</ul>
This is an issue of <a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a> ... only on social systems, not software systems. The concern of specifying a build in most CI systems rests with a separate configuration. In Jenkins this configuration is commonly run through a control panel. That panel is not version controlled, it's not tested code, yet it is effectively a software artifact.</div>
<div>
<br /></div>
<div>
Enter <span style="font-family: Courier New, Courier, monospace;">.travis.yaml</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ZZTQDjG_se4/VDgGMvluPXI/AAAAAAAAdzk/QExSm1PIBD0/s1600/IMG_20141010_090045317.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-ZZTQDjG_se4/VDgGMvluPXI/AAAAAAAAdzk/QExSm1PIBD0/s1600/IMG_20141010_090045317.jpg" height="180" width="320" /></a></div>
<div>
<br /></div>
<div>
The Travis CI build setup is minimal. Point a Travis job at a repository and branch. The configuration work typically carried by an Operations person (those long configuration forms) is carried by the <span style="font-family: 'Courier New', Courier, monospace;">.travis.yaml</span> file. This file is versioned with the code-base itself. That means, when the developer exercises their right to change their own build, the yaml file goes through version control and we can see if things break <i>because</i> of the change in build specification.</div>
<div>
<br /></div>
<div>
We now have two options as the developer:</div>
<div>
<ol>
<li>modify our build to fit current expectations</li>
<li>request a new build environment that fits our new needs</li>
</ol>
<div>
The <span style="font-family: 'Courier New', Courier, monospace;">.travis.yaml </span>file does not eliminate conflict or eliminate the problem, it frames the issue in a different manner. </div>
<div>
<br /></div>
<div>
Using a build specification by configuration file model means, the build configuration is now part of the project it describes. We have placed the control and authority over that process in the correct place ... with the person who's responsibility it is to maintain it. So one possible conflict is removed, the developer no longer has to beg and wait on Operations to donate their time to allow the developers to do their jobs.</div>
</div>
<div>
<br /></div>
<div>
The other part of this new social reality is, if we build a <span style="font-family: 'Courier New', Courier, monospace;">.travis.yaml </span>file that our CI can't support we know it will fail. What's the conversation we're going to have now? The developer now has highlighted boldly that Operations is prepared to give certain services but not others and to ask for new services is to <i>ask someone to go beyond their normal duties.</i></div>
<div>
<i><br /></i></div>
<div>
Operations persons now equipped with the right back-end tools can see what kinds of build requests are coming in, what their resource consumption and performance profiles look like... and without having to interfere with the <i>developer's jobs</i> they can tune their environment to cope. Build configuration by document now becomes a <i>workload specification</i> that an IaaS or a PaaS operator can judge for themselves whether or not they can service.</div>
<div>
<br /></div>
<div>
The conflict and struggle is still there, but now it's <i>framed</i> properly. We accomplish this through <i>software</i>. And, this ability to shape social interaction through software tools is why Software Engineering with more than a handful of people who know each other personally is <i>really</i> Social Engineering.</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-31183744262765932482014-10-03T17:20:00.004-04:002014-10-03T17:20:53.446-04:00This week in pyVmomi & rbVmomi<h2>
rbVmomi</h2>
<br />
<ul>
<li>version 1.8.2 is <a href="https://rubygems.org/gems/rbvmomi">live </a>on rubygems</li>
<li>release notes are <a href="https://github.com/vmware/rbvmomi/releases/tag/v1.8.2">here</a></li>
</ul>
<h2>
pyVmomi</h2>
<div>
<ul>
<li>here's an example of using <a href="https://github.com/kevin1024/vcrpy">vcrpy</a> as a <a href="https://github.com/vmware/pyvmomi-community-samples/pull/122">flight recorder</a> for <a href="https://github.com/vmware/pyvmomi">pyvmomi</a>.</li>
</ul>
<div>
<br /></div>
</div>
<div>
I'm in Silicon Valley next week for an unrelated project so it will likely be a slow week on the *Vmomi projects. If folks would like to meet up I'm trying to organize a hack-night for projects in pyVmomi or rbVmomi while I'm in town. Contact me for details.</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-60150577823177966992014-09-26T12:38:00.002-04:002014-09-26T12:38:43.183-04:00This week in pyVmomi & rbVmomi<h4>
pyVmomi</h4>
Not much motion this week. I've spent the majority of the week focused on coming up to speed on <a href="https://twitter.com/rbvmomi">rbVmomi</a>. Of note we did have a bug report of sockets getting left open and I'll be spending quality time debugging that next week.<br />
<br />
<br />
<ul>
<li>The next major revision of pyVmomi is slipped to December now in light of my new work commitments. I will keep github up to date on how these projects are going.</li>
<li><a href="https://github.com/vmware/pyvmomi-community-samples/issues/118">Disconnect doesn't close socket</a> is this a pervasive bug or a quirk? TBD I'll carve time from my schedule next week to attempt to reproduce and resolve the bug as either a quirk or create a fix. The fix will go in 2014.2 at minimum but might be bad enough to cut 2014.1.2 if needed.</li>
<li>We need some more education and evolution <a href="https://github.com/vmware/pyvmomi-community-samples/issues/113">on tasks</a>. I've shelved my work on <a href="https://github.com/vmware/pyvmomi-tools">pyvmomi-tools</a> temporarily while I come up to speed on rbVmomi. But, tasks are one of those areas I feel the raw API is too <i>rich</i> for new developers to grasp right away. Some syntax sugar should help.</li>
<li>Currently stalled on my desktop is an effort to introduce an SMS "plugin" (plugin isn't the right word but it's close) which I wanted to introduce through pyvmomi-tools. I'll ask for review inside VMware and from key thought leaders in the python and pyVmomi communities before shipping it to pypi ... more on this as we have time.</li>
<li>We changed version conventions <a href="https://github.com/vmware/pyvmomi/pull/175">yet again</a>. On pyVmomi we wanted the version number to communicate freshness and compatibility. So the year-dot-quarter method was used. Then releases moved to every six months so it's 1st half and 2nd half now. Then we found out `-` means something in pypi so now it's just a `.` character. Finally we have 5.5.0.2014.1 and 5.5.0.2014.1.1 to indicate 1st half of 2014 bug fix 1 is compatible with vSphere 5.5.0. Part of this is we still don't know precisely how pyVmomi github and pyVmomi vSphere will interact on a code-base level going forward. That's TBD be the vSphere teams in charge of that. The admittedly complex interaction between these two things </li>
</ul>
<div>
<br /></div>
<h4>
rbVmomi</h4>
<div>
Just coming up to speed on the modern state of <a href="https://rubygems.org/profiles/hartsock">Ruby gem management</a> since it's been a number of years since I've had to work with them. I'm also moving cautiously since there's a standing development practice and tradition in place that I need to be mindful of.</div>
<div>
<br /></div>
<div>
<ul>
<li>A <a href="https://github.com/vmware/rbvmomi/releases/tag/v1.8.2.pre">prerelease</a> for <a href="https://github.com/vmware/rbvmomi/issues/56">rbVmomi 1.8.2</a> is available on <a href="https://rubygems.org/gems/rbvmomi/versions/1.8.2.pre">rubygems now</a> please test!</li>
<li>A regular release for 1.8.2 will happen October 1st barring any negative testing results</li>
<li>A <a href="https://github.com/vmware/rbvmomi/milestones/v1.8.3">1.8.3 release </a>is tentatively set to got to pre-release October 17th (or so) depending on how well we can manage the process of upstreaming pull requests and this is very tentative. Note: this is a change I had intended to hold the release 2 weeks for myself to gain familiarity first. Instead I like this pre-release, delay for 3rd party testing/review, then release strategy and I'll likely adopt it as my normal operating style from now on.</li>
<li>Long term planning will have to happen for a 1.9.1 release but I'll not comment much on that until I know what my long term relationship to the project looks like.</li>
<li>I opened a low priority research ticket for [higher performance XML](https://github.com/vmware/rbvmomi/issues/57) which seems to be a minor scalability problem rbVmomi faces. My initial research is in the ticket. It's a help wanted item so feedback is much appreciated.</li>
<li>NOTE: any item I tag 'help wanted' is an area I feel a 3rd party can either easily help with (usually also tagged 'low hanging fruit') or an area we can't really move on without outside help.</li>
<li>NOTE: any item I tag 'VMware staff assistance needed' is something that I feel a 3rd party should probably avoid working on since the issue is fuzzy and bleeds into VMware internal technical details, decisions, or other issues muddy the ticket such that it's not going to move without someone (usually me) bridging the Open Source and VMware internal engineering communities.</li>
</ul>
<h4>
General Status</h4>
<div>
My Friday posts will probably take this two part pyvmomi then rbvmomi flavor as long as I'm bridging both communities. Sorry if that confuses things but that's a function of <a href="http://en.wikipedia.org/wiki/Conway's_law">Conway's law</a> and at the moment the Open Source to VMware and back communications conduit is basically <i>me </i>for both projects so you have to expect a bit of that.</div>
</div>
<div>
<br /></div>
<div>
Thanks for your support! The following freenode IRC channels will at least have my IRC 'bot in them <span style="font-family: Courier New, Courier, monospace;">#pyvmomi</span> , <span style="font-family: Courier New, Courier, monospace;">#pyvmomi-dev</span> , <span style="font-family: Courier New, Courier, monospace;">#rbvmomi</span> , <span style="font-family: Courier New, Courier, monospace;">#rbvmomi-dev</span> , <span style="font-family: Courier New, Courier, monospace;">#govmomi</span> , <span style="font-family: Courier New, Courier, monospace;">#govmomi-dev </span>and I'll eventually see IRC messages in those channels through my 'bots. The <span style="font-family: Courier New, Courier, monospace;">-dev</span> channels are for advanced programming topics while the other channels will be open for newblings and will need community support since I'm pretty bad at dealing with neophyte level problems these days.</div>
<div>
<br /></div>
<div>
More on each of these threads as progress is made...</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-39864142857308376652014-09-24T12:00:00.000-04:002014-09-24T12:00:02.601-04:00On the topic of rbVmomi<a href="https://twitter.com/cdickmann/status/514171886952271872">Earlier this week</a> I started helping out on the rbVmomi project. My involvement is just to help take some pressure off of <a href="https://twitter.com/cdickmann">Christian Dickmann</a> around reviewing and releasing the <a href="https://github.com/vmware/rbvmomi/issues?q=milestone%3Av1.8.2">next version</a> of <a href="https://github.com/vmware/rbvmomi">rbVmomi</a>.<br />
<br />
Compared with <a href="https://github.com/vmware/pyvmomi">pyVmomi</a>, the <a href="https://github.com/vmware/rbvmomi">rbVmomi</a> project has a longer history in Open Source. While pyVmomi has existed longer, rbVmomi has the benefit of being designed from the ground up for the type of collaborative effort an API binding like this can represent. I'll want to be cautious and observant of that established project workflow and primarily act as an accelerant for the processes already there.<br />
<br />
To address the initial problem of there being no release this year, I've begun drafting <a href="https://github.com/vmware/rbvmomi/issues?q=milestone%3Av1.8.2+">v1.8.2</a> which should be ready for release in a few days. Having learned from pyVmomi, I've set up a follow up release <a href="http://v1.8.3/">v1.8.3</a> to try and catch anything we miss in the earlier release. The follow up release should hit in mid-October if we need it. If it turns out we don't or can't hit mid-October I'll drop the milestone and we'll move to long-term planning. Future release schedules are TBD.<br />
<br />
For pyVmomi, this means my attentions are divided and I've shifted out <a href="https://github.com/vmware/pyvmomi/milestones">milestones</a> for that project to match my expectations. The second release of 2014 for pyVmomi is now tentatively set for mid-December. (I hope that pyVmomi reaches feature parity with rbVmomi by that release.) Our big additions for the next release of pyVmomi should be SMS and SPBM API support provided we don't hit any hidden issues. We'll hopefully have time for EAM as well.<br />
<br />
My role on rbVmomi at this time is just to assist in the current release plan. Christian is very much still the lead developer. I'll be using tags on the open issues and pull requests to help decide what to call out for Christian's direct attention. There's also a bit of process for this project that I'll need to work out on the fly.<br />
<br />
More on these topics as things happen...<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-21946408257384467022014-09-19T15:15:00.000-04:002014-09-19T21:51:08.629-04:00How to use Conway's Law for good and not evilIf you've been paying attention to our <a href="https://github.com/vmware/pyvmomi">github repository</a> you'll have noticed some noise around the following API additions to pyVmomi...<br />
<ul>
<li><a href="https://github.com/vmware/pyvmomi/issues/170">SMS</a></li>
<li><a href="https://github.com/vmware/pyvmomi/issues/171">SPBM</a></li>
<li><a href="https://github.com/vmware/pyvmomi/issues/172">EAM</a></li>
</ul>
<div>
These are all presently scheduled for the next major release of pyVmomi which is currently set for December of 2014 and will be called 5.5.0-2014.2 barring any major issues.<br />
<br />
I'll be working with the various feature teams inside VMware to figure out how best to Open Source their existing API bindings. More importantly, I'll be work with these teams to find a way that allows the effect described in <a href="http://en.wikipedia.org/wiki/Conway's_law">Conway's Law</a> to function beneficially on this set of projects.</div>
<div>
<br /></div>
<div>
In other words, pyVmomi isn't one large project with one <a href="http://en.wikipedia.org/wiki/Benevolent_dictator_for_life">BDFL</a> directing the entire API. The reality is that the APIs potentially exposed by pyVmomi are in fact the result of multiple collaborating teams. Each of these teams will tend to be their own unique snowflake.<br />
<br />
Couple this with the fact that we will also have the opportunity to leverage contributions from interested third parties, vendors, and partners and you can see that the previous monolithic structure might not survive the strain. I'll be taking some vital time to implement at least one or more extension strategies for the library and have them evaluated. This will probably cost 3 or more weeks worth of time but it will be worth the pain because these are long-lived projects with minimum life-spans on the order of 3 or more <i>years</i>.</div>
<div>
<br /></div>
<div>
As part of this research I've come back time and again to a talk by Doug Hellmann titled <a href="http://stevedore.readthedocs.org/en/latest/essays/pycon2013.html">Dynamic Code Patterns</a>.</div>
<div>
<br /></div>
<div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/7K72DPDOhWo" width="420"></iframe>
</div>
<div>
<br /></div>
<div>
Not to diminish Doug's work at all, but his <a href="http://stevedore.readthedocs.org/en/latest/">Stevedore</a> project is an implementation of the <a href="http://en.wikipedia.org/wiki/Extensibility_pattern">Extensibility Pattern</a> which is itself part of the previous generation's <a href="http://en.wikipedia.org/wiki/Software_design_pattern">Software Design Patterns</a> movement. The design patterns technique came under <a href="http://en.wikipedia.org/wiki/Software_design_pattern#Criticism">understandable criticism</a> for not really contributing much to programming and more than occasionally over complicating things. It's these concerns about <i>over complication</i> that are going to slow me down a bit. After all, making things simple is not easy and my goal is to make things as <i>simple as possible </i>and no simpler.<br />
<br />
The Stevedore project does offer something to a library like pyVmomi. It is a tool to create <i><a href="http://stevedore.readthedocs.org/en/latest/patterns_loading.html#extensions-many-names-many-entry-points">extensions</a>.</i> The term 'plugin' is not really accurate when we're talking about modules like SMS. The SMS module is neither a driver, nor is it a hook, but it is an extension. These are new classes and methods that provide new capabilities from the primary facade of the pyVmomi library itself. You can call these <i>plugins</i> but not in the normal sense.<br />
<br />
There is also danger in approaching the problem of extending into these new API as a <i>plugin</i>. It quite possibly introduces the problem of turning pyVmomi into a <i>framework</i> and such a transformation would be <i>wholly inappropriate</i>. In particular, I am considering the use case for pyVmomi as a helper library to deliver a driver for <a href="https://github.com/saltstack/salt/blob/develop/salt/cloud/clouds/vsphere.py">SaltStack</a>. What happens to the outer project if pyVmomi itself becomes a <i>framework</i> and does this make those consumer projects unnecessarily more complex?<br />
<br />
We want extensibility but not at the cost of adding the need to be <i>aware</i> of more details. We want the library to appear as a unit even though it is actually composed of multiple sub-units. That's something that requires some subtlety. It's not something to bother with if we don't need it so... why do I think we need it?<br />
<br />
Over the next 2 weeks I'll be experimenting with SMS support provided in a couple of different ways in the hopes of finding a sustainable, flexible, and robust mechanism to use <a href="http://www.thoughtworks.com/insights/blog/demystifying-conways-law">Conway's law</a> as a means of enforcing a structure of collaboration between teams. In particular there's a set of existing organizational and structural relationships that I feel the current design violates..<br />
<br />
In particular, at VMware, I do not personally manage, dictate, or control what the structure or design a given ... feature interface (or sub-API) looks like. It's impractical to think I could. My role is to act as a bridge between VMware and the developer communities interested in building software on-top of the VMware <i>platforms</i>.<br />
<br />
Some details about the practical nature of how modules like SMS, SPBM, and EAM for use in pyVmomi are produced directly <i>informs</i> our library design considerations. For example...<br />
<br />
<ul>
<li>Feature teams (and their management)</li>
<ul>
<li>design, maintain, and release their own API</li>
<li>dictate what API are official, unofficial, and deprecated</li>
<li>have their own schedules, priorities, and deadlines</li>
<li>are fundamentally disinterested in <i>low-level</i> concerns</li>
</ul>
</ul>
<div>
Knowing this, any design I create for pyVmomi that dictates that a feature team <i>must talk to me first</i> and then <i>convince me </i>to do things a certain way are very likely to fail. Why? Well, let's take the opposite approach as a thought experiment and see what happens.</div>
<div>
<br /></div>
<div>
If I were to decide that I was going to <i>tightly control</i> pyVmomi and force feature teams to first get approval for API from me before I clicked my big "approved" button and there by uploading their API to github that would mean I could conceivably derail their priorities or deadlines. </div>
<div>
<br /></div>
<div>
What do you think would happen? I could cause a vital product or feature to slip it's release; I could force an unnecessary conflict between managers; I could find my project usurped by something the feature team felt could disentangle themselves from my meddling in their affairs. Any or all these and other scenarios could happen. In short, I would create an unnecessary friction and unintentional power-struggle as people tried to focus on issues wholly unrelated to something as trivial as providing API to people like yourself.</div>
<div>
<br /></div>
<div>
So, if I want to instead create a successful project in this environment I have to engineer my software so that it can function <i>with </i>the natural (and proper) social boundaries already present. The structure of the <i>code itself</i> will also influence how social interactions occur around the code base. And finally, the modularity of the code will <i>allow</i> me to potentially delegate power, authority, and autonomy to other people.<br />
<br /></div>
<div>
So what are our design concerns?</div>
<div>
<ul>
<li>For feature creators adding to pyVmomi we should,</li>
<ul>
<li>leverage existing library features</li>
<li>hide low-level concerns</li>
<li>allow independent ownership</li>
<li>simplify the process of creating a binding as much as possible</li>
</ul>
<li>For integrating developers working <i>with</i> pyVmomi in their separate projects we should,</li>
<ul>
<li>present a single unified "surface" for them to use</li>
<li>hide <a href="http://en.wikipedia.org/wiki/No_Silver_Bullet">accidental complexity</a> but expose <i>essential complexity</i></li>
<li>follow a rule of <i>least surprise</i></li>
</ul>
</ul>
<div>
I admittedly may think of more as I work through the problems but this captures what we're after in a nutshell. This library in the world of Conway's Law represents a bridge between multiple parties and it's structure will end up reflecting how these groups relate. The pyVmomi software sitting between these groups will be least painful to work with for everyone if it can be molded to it present reality.</div>
</div>
<div>
<br /></div>
<div>
After we tackle Open Sourcing these three new API I'll have a better picture of what that reality is. And, that's what large-scale software development is really about, not as much computers and code so much as people, relationships, and communication. Our tools affect our lives and better tools make better lives.</div>
<div>
<br /></div>
<div>
More on this another time...</div>
</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-85897197457395886292014-09-12T15:41:00.004-04:002014-09-12T16:17:14.567-04:00Developer Community EngagementIf you've not been following along at home, pyVmomi was run in a <a href="http://hartsock.blogspot.com/2014/05/how-pyvmomi-is-something-different.html">different manner</a> from most VMware Open Source projects. It's been a bit of a social experiment. The last two weeks since our <a href="https://github.com/vmware/pyvmomi/releases">release</a>, I've been working on distilling lessons learned from the past five months of the project.<br />
<br />
I did not plan on also looking into <a href="https://rubygems.org/gems/rbvmomi">rbVmomi</a> ... but ... at the same time just after <a href="http://www.networkworld.com/article/2466485/virtualization/top-5-things-to-watch-for-at-vmworld-2014.html">VMworld</a> a <a href="http://www.mattwrock.com/blog/dear-vmware-please-give-us-nice-things-to-automate-the-things">certain blog post</a> started making the rounds on <a href="https://twitter.com/dberkholz/status/507543475735527424">social media</a>. It's clearly an opportunity to examine what we're doing at VMware around OpenSource development projects.<br />
<br />
<a href="https://github.com/vmware/rbvmomi">rbVmomi</a> is a more typical VMware fling project. These start as a developer driven POC project and these are developed on a best-effort basis. The rbVmomi project has closed <a href="https://github.com/vmware/rbvmomi/issues?q=is%3Aissue+is%3Aclosed">6 issues</a> and closed <a href="https://github.com/vmware/rbvmomi/pulls?q=is%3Apr+is%3Aclosed">10 pull requests</a> during its entire lifetime as a VMware project.<br />
<br />
<a href="https://github.com/vmware/pyvmomi">pyVmomi</a> has benefited from having my attention full time since April/May of 2014. The total number of issues closed <a href="https://github.com/vmware/pyvmomi/issues?q=is%3Aissue+is%3Aclosed">to date is 59</a> with a total number of <a href="https://github.com/vmware/pyvmomi/pulls?q=is%3Apr+is%3Aclosed">70 merges.</a> These differences in numbers shouldn't be surprising, that's to be expected when you go from <i>free time</i> development to <i>full time</i> development. My personal stats have become <a href="https://twitter.com/hartsock/status/510509689688170496">quite impressive</a> due to the full-time activity on GitHub.<br />
<br />
That's all nice for me, but, what does that really mean for the library? What does that mean for developer use, experience, and over-all for VMware? It's a matter of audience and SDK adoption.<br />
<br />
Over on stackoverflow, you can see that in its entire life-span rbVmomi has had <a href="http://stackoverflow.com/search?q=rbvmomi">9 questions</a> asked as of this writing. That indicates 9 times people who are likely to seek help on stackoverflow have sought help and those 9 times only 4 of those questions got answers.<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="http://1.bp.blogspot.com/-tjIRRbqg1Mk/VBNJtzYyGZI/AAAAAAAActQ/cPVn4EmV-yk/s1600/Screen%2BShot%2B2014-09-09%2Bat%2B4.54.18%2BPM.png" height="273" width="320" /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Taking a look at the same search for pyVmomi yields <a href="http://stackoverflow.com/search?q=pyvmomi">24 questions</a> over a much shorter life-span. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Rq23ZrTs3js/VBNLZfmR36I/AAAAAAAActY/VcskoNvEqe8/s1600/Screen%2BShot%2B2014-09-09%2Bat%2B4.55.58%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Rq23ZrTs3js/VBNLZfmR36I/AAAAAAAActY/VcskoNvEqe8/s1600/Screen%2BShot%2B2014-09-09%2Bat%2B4.55.58%2BPM.png" height="320" width="285" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
13 of these questions have been answered and 19 of times people voted on the questions where as with rbVmomi <i>no one voted</i>. If you take a closer look, 17 of those questions occur <i>after</i> my full time commitment to the project. In the shorter time-frame my public commitment and effort to the library has helped increase developer engagement with the library improve by an order of magnitude.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The next question is... is this effort <i>worth it</i>? And <i>how do we determine that</i>? </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I'm open to suggestions. What else should I be looking at?</div>
<br />Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-55499127445454248002014-09-05T13:30:00.001-04:002014-09-05T13:30:03.791-04:00This week: RetrospectivesThis was a short week, so I would like to take a moment and reflect on where we've been <a href="https://github.com/vmware/pyvmomi/graphs/contributors?from=2014-05-01&to=2014-08-31&type=c">since May</a>.<br />
<br />
This week I've been getting ready for a creating a set of new <a href="http://www.extremeprogramming.org/rules/spike.html">spikes</a> around a few of our <a href="https://github.com/vmware/pyvmomi-community-samples/issues">unanswered sample requests</a>. Out of these will come my development plan is to create <a href="https://github.com/vmware/pyvmomi-tools/issues">new features</a> to include in <a href="https://github.com/vmware/pyvmomi-tools">pyvmomi-tools</a>. By the way, if you're new to the projects or haven't been following along, part of the reason for breaking out pyvmomi from pyvmomi-tools is to allow us to develop different release cycles and development standards and styles. It would allow a quicker-turn around on some items and also allow some experimentation in pyvmomi-tools that we might not want to risk in the core pyvmomi library.<br />
<br />
This is all part of a social experiment I'm conducting trying to help VMware at large find the best way to engage with the open source communities. Earlier in the week <a href="https://twitter.com/dberkholz/status/507543475735527424">someone called out</a> this negative reaction in the <a href="http://www.mattwrock.com/blog/dear-vmware-please-give-us-nice-things-to-automate-the-things">rbVmomi community</a>. Ironically, rbVmomi is much older, more robust, and feature complete than pyVmomi but the <a href="http://www.geeklee.co.uk/tag/pyvmomi/">community</a> <a href="https://twitter.com/lamw/status/504375054982193152">reception</a> to pyVmomi has <a href="http://dantehranian.wordpress.com/2014/08/11/building-a-better-dashboard-for-virtual-infrastructure/">been</a> <a href="https://twitter.com/mcowger/status/503701928836993025">much</a> <a href="https://twitter.com/ohh_wut/status/505806156657598465">warmer</a> in recent weeks.<br />
<br />
I'm getting reports of a number of python projects shifting from other vSphere API bindings to pyVmomi as the confidence in the library grows. I've been getting almost nothing but positive feedback from users of the library and I think we're well on our way to becoming the best way for integrators to work with vSphere. And, we're reaching that goal by encouraging <a href="http://youtu.be/N0x_mxnTs_k">better developer practice</a>.<br />
<br />
From some <a href="http://webchat.freenode.net/?channels=#pyvmomi,#pyvmomi-dev">IRC chats</a> earlier in the week I found out that at least one shop has traded from <a href="http://vijava.sourceforge.net/">vijava </a>to <a href="http://vmware.github.io/pyvmomi/">pyVmomi</a> running in <a href="http://www.jython.org/">jython</a>. I've not tested or verified jython for use with pyVmomi but I'm encouraged to hear the work is progressing well. If anyone else is attempting this kind of work I would appreciate hearing and/or reading about the experience.<br />
<br />
I also find this language switch curious because vijava is actually quite well done. As a side note I am doubly curious because of my own past involvement in alternative languages for the JVM. I've not attempted jython with Java hybrid projects before and I'm curious as to how and why these fit together.<br />
<br />
I'll be presenting these stories to VMware teams to help build the case for this style of community engagement and I plan on having a series of discussions around <a href="https://github.com/vmware/rbvmomi">rbVmomi</a> as well. As I've mentioned multiple times in this blog, merely building pyVmomi up is only one of the objectives toward my much larger goal of helping change the way we write software for the cloud.<br />
<br />
Part of that larger goal is <a href="http://hartsock.blogspot.com/2014/08/what-every-developer-should-know-about.html">testing,</a> <a href="http://hartsock.blogspot.com/2014/08/notes-on-developing-pyvmomi-itself.html">process</a>, and <a href="http://hartsock.blogspot.com/2014/05/how-pyvmomi-is-something-different.html">engagement</a>.<br />
<br />
More on this next time...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-1755900818860402192014-08-29T18:40:00.000-04:002014-09-05T13:39:27.490-04:00pyVmomi v5.5.0-2014.1.1 - bug fix - is available from pypi.This week was <a href="http://www.vmworld.com/">VMworld</a> and we still managed to release a quick turn-around bug-fix release for pyVmomi. Up on pypi <a href="https://pypi.python.org/pypi/pyvmomi/">right now</a> is the v5.5.0-2014.1.1 release. Part of the changes made involved improving our release process and incorporating feedback from RPM and DEB package maintainers.<br />
<ul>
<li>Here's the v5.5.0-2014.1.1 <a href="https://github.com/vmware/pyvmomi/releases/tag/v5.5.0-2014.1.1">release notes</a></li>
</ul>
<ul>
<li>Here's the v5.5.0-2014.1 r<a href="https://github.com/vmware/pyvmomi/releases/tag/v5.5.0-2014.1">elease notes</a></li>
</ul>
<hr />
If you're still using the December release, here's a unified change list between 5.5.0 and 5.5.0_2014.1.1:<br />
<br />
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><a href="https://github.com/vmware/pyvmomi/issues/55" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">Python 3 support</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">added <a href="https://github.com/vmware/pyvmomi/issues/42" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">unit testing using fixtures</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">fixed <a href="https://github.com/vmware/pyvmomi/issues/43" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">session timeouts issue</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">fixed <a href="https://github.com/vmware/pyvmomi/issues/24" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">Querying datastore cluster fails</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">fixed <a href="https://github.com/vmware/pyvmomi/issues/72" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">Malformed Faults fail in non-informative ways</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">added <a href="https://github.com/vmware/pyvmomi/pull/58" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">RST documentation</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">fixed <a href="https://github.com/vmware/pyvmomi/issues/93" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">getheader does not always fetch cookie value</a></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Fixes bug with <a href="https://github.com/vmware/pyvmomi/issues/112" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">Iso8601 date serialization</a> (for messages sent to the service)</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Simplifies test-requirements.txt</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Introduces support for <code style="background-color: rgba(0, 0, 0, 0.0392157); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.3333339691162px; margin: 0px; padding: 0.2em 0px;">tox</code></li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Changes version number scheme</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Fixes README to be pypi compatible</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Improved sdist and bdist packaging support</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Changes to package information based on <em style="box-sizing: border-box;">The Python Packaging Authority</em> instructions</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Fix <a href="https://github.com/vmware/pyvmomi/issues/131" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">bug</a> that produces traceback when running tests for the first time</li>
</ul>
<ul class="task-list" style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 1.6; margin-bottom: 0px !important; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Fixes <a href="https://github.com/vmware/pyvmomi/issues/147" style="background: transparent; box-sizing: border-box; color: #4183c4; text-decoration: none;">testing bug</a> present on some distributions.</li>
</ul>
<hr />
<br />
Far and away, working on the pyVmomi has been one of the most professionally <i>satisfying</i> projects of my career. That's chiefly because of how immediate the interaction and feedback from users of pyVmomi has been. In most other projects feedback from users of your code base has to navigate its way back to you over time, instead on pyVmomi the feedback has been immediate.<br />
<br />
Part of this is due to the ease of public interaction that tools like <a href="https://github.com/">github</a>, <a href="http://freenode.net/">freenode</a>, <a href="https://pypi.python.org/pypi"><span id="goog_338468265"></span>pypi<span id="goog_338468266"></span></a>, and <a href="https://twitter.com/">twitter</a> (with <a href="https://ifttt.com/recipes/search?q=github+twitter">ifttt</a> automations) offers. I plan on evangelizing this working-style to other teams within VMware and your positive feedback can only help. For a developer it's a very rewarding way to work and hopefully for a customer it's also very satisfying.<br />
<br />
Next week, I'll be working on our <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%205.5.0-2014.2">2014.2 milestone</a> and setting up to make a go at some more <a href="http://vmware.github.io/pyvmomi-community-samples/">community samples</a>. It should be noted that while pyVmomi itself is able to run just fine on Python 3, many of the samples are written assuming Python 2.7 ... this is fine since the two projects are decoupled.<br />
<br />
The reason we keep the <a href="https://github.com/vmware/pyvmomi-community-samples">community samples</a> repository separate from the <a href="https://github.com/vmware/pyvmomi/">core pyvmomi</a> project is to allow for each project to exercise its own standards. The samples project is very loose while pyVmomi is run extremely tightly. That's a function of where on the stack each project lives. In general the deeper down the stack you go, the more rigid the project needs to run to ensure quality and stability for all the projects built on top of it.<br />
<br />
More on the community project next week...<br />
<div style="background-color: white; box-sizing: border-box; overflow: hidden; word-wrap: break-word;">
<span style="color: #333333; font-family: Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif;"><span style="line-height: 25.6000003814697px;"><br /></span></span></div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-91736140534956754982014-08-22T13:01:00.001-04:002014-08-22T13:01:44.627-04:00pyVmomi: preparing for 5.5.0-2014.1.1 our first bug fix release.I've been heads down this week, so a short update this time.<br />
<br />
Last week, we released <a href="http://hartsock.blogspot.com/2014/08/pyvmomi-version-550-20141-is-available.html">pyVmomi 5.5.0_2014.1</a> to pypi. This week we started work on preparing <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1132971">RPM</a> and <a href="https://github.com/vmware/pyvmomi/pull/125">Debian</a> packages which will allow pyVmomi to be included with Linux distributions important for OpenStack work.<br />
<br />
Having released 2014.1 I opened a milestone for <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%205.5.0-2014.1.1">2014.1.1</a> as a bug fix release and identified a few smaller quick turn around tasks. We have one <a href="https://github.com/vmware/pyvmomi/issues/112">known bug</a> and a few minor improvements and changes that we'll have to get in place. (Being right up against <a href="http://www.vmworld.com/">VMworld</a> has slowed down a few tasks, but we're still moving rapidly.)<br />
<br />
Notably the 5.5.0-2014.1.1 release will:<br />
<br />
<ul>
<li><a href="https://github.com/hartsock/pyvmomi/commit/40e5501a92d0a8bd52e396f5a6bf81d72df9853f">Fix </a>a <a href="https://github.com/vmware/pyvmomi/issues/112">bug</a> with sending date-time stamps to the server</li>
<li><a href="https://github.com/vmware/pyvmomi/issues/127">Tweak</a> the version number standard to fit better with pypi and RPM.</li>
<li>Standardize <a href="https://github.com/vmware/pyvmomi/issues/122">packaging</a> for the pyVmomi library</li>
<li>Improve <a href="https://github.com/vmware/pyvmomi/issues/129">release documentation</a> and processes for versions.</li>
</ul>
I got a bit side-tracked this week as I investigated more of the pyVmomi internals and noted that the XML documents are non-deterministically assembled. This means from one run to the next the SOAP message coming out of pyVmomi can be different in certain <i>trivial</i> ways.<br />
<br />
I noted that...<br />
<br />
<ul>
<li>The order of <i>xmlns="*"</i> attributes inside tags can occur in random order</li>
<li>The amount of whitespace in documents can vary in some situations</li>
</ul>
This meant that naive string-based comparisons done in vcrpy's built-in <a href="https://github.com/kevin1024/vcrpy#request-matching">body request matcher</a> can't actually compare XML document contents for <i>logical</i> consistency. I wrote the start of an <a href="https://github.com/hartsock/pyvmomi/tree/xml_compare_test_feature">XML based comparison system</a> but after burning more than three days on the problem I have to stop and wonder if this is <a href="https://travis-ci.org/hartsock/pyvmomi/builds/33297014">worth the effort</a> and if it wouldn't be simpler to just figure out <i>why</i> pyVmomi creates random ordered XML and then <i>fix that</i> instead.<br />
<br />
In the next week-or-so, we should be able to deliver a quick-turn around bug fix release with the improvements I've listed here. We're doing well for this now that we're getting more attention from last week's release. The <a href="https://github.com/vmware/pyvmomi/milestones/pyVmomi%205.5.0-2014.2">2014.2</a> is tentatively scheduled for November 15th this year.<br />
<br />
More on these topics next week...<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-60883913993404788192014-08-15T17:26:00.002-04:002014-08-15T17:26:55.996-04:00pyVmomi version 5.5.0-2014.1 is available.Earlier today with help from other VMware employees and #python IRC users, I pushed the buttons necessary to release <a href="https://pypi.python.org/pypi/pyvmomi/5.5.0-2014.1">pyVmomi version 5.5.0-2014.1</a> to the general public. This is the first open source community built and released version of the <a href="http://pubs.vmware.com/vsphere-55/topic/com.vmware.wssdk.apiref.doc/right-pane.html">vSphere Management API library</a> since VMware open sourced the project in <a href="http://www.virtuallyghetto.com/2013/12/early-xmas-gift-from-vmware-pyvmomi.html">December</a>.<br />
<br />
This release featured <a href="https://github.com/vmware/pyvmomi/compare/v5.5.0...v5.5.0_2014.1">contributions</a> from 13 contributors, 10 of which were completely unaffiliated with VMware. With the exception of myself the <a href="https://github.com/vmware/pyvmomi/graphs/contributors?from=2013-12-18&to=2014-08-15&type=c">most active contributors</a> are not at all affiliated with VMware.<br />
<br />
Special Thanks to...<br />
<br />
<ul>
<li><a href="https://github.com/vmware/pyvmomi/compare/v5.5.0...v5.5.0_2014.1">Kevin McCarthy</a> for his <a href="https://github.com/kevin1024/vcrpy">vcrpy</a> project and his <a href="https://github.com/vmware/pyvmomi/commits?author=kevin1024">contributions to pyVmomi</a> that made stand-alone and automated testing possible.</li>
<li><a href="https://github.com/vmware/pyvmomi/commits?author=michaelrice">Michael Rice</a> for is help in setting up Travis builds, tracking down issues, and helping out on IRC when I wasn't around.</li>
</ul>
<br />
Thanks as well to William Lam for <a href="http://www.virtuallyghetto.com/2014/08/pyvmomi-vsphere-sdk-for-python-5-5-0-2014-1-released.html">championing our project</a> as well.<br />
<br />
This release marks an important step for pyVmomi, most notably the ability to use pyVmomi with vcrpy means we can do much more in-depth and thorough bug reporting for 3rd party developers. It also means that the focus of development can move from infrastructure to feature parity.<br />
<br />
More on that next time...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-12049059632844325142014-08-13T12:30:00.000-04:002014-08-13T12:30:01.133-04:00On the topic of Goals and Objectives for pyVmomiAs long as I'm working on the <a href="http://vmware.github.io/pyvmomi/">pyVmomi </a>project, its goal will be to become the single best way to talk to vSphere technologies. This is a broad and hard to measure thing, and with luck as VMware technologies evolve, it's also a moving target. Once we arrive at one location there will be a new version to sail toward. In order to steer accurately, we must set a course by some kind of metaphorical guiding star, and this is what <i>objectives</i> are meant to be.<br />
<br />
While the goal is the destination we are sailing our metaphorical ship toward, our near-term objectives are the metaphorical stars we choose to help guide us toward that goal. Just as sailing a ship may require course corrections, which implies choosing different stars; so too might managing a project require course corrections which implies choosing different near term objectives. When we course-correct ourselves, our projects, our teams, or our careers, we are changing the objectives much as a ship navigator might choose a different guiding star at different times during a ships journey toward a distant destination.<br />
<br />
In common parlance, the terms goal and objective are virtually synonymous but it makes sense to make a distinction between them when we're talking about conducting the daily business of building software. Being "the best" is kind of hard to measure, it implies quality, adaptiveness, and nimbleness in the library as well as a breadth of uses for the library. This requires us to choose some guiding stars with wisdom.<br />
<br />
How do you design a library for these attributes? How do you pick the correct guiding stars?<br />
<h3>
A little philosophy</h3>
A little philosophy is necessary to guide how we go about setting our objectives to achieve our goals. Just a little philosophy is necessary, too much and we spend our days navel gazing, too little and we flail about wildly wondering why we work so hard and accomplish so little. Regular periods of slack followed by pressure are best for this. Creativity can only come when you are free to explore but productivity only really truly solidifies itself under threat of deadline.<br />
<br />
So what are some philosophies I could hold in this case?<br />
<h3>
A few contrary points of view</h3>
I might think that audience size is the best measure of project success. That might mean I would have less priority on other aspects of the software and more on things that make the software appeal to a wide audience. In other words, a bug's priority only matters as a measure of the number of new users it can net.<br />
<br />
<i>Examples of projects guided by this principle to the exclusion of others might include things like <a href="http://blog.codinghorror.com/the-php-singularity/">PHP</a>. The design choices in PHP were early on driven by getting broad adoption and rapidly securing mind-share. Very little time was spent thinking about the long-term impact of design decisions. The result is PHP is the <a href="http://w3techs.com/technologies/overview/programming_language/all">most successful programming language (in its niche) of all time</a> and one of the <a href="http://devhell.info/post/2011-12-10/what-we-hate-about-php/">most</a> <a href="http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/">hated</a>.</i><br />
<br />
I might choose to believe that 'feature count' was a better measure for project success. If I believed that cranking out code was the way to 'get stuff done', then I would probably believe that anything that got in your way of 'getting stuff done' was a waste of time. That would probably mean I would be after the largest volume of code in the shortest amount of time. More code means more function right?<br />
<br />
<i>The problem with this is <a href="http://www.agileweboperations.com/how-non-negotiable-features-kill-software-products">feature creep</a>. If you want to keep a light nimble software project that can respond quickly to changes in its environment a small modular project is best. You keep the project itself <a href="http://en.wikipedia.org/wiki/Broken_Age#Game_development">small</a> or <a href="http://en.wikipedia.org/wiki/The_Elder_Scrolls:_Arena#Design_goals">suffer the consequences</a>. There's usually an 80/20 rule for features and following it can result in faster release cycles.</i><br />
<br />
After years of working on software systems big and small, with tiny audiences and accidental audiences of millions, I've come to believe a few things.<br />
<h3>
In Generalities</h3>
I feel that the competition between Xbox versus Playstation in the marketplace is a good case-study of these philosophical disagreements in action. The results have mostly played out in the marketplace for us all to study. If we take a lesson from this history we might be able to improve our own state of practice.<br />
<br />
In 2012 it was hard to tell if there was a marketplace winner in the video game console market. The three top video game consoles of the time period had traded top position on <a href="http://www.geekwire.com/2013/xbox-360-wii-ps3-won-console-generation/">various metrics</a> repeatedly but by Q2 2014 there is a <a href="http://www.forbes.com/sites/davidthier/2014/07/31/sony-reveals-playstation-outselling-xbox-31/">clear winner in market sales</a> (only time will tell if this is a permanent state of affairs).<br />
<br />
Sony had always invested in a complete engineering package for its consoles and frequently talked about <a href="http://www.edge-online.com/features/why-sonys-10-year-plan-makes-sense/">10 year plans</a> with its ecosystem. Ironically, this same business strategy had failed them before. When it came to <a href="http://youtu.be/ddYZITaxlTQ">BetaMax versus VHS</a> this same strategy of 'technical superiority' did not pay off, however, and that's a cautionary tale. The entire <i>engineering process</i> matters.<br />
<br />
When building a system you have to take into account <i>all the pertinent</i> forces shaping its market share. These include <i>multiple </i>product audiences, shareholders, and customers, as well as multiple engineering considerations about how the product functions. Not the least of which includes the process by which you create the product itself.<br />
<h3>
Engineering Objectives</h3>
Audience size matters, feature count matters, and perceived quality matters. Each affects the other and each affects the total impact of your software project. <a href="http://en.wikipedia.org/wiki/Minimax">Minmaxing</a> on only one dimension or another doesn't necessarily equate to a lasting victory. So we need to find ways to incorporate all these elements into our daily choices. That's what setting objectives is all about.<br />
<br />
Over the years, I've been thoroughly impressed at how products generated by very bad engineering can sometimes capture and dominate markets when very good engineering fails. I believe the problem comes from improperly balancing objectives. A single dimension of engineering and design has been maximized at the expense of balancing concerns. It's far too easy to make an easy to measure metric, set it as an objective, and steer the metaphorical ship by a star that has nothing to do with the goal. Such engineering produces something that is arguably beautiful yet broken.<br />
<h3>
Broken Strategy</h3>
For example, a typical strategy used to solve quality issues in software systems is to increase <a href="http://martinfowler.com/bliki/TestCoverage.html">test coverage</a>. Coverage is an easy number to measure. It makes nice charts and gives a wonderful feeling of progress to developers. It's also a trap.<br />
<br />
Merely increasing code coverage does not universally improve the code in all its dimensions. In fact, improperly applied test coverage can create tightly coupled systems that are worse suited. This is perhaps the starkest lesson you can learn about successfully reaching a 100% code-coverage goal: you can end up with <i>more technical debt not less</i>. (I could call out certain open source projects here but I won't for brevity's sake.)<br />
<br />
If no metric can measure this concept of tight coupling to balance the code coverage metric, then, merely measuring code coverage percentages pushes the software design in the wrong direction. Your team will optimize for coverage at the expense of other attributes. One of those attributes can actually be code quality (in that fixing a simple bug can take an inordinately long time) and flexibility (in the sense that your code can lose the ability to respond to new requirements).<br />
<br />
I have come to believe Test Driven Development just as code coverage can also become a trap. Improperly applied, it similarly optimizes systems for unit tests which may not reflect the real design forces that the unit of code is under. These circumstances the code developed can end up very far from the intended destination just as high code coverage numbers can degrade actual quality of a software system.<br />
<h3>
Actively Compensating</h3>
Agile methodologies were <i>intended</i> as a tool to compensate for this dis-joint between the steering stars of objectives and the actual destination. The ability to course correct is vital. That means one set of objectives are perfect for a certain season while the same objectives might be completely wrong for another season.<br />
<br />
To effectively use these tools (agile or otherwise) you can't fly by instrument. You need to get a feel for the real market and engineering forces at play in building your software product. These are things that require a sense of <i>taste and refined aesthetics</i>. You don't get these from a text book, you get them from experience.<br />
<br />
My experience has taught me that you actually don't want to write <i>more code</i> you actually want to write <i>less</i>. You want to accomplish as much as possible while writing as little code as necessary without falling into <a href="http://en.wikipedia.org/wiki/Code_golf">code golf</a>. That means that the most effective programmer may have some of the worst numbers on your leader board. Negative lines of code might be more productive than positive, fewer commits may be more profound than more. The mark of good engineering is <a href="http://youtu.be/4j4Q_YBRJEI">doing a great deal with very little</a> and that's what we strive for in software engineering.<br />
<h3>
From Philosophy to Concrete Objective</h3>
In the case of <a href="https://github.com/vmware/pyvmomi">pyVmomi</a>, we have no open sourced tests that shipped with <a href="https://github.com/vmware/pyvmomi/tree/v5.5.0">version 5.5.0</a> as released from VMware's core API team. (Note: there are tests but they are fenced off from public contributors and this is a problem when it comes to getting quality contributions from the general population.) With no unit tests available it is almost impossible for a contributor to independently determine if their change positively or negatively impacts the project's goals. Some over-steer in the area of code coverage would be forgivable.<br />
<br />
I also want to avoid solidifying library internals around dynamic package and class creation as well as internal aspects of the SOAP parser and its details. This puts me in an awkward position because the simplest most naive way to fence off units and begin <a href="http://idioms.thefreedictionary.com/bust+a+gut">busting-gut </a>on test coverage would also force the tests to tightly couple onto the classes currently defined in what long-time pyVmomi developers refer to as the pyVmomi infrastructure.<br />
<h3>
Separation of Concerns</h3>
The fact that there is <i>even</i> a term '<i>pyVmomi infrastructure</i>' means that there is an aspect of the library that some people need to talk about separately from some other aspect of the library. That indicates a conflation of <a href="http://en.wikipedia.org/wiki/Separation_of_concerns">separate concerns</a>. This particular point in itself would be a lovely talking point for a whole different article on how software engineering becomes <a href="http://en.wikipedia.org/wiki/Conway's_law">social engineering</a> after a certain point. To become a highly used, trusted, and distributed library; pyVmomi should disambiguate these concerns. But, I digress.<br />
<h3>
Application of Philosophy as Strategy</h3>
I spent no less than <a href="http://hartsock.blogspot.com/2014/08/what-every-developer-should-know-about.html">three weeks</a> developing the <a href="https://github.com/vmware/pyvmomi/commit/e93a6e0a7ff08e29e1501b632b8d89734a10e946">test strategy</a> for pyVmomi that will allow us to test without boxing in the library itself. The strategy leans heavily on <a href="http://en.wikipedia.org/wiki/Test_fixture#Test_fixture_in_xUnit">fixture based testing</a> and specifically on the <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a> library. In our case, the nuance is that our fixture needs to setup a fake socket with all the correct information in it to simulate an interaction with vCenter and/or ESXi without requiring mocked, stubbed, or simulated versions of each.<br />
<br />
If we avoid testing directly design elements (things like the XML parser itself), and we avoid testing in isolation concerns that are deemed <i>infrastructure</i> versus not-infrastructure, then we are left with testing the API "surface" as exposed by pyVmomi. The unit tests call on the <i>actual</i> symbols we want to expose to developers and these are the API <i>surfaces</i> as I call them. The outermost exposed interface intended for end consumption.<br />
<br />
The shape of these fixture-based tests are virtually identical to <a href="https://github.com/vmware/pyvmomi/blob/19e5029d14677c639175ca0806aa718c1f8c9cc1/tests/test_connect.py#L56">targeted samples</a> of the API pyVmomi is binding. Given a large enough volume of use-cases these unit tests with fixtures might eventually encompass a body of official samples. Existing as tests means that these samples will also validate the fitness of any changes against known uses of the library.<br />
<br />
This strategy effectively retro-fits tests onto the library without locking in design decisions that may not have had very much thought. It frees us to build use-cases and eventually fearlessly refactor the library since the tests will not tightly couple to implementation specifics and instead the tests couple to interface symbols.<br />
<h3>
Objectives Accomplished</h3>
We want pyVmomi to continue to exist long enough that it can accomplish its goal of being the <i>best</i> library for working with vSphere. To survive, we need the library to have a lifespan beyond Python 2. We need the library to allow contributors to objectively measure the quality and fitness of their own contributions so it attracts enough developers to evolve and spread toward its goal.<br />
<br />
So far we've accomplished the following objectives in the up-coming release due to come out in mere days:<br />
<ul>
<li><a href="https://github.com/vmware/pyvmomi/issues/55">Python 3 support </a>gives the pyVmomi library time to live and flexibility to grow</li>
<li><a href="https://github.com/vmware/pyvmomi/tree/master/tests/fixtures">Fixture based tests</a> give users and contributors confidence to develop while also...</li>
<ul>
<li>avoiding design detail lock-in</li>
<li>hiding irrelevant library <i>infrastructure</i> details</li>
<li>providing official samples based on actual API units that will not break as the API changes</li>
</ul>
<li>we also established <a href="https://github.com/vmware/pyvmomi/wiki/Contributions">contribution standards</a></li>
</ul>
<h3>
Objectives to Accomplish</h3>
While we want <a href="https://github.com/vmware/pyvmomi-community-samples">pyVmomi community samples</a> to evolve unrestricted and rapidly, it is also the source for <a href="http://en.wikipedia.org/wiki/Software_requirements">requirements</a> for the library. The samples project is separate so that it can welcome all comers with a low barrier to entry. But, it is very important as it will feed the main pyvmomi project in a very vital way. The samples become the requirements for pyVmomi.<br />
<br />
The samples and the <a href="https://github.com/vmware/pyvmomi/tree/master/tests">pyvmomi unit tests</a> need not have a 1-to-1 relationship between sample script and test, but each sample should have a set of corollary unit tests with fixtures that give basic examples and tests for the use case illustrated in the parent sample. That means one sample might inspire a large number of unit tests.<br />
<br />
These are some of the high level objectives to reach going forward on pyVmomi:<br />
<ul>
<li>remain highly reliable and worthy of trust</li>
<ul>
<li>cover all major vSphere API use cases in unit tests with fixtures</li>
<li>squash all high priority bugs rapidly which implies releasing fixes rapidly</li>
</ul>
<li>reach feature parity with all competing and cooperating API bindings</li>
</ul>
To reach these new objectives we'll need to do some leg work to find way-points along the way. We may change some of our finer targeted objectives later, but these objectives help us reach the goal of being so good nobody working in this space can ignore us, being so good we deserve the title <i>the best</i>.<br />
<br />
More on that in a future post...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comChapel Hill, NC, USA35.9131996 -79.05584450000003535.8103276 -79.217206000000033 36.0160716 -78.894483000000037tag:blogger.com,1999:blog-28383337.post-7262135553742064002014-08-08T12:30:00.000-04:002014-08-08T12:30:00.597-04:00Notes on Developing pyVmomi itself.Most of my development work over the last few weeks has been spent finding more efficient ways to develop pyVmomi itself. The problem with networked libraries is that they sit between metal and user code.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-mxDTDs96oaE/U9vhB8Ws_aI/AAAAAAAAbZ0/oFnmXDd9bbs/s1600/Screen+Shot+2014-08-01+at+1.55.52+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-mxDTDs96oaE/U9vhB8Ws_aI/AAAAAAAAbZ0/oFnmXDd9bbs/s1600/Screen+Shot+2014-08-01+at+1.55.52+PM.png" height="73" width="320" /></a></div>
As I've pointed out before, virtually all code written in the modern world fits in this model. There's a 'core system' under the code you are writing... that is to say the code you write orchestrates some other system of libraries, then you test the core system by writing tests that anticipate what the 'user' of your library is going to do. This is basically API development, at least in spirit.<br />
<br />
<h3>
Everyone does API development (somewhat)</h3>
The interesting thing is that in today's world virtually all development <i>is</i> API development if you allow for this loose interpretation of what an API is. The 'user' code may end up being a Selenium test or a unit test. The 'user' party may be yourself or your coworkers ... or they maybe the industry at large. If code gets reused then that code is essentially part of the vocabulary of an API.<br />
<br />
I advocate that you write one test per use-case to describe each of the types of anticipated use of your API. These tests define the surface of the library and you should have no distinction between the library's tests and it's public API. That means anything private or internal should only be tested indirectly if it exists at all.<br />
<h3>
Porting pyVmomi to Python 3</h3>
In the case of porting pyVmomi from python 2.x to python 3.x (as I covered <a href="http://hartsock.blogspot.com/2014/06/pyvmomi-and-road-to-python3-part-1.html">in</a> <a href="http://hartsock.blogspot.com/2014/07/pyvmomi-and-road-to-python3-part-2.html">this</a> <a href="http://hartsock.blogspot.com/2014/07/pyvmomi-and-road-to-python3-part-3.html">3 part post</a>) the problem has been finding a way to rapidly regression test the library on python 2.x and python 3.x interpreters. The technique I settled on was using <a href="http://youtu.be/N0x_mxnTs_k">fixtures for testing</a>.<br />
<br />
To build these fixtures I alluded to what I call <i>the simulator problem</i>. In this situation, your back-end is so complex that your stubs and/or mocks become so comparably complex that these fake components approach the complexity of the actual system you are substituting for. At this point, your mock has become a simulator. This is a lot of effort and typically non-unique for any given project. That's why you can find <a href="http://wiremock.org/getting-started.html">multiple</a> <a href="https://github.com/jamesdbloom/mockserver">simulators</a> for <a href="https://github.com/jharlap/mock-http-server">webservers</a> out there. It makes sense to share effort.<br />
<br />
In the vSphere space we have <a href="http://www.datacenterdan.com/blog/15360-vms-in-your-pocket-vcsa-55-vcsim">VCSIM </a>which can be used to simulate vCenter. In most situations these simulations will be good enough for writing test cases with fixtures. These test cases with fixtures <i>do not</i> obviate the need for integration testing, but they do shorten the feedback loop for an individual developer. This shorter feedback loop is critical.<br />
<br />
<h3>
Simulating for Success</h3>
I recorded a short video this week on how to setup VCSIM. My video is by no means definitive, but I hope it helps get you started. In the video I show how my setup works. I chose to alias my VCSIM to the fake DNS name 'vcsa' and I setup the user 'my_user' with the password 'my_password'. I make thes substitutions so that real IP, usernames, or passwords, do not leak into unit tests. The resulting setup helps me explore the API exposed on the wire by vCenter in my unit tests. Once I hit the scenario I want to develop on I metaphorically freeze it in amber by<a href="http://youtu.be/N0x_mxnTs_k"> recording a fixture</a> (as recorded in the preceding video).<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/N0x_mxnTs_k?list=UUf3z3twWumSOuOFYO2s2O8g" width="560"></iframe><br />
<br />
<h3>
Release Plans</h3>
I plan on releasing officially the next version of pyVmomi (with python 3 support) in the next 2 weeks. The goal was always to release in front of VMworld. That means we'll be flat-out on the release war-path the next few days until we have a solid, stable, and tested release to push out. Fortunately, we are very nearly there. Python 3 support itself would be a big enough win without any additional changes. The ability to record fixtures in tandem with the library is icing on the proverbial cake and it will help us as a community develop pyVmomi more reliably and uniformly.<br />
<div>
<h3>
In summary</h3>
The key to successfully navigating the change from python 2.x to python 3.x is testing, testing, and more testing. The *faster* you can get testing feedback (test, change, retest as a feedback loop) the better off you'll be. Waiting for a CI to kick back results is *far too long* to wait. You want all this to happen in a developer's local development environment. The more *automated* and *stand alone* your tests are the broader the total population of possible contributors are. The standalone test means a CI like Travis CI or Jenkins can run your tests without infrastructure. This does not obviate the need for integration testing but it will hopefully let you catch issues earlier.<br />
<br /></div>
<div>
If you have a python project on Python 2.x and you want to follow pyVmomi into Python 3, I hope these posts have helped! Now that we have a solid way to test for regression on the library we can start work on feature parity. Future development after the next upcoming release will be focused on building up the library's capabilities.</div>
<div>
<br />
More on that next time...</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-47298976808392631852014-08-01T17:12:00.001-04:002014-08-01T17:53:36.200-04:00What every developer should know about testing - part 3For the <a href="https://github.com/vmware/pyvmomi">pyVmomi</a> folks in a hurry, <a href="http://youtu.be/n3CP_ObMP0g?list=UUf3z3twWumSOuOFYO2s2O8g">this video</a> covers the big shift in the project and the code from the video is <a href="https://github.com/vmware/pyvmomi/commit/e93a6e0a7ff08e29e1501b632b8d89734a10e946">here</a>. This week I'll finally dig into some detail on fixture-based testing.<br />
<br />
<h3>
Summary</h3>
<blockquote class="tr_bq">
<span style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">If you don't bother reading more from <a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about.html">part 1</a> and <a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about_25.html">part 2</a> in this series, the one thing to take away is: </span><span style="background-color: yellow;"><span style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">testing must be </span><i style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">stand alone</i><span style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">, </span><i style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">automated</i><span style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">, and <i>deterministic </i>no matter <i>what</i> you are writing</span></span><span style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">. </span></blockquote>
<span style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">No matter what you are doing the bulk of your effort should go toward creating ways to write as little code and as few tests as possible <i>yet still cover the domain.</i> This is a much harder philosophy to follow than '<a href="http://en.wikipedia.org/wiki/Code_coverage">cover all the lines</a>' but it is much more robust and meaningful. </span><br />
<span style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;"><br /></span>
<span style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">Good code coverage should be the outcome of good testing, not the goal. Because <a href="http://www.thoughtworks.com/insights/blog/test-induced-design-damage-fallacy-or-reality" style="font-style: italic;">testing is hard</a> and getting it wrong is <a href="http://vimeo.com/68375232" style="font-style: italic;">bad</a> you should write tests as sparingly as possible without sacrificing quality<i>. </i>Finally, unit boundaries <i>are API</i> and you should write tests to reflect the <i>unit boundary</i> which is an art in and of itself.</span><br />
<br />
In <a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about.html" style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">part 1</a> I covered why your testing is bad. In <a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about_25.html" style="font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">part 2</a> I covered what are stubs, mocks, and fixture testing. In part 3 we'll get specific and cover how to build a fixture and what it represents as a programming technique.<br />
<br />
<h3>
What your code <i>is</i> determines what your test <i>is</i>.</h3>
Virtually <i>all</i> software built today is going to fall into this pattern:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-mxDTDs96oaE/U9vhB8Ws_aI/AAAAAAAAbZw/l7Vg7kpzxD0/s1600/Screen+Shot+2014-08-01+at+1.55.52+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="core system -> [your code] -> user's code" border="0" src="http://2.bp.blogspot.com/-mxDTDs96oaE/U9vhB8Ws_aI/AAAAAAAAbZw/l7Vg7kpzxD0/s1600/Screen+Shot+2014-08-01+at+1.55.52+PM.png" height="73" title="" width="320" /></a></div>
Virtually <i>everyone</i> who writes software writes it in a space sandwiched between the software <i>you use</i> and the software that <i>uses you</i>. Interesting things happen when you move <i>up stack</i> far enough that '<i>user's code</i>' becomes actual human interaction or you move <i>down</i> stack far enough that '<i>core system</i>' means <i>physics</i>.<br />
<div>
<br /></div>
In most projects, however, code that has to perform actual human interaction means code written for a <i>web app</i> or some kind of <i>GUI</i>. In these special cases you need tools like <a href="http://www.seleniumhq.org/">Selenium</a> or some other 'bot like <a href="http://www.sikuli.org/">Sikuli</a> to drive your tests. In that case the far right of my diagram "<i>User's Code</i>" is simulated in that test framework. It's ultimately code at the end of the day and the code you write for test is something you create anticipating how that middle category "<i>your code</i>" is going to be used.<br />
<br />
The more familiar case, where you are sitting between an end-developer (sometimes yourself later in the project's lifecycle) and a core-system of libraries that constitute the framework, runtime, or operating system <i>your code</i> is build on is what most unit test philosophies are build around. This is the world that is most comfortable for <a href="http://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs">mock and stub</a> based testing. It's the world of TDD and other methodologies. But, what happens when you start getting close to the <i>metal</i> when the things we need to mock are on the network or some other physical or transient infrastructure?<br />
<br />
This is the case where I advocate the use of fixtures. Depending on what's on the other side of <i>your code</i> the right tool to craft a fixture will differ. I've worked in environments where fixtures had to be physical because we were testing micro-code. Most of the time these days I need a network based fixture.<br />
<br />
I am a big fan of <a href="https://rubygems.org/gems/vcr">vcr</a>, <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a>, and <a href="http://freeside.co/betamax/">betamax</a>. These are tools for recording HTTP transactions to create a fixture. In generic terms, a testing fixture helps you fast forward a system to get it into the state you need for testing. In our specific purposes the fixtures replace the need for a network and related network servers.<br />
<h3>
Recording transactions</h3>
BTW: The source code for this test is <a href="https://github.com/vmware/pyvmomi/commit/e93a6e0a7ff08e29e1501b632b8d89734a10e946">available on github</a> now.<br />
<br />
Here's the sample interaction we want to support. It's a simple set of interactions... we login, get a list of objects, loop through them, and put things away.<br />
<br />
<pre class="brush: python"> def test_basic_container_view(self):
si = connect.SmartConnect(host='vcsa',
user='my_user',
pwd='my_password')
atexit.register(connect.Disconnect, si)
content = si.RetrieveContent()
datacenter_object_view = content.viewManager.CreateContainerView(
content.rootFolder, [vim.Datacenter], True)
for datacenter in datacenter_object_view.view:
datastores = datacenter.datastore
pprint(datastores)
datacenter_object_view.Destroy()
</pre>
<br />
As written this test goes over the network <i>nine</i> times. Without a tool like <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a> running this test in any automated way would require us to use a whole pile of cloud infrastructure or at least a smartly built simulator. This means doing special setup work to handle edge cases like faults, or large inventories. It requires the construction of an entire mockup of the production scenario we want to test. This could be automated in itself; but then, if the tool to perform such automations is literally what we're writing; how do we develop and test those automations? That's an extremely time consuming and wasteful <a href="http://www.markhneedham.com/blog/2008/10/25/dont-shave-the-yak-ask-why-are-we-doing-this/">yak shaving</a> exercise.<br />
<br />
Fortunately, in our project a simple one liner can help us remove the need to always have a service or simulator running somewhere for every test.<br />
<br />
<pre class="brush: python"> @vcr.use_cassette('basic_container_view.yaml',
cassette_library_dir=fixtures_path, record_mode='once')
</pre>
<br />
This decorator allows us to record the observed transactions into a <a href="https://github.com/vmware/pyvmomi/blob/e93a6e0a7ff08e29e1501b632b8d89734a10e946/tests/fixtures/basic_container_view.yaml">YAML file</a> for later consumption. We can't completely remove the need for a simulator or service, but we can remove the need for such beasts during test.<br />
<h3>
Modifying Recordings</h3>
Once you have the capacity to record network events into a fixture you can <a href="https://github.com/hartsock/pyvmomi/blob/87bb7080649932328b132201ead87f0760b8b153/tests/fixtures/test_unknown_fault.yaml#L261">tamper</a> with these recordings to produce new and unique scenarios that are otherwise hard to reproduce. That means <i>your code</i> can rapidly iterate through development cycles for situations that are really hard to get the <i>core-system</i> code on that remote server into.<br />
<br />
You "shave the yak" once to get a VCSIM to a state that represents the scenario that you want. Then you script your interactions anticipating a use case your end-developer would want to exercise. Finally, using <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a> decorators, you record the HTTP interactions and preserve them so that you can reproduce the use-case in an automated environment.<br />
<br />
Once you have that fixture you can develop, regression test, and refactor <i>fearlessly</i>. You can synthesize new fixtures approximating use cases you might never be able to reliably achieve. And that's how you take something very chaotic an turn it into something deterministic.<br />
<br />
This is of course predicated on the idea that you have a <a href="http://www.datacenterdan.com/blog/15360-vms-in-your-pocket-vcsa-55-vcsim">VCSIM </a>setup for testing, more on that next time...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-3805557747448599572014-07-25T17:50:00.001-04:002014-09-05T13:39:13.375-04:00What every developer should know about testing - part 2<h4>
The short version of this post:</h4>
<a href="https://github.com/vmware/pyvmomi">pyVmomi</a> contributions from this point forward will be required to follow <a href="https://github.com/vmware/pyvmomi/commit/19e5029d14677c639175ca0806aa718c1f8c9cc1">this pattern.</a> They include a fixture based unit test build around <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a>.<br />
<blockquote class="tr_bq">
Note: While these posts are python specific, the techniques I advocate are not. If you happen to be working in a JVM language, then I recommend <a href="https://github.com/robfletcher/betamax">Betamax</a>. And, if you happen to be on Ruby, then use <a href="https://github.com/vcr/vcr">vcr</a>. The point of any unit test is that it should be <i>stand alone</i>, <i>automated</i>, and deterministic. These posts discuss how to create deterministic and automated tests in situations where people often argue it's <i>impossible</i> to create such tests.</blockquote>
<h3>
Overview</h3>
<a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about.html">Last week</a> I covered some basics about unit testing. What is a unit? What do you need to test? What don't you? This week we'll dive a bit deeper and cover why a <a href="http://en.wikipedia.org/wiki/Test_stub">Stub</a>, a <a href="http://en.wikipedia.org/wiki/Mock_object">Mock</a>, or any other trick may not solve your problems and how we create a unit test where there's arguably no '<a href="http://bulldozer00.com/2009/11/06/cscis-cscs-csus/">unit</a>' only a <a href="http://en.wikipedia.org/wiki/Client_(computing)">client</a>.<br />
<br />
In this post we'll briefly recap what a unit test is. Then we'll cover stubs and mocks and why they are useful but aren't sufficient. Finally I'll cover fixtures.<br />
<br />
If I'm in the mood, I may cover <a href="http://www.slideshare.net/FranklinChen/handout-23548866">property based testing</a> at some future date ... but that's an intermediate to advanced topic in my book.<br />
<h4>
Recap: What a Unit Test is, what it isn't</h4>
The <a href="http://bulldozer00.com/2009/11/06/cscis-cscs-csus/">dividing line between units</a> is 'human hard' because it's not just 'a method is a unit' ... a method very frequently <i>is</i> a unit but then so is a <i>class</i> and there can be hidden classes and methods. I'm advocating a somewhat controversial position based on the <a href="http://vimeo.com/68375232">back-lash to TDD</a> you'll find around the <a href="http://martinfowler.com/articles/is-tdd-dead/">blogosphere</a> recently. My position in a nutshell is that tests are best defined at 'unit boundaries' which are necessarily <i>abstract</i> borders between software units (and units themselves are a <a href="http://www.merriam-webster.com/dictionary/term%20of%20art">term of art</a>).<br />
<br />
<h3>
What is a good Unit Test?</h3>
There is some debate over what makes a good unit test. In general, your tests should be <a href="http://en.wikipedia.org/wiki/Standalone_software">stand alone</a>, <a href="http://en.wikipedia.org/wiki/Automated_testing">automated</a>, and <a href="http://en.wikipedia.org/wiki/Deterministic_automaton">deterministic</a> (and those three words in this context have very precise meanings). This is simple enough when a unit is simple. For example, the canonical <a href="http://www.diveintopython3.net/unit-testing.html">roman numeral example</a> is easy enough to unit test.<br />
<br />
In the <a href="http://www.diveintopython3.net/examples/romantest1.py">roman numeral example</a> the unit is easily isolated since the <i>concept</i> of a roman numeral does not require the introduction of additional units. This is the most basic tier of unit testing that every developer must learn.<br />
<br />
The next set of techniques are to use Fakes and Stubs, and then later maybe Mocks, and these work as long as system interactions remain relatively simple. But, these are not sufficient tools for your tool box. You have to learn <i>one more trick</i> before you have all the basic tools you'll need for modern development. You need to know how to build fixtures and the resources that go with them.<br />
<br />
<h4>
When to Stub</h4>
If your programming language supports interfaces and dependency injection then <a href="http://spring.io/blog/2007/01/15/unit-testing-with-stubs-and-mocks/">creating stubs</a> will feel natural to you. If your unit uses several other objects by <a href="http://learnpythonthehardway.org/book/ex44.html">composition</a> to accomplish it's work, one of the simplest things to do is write a fake version of the objects your unit under test uses.<br />
<br />
That means you have to create an object that implements all the methods of the dependent class that your particular test unit will use. The stub will have to cover as many calls as your unit of code uses. If you call on method 'foo' you need to write something that reasonably reproduces the expected output of 'foo'. This is fine when the call number is small, but it can quickly get out of hand. Take for example that someone felt compelled to write an entire <a href="https://github.com/kristofa/mock-http-server">fake server</a> in Java.<br />
<br />
The fake HTTP server author calls their product a mock server but this is in fact a stub. You have no facility to assert call order, parameters, or the absence of calls.<br />
<h4>
When to Mock</h4>
<div>
A <a href="http://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs">mock is not a stub</a>. With a stub you have to provide a stub implementation of all possible call paths and have no facility to later go back and make assertions on call order. If you do, you probably wrote it yourself... and you've probably neglected what your day job really is.</div>
<div>
<br /></div>
<div>
A mock is about coding for expected calls and call order. The problem with doing this with your stub is that you will have to either be organically <i>grow</i> your stub into a mock to get this information (and that's a whole new project worth of complexity) or you'll have to invent a whole system of semaphores and messages to watch for these details.</div>
<div>
<br /></div>
<div>
With mocks, you can assert how a method was called; you can make assessments about call order; you can also assert that there is an absence of calls. This is all very important for you to be able to do in your unit tests. With these tools you can continue to assert that no matter how you evolve your intervening code the <i>units</i> code continues to use it's underlying API within acceptable parameters.</div>
<div>
<br /></div>
<div>
A concrete example is if you are <i>consuming</i> pyVmomi or rbVmomi as your client library bindings, you can mock the calls to the client binding library. If you observe that vim.VirtualMachine's PowerOff method is still called properly even after you refactor your own library then there's no need for a VCSIM to run your tests at the unit testing phase.</div>
<div>
<br /></div>
<div>
Too much of this, however, and you <a href="http://googletesting.blogspot.com/2013/05/testing-on-toilet-dont-overuse-mocks.html">can't make assertions</a> about the code's behavior outside of test. Not to mention that creating mocks and stubs are programming efforts of their own. This can lead to wonderful code coverage numbers, tightly coupled designs, and a frustrating body of work.</div>
<div>
<br /></div>
<h3>
Enter the Network</h3>
<div>
What if you're writing a client library? On the <a href="https://github.com/vmware/pyvmomi">pyVmomi project</a>, that's what we're doing. A highly efficient and specifically tailored API binding in Python for vSphere. How can we unit test something that's intended for use with a networked appliance?</div>
<br />
<h3>
Fixtures</h3>
In the case of building tests for networked software, the <a href="https://github.com/kristofa/mock-http-server">simulator problem</a> is a common problem. In order to deal with this it's vital to have <i>some tool</i> that can record your interactions then play them back. The ability to deliberately <i>tamper</i> with the interaction recording is vital. There are bound to be states that the complex server or simulator on the other end can't reach.<br />
<br />
If you only use a simulator for your tests, then they are by definition not stand-alone. You have to exit the testing context and enter an administration context to build an orchestrate the situation you want to test. This can be costly and it can be a problem very similar to the simulator problem. You will inevitably have to build a complex environment that will harm the determinism of your tests.<br />
<br />
Next week, I'll get specific and cover how to build a test with a recording, we'll have to get into details and I'll cover how I use <a href="http://www.virtuallyghetto.com/2012/12/vcenter-server-simulator.html">VCSIM</a> to create the basis for complex situations I can't even create in my environment.<br />
<br />
<br />
More on that <a href="http://hartsock.blogspot.com/2014/08/what-every-developer-should-know-about.html">next time</a>...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-25345391950496834252014-07-18T19:27:00.001-04:002014-08-01T17:48:14.244-04:00What every developer should know about testing - part 1<h3>
<div style="font-size: medium; font-weight: normal;">
The short version of this blog post is that this week and next week on pyVmomi will be spent on radically improved testing code and processes. This testing process will become part of the commit cycle. And, it's about damn time.</div>
<div style="font-size: medium; font-weight: normal;">
<br /></div>
<div style="font-size: medium; font-weight: normal;">
Once these measures are in place over the next few days the project will be better able to absorb new commits from interested parties.</div>
</h3>
<h3>
Overview </h3>
Over the last three weeks I've been working on <a href="https://github.com/vmware/pyvmomi/issues?milestone=1&state=open">pyVmomi's next release</a>. If you've not been following along, it's a python client for a SOAP server and it's a code base dating back to at least <a href="https://github.com/vmware/pyvmomi/blob/v5.5.0/pyVmomi/SoapAdapter.py#L736">Python 2.3 </a>but it has only been in the wild as OpenSource now since <a href="https://github.com/vmware/pyvmomi/commit/f6eef2964463e94666ef7111fb93d16ac5bd6ead">December 2013</a>. The pyVmomi library has a long <a href="http://www.doublecloud.org/2013/11/hacking-vmware-private-python-api-for-vsphere-with-a-quick-sample/">internal history</a> at VMware and has served many teams well over the years. But, it does have problems.<br />
<br />
The OpenSource version of the library has *no* unit testing shipping with it this makes it hard for interested third parties to contribue. It's time to change that. But, it's a client library for a network service. How do you test such a beast?<br />
<br />
In this post I will cover what unit testing is and what integration testing is and how this impacts the design choices made on libraries. This discussion is directly applicable to the long-term evolution of a library like pyVmomi and is generally applicable to Software Design. I'm bothering to write all this down because I want everyone to be on the same page and I don't particularly want to repeat myself too much. Over the years I expect to be involved with this project I expect to point at this post frequently.<br />
<br />
<h3>
The Problem</h3>
Work on pyVmomi has been rather painful. For much of it, I have had to spend vast amounts of time deep in the debugger. Testing on this library involves building a <a href="http://www.virtuallyghetto.com/tag/vcsim">VCSIM</a> and simulating a vCenter environment. This in turn means the creation of a suitable inventory and potentially setting up a <a href="https://github.com/vmware/pyvmomi/issues/72">suitable Fault </a>to work with. This is a lot of <a href="http://learnpythonthehardway.org/book/ex46.html#p5">yak shaving</a> to get to the point you <i>can even start</i> considering doing development work.<br />
<br />
<h4>
The root of the <i>specific</i> problem</h4>
The problem in specific is that pyVmomi as a library speaks to a server. No other <i>thing</i> can completely simulate all the inputs, outputs, and exposed states that such a <i>thing</i> achieves <i>except</i> the big complex <i>thing</i> itself. This problem is routinely solved by developers in this <i>entire cloud infrastructure space</i> by spinning up <i>virtual environments</i> to create the scenarios they need.<br />
<br />
This is a natural inclination since you have a beautiful hammer, why not nail all the bugs with this beautiful hammer? Virtualization is powerful and has transformed our industry. One day I will be an old man and tell stories of how infrastructure and development worked in the <i>bad old days</i> of <a href="http://en.wikipedia.org/wiki/Dot-com_bubble">Dot-Com Boom</a> but this inclination is an example of the <a href="http://en.wikipedia.org/wiki/Hype_Cycle">hype-cycle</a> in full detrimental effect.<br />
<h4>
The problem in <i>general</i></h4>
Because <i>client</i> library code<b> development</b> starts<b> at the integration phase</b> the units that end up defined by the client library programmer are inherently <i>integrations. </i>How do you test integrations? With <a href="http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests">integration tests</a>. But, how do you do <i>integration testing</i> when the thing you are testing isn't even <i>on</i> your build machine? If it's a server (such as our case) you have to fall back to either a <a href="https://communities.vmware.com/message/2095872">simulator</a> or you have to stand up <a href="http://www.thomas-franke.net/vmware-vsphere-5-5-workshop-building-a-test-environment-part-1overview/">a whole new of your environment just for testing</a>.<br />
<br />
Unsurprisingly, this is fairly standard practice for every step of <i><a href="http://en.wikipedia.org/wiki/IaaS#Infrastructure_as_a_service_.28IaaS.29">IaaS</a> and <a href="http://en.wikipedia.org/wiki/IaaS#Platform_as_a_service_.28PaaS.29">PaaS</a></i> development. You stand up the universe to author a new function then you retest the whole thing on a fresh copy of the universe. Then, you wash-rinse-repeat for the whole integrated system. It's so <i>easy</i>. It's also so <i>very wrong. </i>Because code that is <a href="https://www.destroyallsoftware.com/blog/2014/test-isolation-is-about-avoiding-mocks">hard to test (or completely untestable) in isolation </a>is poorly designed. If you're defending the fact that it's tested, you're missing the point.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vr4Tt9TOEqg/U8mIGb99sSI/AAAAAAAAaxY/u369wrc5rUM/s1600/Screen+Shot+2014-07-18+at+4.48.01+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-vr4Tt9TOEqg/U8mIGb99sSI/AAAAAAAAaxY/u369wrc5rUM/s1600/Screen+Shot+2014-07-18+at+4.48.01+PM.png" width="50%" /></a></div>
<br />
This isn't just a problem with the one library I'm working on now. I've seen this repeatedly in development environments of every kind at huge shops and tiny shops. You build up a pile-o-software that glues systems together and to test it you build a pile-o-infrastructure that you bring to a pile-o-state so you can validate the right calls and responses.<br />
<br />
When you test this way (bringing a whole simulated universe into existence to test your new 'if' statement), invariably something's state gets out of sync and what do you do? You have to test the test environment to validate that you don't have false positives for your failure report, then you have to retest and you re-start the whole process which typically grows into hours. This is, frankly, <i>an <a href="http://www.agilemodeling.com/essays/costOfChange.htm">extremely expensive</a> way to develop software.</i><br />
<br />
And, for the record I've seen this in JEE, Spring, Grails, Python, Bash, Perl, C, C++, projects on Solaris, Linux, Irix, BSD, and now ESX based environments. This is not a problem unique to <i>those </i>crappy developers on <i>that</i> crappy environment. This is an intrinsic integration development problem that crops up when you routinely write code that takes big complex systems and makes them work <i>together</i>. It's a far too easy trap to fall into and a far too difficult of a pit to climb out of.<br />
<br />
<h3>
Unit Testing?</h3>
So the story so-far is that we have a library, maybe that library talks to things "<i>not of this machine"</i>. Maybe, it speaks over the wire, talks to other things we can't see or directly control. These are things well outside of anything we could define as our <i>unit of code</i>. So if that's our fundamental unit (because what *else* is something like pyVmomi?) How the heck do we test it?<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-O4MijwK7IIc/U8lOX7qUqxI/AAAAAAAAaxI/dA6zEA_QgHQ/s1600/Screen+Shot+2014-07-18+at+12.41.29+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="http://youtu.be/G2y8Sx4B2Sk" border="0" src="http://1.bp.blogspot.com/-O4MijwK7IIc/U8lOX7qUqxI/AAAAAAAAaxI/dA6zEA_QgHQ/s1600/Screen+Shot+2014-07-18+at+12.41.29+PM.png" title="An expert in word usage." width="50%" /></a></div>
<br />
The term <a href="http://blog.cm-dm.com/post/2013/01/11/What-is-a-Software-Unit">unit is deliberately ambiguous</a> in this context. Did we mean class? Did we mean method? The answer is <i>it depends</i>. Getting the logical border of the unit is <i><a href="http://frankcode.wordpress.com/2014/07/01/tdd-where-did-i-go-wrong/">hard</a>.</i> It's actually <i>human intelligence</i> hard. It's "why AI do not yet write code" hard. Why is it hard? It's hard in the same what the making <i>beautiful art </i>is hard it's a fuzzy problem that requires aesthetics.<br />
<br />
The definition of where a unit is, is <i>hard</i> and simultaneously <i>critical </i>to get right. Define the <i><a href="http://vimeo.com/68375232">wrong unit</a></i> and <a href="http://david.heinemeierhansson.com/2014/test-induced-design-damage.html">pay the price</a>. This doesn't mean testing is wrong, it just means <a href="http://www.thoughtworks.com/insights/blog/test-induced-design-damage-fallacy-or-reality">testing is a <i>programming-hard</i></a> problem. Looking for easy answers here just means you don't know what you're doing.<br />
<blockquote class="tr_bq" style="background-color: #fffff7; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; font-size: 13px; line-height: 20.15999984741211px; margin: 1em 1ex !important; padding: 0px; text-align: justify;">
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.<br />
— <a href="http://genius.cat-v.org/brian-kernighan/" style="background-color: transparent; color: #0066cc; text-decoration: none;">Brian W. Kernighan</a> and P. J. Plauger in <a href="http://www.amazon.com/gp/product/0070342075?ie=UTF8&tag=catv-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0070342075" style="background-color: transparent; color: #0066cc; text-decoration: none;"><em>The Elements of Programming Style</em></a>.</blockquote>
<div>
<h3>
</h3>
<h3>
I mock your Mocks!</h3>
A simple answer to the problem is to <a href="http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html">Mock and Stub everything</a>. (<a href="http://martinfowler.com/articles/mocksArentStubs.html#DrivingTdd">Mock objects are not Stubs</a>, and you should know the difference.<i> Edit: this is a whole topic unto itself and I will cover it separately at a later date.</i>) The problem is when you work with a sufficiently complex interactions you will be forced to write sufficiently complex mocks and stubs. You will back your way into the <i>simulator problem</i> I mentioned before. In our specific case this means essentially re-inventing something like VCSIM except all in Python mock objects and that's absurd.<br />
<br />
<h4>
What are you forging, o' library author?</h4>
Consider also, where is the unit <i>boundary</i> when it comes to a client library? The library <i>absolutely</i> has a boundary at its public interfaces. If the bit-o-code you just wrote is <b>private</b> why did you write it? The private method is not part of the <i>interface</i> and so therefore it's not part of the library's unit definition. The unit <i>in this context</i> only makes sense as a test-first tested component if it's going to be exposed. By definition a private method isn't exposed so it's an implementation <i>detail</i> and we don't test our programs to make sure implementation details work. We don't test if the 'if' statement works. So where is the detail and where is the interface?<br />
<br />
This means your test-first tests should be your <i>surface. </i>To develop a library that you intend on providing to people to interact with you should <i>model</i> sets of expected interactions. Each interaction should then be codified as a set of calls to the library.<br />
<br />
<h4>
Code as little as possible, test as little as possible</h4>
Tests <i>are</i> code. The mark of a good programmer is not how <i>much</i> code they write, but how much they can accomplish with how <i>little</i>. If you are following the aesthetic of minimalist code, then this attitude should also follow into your tests. Your tests should cover <i>as many lines</i> as is needed to <i>validate</i> the code and should do this as effectively as possible. Ideally, you should have an efficiency to your tests. <b>No two tests should cover exactly the same unit.</b> Covering a unit multiple times is effectively <i>wasted effort</i>.<br />
<br />
This is a <i>much harder</i> philosophy and practice to follow than the lazy <a href="http://en.wikipedia.org/wiki/Code_coverage">'cover all the lines'</a> strategy. It requires you to understand the <i>functional</i> cases your code can cover. In a rarified ideal world, this might mean you get 100% coverage <i>anyway</i> but the percentage isn't what we care about. You can have 100% code coverage and still have horrible comprehension of what your project even <i>is</i>.<br />
<br />
Breaking down your tests to cover <i>all</i> the methods, even the private ones is a horrible idea. If you cover your private methods you will be tying your <i>tests that matter</i> to what (by defining them as private methods) you have decided are <i>implementation details</i>. That equals tight coupling; <a href="http://www.codethinked.com/why-do-we-keep-building-tightly-coupled-software">tight coupling is bad</a>.<br />
<br />
How do you test something where it provides very little function other than basic interactions with a service? How do you exercise a library that is arguably <i>mostly</i> private and hidden code?<br />
<br />
<h3>
Introducing Fixtures</h3>
The concept of a <a href="http://en.wikipedia.org/wiki/Test_fixture">testing fixture</a> is a very old testing concept. It even predates software as a <i>thing</i> and yet I <i>rarely if ever</i> see a shop using fixtures. The truly sad thing is that for most development languages <i><a href="http://pyunit.sourceforge.net/pyunit.html">fixtures are old as the hills</a>. </i>So, WHY are so few projects using them?<br />
<h3>
A Specific Solution: vcrpy</h3>
I reviewed several Python fixture libraries this week and was fairly well impressed with <a href="https://pypi.python.org/pypi/vcrpy">vcrpy</a> for our purposes. The description may mention '<i>mocking</i>' but function of the library is to provide you with testing fixtures <i>at the socket</i> level. In libraries like pyVmomi we are effectively a skin over a very complex back end web service. This 'skin' nature of ours means that a simple set of library interactions may hide <i>dozens</i> of network conversations.<br />
<br />
Manually creating dozens of HTTP interaction mocks to explore a single high-level test can be so painful that you are likely to just not do it. Fortunately tools like vcrpy exist and can <a href="https://github.com/kevin1024/vcrpy#record-modes">record</a> your HTTP traffic. Now you can do the lazy thing and toy with your client-server a bit, record the on the wire interactions, and then later (and more importantly) <i>edit</i> the conversations to represent the larger API cases you want to cover.<br />
<br />
With the recorded HTTP fixtures at our disposal we can now work with the binding in much more predictable and controlled ways.<br />
<br />
<br />
More on that <a href="http://hartsock.blogspot.com/2014/07/what-every-developer-should-know-about_25.html">next week</a>... (or skip to <a href="http://hartsock.blogspot.com/2014/08/what-every-developer-should-know-about.html">the end</a>)</div>
Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-18409859935356080102014-07-11T16:09:00.000-04:002014-07-11T16:23:07.070-04:00pyVmomi and the road to Python3 - part 3<h3>
The Good News</h3>
It <i>works</i>! And without <i>major</i> surgery!<br />
<br />
I currently have a working branch of the pyVmomi code base that runs on python 3.x interpreters. We are working to get this version usable under Python 2.6, 2.7, 3.3, and 3.4 as well and hope to post on that next week. I'd also like to thank <a href="http://www.rackspace.com/">Rackspace</a> for offering to host our <a href="http://en.wikipedia.org/wiki/Continuous_integration">CI</a> servers. Kudos to <a href="https://github.com/michaelrice">Michael Rice</a> for getting that to happen.<br />
<h3>
</h3>
<h3>
The bad bits...</h3>
One of the most frustrating aspects of porting pyVmomi on to Python 3.x has been the fact that many of the language changes caused pyVmomi to fail to load or fail silently. This is in part due to design considerations made in the library early on, and in part due to how the language has changed.<br />
<br />
In particular the way imports are done were instrumental in basically masking the failures. The try-except-swallow pattern is frequently used and it tended to hide why a vim.* or vmodl.* data type wasn't loading into memory.<br />
<hr />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-5oqdrzfZcpA/U8A8l909pBI/AAAAAAAAamc/PgSCCROWey0/s1600/Screen+Shot+2014-07-11+at+3.35.20+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-5oqdrzfZcpA/U8A8l909pBI/AAAAAAAAamc/PgSCCROWey0/s1600/Screen+Shot+2014-07-11+at+3.35.20+PM.png" width="100%" /></a></div>
<hr />
<br />
Simple porting techniques and tools also helped mask the problems, however, now that they are known I may back off some of the changes in favor of cleaner more generic solutions.<br />
<h3>
</h3>
<h3>
Simple 2 to 3</h3>
A number of changes are rather trivial, take the case of exceptions for example...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/--qPr80m228k/U8Ae__9e6NI/AAAAAAAAak4/-sV1Zmoj-_U/s1600/Screen+Shot+2014-07-10+at+2.53.11+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="replacing a ',' with the key word 'as' is enough to 'fix' a python 2 to 3 exception block in some cases." border="0" src="http://4.bp.blogspot.com/--qPr80m228k/U8Ae__9e6NI/AAAAAAAAak4/-sV1Zmoj-_U/s1600/Screen+Shot+2014-07-10+at+2.53.11+PM.png" title="syntax changes made" width="100%" /></a></div>
... there were a number of these trivial cases where tools like the <a href="https://www.youtube.com/watch?v=1GcJTugBnzE">2 to 3</a> tool could help. But, in general libraries like <a href="https://pypi.python.org/pypi/six/1.7.3">six</a> and tools like <a href="https://docs.python.org/2/library/2to3.html">2to3</a> tended to mask underlying problems with more complex issues such as unicode and type inheritance in the library.<br />
<br />
There were a number of these kinds of changes<br />
<h3>
</h3>
<h3>
When is a Type not a Type?</h3>
Inheriting off of base classes is considered very bad practice. It tends to gain you very little and tends to complicate code unnecessarily. Consider the Link class in pyVmomi's VmomiSupport.py which very naughtily extends the core unicode class in Python.<br />
<hr />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-v2NfLzj0Qbk/U8AhylrR_7I/AAAAAAAAalI/Ewlw1_mhcJ8/s1600/Screen+Shot+2014-07-11+at+1.40.58+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-v2NfLzj0Qbk/U8AhylrR_7I/AAAAAAAAalI/Ewlw1_mhcJ8/s1600/Screen+Shot+2014-07-11+at+1.40.58+PM.png" width="100%" /></a></div>
<hr />
The Link class here serves the sole purpose of allowing a string to be recognized as a type temporarily so that when we do type mapping during SOAP deserialization we have a type to latch on to in <a href="https://github.com/vmware/pyvmomi/blob/v5.5.0/pyVmomi/VmomiSupport.py#L931">key branching logic</a>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-jLADf1obNBs/U8A0s3lMFEI/AAAAAAAAamI/GH_OYp40n5U/s1600/Screen+Shot+2014-07-11+at+3.01.43+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-jLADf1obNBs/U8A0s3lMFEI/AAAAAAAAamI/GH_OYp40n5U/s1600/Screen+Shot+2014-07-11+at+3.01.43+PM.png" width="100%" /></a></div>
<br />
This is clearly not within the use cases most people are thinking about when they are thinking about Python 2to3 and while the practice is naughty, it does provide an interesting orthogonality to the mapping code.<br />
<br />
So, because of that, while it's bad practice to extend a built in type I can't think of something cleaner that wouldn't immediately ugly up the code-base. However, I'm <i>also</i> not sure how that bit of logic currently performs since any use of Link is going to return ostensibly a string (albeit a unicode one) and said string is <i>never</i> going to to be of type Link. So the first point still stands... extending a base class is more confusing than it is useful.<br />
<br />
That's just out of scope for strictly Python portability work, so for the time being the class stays in. It also seems mostly benign at the moment. There's a significant lack of testing around the lib and that needs to be addressed before I will be confident doing any major refactoring work. IMHO: The python 3 support work is pushing our luck as it is.<br />
<h3>
</h3>
<h3>
Unicode uncoded</h3>
<div>
Of particular interest is in testing our Unicode related code no longer make sense in Python 3.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-SlAqf5CcLVs/U8BBRgh_REI/AAAAAAAAamo/Jfou0GAJezE/s1600/Screen+Shot+2014-07-10+at+3.48.48+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-SlAqf5CcLVs/U8BBRgh_REI/AAAAAAAAamo/Jfou0GAJezE/s1600/Screen+Shot+2014-07-10+at+3.48.48+PM.png" width="100%" /></a></div>
<div>
Hopefully, we can do away with the uglier bits I've hacked on here to make things work. We will also need to back-track the assumptions made when the 'unicode' and 'basestring' symbols were used and make sure they still hold.<br />
<br />
<iframe allowfullscreen="" frameborder="1" height="315" src="//www.youtube.com/embed/sgHbC6udIqc" width="100%"></iframe>
</div>
<h3>
<span style="font-size: small; font-weight: normal;">Special thanks to the friendly folks on </span><a href="http://webchat.freenode.net/?channels=#python" style="font-size: medium; font-weight: normal;">#python</a><span style="font-size: small; font-weight: normal;"> for their help with understanding the issues around Python and unicode.</span></h3>
<h3>
</h3>
<h3>
Next steps: testing, testing, testing</h3>
My next set of tasks will be to clean up and refine the python 3 related changes to try and make them as targeted an small as possible. I can't realistically do this with much confidence if I can't make assertions about the library's operation. While VMware has internal build systems and tests that validate and verify the library against a variety of product builds I can't realistically expose these since they are intimately related to shipping product itself.<br />
<br />
The <a href="https://github.com/hartsock/pyvmomi-integration-tests">pyVit</a> (pronounced pi-vət) project is a first step toward creating a test suite for pyVmomi that a 3rd party could easily consume to validate the library and their environments. This will help us move the library from its current status of beta to a 'stable' category. I also hope this will enable broader stewardship of the pyVmomi library allowing it to take on a life of its own. Ideally, this will also enable anyone to <i>fearlessly</i> refactor the library.<br />
<br />
More on that next week...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.comtag:blogger.com,1999:blog-28383337.post-18888232285003067792014-07-03T13:13:00.001-04:002014-07-03T13:19:44.282-04:00pyVmomi and the road to Python3 - part 2Short week this week, so a short update ...<br />
<br />
I've spent most of my time with my head in the debugger flipping between Python 2.7 and Python 3.4 interpreters. I've been observing the differences in behavior between the two versions and finding ways to make pyVmomi behave with both. Some of the more interesting work has had to do with how Python 3 handles class loading and namespaces. I could probably write a whole post on that alone.<br />
<br />
In my <a href="https://github.com/hartsock/pyvmomi/commit/45f35151e9a2808cbe6e05558a761d0173c1c070">current attempt</a>, even with a good debugger I've been forced to resort to bear-skins-and-bone-knives development. The problem being that the <a href="https://gist.github.com/hartsock/52bd5fab36e9bd488a9f">critical fault </a>occurs during interpreter load. That has to do with how pyVmomi builds its binding.<br />
<br />
At runtime pyVmomi uses a <a href="https://github.com/vmware/pyvmomi/blob/v5.5.0/pyVmomi/VmomiSupport.py#L211">LazyModule</a> class to hold instances of class definitions it needs. This leads to some efficiencies in cases where very little of the actual API is being used. The API is enormous as you can see from the <a href="https://github.com/vmware/pyvmomi/commit/15f7be9a526d209fb7f0940cbf6b8e7cc481c0dd">generated documents</a> I posted so this efficiency makes sense. It does mean that the pyVmomi classes that you use in your own code are not python types as you normally experience them. The binding does produce a convincing illusion, however.<br />
<br />
I've bumped back the next release milestone from July 15th to July 31st to give us time to validate the changes for Python 3 support since they will be slightly more invasive than I had hoped for. I want the next post to pypi to include that Python 3 support patch if possible.<br />
<br />
Lessons learned from porting pyVmomi to Python 3 will be generally valuable beyond just pyVmomi but, I'm still in the thick of it. So far progress is encouraging but there is still a way to go before declaring the new version stable.<br />
<br />
More on that next week...Anonymoushttp://www.blogger.com/profile/07041739178513685832noreply@blogger.com