Nov 21, 2008
Benefits of working from home - Part IX- Infrastructure
In this post I'll take a look in the other side of the coin: the investment in infrastructure.
When my home computer used to be only that, i.e, my home computer, I had no hard requirements to keep it up to date. I could simply update it each 5 years or more if I wanted to; also, my internet connection need not to be very fast; the same applies for my desk; it could be very ordinary as I didn't spent a lot of time in my computer.
Of course, being a computer/programmer addicted as I am, shortened my computer's update cycle for something between 2 ~ 3 years, and
internet connection, you know: you never get enough bandwidth ;)
By the other hand, using my computer to work pushes it to its limits... and of course, each minute I spend looking at the hour glass represents a minute less with my family (or my Wii :) so I want to wait the lesser amount of time possible in front of it.
Just to put some numbers, the first time I run db4o build on my machine it took more or less 1 hour to run to completion (mostly running tests). I just couldn't believe that. My machine was not a top one but it was not so old/slow either. After a lot of tweaking I managed to get the build running in 15 minutes but that required some $$$ (nowadays, even with a new machine tests take 20 ~ 25 minutes to run due to lots of new tests).
Also, I never considered (or had the requirement to) run 2 VMs, 2 Visual Studio (one in one VM and another in the host OS), Eclipse and some other apps at the same time. So now, 2Gb of memory doesn't look that much anymore.
Another important aspect that will have great impact on your productivity/health is the overall quality of your office furniture: remember when you used to complain about your boss not willing to spend a few extra dollars on a good chair for you? I certainly remember myself complaining with mine :( Of course you don't need to go out and get the best chair in the world, but make sure you'll not get a "not so good" one only to save a few extra bucks either (If you are going to spend more than 4 hours seated I do recommend you to get a very good one - for instance, this one).
Well, that's not the end yet; telecommuting meant also that I became my own IT department ;). Not that I have any problem fixing my computer, installing software or whatsoever; the really big point is that all these maintenance work takes time (and time is money) and also that the burden to keep everything working is on me (to be fair, I'd rather be the one in charge for this task than to let someone else doing it anyway).
Last, but not least, consider having "hardware" backup; I mean, what are you going to do if next morning when you turn your computer on it don't actually turns on? Of course you do have backups of your important data (don't you?), but what about your hardware? How long it will take to be fixed? Are you willing to spend time on fixing it? Or do you have another computer that can be used so you can continue to work while someone else fixes it for you.
In the end of the day, you'll need to put some money on your office / infrastructure, so don't forget to take this into account.
That's it.
Bear with me ! We are approaching the end :)
See you
Adriano
Nov 17, 2008
Changes in Db4o configuration.....
If you take a look in our svn repository you'll see that lots of changes were applied to configuration code (starting with version 7.7). Take it easy, we kept the "old" configuration interface in place; we just deprecated it, so update your code to use the new interfaces if you have the chance ;)
In this post I'd like to discuss some of these changes.
New, specific, factory classes
Do you remember Db4oFactory OpenFile(), OpenServer() and OpenClient() methods? We decided to move them to more specific factory classes:
- Db4oClientServer
- Db4oEmbedded
IObjectContainer db = Db4oFactory.OpenFile("MyData.odb");
to:
IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), "MyData.odb");
As an additional benefit now we use the same class in both platforms (Java/.Net) (Remember, we used to have Db4o.openXXXX() for Java and Db4oFactory.OpenXXX()for .Net).
Configuration interface split in File / Network / Common
We are applying Interface Segregation principle to configuration, so, now related configuration options are close together in specific interfaces.
For instance, all embedded related configuration lives in IEmbeddedConfiguration. But we didn't stopped there. We went a step further and broke common functionality in more coarse grained interfaces. For instance, there are configurations that do apply to both embedded and client server modes. So we introduced the concept of Configuration Providers which sole purpose is to help to aggregate configuration into specific interfaces, so it's easier (at least in our opinion :) to identify which configuration applies to each db4o mode and also make it more clear which aspect of db4o are being affected by that configuration.For instance:
IEmbeddedConfig config = Db4oEnbedded.NewConfiguration(); config.File.ReadOnly = true;
In this sample there's no space for doubts that ReadOnly configuration relates to a file system aspect of an embedded database.
That said, we basically partitioned configuration into four categories:
- Embedded
- Server
- Client
- Common
No more "default" configuration;
Suppose your application, at some point, requires a Db4o database with an activation depth configured to the highest possible value (in most scenarios this is not recommended) so you use some code like this:
IConfiguration globalConfig = Db4oFactory.Configure(); globalConfig.ActivationDepth(Int32.MaxValue); using(IObjectContainer db = Db4oFactory.OpenFile("test.yap")) { /* Use the database */ }
So far, so good. Now, in a completely different point in your application you need to open another Db4o database and so you just type:
using(IObjectContainer anotherDb = Db4oFactory.OpenFile("test1.yap")) { /* Use the database */ }
This new database ends up configured to fully activate objects! Even knowing that you should avoid configuring activation depth this way (you did your homework, right?) it's possible to do it by accident.
The problem is that it is relatively easy to mess with configuration.
That's the reason that now, all OpenXXXX() methods (in the new factories) requires a configuration to be passed through!
We are considering reintroducing the original signature methods but with different semantics; instead of return a clone of the global configuration we can return a fresh configuration object populated with default values so developers can be sure about what configuration they get!
To wrap up the session on configuration I'd like to present a short "cheat sheet":
Emdedded | Old | Db4oFactory.OpenFile("dbfile"); |
New | Db4oEmbedded.OpenFile( Db4oEmbedded.NewConfiguration(), "dbfile"); | |
S e r v e r | Old | Db4oFactory.OpenServer("dbfile", port); |
New | Db4oClientServer.OpenServer( Db4oClientServer.NewServerConfiguration(), "dbfile", port); | |
C l i e n t | Old | Db4oFactory.OpenClient( "dbfile", port, "user", "pwd"); |
New | Db4oClientServer.OpenClient( Db4oClientServer.NewClientConfiguration(), "dbfile", port, "user", "pwd") |
ExceptionsOnNotStorable is turned on by default
That's (IMHO) really nice. I don't like to just pretend that classes are storable on Db4o and let customers struggling trying to figure out why their applications doesn't work when we could follow fail fast principles and let they know that one or more classes may have problems as it is.
Use of properties in .Net
That's mean more natural code style for .Net developers :). Now, instead of saying:
config.OutStream(Console.Out);
you will write:
config.OutStream = Console.Out;
We are aware that there other places where using properties instead of methods (or even using a different approach) would make more sense (on .Net of course) but we just don't have the time to improve them now. But you may be sure we'll do our best to keep improving both .Net/Java developers experience.
That's it!
See you.
Nov 5, 2008
Are you a C# developer?
(I already own a copy of another addin, but I'll give it a try anyway :)
Adriano
Nov 2, 2008
PDC 2008 Videos - For free!! :)
Are you a Windows developer? Or simple a Windows enthusiast? So you probably is aware of Microsoft PDC 2008.
I'd love attend it but I couldn't :(
At least we can grab (all?) Microsoft PDC 2008 Videos.
Have fun!
Adriano
Benefits of working from home - Part VII - Alone in the office
(sorry for the subject, I just couldn't resist :)
Note that some points that I first took as an advantage may appear again, but this time, with a focus on possible disadvantages; this doesn't mean I've changed my mind (what I would say is perfectly normal); its just the other side of the same coin.
I'll start with the most problematic one (at least in my case), working from home meant to loose almost all contact with my friends and coworkers. I remember it perfectly when I was being interviewed (through skype) and I was asked how I felt about working alone, 8 hours per day; honestly, at that moment I did think it would not be an issue, but sometimes it is a little bit lonely.
Since I was not bound to an office anymore, after 4 months we (I and my wife) decided that the time to move to a quieter, safer, less violent place had come, so we moved from São Paulo to Londrina; you see, most of my friends still live in São Paulo and even having some (good) old friends (and my wife's parent) here in Londrina I somewhat miss personal contact.
Another important aspect of working from home is that all discussions (at least in my case) are done through some IM software (be it skype/msn/etc) and this is considerably harder to do than when you are engaged in a face-to-face talking.
It's enough for the first "not so good" series... let me play a little bit of "Star Wars" on my Wii ;)
See you.
Adriano
Oct 30, 2008
Benefits of working from home - VI - Mange my time
Have you ever needed to ask (embarrassed) your boss to let you leave early so you could go to the doctor or to address some personal issue?
Well, not have to do this is another benefit of working from home :) as (usually) you are in charge of managing your own time!
Of course this is not an "all or nothing situation". Even when I had a "traditional" job my bosses were kind (or intelligent) enough (I bet they were both :) to let me deal with my personal issues during my working time if that were necessary.
My point is that nowadays all I have to do is to get organized so I don't miss any meeting, pair session and/or a dead line and everything is fine :). It's even better as I can choose the best time (a time in which I'll get less traffic, that is not to hot, etc.) to do my personal stuff.
Thats it! Even though being far from a comprehensive list of the advantages of working from home, I finally reached the last (but not least) advantage I wanted to blog about. In the next posts I'll talk about some drawbacks.
Do you have any other advantages in mind? Please, share with us!
Best,
Adriano
PDC Talk: The future of C#
A very interesting PDC talk (by Anders Hejlsberg) about the future of C#.
As a teaser, just some subjects covered in the this talk:
- More dynamic constructs
- Optional / Named arguments
- Concurrency
Adriano
Oct 22, 2008
Never give up
In the last couple weeks I received at least 7 messages from the same sender, with the exact same contents:
It's in portuguese (at least) and says something like: "Hey dude, here are the photos!".
What photos? I don't remember asking any friend called "gabriel" to send me any photo ;) even more with supposedly annexed photos linked to files like "fotos_237.com" on a very suspicious server (at least the guy wrote my name correctly)! No thanks !!!
In this same time range I got other "phishing" emails like:
Another email in Portuguese, pretending to be from hotmail trying to foolish me to get in panic and click on a link.
This one (also in portuguese) is supposedly a "Virtual Card" from a girl named "Carla". It even includes a "copyright" notice in the end of the email.
Well, maybe may mommy would be tempted to clink on these links but not me. Anyway, this kind of threat is getting more sophisticated as time passes so pay attention where you put your mouse :).
Best.
Adriano
Oct 21, 2008
Oct 17, 2008
Benefits of working from home - Part V - Show me the money
I've always the feeling that my investment in computer hardware/software was somewhat a waste of money; you see, usually I get a pretty descent machine and stick with it for at least 3 years; so every 3 years I spend a lot of money to get a new one and I didn't get a direct return from my investment (not to mention that most of the day it keeps turned off), and to be fair, I should take internet connection fees into account.
Since I started working from home I may say that this is the first time I am getting a direct¹ (and measurable) return from this investment. It's even better, now it's easier to justify new hardware, software and other gadgets to the financial department, i.e, my wife :).
In other words, now my computer generates income and I feel compelled to invest more money to keep it up to date.
Adriano
¹ I mean, direct, because I always studied a lot in my home computers so, at least indirectly, they always gave me a financial return (even tough it is hard to measure how much return I got).
Oct 15, 2008
Running Sharpen tests faster...
While talking about how to run Sharpen test suite in this post I told that I'd show how to improve these tests startup time.
After a long wait, here it is. So let's go.
If you tried to run Sharpen tests you probably noticed that whenever you launch them a new Eclipse instance starts also (with it's full GUI) and this is one of the culprits for these tests to take longer than necessary to run. The good news is that it's (relatively) easy to configure Eclipse to not display any GUI at all (since all feedback will be given through the main Eclipse window).
To do this, once you checkout all required projects from db4o SVN, just Right Click sharpen.ui.tests project and select Run As / Run Configurations menu.
Now, in "Run Configuration" dialog, right click on "JUnit Plug-in Test" and select New.
If you followed the previous steps, "Run all tests ...." should contain the right value (sharpen.ui.tests). Just make sure that you have the latest JUnit selected on "Test Runner" dropdown.
We are almost there... :)
The next step is to click on "Main" tab (1), then select "Run as Application" checkbox and select "[No Application] - Headless mode" in the dropdown (2) and finally, click "Run" button (3).
That's it :)
Notice that now sharpen test suite starts faster.
Many thanks to a great friend (Rodrigo) for sharing this information with me.
See you.
Oct 13, 2008
Benefits of working from home - Part IV - DIY
How many times a developer approached you to ask something he/she could have easily find by himself have he/she bothered to spend 10 minutes to do a google search?
And let's be fair, how many times you feel compelled to do the same? I have to confess that even being a firm believer of "search before asking" principle, sometimes I do find myself doing the opposite: asking before looking for information.
And this lead us to this post subject: Working from home gave me more incentive to do "the right thing™" :), i.e, to look for solutions prior to asking the guy next to me - after all there's no such thing as the "guy next to me" :)
At db4o we do exchange lots of information/knowledge but since we are not at the same room (and in most cases we are at different timezones also) it's more practical to do a quick search and try to fix/solve issues by myself. Only after spending some time in my own research I think about asking the gurus.
This attitude (searching before asking) leads to a better understanding of the subject and other developers will not be interrupted to explain. Of course (IMHO) there are times (and subjects) that requires someone with more knowledge to guide other developers.
Anyway, I do believe that the process of explaining some subject may help you to get more insight about it and I do appreciate helping other teammates to improve their knowledge (Nowadays I'm learning more than helping :).
What do you think?
Adriano
Oct 11, 2008
Benefits of working from home - Part VIII - Working Time
Working from home is a very different experience and you can find yourself working a lot more than you'd expect/are willing to :(. The problem (again, IMHO) is that it's hard to separate the matters; you see, the work is there, you are there, and the rest you can guess.
Of course other factors like your productivity, how your manager and you decide on what to do and how long it is expected to last, etc. also plays an important role and can turn your working experience more pleasant or more like a nightmare.
In my specific case, I participate in deciding which tasks I'll be working on every week so I am the only one to be blamed when my working days extends a little bit.
And theres an aggravating factor: I am kinda addicted to computers/programming and sometimes I get so excited to see the outcome of my code that I can't just stop :)
So if you are going to work from home, pay attention to these pretty common pitfalls to avoid getting trapped into them.
See you.
Adriano
Oct 7, 2008
Benefits of working from home - Part III - Time efficiency
Today, I'm going to talk about some more benefits (directly related to the previous one), so let's go.
As I explained in the previous post I used to spend 2 hours in traffic; well, since I started working from my home this was not an issue any more and not wasting my time on traffic jams made it possible to do other things (like sleep more, post more frequently, etc. :) and spend less money with gas, but (IMHO), more important than all, it made it possible to spend more time with my family.
Prior to joining db4o, I used to wake up at 7:00, take a short breakfast and drive to my work so I rarely joined my wife/daughter at breakfast. At lunch time I was not with them again (since it would take me 1 hour to go to home and another one to get back).
Now, even though I usually wake up at the same time, instead of having a (lonely) fast breakfast and going to my work I just go down to my office and start working (usually I put may email/web reading up to date) then 1 hour latter my daughter wakes up and we (I, my wife and my daughter) can have breakfast together. Them, at lunch time, we can have lunch together again :)
Pretty nice!
At the end of the day when my daughter returns from school I'm finishing my working day and we can spend a little more time together.
Well, as an interesting tv ad says:
Have a good breakfast: U$ 20,00; getting out to have a good meal: U$ 50,00; to be with your beloved ones at these moments: has no price! :)See you!
Adriano
Oct 5, 2008
Back to Vista x64
Some time ago (sometime around 10/2006) I installed Windows Vista (a release candidate at that time) on my home machine in order to "try" it (to be sincere I've installed various Vista beta/release candidates).
Performance was not impressive but since I'm a software developer (and I didn't used the machine to work anyway) I decided that it worths to be able to experiment with new API / functionality so I kept it.
Some time after that it was released so I got a copy and installed in the same machine.
On 10/2007 I joined db4o and started to work from my home which means that my machine now plays an important role in my development productivity and I decided that I'd rather go with Windows XP (x86 or 32 bits) again (due to the performance impacts I got with Vista x64).
Well, one year passed and I got a new machine (a pretty fast one, lets say) and so I decided to give Vista x64 a try again.
In the first days I do got some BSODs (which made me feel frustrated) but after spending some time searching I found some suggestions regarding memory configurations; after applying such changes (I just set the times after memory manufacturer specifications and increased memory voltage by 0,1 volts) it became stable (no BSOD since them).
I can say that I'm satisfied up to now; no hardware or software conflicts, performance is pretty good (much faster than my previous machine running Windows XP - I know, XP would run even faster on this machine).
See you.
Adriano
Oct 3, 2008
Benefits of working from home - Part II : No need to commute
Let's take the half-full approach and present the advantages first starting with not needing to commute.
Well, before joining db4o I used to live in São Paulo - Brazil, so this point is pretty easy one ;)
Anyone that knows just a little bit about São Paulo knows that it has a very bad traffic! Usually, in the days that the traffic was not that bad, it used to took me no less than 1 hour from my house to my work place (and I was fortunate enough to not live that far from my job). So 2 hours of my life was spent in a car every day.
Also, not being required to commute (and so avoiding traffic jams) made my expenses with car maintenance drop a little bit and getting involved in a car crash less likely.
As a bonus of not commuting I don't have to find a place to park in a, usually, crowed place :)
So, IMHO this is a huge advantage.
The next post will be closely related to this one but I'll talk about my working time.
PS: Do you work from home? What are your opinion about the subject?
See you!
Adriano
Oct 1, 2008
Benefits of working from home - Part I - The dream job
Since one year has passed, I think it is a good time to review this journey and rethink whenever its paying off or not.
In the next posts I'll discuss (shortly) some advantages and some shortcomings (from my point of view, of course :) regarding working from home. The order in which these topics are presented has no particular meaning.
Keep in mind that my opinion is largely influenced by the place I live in, the environment I am inserted into and the kind of work I am involved with, so, what I see as an disadvantage you may well see as an advantage :). Don't worry, we are not supposed to agree on everything.
Another important point is that some teleworkers (as people that work from home are called) usually do work "part time" in a real office; that's not my case; I am working 100% of the time from my home and the nearest fellow is at least 100 Km (and the others are 1000 Km) away.
To start with, here are a couple of interesting articles to read.
Hope you find this information useful/fun :)
See you.
Adriano
[edit: added link to following posts]
Sep 10, 2008
Here we come again :) - Part III - The end
Component | Detail |
Motherboard | GIGABYTE GA-EP45-DS3R |
Processor | INTEL Core 2 Quad Q3300 2.66GHz 12MB 1.333MHz |
Memoty | 8 Gb - OCZ DDR2 800 |
Cooler | Cooler Master Vortex |
Power | 550W - Corsair |
Keyboard | Microsoft Wireless Desktop 2000 |
Video Card | Geforce XFX 9600GSO 384MB |
HD | 750GB Samsung |
Aug 11, 2008
Extracting files from a MSI file.
Aug 4, 2008
Here we come again :) - Part II
Component | Detail |
Motherboard | GIGABYTE GA-EP45-DS3R |
Processor | INTEL Core 2 Quad Q9450 2.66GHz 12MB 1.333MHz |
Memoty | 8 Gb - G.SKILL DDR2 800 |
Cooler | ARCTIC COOLING Freezer 7 Pro |
Power | 550W - Seventeam |
Keyboard | Microsoft Wireless Desktop 2000 Optico |
Video Card | Geforce XFX 8600GT 256MB |
HD | 750GB SEAGATE |
Aug 1, 2008
Here we come again :)
Year | Processor | Freq. | # Core | RAM | Hard Disk | Graphics Card | Internet |
1989 | 6502 | 0,75 Mhz | 1 | 256 Kb | NA | OnBoard | NA |
1992 | Ciryx 486 DLC | 40 Mhz | 1 | 4 Mb | 100 Mb | Trident | NA |
1996 | Pentium 100 | 100 Mhz | 1 | 16 Mb | 1.0 Gb | ? | 28 Kbps |
1999 | Athlon 400 | 400 Mhz | 1 | 128 Mb | 30 Gb | 4 Mb | 56 Kbps |
2002 | Athlon XP 2.1 | 1.8 Ghz | 1 | 512 Mb | 60 Gb | AGP 64Mb | 350 Kbps |
2006 | Athlon 64 3.8 X2 | 2.0 Ghz | 2 | 2.0 Gb | 370 Gb | PCI-X 256Mb | 2.0 Mbps |
2008? | Core 2 Quad 9XXXX | > 2.50 Ghz | 4 | 8.0 Gb | 500 Gb | PCI-X 256Mb | 6.0 Mbps |
Jul 23, 2008
My mind is about to blow
Jul 17, 2008
Implications of instrumenting assemblies for Transparent Activation / Persistence in db4o - Part I
Jul 16, 2008
Jul 15, 2008
Another one in the obscure codding practices ...
void main(int argc, char* argv[]) { int n = 255; size_t size = sizeof(++n); printf("%d", n); }Maybe this be can pretty obvious to you, but it was not to me (maybe because I avoid to write obscure code as much as I can :) Adriano
CERT C++ Secure Coding Standard
Jul 2, 2008
What is wrong with this code?
#include "stdafx.h" #include "stdio.h" class SimpleClass { public: SimpleClass(int n) { value = n; } void FirstMethod(TCHAR* str) { wprintf(str); } void SecondMethod() { wprintf(L"Value: %d", value); } private: int value; }; void Test(SimpleClass &ref, int i) { switch(i) { case 1: ref.FirstMethod(L"Hello world\r\n"); break; case 2: ref.SecondMethod(); break; } } int _tmain(int argc, _TCHAR* argv[]) { SimpleClass *p = 0; Test(*p, 1); Test(*p, 2); return 0; }
- Will it compile? run?
- What would be the outcome from Test being called in line 39?
- What about line 40?
- Is there any other issues?
Jun 29, 2008
Do it yourself
Jun 25, 2008
Type safe / refactor friendly configuration for Db4o - Part III
- Only constants: Throw exception
- More than one field involved: Throw exception
- Chained method: returns the called method / property accessed field.
public FieldReference Resolve(MethodDefinition method) { if (CheckRecursion(FullName(method))) return null; callStack.Push(FullName(method)); ControlFlowGraph graph = FlowGraphFactory.CreateControlFlowGraph(method); graph.Dump(Console.Out); Resolve( graph.Blocks[0], firstInstruction => Array.Find( graph.Blocks, candidate => candidate.FirstInstruction == firstInstruction)); callStack.Pop(); FieldReference reference = CheckReferencedFields( referencedFields, method.Name); referencedFields.Clear(); return reference; }Next, for each control block we inspect it's IL as shown in the following code:
void Resolve( InstructionBlock block, Func<Instruction, InstructionBlock> blockForStartingInstruction) { if (AnalyzeInstructions(block.FirstInstruction, block.LastInstruction)) { Resolve( blockForStartingInstruction(block.LastInstruction.Next), blockForStartingInstruction); } for (int i = 0; i < block.Successors.Length; i++) { Resolve(block.Successors[i], blockForStartingInstruction); } }In Line 5 we call a function that do the dirt work of analyzing the IL instructions. This function returns true if the block containing the next instruction (after the last instruction of the current block) should be handled as the "next block" (this is done to support finally blocks). Lines 12-15 just process the remaining blocks calling Resolve() recursively. The real fun is in AnalyzeInstructions() function which do the following:
- Line 7/9: For Ldfld / Ret instruction sequences, add ldfld target to return field list (lines 11 and 12).
- Line 16: Add an alias for the each Ldfld /Stloc sequence;
- For Ldloc / Ret sequences, search the aliases to see if ldloc's operand is an alias for a field and add any alias found to the return field list (line 23).
- If a method call is found, analyze the target's method body (lines 35 - 41).
bool AnalyzeInstructions( Instruction current, Instruction last) { while (current != last.Next) { if (IsLoadField(current)) { if (IsReturn(current.Next)) { referencedFields.Add( (FieldReference)current.Operand); } else { EnsureLocalVariableAliasFor(current, () => (FieldReference)current.Operand); } } else if (IsLdloc(current.OpCode)) { if (IsReturn(InstructionOrBranchTarget(current.Next))) { FlushAliasesFor(current); } else if (IsStore(InstructionOrBranchTarget(current.Next))) { EnsureLocalVariableAliasFor( current, () => aliases.Find( candidate => candidate.OpCode == current.OpCode).Field); current = current.Next; } } else if (IsMethodCall(current)) { EnsureLocalVariableAliasFor( current, () => Resolve( ResolveMethod((MethodReference)current.Operand))); } current = current.Next; } return IsLeave(last); }That's it! You can download the full source code here. [Updated on 7/23/2008: Fixed the source code download link] Just in case you want to play with the code, one point can (need to) be improved is the handling of exception blocks. Thoughts? Adriano
Jun 23, 2008
Very interesting (and funny)
Jun 21, 2008
You are not paid to introduce bugs :)
- for each configured version, create an database using it and perform a series of tests with the trunk version.
private const double MinimumVersionToTest = 6.0;At some point in the code we called the following function (wrong version):
double VersionFromVersionName(string versionName) { Version version = new Version(versionName); return version.Major + version.Minor / 10; }This function is supposed to return the double representation of an assembly version (string) but it fails miserably (this code works correctly only for versions with a decimal value 0 (zero); for instance, 6.0, 7.0, etc). Now the question is, what's is wrong with this function? To be fair I have to admit that it's not a hard to spot bug, but when you are in a hurry and have no test for your test code... The problem is that version.Minor is an integer field and so,
version.Minor / 10will result in a integer number and the decimal part will be happily discarded. The developer who wrote this code (me) is aware of language type conversions but he didn't notice the error (shame on me) ; so whenever we passed a version number not finished in 0 (zero) we got the wrong double representation for it!
Actual Version | Function Return |
6.0 | 6 |
6.1 | 6 |
7 | 7 |
7.2 | 7 |
double VersionFromVersionName(string versionName) { Version version = new Version(versionName); return version.Major + version.Minor / 10.0; }The bottom line? This episode just highlights (and reminds me about) the importance of double checking our test code! after all, as a friend of mine likes to ask:
who test that the tests test what they should test?Have fun. Adriano
Jun 3, 2008
Running Sharpen Tests
If you start using sharpen, you'll probably find some limitation / bug and, maybe, want to take a look into the issue.
In this case the best approach (IMHO) would be to i) start a discussion in Sharpen Forum and, if appropriated (in the case there's no issue filed already), ii) file a new Jira issue into our issue tracking system.
Next, if you have the time, iii) try to replicate the behavior with a minimal test case. The last step iv) would be trying to fix the issue.
This post is all about iii, or to be more clear, on how to run / write unit tests for Sharpen.
Let's start by opening an empty eclipse workspace:
Next, open SVN perspective and add a new SVN repository pointing to
https://source.db4o.com/db4o/trunk/sharpen/
and checkout all projects.
No install the plugin (as explained here):
- In package explorer (Java perspective), right click on sharpen.core and select "Export" from the context menu.
- Expand the "Plug-in Development" folder and select "Deployable plug-ins and fragments".
- Set "Destination" to the root folder of your eclipse installation and click "Finish";
after some processing your screen should look something like:
When the tests finishes you should see 0 (zero) errors and failures (as of today, there's some issue with sharpen.builder and sometimes you will get 2 errors in its tests but these errors don't prevent sharpen to work properly and, as you can see, when I executed the tests the errors didn't showed up).
Now let's explore the general look 'n' feel of a Sharpen test. In package explorer expand the node sharpen.ui.tests then testscases.
For each sharpen functionality there will be at least one pair of files (collectively called Test Case Resource):
- One .java.txt that stores the java source to be converted;
- One .cs.txt storing the expected sharpened file;
The next logical step is to add new tests. Basically to add a new tests we need to:
- Create the original java source (.java.txt)
- Create the expected cs file (.cs.txt)
- Plug these two files into the test engine. In the common scenarios, all we have to do is to call runResourceTestCase() function.
To see an example, just expand sharpen.ui.tests/src/sharpen.ui.tests folder and double click on NativeInterfacesTestCase.java.
In a future post (soon I hope) I want to take a look in a few other points such as:
- Getting a little better performance when starting sharpen using the approach presented in this post.
- How to debug sharpen.
- A trick to see the expected / actual values (useful when creating new tests).
Adriano
Jun 2, 2008
Dumb security...
New programing language!
A skilled professional with 3 years of experience in C, Sharp and VB.NET.I have to admit that I do know C and also a little of VB.NET, but I have never seen SHARP :) Ok, probably it was just a mistyping, but I bet the person who wrote this subject has no idea about programing languages whatsoever ;)
May 22, 2008
Where do you search for .Net tools?
- The Free Country (www.thefreecountry.net)
- Source Forge (www.sourceforge.net)
- Codeplex (www.codeplex.com)
- Fresgmeat (freshmeat.net/)
May 15, 2008
Usefull firefox trick
As an example let's take the free dictionary, very nice (guess what ??) dictionary site :)
When you browse to www.tfd.com and enter a word to search it navigates to www.tdf.com/word.
In Firefox we can add a shortcut so we can speedy our browsing experience. See the example below
Instead going to the TheFreeDictionary site and then typing the word we want to look for (for instance, cake), just type tfd cake in firefox address bar! Simple like that! :)In order to make this work we need to tell firefox that we want a shortcut named tfd (you can name it at your will) and that it must navigate to www.tfd.com/whatever-we-type-in-address-bar.
To do this, open bookmark manager (CTRL-B) add a new bookmark as follow:
(note the url: http://www.tfd.com/%s)
Press Add and you are done! Now just type tfd cake on firefox address bar!
Adriano
May 14, 2008
Type safe / refactor friendly configuration for Db4o - Part II
In my last post I proposed to derive field names from a property accessor in order to gain type safety and compiler support when configuring some aspects of D4bo.
So, given the following class:
public class Test { private int _age; public int Age { get { return _age; } set { _age = value; } } }we could use the following code:
IConfiguration cfg = Db4oFactory.NewConfiguration(); cfg.ObjectField((Test t) => t.Age).Indexed = true;instead of:
IConfiguration cfg = Db4oFactory.NewConfiguration(); cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;to configure a field to be indexed. The first step to use this syntax is to be able to figure out the property being accessed. To demonstrate how this can be done let's write a simple function that takes advantage of C# Expression Trees:
public string GetPropertyName<T,R>( Expression<Func<T,R> exp) { // Get the property name here. } public static void Main() { string s = GetPropertyName((Test t) => t.Age); }When compiling the above code, the C# compiler will create an expression tree representing our lambda expression ( (Test t) => t.Age) and pass it along to GetPropertyName() function.
Inside this function we can just use the Body property (which in this case represents t.Age part of our lambda expression) and cast it to MemberExpression. Now all we have to do is to consult MemberExpression.Meber.Name property:
public string GetPropertyName<T,R>( Expression<Func<T,R> exp) { MemberExpression me = fieldExp.Body as MemberExpression; if (me == null) return "na"; MemberInfo m = me.Member; return m.DeclaringType.FullName + "." + m.Name; }
At this point we are able to figure out the name of the property being accessed! If you take a deeper look into me.Member we will see that it is a PropertyInfo instance where you can get a lot more information about the property.
In the next post I'll dig a little bit deeper and investigate how we can select a field based on the property being accessed ;)
Thoughts?
Adriano
May 10, 2008
Linq Console Update
May 1, 2008
Type safe / refactor friendly configuration for Db4o
- SODA queries
- Configuration
See the sample bellow:
IConfiguration cfg = Db4oFactory.NewConfiguration(); cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;IMHO, using strings in these situations is sub-optimal as:
- Such solution relies in internal class details (field names)
- Compiler can't check whenever the field actually exists.
- We don't take advantage of modern IDE's refactorings so, chances are that these entities and references to them get out of sync breaking your code; it's even worst because you will figure it out only at runtime :(; it may even get unnoticed as Db4o is completely happy with some invalid field names.
I do believe that this approach was chosen due to technical limitations at the time the code was written, but now, with the debut of C# 3.0 and its new features like extension methods, lambda expressions, expression trees, etc. I bet we can do better :).
To be fair, we've already been improving (removing) some string usages, for instance, Linq / Native Queries uses strong typing instead of strings to reference fields (under the hood they generate SODA queries that still use strings, but the crux here is that these "names" will always be in sync with its entities).One area that, in my opinion, can be improved is configuration. For instance, in order to setup indexes, deletion behavior (when to cascade delete), etc. we still use strings to identify the field we want to apply the configuration. Suppose we have the following code to configure indexes:
IConfiguration cfg = Db4oFactory.NewConfiguration(); cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;We could introduce new methods to IConfiguration interface so one would be able to do something like this:
IConfiguration cfg = Db4oFactory.NewConfiguration(); cfg.ObjectField((Test s) => s.Age).Indexed = true;
Wow! Using this syntax we no longer have issues with refactorings, abusive internal class knowledge and we get compiler time support for free :) (for instance, if we mistype "s.Afe" C# compiler will complain).
To be fair, we have some issues with refactorings. If we change field/class's name we need to inform Db4o about this changes as explained here (I do have some ideas on how to express these calls also but this is a little bit more complex topic that I won't cover here).What do you think?
In a following post I'll discuss how we could implement this new configuration method. Go to part II of this post. Adriano